/** Convert a jsval to a string and store it in struct bookmark. * * @param ctx * Context for memory allocations and error reports. * @param val * The @c jsval that should be converted. * @param[in,out] result * A string allocated with mem_alloc(). * On success, this function frees the original string, if any. * * @return JS_TRUE if successful. On error, report the error to * SpiderMonkey and return JS_FALSE. */ static JSBool jsval_to_bookmark_string(JSContext *ctx, jsid id, unsigned char **result) { JSString *jsstr = NULL; unsigned char *str; jsval val; /* jsstring_to_utf8() might GC; protect the string to come. */ if (!JS_AddNamedStringRoot(ctx, &jsstr, "jsval_to_bookmark_string")) return JS_FALSE; if (JS_TRUE != JS_IdToValue(ctx, id, &val)) { JS_RemoveStringRoot(ctx, &jsstr); return JS_FALSE; } jsstr = JS_ValueToString(ctx, val); if (jsstr == NULL) { JS_RemoveStringRoot(ctx, &jsstr); return JS_FALSE; } str = jsstring_to_utf8(ctx, jsstr, NULL); if (str == NULL) { JS_RemoveStringRoot(ctx, &jsstr); return JS_FALSE; } JS_RemoveStringRoot(ctx, &jsstr); mem_free_set(result, str); return JS_TRUE; }
void jsd_RefreshValue(JSDContext* jsdc, JSDValue* jsdval) { JSContext* cx = jsdc->dumbContext; JSCrossCompartmentCall *call = NULL; if(jsdval->string) { /* if the jsval is a string, then we didn't need to root the string */ if(!JSVAL_IS_STRING(jsdval->val)) { JS_BeginRequest(cx); call = JS_EnterCrossCompartmentCall(cx, jsdc->glob); if(!call) { JS_EndRequest(cx); return; } JS_RemoveStringRoot(cx, &jsdval->string); JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); } jsdval->string = NULL; } jsdval->funName = NULL; jsdval->className = NULL; DROP_CLEAR_VALUE(jsdc, jsdval->proto); DROP_CLEAR_VALUE(jsdc, jsdval->parent); DROP_CLEAR_VALUE(jsdc, jsdval->ctor); _freeProps(jsdc, jsdval); jsdval->flags = 0; }