Exemplo n.º 1
0
JSString*
jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JSExceptionState* exceptionState;
    JSCompartment* oldCompartment = NULL;
    jsval stringval;
    JS::RootedString string(cx);
    JS::RootedObject scopeObj(cx);

    if(jsdval->string)
        return jsdval->string;

    /* Reuse the string without copying or re-rooting it */
    if(JSVAL_IS_STRING(jsdval->val)) {
        jsdval->string = JSVAL_TO_STRING(jsdval->val);
        return jsdval->string;
    }

    JS_BeginRequest(cx);

    /* Objects call JS_ValueToString in their own compartment. */
    scopeObj = !JSVAL_IS_PRIMITIVE(jsdval->val) ? JSVAL_TO_OBJECT(jsdval->val) : jsdc->glob;
    oldCompartment = JS_EnterCompartment(cx, scopeObj);
    exceptionState = JS_SaveExceptionState(cx);

    string = JS_ValueToString(cx, jsdval->val);

    JS_RestoreExceptionState(cx, exceptionState);
    JS_LeaveCompartment(cx, oldCompartment);
    oldCompartment = NULL;

    if(string) {
        stringval = STRING_TO_JSVAL(string);
        oldCompartment = JS_EnterCompartment(cx, jsdc->glob);
    }
    if(!string || !JS_WrapValue(cx, &stringval)) {
        if(oldCompartment)
            JS_LeaveCompartment(cx, oldCompartment);
        JS_EndRequest(cx);
        return NULL;
    }

    jsdval->string = JSVAL_TO_STRING(stringval);
    if(!JS_AddNamedStringRoot(cx, &jsdval->string, "ValueString"))
        jsdval->string = NULL;

    JS_LeaveCompartment(cx, oldCompartment);
    JS_EndRequest(cx);

    return jsdval->string;
}
Exemplo n.º 2
0
JSDValue*
jsd_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval)
{
    JSCompartment* oldCompartment = NULL;
    JSContext* cx = jsdc->dumbContext;

    if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_CTOR)))
    {
        JS::RootedObject obj(cx);
        JS::RootedObject proto(cx);
        JS::RootedObject ctor(cx);
        JS_ASSERT(!jsdval->ctor);
        SET_BIT_FLAG(jsdval->flags, GOT_CTOR);
        if(JSVAL_IS_PRIMITIVE(jsdval->val))
            return NULL;
        obj = JSVAL_TO_OBJECT(jsdval->val);
        if(!JS_GetPrototype(cx, obj, proto.address()))
            return NULL;
        if(!proto)
            return NULL;
        JS_BeginRequest(jsdc->dumbContext);
        oldCompartment = JS_EnterCompartment(jsdc->dumbContext, obj);
        ctor = JS_GetConstructor(jsdc->dumbContext,proto);
        JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);
        JS_EndRequest(jsdc->dumbContext);
        if(!ctor)
            return NULL;
        jsdval->ctor = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(ctor));
    }
    if(jsdval->ctor)
        jsdval->ctor->nref++;
    return jsdval->ctor;
}
Exemplo n.º 3
0
void
jsd_RefreshValue(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JSCompartment* oldCompartment = 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);
            oldCompartment = JS_EnterCompartment(cx, jsdc->glob);
            JS_RemoveStringRoot(cx, &jsdval->string);
            JS_LeaveCompartment(cx, oldCompartment);
            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;
}
Exemplo n.º 4
0
ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime) :
	m_runtime(runtime), m_glob(runtime->m_rt), m_nativeScope(runtime->m_rt)
{
	bool ok;

	m_cx = JS_NewContext(m_runtime->m_rt, STACK_CHUNK_SIZE);
	ENSURE(m_cx);

	JS_SetParallelIonCompilationEnabled(m_runtime->m_rt, true);

	// For GC debugging:
	// JS_SetGCZeal(m_cx, 2);

	JS_SetContextPrivate(m_cx, NULL);

	JS_SetErrorReporter(m_cx, ErrorReporter);

	JS_SetGlobalJitCompilerOption(m_runtime->m_rt, JSJITCOMPILER_ION_ENABLE, 1);
	JS_SetGlobalJitCompilerOption(m_runtime->m_rt, JSJITCOMPILER_BASELINE_ENABLE, 1);

	JS::ContextOptionsRef(m_cx).setExtraWarnings(1)
		.setWerror(0)
		.setVarObjFix(1)
		.setStrictMode(1);

	JS::CompartmentOptions opt;
	opt.setVersion(JSVERSION_LATEST);

	JSAutoRequest rq(m_cx);
	JS::RootedObject globalRootedVal(m_cx, JS_NewGlobalObject(m_cx, &global_class, NULL, JS::OnNewGlobalHookOption::FireOnNewGlobalHook, opt));
	m_comp = JS_EnterCompartment(m_cx, globalRootedVal);
	ok = JS_InitStandardClasses(m_cx, globalRootedVal);
	ENSURE(ok);
	m_glob = globalRootedVal.get();

	// Use the testing functions to globally enable gcPreserveCode. This brings quite a 
	// big performance improvement. In future SpiderMonkey versions, we should probably 
	// use the functions implemented here: https://bugzilla.mozilla.org/show_bug.cgi?id=1068697
	JS::RootedObject testingFunctionsObj(m_cx, js::GetTestingFunctions(m_cx));
	ENSURE(testingFunctionsObj);
	JS::RootedValue ret(m_cx);
	JS_CallFunctionName(m_cx, testingFunctionsObj, "gcPreserveCode", JS::HandleValueArray::empty(), &ret);

	JS_DefineProperty(m_cx, m_glob, "global", globalRootedVal, JSPROP_ENUMERATE | JSPROP_READONLY
			| JSPROP_PERMANENT);

	m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
			| JSPROP_PERMANENT);

	JS_DefineFunction(m_cx, globalRootedVal, "print", ::print,        0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "log",   ::logmsg,       1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "warn",  ::warn,         1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "error", ::error,        1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "deepcopy", ::deepcopy,  1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);

	Register("ProfileStart", ::ProfileStart, 1);
	Register("ProfileStop", ::ProfileStop, 0);

	runtime->RegisterContext(m_cx);
}
Exemplo n.º 5
0
JSDScript*
jsd_GetScriptForValue(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JS::RootedValue val(cx, jsdval->val);
    JSFunction* fun = NULL;
    JSExceptionState* exceptionState;
    JS::RootedScript script(cx);
    JSDScript* jsdscript;
    JSCompartment* oldCompartment = NULL;

    if (!jsd_IsValueFunction(jsdc, jsdval))
        return NULL;

    JS_BeginRequest(cx);
    oldCompartment = JS_EnterCompartment(cx, JSVAL_TO_OBJECT(val));
    exceptionState = JS_SaveExceptionState(cx);
    fun = JSD_GetValueFunction(jsdc, jsdval);
    JS_RestoreExceptionState(cx, exceptionState);
    if (fun)
        script = JS_GetFunctionScript(cx, fun);
    JS_LeaveCompartment(cx, oldCompartment);
    JS_EndRequest(cx);

    if (!script)
        return NULL;

    JSD_LOCK_SCRIPTS(jsdc);
    jsdscript = jsd_FindJSDScript(jsdc, script);
    JSD_UNLOCK_SCRIPTS(jsdc);
    return jsdscript;
}
Exemplo n.º 6
0
JSString*
jsd_GetValueFunctionId(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JS::RootedFunction fun(cx);
    JSExceptionState* exceptionState;
    JSCompartment* oldCompartment = NULL;

    if(!jsdval->funName && jsd_IsValueFunction(jsdc, jsdval))
    {
        JS_BeginRequest(cx);

        oldCompartment = JS_EnterCompartment(jsdc->dumbContext, JSVAL_TO_OBJECT(jsdval->val));
        exceptionState = JS_SaveExceptionState(cx);
        fun = JSD_GetValueFunction(jsdc, jsdval);
        JS_RestoreExceptionState(cx, exceptionState);
        JS_LeaveCompartment(cx, oldCompartment);
        JS_EndRequest(cx);
        if(!fun)
            return NULL;
        jsdval->funName = JS_GetFunctionId(fun);

        /* For compatibility we return "anonymous", not an empty string here. */
        if (!jsdval->funName)
            jsdval->funName = JS_GetAnonymousString(jsdc->jsrt);
    }
    return jsdval->funName;
}
Exemplo n.º 7
0
static void
gjstest_test_func_gjs_jsapi_util_string_js_string_utf8(void)
{
    GjsUnitTestFixture fixture;
    JSContext *context;
    JSObject *global;

    const char *utf8_string = "\303\211\303\226 foobar \343\203\237";
    char *utf8_result;
    jsval js_string;

    _gjs_unit_test_fixture_begin(&fixture);
    context = fixture.context;
    global = JS_GetGlobalObject(context);
    JSCompartment *oldCompartment = JS_EnterCompartment(context, global);

    g_assert(gjs_string_from_utf8(context, utf8_string, -1, &js_string) == JS_TRUE);
    g_assert(JSVAL_IS_STRING(js_string));
    g_assert(gjs_string_to_utf8(context, js_string, &utf8_result) == JS_TRUE);

    JS_LeaveCompartment(context, oldCompartment);
    _gjs_unit_test_fixture_finish(&fixture);

    g_assert(g_str_equal(utf8_string, utf8_result));

    g_free(utf8_result);
}
Exemplo n.º 8
0
JSBool
jsd_IsValueNative(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JS::RootedFunction fun(cx);
    JSExceptionState* exceptionState;
    JSCompartment* oldCompartment = NULL;

    if(jsd_IsValueFunction(jsdc, jsdval))
    {
        JSBool ok = JS_FALSE;
        JS_BeginRequest(cx);
        oldCompartment = JS_EnterCompartment(cx, JSVAL_TO_OBJECT(jsdval->val));
        exceptionState = JS_SaveExceptionState(cx);
        fun = JSD_GetValueFunction(jsdc, jsdval);
        JS_RestoreExceptionState(cx, exceptionState);
        if(fun)
            ok = JS_GetFunctionScript(cx, fun) ? JS_FALSE : JS_TRUE;
        JS_LeaveCompartment(cx, oldCompartment);
        JS_EndRequest(cx);
        JS_ASSERT(fun);
        return ok;
    }
    return !JSVAL_IS_PRIMITIVE(jsdval->val);
}
Exemplo n.º 9
0
JSDValue*
jsd_GetValueParent(JSDContext* jsdc, JSDValue* jsdval)
{
    JSCompartment* oldCompartment = NULL;

    if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PARENT)))
    {
        JSContext* cx = jsdc->dumbContext;

        JS::RootedObject obj(cx);
        JS::RootedObject parent(cx);
        JS_ASSERT(!jsdval->parent);
        SET_BIT_FLAG(jsdval->flags, GOT_PARENT);
        if(JSVAL_IS_PRIMITIVE(jsdval->val))
            return NULL;
        obj = JSVAL_TO_OBJECT(jsdval->val);
        JS_BeginRequest(jsdc->dumbContext);
        oldCompartment = JS_EnterCompartment(jsdc->dumbContext, obj);
        parent = JS_GetParentOrScopeChain(jsdc->dumbContext,obj);
        JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);
        JS_EndRequest(jsdc->dumbContext);
        if(!parent)
            return NULL;
        jsdval->parent = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(parent));
    }
    if(jsdval->parent)
        jsdval->parent->nref++;
    return jsdval->parent;
}
Exemplo n.º 10
0
ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime) :
	m_runtime(runtime), m_glob(runtime->m_rt), m_nativeScope(runtime->m_rt)
{
	bool ok;

	m_cx = JS_NewContext(m_runtime->m_rt, STACK_CHUNK_SIZE);
	ENSURE(m_cx);

	JS_SetOffthreadIonCompilationEnabled(m_runtime->m_rt, true);

	// For GC debugging:
	// JS_SetGCZeal(m_cx, 2, JS_DEFAULT_ZEAL_FREQ);

	JS_SetContextPrivate(m_cx, NULL);

	JS_SetErrorReporter(m_runtime->m_rt, ErrorReporter);

	JS_SetGlobalJitCompilerOption(m_runtime->m_rt, JSJITCOMPILER_ION_ENABLE, 1);
	JS_SetGlobalJitCompilerOption(m_runtime->m_rt, JSJITCOMPILER_BASELINE_ENABLE, 1);

	JS::RuntimeOptionsRef(m_cx).setExtraWarnings(1)
		.setWerror(0)
		.setVarObjFix(1)
		.setStrictMode(1);

	JS::CompartmentOptions opt;
	opt.setVersion(JSVERSION_LATEST);
	// Keep JIT code during non-shrinking GCs. This brings a quite big performance improvement.
	opt.setPreserveJitCode(true);

	JSAutoRequest rq(m_cx);
	JS::RootedObject globalRootedVal(m_cx, JS_NewGlobalObject(m_cx, &global_class, NULL, JS::OnNewGlobalHookOption::FireOnNewGlobalHook, opt));
	m_comp = JS_EnterCompartment(m_cx, globalRootedVal);
	ok = JS_InitStandardClasses(m_cx, globalRootedVal);
	ENSURE(ok);
	m_glob = globalRootedVal.get();

	JS_DefineProperty(m_cx, m_glob, "global", globalRootedVal, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);

	m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);

	JS_DefineFunction(m_cx, globalRootedVal, "print", ::print,        0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "log",   ::logmsg,       1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "warn",  ::warn,         1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "error", ::error,        1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "deepcopy", ::deepcopy,  1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);

	Register("ProfileStart", ::ProfileStart, 1);
	Register("ProfileStop", ::ProfileStop, 0);
	Register("ProfileAttribute", ::ProfileAttribute, 1);

	runtime->RegisterContext(m_cx);
}
Exemplo n.º 11
0
bool JSAPITest::init()
{
    rt = createRuntime();
    if (!rt)
        return false;
    cx = createContext();
    if (!cx)
        return false;
    JS_BeginRequest(cx);
    JS::RootedObject global(cx, createGlobal());
    if (!global)
        return false;
    JS_EnterCompartment(cx, global);
    return true;
}
Exemplo n.º 12
0
/*
 * Retrieve a JSFunction* from a JSDValue*. This differs from
 * JS_ValueToFunction by fully unwrapping the object first.
 */
JSFunction*
jsd_GetValueFunction(JSDContext* jsdc, JSDValue* jsdval)
{
    JSObject *obj;
    JSFunction *fun;

    JSCompartment* oldCompartment = NULL;
    if (JSVAL_IS_PRIMITIVE(jsdval->val))
        return NULL;

    obj = JS_UnwrapObject(JSVAL_TO_OBJECT(jsdval->val));
    oldCompartment = JS_EnterCompartment(jsdc->dumbContext, obj);
    fun = JS_ValueToFunction(jsdc->dumbContext, OBJECT_TO_JSVAL(obj));
    JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);

    return fun;
}
Exemplo n.º 13
0
const char*
jsd_GetValueClassName(JSDContext* jsdc, JSDValue* jsdval)
{
    jsval val = jsdval->val;
    JSCompartment* oldCompartment = NULL;

    if(!jsdval->className && !JSVAL_IS_PRIMITIVE(val))
    {
        JSObject* obj = JSVAL_TO_OBJECT(val);
        JS_BeginRequest(jsdc->dumbContext);
        oldCompartment = JS_EnterCompartment(jsdc->dumbContext, obj);
        jsdval->className = JS_GetDebugClassName(obj);
        JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);
        JS_EndRequest(jsdc->dumbContext);
    }
    return jsdval->className;
}
Exemplo n.º 14
0
bool JSAPITest::init()
{
    rt = createRuntime();
    if (!rt)
        return false;
    cx = createContext();
    if (!cx)
        return false;
#ifdef JS_GC_ZEAL
    JS_SetGCZeal(cx, 0, 0);
#endif
    JS_BeginRequest(cx);
    js::RootedObject global(cx, createGlobal());
    if (!global)
        return false;
    oldCompartment = JS_EnterCompartment(cx, global);
    return oldCompartment != NULL;
}
Exemplo n.º 15
0
/*
 * Retrieve a JSFunction* from a JSDValue*. This differs from
 * JS_ValueToFunction by fully unwrapping the object first.
 */
JSFunction*
jsd_GetValueFunction(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;

    JS::RootedObject obj(cx);
    JS::RootedFunction fun(cx);

    JSCompartment* oldCompartment = NULL;
    if (JSVAL_IS_PRIMITIVE(jsdval->val))
        return NULL;

    obj = js::UncheckedUnwrap(JSVAL_TO_OBJECT(jsdval->val));
    oldCompartment = JS_EnterCompartment(cx, obj);
    fun = JS_ValueToFunction(cx, OBJECT_TO_JSVAL(obj));
    JS_LeaveCompartment(cx, oldCompartment);

    return fun;
}
Exemplo n.º 16
0
static JSBool _buildProps(JSDContext* jsdc, JSDValue* jsdval)
{
    JSContext* cx = jsdc->dumbContext;
    JS::RootedObject obj(cx);
    JSPropertyDescArray pda;
    unsigned i;
    JSCompartment* oldCompartment = NULL;

    JS_ASSERT(JS_CLIST_IS_EMPTY(&jsdval->props));
    JS_ASSERT(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROPS)));
    JS_ASSERT(!JSVAL_IS_PRIMITIVE(jsdval->val));

    if(JSVAL_IS_PRIMITIVE(jsdval->val))
        return JS_FALSE;

    obj = JSVAL_TO_OBJECT(jsdval->val);

    JS_BeginRequest(cx);
    oldCompartment = JS_EnterCompartment(jsdc->dumbContext, obj);

    if(!JS_GetPropertyDescArray(cx, obj, &pda))
    {
        JS_EndRequest(cx);
        JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);
        return JS_FALSE;
    }

    for(i = 0; i < pda.length; i++)
    {
        JSDProperty* prop = _newProperty(jsdc, &pda.array[i], 0);
        if(!prop)
        {
            _freeProps(jsdc, jsdval);
            break;
        }
        JS_APPEND_LINK(&prop->links, &jsdval->props);
    }
    JS_PutPropertyDescArray(cx, &pda);
    JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);
    JS_EndRequest(cx);
    SET_BIT_FLAG(jsdval->flags, GOT_PROPS);
    return !JS_CLIST_IS_EMPTY(&jsdval->props);
}
Exemplo n.º 17
0
void
jsd_DropValue(JSDContext* jsdc, JSDValue* jsdval)
{
    JSCompartment* oldCompartment = NULL;

    JS_ASSERT(jsdval->nref > 0);
    if(0 == --jsdval->nref)
    {
        jsd_RefreshValue(jsdc, jsdval);
        if(JSVAL_IS_GCTHING(jsdval->val))
        {
            JS_BeginRequest(jsdc->dumbContext);
            oldCompartment = JS_EnterCompartment(jsdc->dumbContext, jsdc->glob);
            JS_RemoveValueRoot(jsdc->dumbContext, &jsdval->val);
            JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);
            JS_EndRequest(jsdc->dumbContext);
        }
        free(jsdval);
    }
}
Exemplo n.º 18
0
static void
gjstest_test_func_gjs_jsapi_util_array(void)
{
    GjsUnitTestFixture fixture;
    JSContext *context;
    JSObject *global;
    GjsRootedArray *array;
    int i;
    jsval value;

    _gjs_unit_test_fixture_begin(&fixture);
    context = fixture.context;

    array = gjs_rooted_array_new();

    global = JS_GetGlobalObject(context);
    JSCompartment *oldCompartment = JS_EnterCompartment(context, global);

    for (i = 0; i < N_ELEMS; i++) {
        value = STRING_TO_JSVAL(JS_NewStringCopyZ(context, "abcdefghijk"));
        gjs_rooted_array_append(context, array, value);
    }

    JS_GC(JS_GetRuntime(context));

    for (i = 0; i < N_ELEMS; i++) {
        char *ascii;

        value = gjs_rooted_array_get(context, array, i);
        g_assert(JSVAL_IS_STRING(value));
        gjs_string_to_utf8(context, value, &ascii);
        g_assert(strcmp(ascii, "abcdefghijk") == 0);
        g_free(ascii);
    }

    gjs_rooted_array_free(context, array, TRUE);

    JS_LeaveCompartment(context, oldCompartment);
    _gjs_unit_test_fixture_finish(&fixture);
}
Exemplo n.º 19
0
/*
 * Create a new JSD value referring to a jsval. Copy string values into the
 * JSD compartment. Leave all other GCTHINGs in their native compartments
 * and access them through cross-compartment calls.
 */
JSDValue*
jsd_NewValue(JSDContext* jsdc, jsval value)
{
    JS::RootedValue val(jsdc->dumbContext, value);
    JSDValue* jsdval;
    JSCompartment* oldCompartment = NULL;

    if(!(jsdval = (JSDValue*) calloc(1, sizeof(JSDValue))))
        return NULL;

    if(JSVAL_IS_GCTHING(val))
    {
        JSBool ok;
        JS_BeginRequest(jsdc->dumbContext);

        oldCompartment = JS_EnterCompartment(jsdc->dumbContext, jsdc->glob);

        ok = JS_AddNamedValueRoot(jsdc->dumbContext, &jsdval->val, "JSDValue");
        if(ok && JSVAL_IS_STRING(val)) {
            if(!JS_WrapValue(jsdc->dumbContext, val.address())) {
                ok = JS_FALSE;
            }
        }

        JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);
        JS_EndRequest(jsdc->dumbContext);
        if(!ok)
        {
            free(jsdval);
            return NULL;
        }
    }
    jsdval->val  = val;
    jsdval->nref = 1;
    JS_INIT_CLIST(&jsdval->props);

    return jsdval;
}
Exemplo n.º 20
0
static void
gjstest_test_func_gjs_jsapi_util_error_throw(void)
{
    GjsUnitTestFixture fixture;
    JSContext *context;
    JSObject *global;
    jsval exc, value, previous;
    char *s = NULL;
    int strcmp_result;

    _gjs_unit_test_fixture_begin(&fixture);
    context = fixture.context;
    global = JS_GetGlobalObject(context);
    JSCompartment *oldCompartment = JS_EnterCompartment(context, global);
    /* Test that we can throw */

    gjs_throw(context, "This is an exception %d", 42);

    g_assert(JS_IsExceptionPending(context));

    exc = JSVAL_VOID;
    JS_GetPendingException(context, &exc);
    g_assert(!JSVAL_IS_VOID(exc));

    value = JSVAL_VOID;
    JS_GetProperty(context, JSVAL_TO_OBJECT(exc), "message",
                   &value);

    g_assert(JSVAL_IS_STRING(value));

    gjs_string_to_utf8(context, value, &s);
    g_assert(s != NULL);
    strcmp_result = strcmp(s, "This is an exception 42");
    free(s);
    if (strcmp_result != 0)
        g_error("Exception has wrong message '%s'", s);

    /* keep this around before we clear it */
    previous = exc;
    JS_AddValueRoot(context, &previous);

    JS_ClearPendingException(context);

    g_assert(!JS_IsExceptionPending(context));

    /* Check that we don't overwrite a pending exception */
    JS_SetPendingException(context, previous);

    g_assert(JS_IsExceptionPending(context));

    gjs_throw(context, "Second different exception %s", "foo");

    g_assert(JS_IsExceptionPending(context));

    exc = JSVAL_VOID;
    JS_GetPendingException(context, &exc);
    g_assert(!JSVAL_IS_VOID(exc));
    g_assert(JSVAL_TO_OBJECT(exc) == JSVAL_TO_OBJECT(previous));

    JS_RemoveValueRoot(context, &previous);

    JS_LeaveCompartment(context, oldCompartment);
    _gjs_unit_test_fixture_finish(&fixture);
}
Exemplo n.º 21
0
JSDProperty*
jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr)
{
    JSContext* cx = jsdc->dumbContext;
    JSDProperty* jsdprop;
    JSDProperty* iter = NULL;
    JS::RootedObject obj(cx);
    JS::RootedString name(cx, nameStr);
    unsigned  attrs = 0;
    JSBool found;
    JSPropertyDesc pd;
    const jschar * nameChars;
    size_t nameLen;
    JS::RootedValue val(cx), nameval(cx);
    JS::RootedId nameid(cx);
    JSCompartment* oldCompartment = NULL;

    if(!jsd_IsValueObject(jsdc, jsdval))
        return NULL;

    /* If we already have the prop, then return it */
    while(NULL != (jsdprop = jsd_IterateProperties(jsdc, jsdval, &iter)))
    {
        JSString* propName = jsd_GetValueString(jsdc, jsdprop->name);
        if(propName) {
            int result;
            if (JS_CompareStrings(cx, propName, name, &result) && !result)
                return jsdprop;
        }
        JSD_DropProperty(jsdc, jsdprop);
    }
    /* Not found in property list, look it up explicitly */

    if(!(obj = JSVAL_TO_OBJECT(jsdval->val)))
        return NULL;

    if (!(nameChars = JS_GetStringCharsZAndLength(cx, name, &nameLen)))
        return NULL;

    JS_BeginRequest(cx);
    oldCompartment = JS_EnterCompartment(cx, obj);

    JS_GetUCPropertyAttributes(cx, obj, nameChars, nameLen, &attrs, &found);
    if (!found)
    {
        JS_LeaveCompartment(cx, oldCompartment);
        JS_EndRequest(cx);
        return NULL;
    }

    JS_ClearPendingException(cx);

    if(!JS_GetUCProperty(cx, obj, nameChars, nameLen, val.address()))
    {
        if (JS_IsExceptionPending(cx))
        {
            if (!JS_GetPendingException(cx, &pd.value))
            {
                JS_LeaveCompartment(cx, oldCompartment);
                JS_EndRequest(cx);
                return NULL;
            }
            pd.flags = JSPD_EXCEPTION;
        }
        else
        {
            pd.flags = JSPD_ERROR;
            pd.value = JSVAL_VOID;
        }
    }
    else
    {
        pd.value = val;
    }

    JS_LeaveCompartment(cx, oldCompartment);
    JS_EndRequest(cx);

    nameval = STRING_TO_JSVAL(name);
    if (!JS_ValueToId(cx, nameval, nameid.address()) ||
        !JS_IdToValue(cx, nameid, &pd.id)) {
        return NULL;
    }

    pd.spare = 0;
    pd.alias = JSVAL_NULL;
    pd.flags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0
        | (attrs & JSPROP_READONLY)  ? JSPD_READONLY  : 0
        | (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0;

    return _newProperty(jsdc, &pd, JSDPD_HINTED);
}
Exemplo n.º 22
0
char* launchApp(char *appName,int isMenu){
	static int nruns = 0;
	char* tmp = NULL,*script = NULL, *addrBack = NULL;
	if(appName){
		static JSContext *cx = NULL;
		static JSObject *gl = NULL;
		script = fileToString(LIBRARY);
		if(!(cx = JS_NewContext(runtime, 8192))){
			fprint(stderr,"Problem creating runtime\n");
			exit(EXIT_FAILURE);
		}
		JS_SetErrorReporter(cx, reportError);
		//if(!(gl = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL))){
		
		static struct JSPrincipals def_principles = {0};
		if(!(gl = JS_NewGlobalObject(cx, &global_class, NULL))){
			fprint(stderr,"Problem creating global object\n");
			exit(EXIT_FAILURE);
		}
		JSCompartment *cmp = JS_EnterCompartment(cx, gl);
		
		if (!(JS_InitStandardClasses(cx, gl))){
			fprint(stderr,"Problem creating standard classes\n");
			exit(EXIT_FAILURE);
		}
		if(!JS_DefineFunctions(cx, gl, jsFunctions)){
			fprint(stderr,"Unable to load native functions\n");
			exit(EXIT_FAILURE);
		}
		globalObject = gl;
		char *pathToFile = NULL;
		if(isMenu){
			pathToFile = (char*)malloc(1+strlen(MENU_DIR));
			strcpy(pathToFile,MENU_DIR);
		} else {
			pathToFile = (char*)malloc(strlen(appName) + 1 + strlen(GAMES_DIR));
			strcpy(pathToFile,GAMES_DIR);
			strcat(pathToFile,appName);
			//strcat(pathToFile,"/");
		}
		
		
		JSBool ran = JS_FALSE;
		jsval retVal;
		
		obj.chrootPath = pathToFile;
		
		JS_SetPrivate(cx,gl,&obj);
		
		SDL_FlushEvents(); //clear queue of events before starting a new app.
		if(isMenu && 0 == nruns) {
			//define the property first_run = true;
			JS_DefineProperty(cx,JS_GetGlobalObject(cx),"first_run",BOOLEAN_TO_JSVAL(JS_TRUE),NULL,NULL,0);
		}
		
		if(script){
			loadBaseClasses(appName,pathToFile,cx); //appName is without the extension, appPath needs the directory to chroot
			ran = JS_EvaluateScript(cx, gl, script, strlen(script) , LIBRARY,0, &retVal);
		}
		nruns++;
		
		clearModules(cx);
		JS_GC(JS_GetRuntime(cx));
		JS_LeaveCompartment(cx,cmp);
		//The user requested to quit.
		if(SDL_QuitRequested()){
			if(script)free(script);
			exitProgram(cx);
			exit(EXIT_SUCCESS);
		}

		if(isMenu && (ran == JS_FALSE)){
			if(script) free(script);
			exitProgram(cx);
			exit(EXIT_FAILURE);
		}
		if(ran != JS_FALSE){
			if(JSVAL_IS_STRING(retVal)){
				addrBack = JS_EncodeString(cx,JSVAL_TO_STRING(retVal));
				tmp = (char*)malloc(strlen(addrBack) +1);
				strcpy(tmp,addrBack);
				JS_free(cx,addrBack);
				addrBack = tmp;
			} 
			if(JSVAL_IS_BOOLEAN(retVal) && isMenu){
				if(script) free(script);
				if(pathToFile) free(pathToFile);
				exitProgram(cx);
				exit(EXIT_SUCCESS);
			}
		} else {
			addrBack = NULL;
		}
		if(script) free(script);
		if(pathToFile) free(pathToFile);
		JS_DestroyContext(cx);
		return addrBack;
	}
}
Exemplo n.º 23
0
static JSDContext*
_newJSDContext(JSRuntime*         jsrt, 
               JSD_UserCallbacks* callbacks, 
               void*              user,
               JSObject*          scopeobj)
{
    JSDContext* jsdc = NULL;
    JSCompartment *oldCompartment = NULL;
    JSBool ok;

    if( ! jsrt )
        return NULL;

    if( ! _validateUserCallbacks(callbacks) )
        return NULL;

    jsdc = (JSDContext*) calloc(1, sizeof(JSDContext));
    if( ! jsdc )
        goto label_newJSDContext_failure;

    if( ! JSD_INIT_LOCKS(jsdc) )
        goto label_newJSDContext_failure;

    JS_INIT_CLIST(&jsdc->links);

    jsdc->jsrt = jsrt;

    if( callbacks )
        memcpy(&jsdc->userCallbacks, callbacks, callbacks->size);
    
    jsdc->user = user;

#ifdef JSD_HAS_DANGEROUS_THREAD
    jsdc->dangerousThread = _dangerousThread;
#endif

    JS_INIT_CLIST(&jsdc->threadsStates);
    JS_INIT_CLIST(&jsdc->sources);
    JS_INIT_CLIST(&jsdc->removedSources);

    jsdc->sourceAlterCount = 1;

    if( ! jsd_CreateAtomTable(jsdc) )
        goto label_newJSDContext_failure;

    if( ! jsd_InitObjectManager(jsdc) )
        goto label_newJSDContext_failure;

    if( ! jsd_InitScriptManager(jsdc) )
        goto label_newJSDContext_failure;

    jsdc->dumbContext = JS_NewContext(jsdc->jsrt, 256);
    if( ! jsdc->dumbContext )
        goto label_newJSDContext_failure;

    JS_BeginRequest(jsdc->dumbContext);
    JS_SetOptions(jsdc->dumbContext, JS_GetOptions(jsdc->dumbContext));

    jsdc->glob = JS_NewGlobalObject(jsdc->dumbContext, &global_class, NULL);

    if( ! jsdc->glob )
        goto label_newJSDContext_failure;

    oldCompartment = JS_EnterCompartment(jsdc->dumbContext, jsdc->glob);

    if ( ! JS_AddNamedObjectRoot(jsdc->dumbContext, &jsdc->glob, "JSD context global") )
        goto label_newJSDContext_failure;

    ok = JS_InitStandardClasses(jsdc->dumbContext, jsdc->glob);

    JS_LeaveCompartment(jsdc->dumbContext, oldCompartment);
    if( ! ok )
        goto label_newJSDContext_failure;

    JS_EndRequest(jsdc->dumbContext);

    jsdc->data = NULL;
    jsdc->inited = JS_TRUE;

    JSD_LOCK();
    JS_INSERT_LINK(&jsdc->links, &_jsd_context_list);
    JSD_UNLOCK();

    return jsdc;

label_newJSDContext_failure:
    if( jsdc ) {
        if ( jsdc->dumbContext && jsdc->glob )
            JS_RemoveObjectRootRT(JS_GetRuntime(jsdc->dumbContext), &jsdc->glob);
        jsd_DestroyObjectManager(jsdc);
        jsd_DestroyAtomTable(jsdc);
        if( jsdc->dumbContext )
            JS_EndRequest(jsdc->dumbContext);
        free(jsdc);
    }
    return NULL;
}