void sm_stop(spidermonkey_vm *vm) { begin_request(vm); spidermonkey_state *state = (spidermonkey_state *) JS_GetContextPrivate(vm->context); state->terminate = 1; JS_SetContextPrivate(vm->context, state); //Wait for any executing function to stop //before beginning to free up any memory. while (JS_IsRunning(vm->context)) { sleep(1); } end_request(vm); //Now we should be free to proceed with //freeing up memory without worrying about //crashing the VM. if (state != NULL) { if (state->error != NULL) { free_error(state); } driver_free(state); } JS_SetContextPrivate(vm->context, NULL); JS_DestroyContext(vm->context); JS_DestroyRuntime(vm->runtime); driver_free(vm); }
/* Execute a string in its own context (away from Synchronet objects) */ static JSBool js_eval(JSContext *parent_cx, JSObject *parent_obj, uintN argc, jsval *argv, jsval *rval) { char* buf; size_t buflen; JSString* str; JSScript* script; JSContext* cx; JSObject* obj; JSErrorReporter reporter; #ifndef EVAL_BRANCH_CALLBACK JSBranchCallback callback; #endif if(argc<1) return(JS_TRUE); if((str=JS_ValueToString(parent_cx, argv[0]))==NULL) return(JS_FALSE); if((buf=JS_GetStringBytes(str))==NULL) return(JS_FALSE); buflen=JS_GetStringLength(str); if((cx=JS_NewContext(JS_GetRuntime(parent_cx),JAVASCRIPT_CONTEXT_STACK))==NULL) return(JS_FALSE); /* Use the error reporter from the parent context */ reporter=JS_SetErrorReporter(parent_cx,NULL); JS_SetErrorReporter(parent_cx,reporter); JS_SetErrorReporter(cx,reporter); #ifdef EVAL_BRANCH_CALLBACK JS_SetContextPrivate(cx, JS_GetPrivate(parent_cx, parent_obj)); JS_SetBranchCallback(cx, js_BranchCallback); #else /* Use the branch callback from the parent context */ JS_SetContextPrivate(cx, JS_GetContextPrivate(parent_cx)); callback=JS_SetBranchCallback(parent_cx,NULL); JS_SetBranchCallback(parent_cx, callback); JS_SetBranchCallback(cx, callback); #endif if((obj=JS_NewObject(cx, NULL, NULL, NULL))==NULL || !JS_InitStandardClasses(cx,obj)) { JS_DestroyContext(cx); return(JS_FALSE); } if((script=JS_CompileScript(cx, obj, buf, buflen, NULL, 0))!=NULL) { JS_ExecuteScript(cx, obj, script, rval); JS_DestroyScript(cx, script); } JS_DestroyContext(cx); return(JS_TRUE); }
char *sm_eval(jaegermonkey_vm *vm, const char *filename, const char *code, int handle_retval) { char *retval = NULL; JSScript *script; jsval result; begin_request(vm); script = JS_CompileScript(vm->context, vm->global, code, strlen(code), filename, 1); jaegermonkey_error *error = (jaegermonkey_error *) JS_GetContextPrivate(vm->context); if (error == NULL) { JS_ClearPendingException(vm->context); JS_ExecuteScript(vm->context, vm->global, script, &result); vm->invoke_count++; error = (jaegermonkey_error *) JS_GetContextPrivate(vm->context); if (error == NULL) { if (handle_retval) { if (JSVAL_IS_STRING(result)) { JSString *str = JS_ValueToString(vm->context, result); retval = copy_jsstring(str); } else if(strcmp(JS_GetStringBytes(JS_ValueToString(vm->context, result)), "undefined") == 0) { retval = copy_string("{\"error\": \"Expression returned undefined\", \"lineno\": 0, \"source\": \"unknown\"}"); } else { retval = copy_string("{\"error\": \"non-JSON return value\", \"lineno\": 0, \"source\": \"unknown\"}"); } } JS_DestroyScript(vm->context, script); } else { retval = error_to_json(error); free_error(error); JS_SetContextPrivate(vm->context, NULL); } } else { retval = error_to_json(error); free_error(error); JS_SetContextPrivate(vm->context, NULL); } if (vm->invoke_count > 200) { JS_GC(vm->context); vm->invoke_count = 0; } else { JS_MaybeGC(vm->context); } end_request(vm); return retval; }
char *sm_eval(spidermonkey_vm *vm, const char *filename, const char *code, int handle_retval) { char *retval = NULL; JSObject *script; jsval result; if (code == NULL) { return NULL; } begin_request(vm); script = JS_CompileScript(vm->context, vm->global, code, strlen(code), filename, 1); spidermonkey_state *state = (spidermonkey_state *) JS_GetContextPrivate(vm->context); if (state->error == NULL) { JS_ClearPendingException(vm->context); JS_ExecuteScript(vm->context, vm->global, script, &result); state = (spidermonkey_state *) JS_GetContextPrivate(vm->context); if (state->error == NULL) { if (handle_retval) { if (JSVAL_IS_STRING(result)) { JSString *str = JS_ValueToString(vm->context, result); retval = copy_jsstring(vm->context, str); } else { char *tmp = JS_EncodeString(vm->context, JS_ValueToString(vm->context, result)); if(strcmp(tmp, "undefined") == 0) { retval = copy_string("{\"error\": \"Expression returned undefined\", \"lineno\": 0, \"source\": \"unknown\"}"); } else { retval = copy_string("{\"error\": \"non-JSON return value\", \"lineno\": 0, \"source\": \"unknown\"}"); } JS_free(vm->context, tmp); } } } else { retval = error_to_json(state->error); free_error(state); JS_SetContextPrivate(vm->context, state); } } else { retval = error_to_json(state->error); free_error(state); JS_SetContextPrivate(vm->context, state); } end_request(vm); return retval; }
spidermonkey_vm *sm_initialize(long thread_stack, long heap_size) { spidermonkey_vm *vm = ejs_alloc(sizeof(spidermonkey_vm)); spidermonkey_state *state = ejs_alloc(sizeof(spidermonkey_state)); state->branch_count = 0; state->error = NULL; state->terminate = 0; int gc_size = (int) heap_size * 0.25; vm->runtime = JS_NewRuntime(MAX_GC_SIZE); JS_SetGCParameter(vm->runtime, JSGC_MAX_BYTES, heap_size); JS_SetGCParameter(vm->runtime, JSGC_MAX_MALLOC_BYTES, gc_size); vm->context = JS_NewContext(vm->runtime, 8192); JS_SetScriptStackQuota(vm->context, thread_stack); begin_request(vm); JS_SetOptions(vm->context, JSOPTION_VAROBJFIX); JS_SetOptions(vm->context, JSOPTION_STRICT); JS_SetOptions(vm->context, JSOPTION_COMPILE_N_GO); JS_SetOptions(vm->context, JSVERSION_LATEST); vm->global = JS_NewCompartmentAndGlobalObject(vm->context, &global_class, NULL); JS_InitStandardClasses(vm->context, vm->global); JS_SetErrorReporter(vm->context, on_error); JS_SetOperationCallback(vm->context, on_branch); JS_SetContextPrivate(vm->context, state); JSNative funptr = (JSNative) &js_log; JS_DefineFunction(vm->context, JS_GetGlobalObject(vm->context), "ejsLog", funptr, 0, 0); end_request(vm); return vm; }
/* Create PJS_Context structure */ PJS_Context * PJS_CreateContext(PJS_Runtime *rt) { PJS_Context *pcx; JSObject *obj; Newz(1, pcx, 1, PJS_Context); if (pcx == NULL) { croak("Failed to allocate memory for PJS_Context"); } /* The 'stack size' param here isn't actually the stack size, it's the "chunk size of the stack pool--an obscure memory management tuning knob" http://groups.google.com/group/mozilla.dev.tech.js-engine/browse_thread/thread/be9f404b623acf39 */ pcx->cx = JS_NewContext(rt->rt, 8192); if(pcx->cx == NULL) { Safefree(pcx); croak("Failed to create JSContext"); } JS_SetOptions(pcx->cx, JSOPTION_DONT_REPORT_UNCAUGHT); obj = JS_NewObject(pcx->cx, &global_class, NULL, NULL); if (JS_InitStandardClasses(pcx->cx, obj) == JS_FALSE) { PJS_DestroyContext(pcx); croak("Standard classes not loaded properly."); } pcx->function_by_name = newHV(); pcx->class_by_name = newHV(); pcx->class_by_package = newHV(); if (PJS_InitPerlArrayClass(pcx, obj) == JS_FALSE) { PJS_DestroyContext(pcx); croak("Perl classes not loaded properly."); } if (PJS_InitPerlHashClass(pcx, obj) == JS_FALSE) { PJS_DestroyContext(pcx); croak("Perl classes not loaded properly."); } if (PJS_InitPerlSubClass(pcx, obj) == JS_FALSE) { PJS_DestroyContext(pcx); croak("Perl class 'PerlSub' not loaded properly."); } pcx->rt = rt; /* Add context to context list */ pcx->next = rt->list; rt->list = pcx; JS_SetContextPrivate(pcx->cx, (void *) pcx); return pcx; }
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); }
void SG_jscore__new_context(SG_context * pCtx, JSContext ** pp_cx, JSObject ** pp_glob, const SG_vhash * pServerConfig) { JSContext * cx = NULL; JSObject * glob = NULL; SG_ASSERT(pCtx!=NULL); SG_NULLARGCHECK_RETURN(pp_cx); if(gpJSCoreGlobalState==NULL) SG_ERR_THROW2_RETURN(SG_ERR_UNINITIALIZED, (pCtx, "jscore has not been initialized")); if (gpJSCoreGlobalState->cb) JS_SetContextCallback(gpJSCoreGlobalState->rt, gpJSCoreGlobalState->cb); cx = JS_NewContext(gpJSCoreGlobalState->rt, 8192); if(cx==NULL) SG_ERR_THROW2_RETURN(SG_ERR_MALLOCFAILED, (pCtx, "Failed to allocate new JS context")); (void)JS_SetContextThread(cx); JS_BeginRequest(cx); JS_SetOptions(cx, JSOPTION_VAROBJFIX); JS_SetVersion(cx, JSVERSION_LATEST); JS_SetContextPrivate(cx, pCtx); glob = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); if(glob==NULL) SG_ERR_THROW2(SG_ERR_JS, (pCtx, "Failed to create JavaScript global object for new JSContext.")); if(!JS_InitStandardClasses(cx, glob)) SG_ERR_THROW2(SG_ERR_JS, (pCtx, "JS_InitStandardClasses() failed.")); if (gpJSCoreGlobalState->shell_functions) if (!JS_DefineFunctions(cx, glob, gpJSCoreGlobalState->shell_functions)) SG_ERR_THROW2(SG_ERR_JS, (pCtx, "Failed to install shell functions")); SG_jsglue__set_sg_context(pCtx, cx); SG_ERR_CHECK( SG_jsglue__install_scripting_api(pCtx, cx, glob) ); SG_ERR_CHECK( SG_zing_jsglue__install_scripting_api(pCtx, cx, glob) ); if (! gpJSCoreGlobalState->bSkipModules) { _sg_jscore__install_modules(pCtx, cx, glob, pServerConfig); SG_ERR_CHECK_CURRENT_DISREGARD(SG_ERR_NOTAFILE); } *pp_cx = cx; *pp_glob = glob; return; fail: if (cx) { JS_EndRequest(cx); JS_DestroyContext(cx); } }
/* Execute a string in its own context (away from Synchronet objects) */ static JSBool js_eval(JSContext *parent_cx, uintN argc, jsval *arglist) { jsval *argv=JS_ARGV(parent_cx, arglist); char* buf; size_t buflen; JSString* str; JSObject* script; JSContext* cx; JSObject* obj; JSErrorReporter reporter; JS_SET_RVAL(cx, arglist, JSVAL_VOID); if(argc<1) return(JS_TRUE); if((str=JS_ValueToString(parent_cx, argv[0]))==NULL) return(JS_FALSE); JSSTRING_TO_MSTRING(parent_cx, str, buf, &buflen); HANDLE_PENDING(parent_cx); if(buf==NULL) return(JS_TRUE); if((cx=JS_NewContext(JS_GetRuntime(parent_cx),JAVASCRIPT_CONTEXT_STACK))==NULL) { free(buf); return(JS_FALSE); } /* Use the error reporter from the parent context */ reporter=JS_SetErrorReporter(parent_cx,NULL); JS_SetErrorReporter(parent_cx,reporter); JS_SetErrorReporter(cx,reporter); /* Use the operation callback from the parent context */ JS_SetContextPrivate(cx, JS_GetContextPrivate(parent_cx)); JS_SetOperationCallback(cx, JS_GetOperationCallback(parent_cx)); if((obj=JS_NewCompartmentAndGlobalObject(cx, &eval_class, NULL))==NULL || !JS_InitStandardClasses(cx,obj)) { JS_DestroyContext(cx); free(buf); return(JS_FALSE); } if((script=JS_CompileScript(cx, obj, buf, buflen, NULL, 0))!=NULL) { jsval rval; JS_ExecuteScript(cx, obj, script, &rval); JS_SET_RVAL(cx, arglist, rval); } free(buf); JS_DestroyContext(cx); return(JS_TRUE); }
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); }
nsresult nsInProcessTabChildGlobal::InitTabChildGlobal() { nsCOMPtr<nsIJSRuntimeService> runtimeSvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1"); NS_ENSURE_STATE(runtimeSvc); JSRuntime* rt = nsnull; runtimeSvc->GetRuntime(&rt); NS_ENSURE_STATE(rt); JSContext* cx = JS_NewContext(rt, 8192); NS_ENSURE_STATE(cx); mCx = cx; nsContentUtils::XPConnect()->SetSecurityManagerForJSContext(cx, nsContentUtils::GetSecurityManager(), 0); nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal)); JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024); JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_PRIVATE_IS_NSISUPPORTS); JS_SetVersion(cx, JSVERSION_LATEST); JS_SetErrorReporter(cx, ContentScriptErrorReporter); xpc_LocalizeContext(cx); JSAutoRequest ar(cx); nsIXPConnect* xpc = nsContentUtils::XPConnect(); const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES | /*nsIXPConnect::OMIT_COMPONENTS_OBJECT ? |*/ nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT; nsISupports* scopeSupports = NS_ISUPPORTS_CAST(nsIDOMEventTarget*, this); JS_SetContextPrivate(cx, scopeSupports); nsresult rv = xpc->InitClassesWithNewWrappedGlobal(cx, scopeSupports, NS_GET_IID(nsISupports), GetPrincipal(), nsnull, flags, getter_AddRefs(mGlobal)); NS_ENSURE_SUCCESS(rv, false); JSObject* global = nsnull; rv = mGlobal->GetJSObject(&global); NS_ENSURE_SUCCESS(rv, false); JS_SetGlobalObject(cx, global); DidCreateCx(); return NS_OK; }
ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptRuntime>& runtime) : m(new ScriptInterface_impl(nativeScopeName, runtime)) { // Profiler stats table isn't thread-safe, so only enable this on the main thread if (ThreadUtil::IsMainThread()) { if (g_ScriptStatsTable) g_ScriptStatsTable->Add(this, debugName); } m_CxPrivate.pScriptInterface = this; JS_SetContextPrivate(m->m_cx, (void*)&m_CxPrivate); }
void SG_jscontext__acquire(SG_context * pCtx, SG_jscontext ** ppJs) { SG_ASSERT(pCtx!=NULL); SG_NULLARGCHECK_RETURN(ppJs); if(gpJSContextPoolGlobalState->ssjsMutable) { _sg_jscontext__create(pCtx, ppJs); return; } SG_ERR_CHECK_RETURN( SG_mutex__lock(pCtx, &gpJSContextPoolGlobalState->lock) ); if(gpJSContextPoolGlobalState->pFirstAvailableContext!=NULL) { SG_jscontext * pJs = gpJSContextPoolGlobalState->pFirstAvailableContext; gpJSContextPoolGlobalState->pFirstAvailableContext = pJs->pNextAvailableContext; pJs->pNextAvailableContext = NULL; ++gpJSContextPoolGlobalState->numContextsCheckedOut; SG_ERR_CHECK_RETURN( SG_mutex__unlock(pCtx, &gpJSContextPoolGlobalState->lock) ); SG_httprequestprofiler__start(SG_HTTPREQUESTPROFILER_CATEGORY__JSREQUEST_TOGGLING); (void)JS_SetContextThread(pJs->cx); JS_BeginRequest(pJs->cx); pJs->isInARequest = SG_TRUE; SG_httprequestprofiler__stop(); JS_SetContextPrivate(pJs->cx, pCtx); *ppJs = pJs; } else { ++gpJSContextPoolGlobalState->numContextsCheckedOut; SG_ERR_CHECK_RETURN( SG_mutex__unlock(pCtx, &gpJSContextPoolGlobalState->lock) ); _sg_jscontext__create(pCtx, ppJs); if(SG_context__has_err(pCtx) || *ppJs==NULL) { /* Use the version of the mutex routines that doesn't touch pCtx, because we're already in an error state. */ SG_mutex__lock__bare(&gpJSContextPoolGlobalState->lock); --gpJSContextPoolGlobalState->numContextsCheckedOut; SG_mutex__unlock__bare(&gpJSContextPoolGlobalState->lock); } } }
~WorkletJSContext() override { MOZ_ASSERT(!NS_IsMainThread()); JSContext* cx = MaybeContext(); if (!cx) { return; // Initialize() must have failed } delete static_cast<WorkletThreadContextPrivate*>(JS_GetContextPrivate(cx)); JS_SetContextPrivate(cx, nullptr); nsCycleCollector_shutdown(); }
void SG_jscontextpool__teardown(SG_context * pCtx) { if(gpJSContextPoolGlobalState!=NULL) { SG_ERR_CHECK_RETURN( SG_mutex__lock(pCtx, &gpJSContextPoolGlobalState->lock) ); // Wait until all outstanding SG_jscontexts have been released. Don't try to terminate // early, otherwise we have a race condition on our hands: If the outstanding SG_jscontext // tries to perform any JavaScript operations before the app terminates, but after we have // called JS_Shutdown(), we'll end up crashing on exit. This of course is worse than // making the user hit Ctrl-C again to do a hard shutdown if it's taking too long. if(gpJSContextPoolGlobalState->numContextsCheckedOut > 0) { SG_ERR_IGNORE( SG_log__report_warning(pCtx, "Waiting on %d SG_jscontexts that are still in use.", gpJSContextPoolGlobalState->numContextsCheckedOut) ); while(gpJSContextPoolGlobalState->numContextsCheckedOut > 0) { SG_ERR_CHECK_RETURN( SG_mutex__unlock(pCtx, &gpJSContextPoolGlobalState->lock) ); SG_sleep_ms(10); SG_ERR_CHECK_RETURN( SG_mutex__lock(pCtx, &gpJSContextPoolGlobalState->lock) ); } } SG_ERR_CHECK_RETURN( SG_mutex__unlock(pCtx, &gpJSContextPoolGlobalState->lock) ); SG_mutex__destroy(&gpJSContextPoolGlobalState->lock); while(gpJSContextPoolGlobalState->pFirstAvailableContext!=NULL) { SG_jscontext * pJs = gpJSContextPoolGlobalState->pFirstAvailableContext; gpJSContextPoolGlobalState->pFirstAvailableContext = pJs->pNextAvailableContext; (void)JS_SetContextThread(pJs->cx); JS_BeginRequest(pJs->cx); JS_SetContextPrivate(pJs->cx, pCtx); JS_DestroyContextNoGC(pJs->cx); if(SG_context__has_err(pCtx)) // An error was produced during GC... { SG_log__report_error__current_error(pCtx); SG_context__err_reset(pCtx); } SG_NULLFREE(pCtx, pJs); } SG_VHASH_NULLFREE(pCtx, gpJSContextPoolGlobalState->pServerConfig); SG_NULLFREE(pCtx, gpJSContextPoolGlobalState); } }
JsExecutionContext::JsExecutionContext(JsParser *jsParser) { parser = jsParser; /* Create a new runtime environment. */ rt = JS_NewRuntime(8L * 1024L * 1024L); if (!rt) { error("JsParser :: error creating runtime"); return; /* XXX should return int or ptr! */ } /* Create a new context. */ cx = JS_NewContext(rt, STACK_CHUNK_SIZE); /* if global_context does not have a value, end the program here */ if (cx == NULL) { error("JsParser :: error creating context"); return; } JS_BeginRequest(cx); // Store a reference to ourselves in the context ... JS_SetContextPrivate(cx, parser); /* Set a more strict error checking */ JS_SetOptions(cx, JSOPTION_VAROBJFIX); // | JSOPTION_STRICT); /* Set the branch callback */ #if defined JSOPTION_NATIVE_BRANCH_CALLBACK JS_SetBranchCallback(cx, js_static_branch_callback); #else JS_SetOperationCallback(cx, js_static_branch_callback); #endif /* Set the error reporter */ JS_SetErrorReporter(cx, js_error_reporter); /* Create the global object here */ // JS_SetGlobalObject(global_context, global_object); // this is done in init_class / JS_InitStandardClasses. obj = JS_NewObject(cx, &global_class, NULL, NULL); init_class(); JS_EndRequest(cx); // deassociate this context from the creating thread // so that it can be used in other threads // https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_NewContext JS_ClearContextThread(cx); /** register SIGINT signal */ // signal(SIGINT, js_sigint_handler); }
bool JetpackChild::Init(base::ProcessHandle aParentProcessHandle, MessageLoop* aIOLoop, IPC::Channel* aChannel) { if (!Open(aChannel, aParentProcessHandle, aIOLoop)) return false; if (!(mRuntime = JS_NewRuntime(32L * 1024L * 1024L)) || !(mCx = JS_NewContext(mRuntime, 8192))) return false; JS_SetVersion(mCx, JSVERSION_LATEST); JS_SetOptions(mCx, JS_GetOptions(mCx) | JSOPTION_DONT_REPORT_UNCAUGHT | JSOPTION_ATLINE | JSOPTION_JIT); JS_SetErrorReporter(mCx, ReportError); { JSAutoRequest request(mCx); JS_SetContextPrivate(mCx, this); JSObject* implGlobal = JS_NewCompartmentAndGlobalObject(mCx, const_cast<JSClass*>(&sGlobalClass), NULL); if (!implGlobal) return false; JSAutoEnterCompartment ac; if (!ac.enter(mCx, implGlobal)) return false; jsval ctypes; if (!JS_InitStandardClasses(mCx, implGlobal) || #ifdef BUILD_CTYPES !JS_InitCTypesClass(mCx, implGlobal) || !JS_GetProperty(mCx, implGlobal, "ctypes", &ctypes) || !JS_SetCTypesCallbacks(mCx, JSVAL_TO_OBJECT(ctypes), &sCallbacks) || #endif !JS_DefineFunctions(mCx, implGlobal, const_cast<JSFunctionSpec*>(sImplMethods))) return false; } return true; }
void SG_jscontext__release(SG_context * pCtx, SG_jscontext ** ppJs) { if(ppJs==NULL || *ppJs==NULL) return; if(gpJSContextPoolGlobalState->ssjsMutable) { SG_httprequestprofiler__start(SG_HTTPREQUESTPROFILER_CATEGORY__JSREQUEST_TOGGLING); JS_EndRequest((*ppJs)->cx); JS_DestroyContext((*ppJs)->cx); SG_httprequestprofiler__stop(); if(SG_context__has_err(pCtx)) // An error was produced during GC... { SG_log__report_error__current_error(pCtx); SG_context__err_reset(pCtx); } SG_NULLFREE(pCtx, (*ppJs)); } else { SG_jscontext * pJs = *ppJs; JS_MaybeGC(pJs->cx); JS_SetContextPrivate(pJs->cx, NULL); // Clear out the old pCtx pointer. SG_httprequestprofiler__start(SG_HTTPREQUESTPROFILER_CATEGORY__JSREQUEST_TOGGLING); JS_EndRequest(pJs->cx); pJs->isInARequest = SG_FALSE; (void)JS_ClearContextThread(pJs->cx); SG_httprequestprofiler__stop(); SG_ERR_CHECK_RETURN( SG_mutex__lock(pCtx, &gpJSContextPoolGlobalState->lock) ); pJs->pNextAvailableContext = gpJSContextPoolGlobalState->pFirstAvailableContext; gpJSContextPoolGlobalState->pFirstAvailableContext = pJs; --gpJSContextPoolGlobalState->numContextsCheckedOut; SG_ERR_CHECK_RETURN( SG_mutex__unlock(pCtx, &gpJSContextPoolGlobalState->lock) ); *ppJs = NULL; } }
void on_error(JSContext *context, const char *message, JSErrorReport *report) { if (report->flags & JSREPORT_EXCEPTION) { spidermonkey_error *sm_error = (spidermonkey_error *) driver_alloc(sizeof(spidermonkey_error)); if (message != NULL) { sm_error->msg = copy_string(message); } else { sm_error->msg = copy_string("undefined error"); } sm_error->lineno = report->lineno; if (report->linebuf != NULL) { sm_error->offending_source = copy_string(report->linebuf); } else { sm_error->offending_source = copy_string("unknown"); } JS_SetContextPrivate(context, sm_error); } }
/* * call-seq: * native_initialize(options={}) * * Initializes the native spidermonkey values. */ static VALUE initialize_native(VALUE self, VALUE rb_runtime, VALUE UNUSED(options)) { JohnsonContext* context; JohnsonRuntime* runtime; Data_Get_Struct(self, JohnsonContext, context); Data_Get_Struct(rb_runtime, JohnsonRuntime, runtime); if ((context->js = JS_NewContext(runtime->js, 8192L))) { // See if the runtime already has a shared global object. JSObject* global = runtime->global; // If it does, use it. If not, if (!global) // create one of our global objects. global = johnson_create_global_object(context->js); // Manually set the context's global object. JS_SetGlobalObject(context->js, global); JS_SetErrorReporter(context->js, report_js_error); JS_SetBranchCallback(context->js, branch_callback); JS_SetContextPrivate(context->js, (void *)self); JS_SetOptions(context->js, JS_GetOptions(context->js) | JSOPTION_DONT_REPORT_UNCAUGHT #ifdef JSOPTION_VAROBJFIX | JSOPTION_VAROBJFIX #endif // #ifdef JSOPTION_XML // | JSOPTION_XML // #endif ); // Success. return init_spidermonkey_extensions(context, self); } if (context->js) JS_DestroyContext(context->js); rb_raise(rb_eRuntimeError, "Failed to initialize SpiderMonkey context"); }
static void *thread_start(void *arg) { thread_stuff ts = (thread_stuff) arg; JSContext *cx; jsval argv[1], rval; uintN argc; cx = JS_NewContext(ts->rt, 8192); JS_SetContextPrivate(cx, ts); if(ts->arg != JSVAL_VOID) { argv[0] = ts->arg; argc = 1; } else argc = 0; ts->state = THREAD_RUN; JS_CallFunction(cx, ts->amber, ts->fun, argc, argv, &rval); ts->state = THREAD_DONE; JS_DestroyContext(cx); return NULL; }
ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptRuntime>& runtime) : m(new ScriptInterface_impl(nativeScopeName, runtime)) { // Profiler stats table isn't thread-safe, so only enable this on the main thread if (ThreadUtil::IsMainThread()) { if (g_ScriptStatsTable) g_ScriptStatsTable->Add(this, debugName); } // JS debugger temporarily disabled during the SpiderMonkey upgrade (check trac ticket #2348 for details) /* if (g_JSDebuggerEnabled && g_DebuggingServer != NULL) { if(!JS_SetDebugMode(GetContext(), true)) LOGERROR("Failed to set Spidermonkey to debug mode!"); else g_DebuggingServer->RegisterScriptinterface(debugName, this); } */ m_CxPrivate.pScriptInterface = this; JS_SetContextPrivate(m->m_cx, (void*)&m_CxPrivate); }
nsresult Initialize(JSRuntime* aParentRuntime) { MOZ_ASSERT(!NS_IsMainThread()); nsresult rv = CycleCollectedJSContext::Initialize(aParentRuntime, WORKLET_DEFAULT_RUNTIME_HEAPSIZE, WORKLET_DEFAULT_NURSERY_SIZE); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } JSContext* cx = Context(); JS_SetContextPrivate(cx, new WorkletThreadContextPrivate(mWorkletThread)); js::SetPreserveWrapperCallback(cx, PreserveWrapper); JS_InitDestroyPrincipalsCallback(cx, DestroyWorkletPrincipals); JS_SetWrapObjectCallbacks(cx, &WrapObjectCallbacks); JS_SetFutexCanWait(cx); return NS_OK; }
MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine) : _engine(engine), _mr(), _runtime(_mr._runtime), _context(_mr._context), _globalProto(_context), _global(_globalProto.getProto()), _funcs(), _internedStrings(_context), _pendingKill(false), _opId(0), _opCtx(nullptr), _pendingGC(false), _connectState(ConnectState::Not), _status(Status::OK()), _quickExit(false), _generation(0), _binDataProto(_context), _bsonProto(_context), _countDownLatchProto(_context), _cursorProto(_context), _cursorHandleProto(_context), _dbCollectionProto(_context), _dbPointerProto(_context), _dbQueryProto(_context), _dbProto(_context), _dbRefProto(_context), _errorProto(_context), _jsThreadProto(_context), _maxKeyProto(_context), _minKeyProto(_context), _mongoExternalProto(_context), _mongoHelpersProto(_context), _mongoLocalProto(_context), _nativeFunctionProto(_context), _numberIntProto(_context), _numberLongProto(_context), _numberDecimalProto(_context), _objectProto(_context), _oidProto(_context), _regExpProto(_context), _timestampProto(_context) { kCurrentScope = this; // The default is quite low and doesn't seem to directly correlate with // malloc'd bytes. Set it to MAX_INT here and catching things in the // jscustomallocator.cpp JS_SetGCParameter(_runtime, JSGC_MAX_BYTES, 0xffffffff); JS_SetInterruptCallback(_runtime, _interruptCallback); JS_SetGCCallback(_runtime, _gcCallback, this); JS_SetContextPrivate(_context, this); JSAutoRequest ar(_context); JS_SetErrorReporter(_runtime, _reportError); JSAutoCompartment ac(_context, _global); _checkErrorState(JS_InitStandardClasses(_context, _global)); installBSONTypes(); JS_FireOnNewGlobalObject(_context, _global); execSetup(JSFiles::assert); execSetup(JSFiles::types); // install process-specific utilities in the global scope (dependancy: types.js, assert.js) if (_engine->getScopeInitCallback()) _engine->getScopeInitCallback()(*this); // install global utility functions installGlobalUtils(*this); _mongoHelpersProto.install(_global); }
static PyObject *spindly_js(PyObject *self, PyObject *args) { JSRuntime *runtime; JSContext *context; JSObject *global; char *script; Py_ssize_t script_length; PyObject *params = NULL; int timeout = 10; jsval rvalue; int error = 0; struct watchdog *wd = NULL; if (!PyArg_ParseTuple(args, "s#|Oi:js", &script, &script_length, ¶ms, &timeout)) { return NULL; } if (params != NULL && !PyDict_Check(params)) { return PyErr_Format(PyExc_TypeError, "params must be a dict"); } runtime = JS_NewRuntime(1024L * 1024L); if (!runtime) { return PyErr_Format(PyExc_SystemError, "unable to initialize JS runtime\n"); } context = JS_NewContext(runtime, 8192); if (!context) { JS_DestroyRuntime(runtime); return PyErr_Format(PyExc_SystemError, "unable to initialize JS context\n"); } JS_SetContextPrivate(context, &error); JS_SetOptions(context, JSOPTION_VAROBJFIX); JS_SetVersion(context, JSVERSION_LATEST); JS_SetErrorReporter(context, raise_python_exception); JS_SetOperationCallback(context, js_destroy); global = JS_NewCompartmentAndGlobalObject(context, &global_class, NULL); JS_InitStandardClasses(context, global); if (params != NULL) { populate_javascript_object(context, global, params); } if (timeout > 0) { wd = run_watchdog(context, timeout); if (wd == NULL) { shutdown(runtime, context); return PyErr_Format(PyExc_SystemError, "unable to initialize JS watchdog\n"); } } JSBool retval = JS_EvaluateScript(context, global, script, script_length, "spindly", 1, &rvalue); if (wd) { shutdown_watchdog(wd); } if (retval == JS_FALSE || error == 1) { shutdown(runtime, context); return NULL; } PyObject *obj = to_python_object(context, rvalue); shutdown(runtime, context); return obj; }
PyObject* Context_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) { Context* self = NULL; Runtime* runtime = NULL; PyObject* global = NULL; PyObject* access = NULL; PyObject* alertlist = NULL; char* keywords[] = {"runtime", "glbl", "access", "alertlist", NULL}; if(!PyArg_ParseTupleAndKeywords( args, kwargs, "O!|OOO", keywords, RuntimeType, &runtime, &global, &access, &alertlist )) goto error; if(global == Py_None) global = NULL; if(access == Py_None) access = NULL; if(alertlist == Py_None) alertlist = NULL; if(global != NULL && !PyMapping_Check(global)) { PyErr_SetString(PyExc_TypeError, "Global handler must provide item access."); goto error; } if(access != NULL && !PyCallable_Check(access)) { PyErr_SetString(PyExc_TypeError, "Access handler must be callable."); goto error; } if(alertlist != NULL && !PyList_Check(alertlist)) { PyErr_SetString(PyExc_TypeError, "Alert list must be a list object."); goto error; } self = (Context*) type->tp_alloc(type, 0); if(self == NULL) goto error; // Tracking what classes we've installed in // the context. self->classes = (PyDictObject*) PyDict_New(); if(self->classes == NULL) goto error; self->objects = (PySetObject*) PySet_New(NULL); if(self->objects == NULL) goto error; self->cx = JS_NewContext(runtime->rt, 8192); if(self->cx == NULL) { PyErr_SetString(PyExc_RuntimeError, "Failed to create JSContext."); goto error; } JS_BeginRequest(self->cx); /* * Notice that we don't add a ref to the Python context for * the copy stored on the JSContext*. I'm pretty sure this * would cause a cyclic dependancy that would prevent * garbage collection from happening on either side of the * bridge. * */ JS_SetContextPrivate(self->cx, self); // Setup the root of the property lookup doodad. self->root = JS_NewObject(self->cx, &js_global_class, NULL, NULL); if(self->root == NULL) { PyErr_SetString(PyExc_RuntimeError, "Error creating root object."); goto error; } if(!JS_InitStandardClasses(self->cx, self->root)) { PyErr_SetString(PyExc_RuntimeError, "Error initializing JS VM."); goto error; } // Don't setup the global handler until after the standard classes // have been initialized. // XXX: Does anyone know if finalize is called if new fails? if(global != NULL) Py_INCREF(global); self->global = global; if(access != NULL) Py_INCREF(access); self->access = access; if(alertlist != NULL) Py_INCREF(alertlist); self->alertlist = alertlist; // Setup counters for resource limits self->branch_count = 0; self->max_time = 0; self->start_time = 0; self->max_heap = 0; JS_SetBranchCallback(self->cx, branch_cb); JS_SetErrorReporter(self->cx, report_error_cb); Py_INCREF(runtime); self->rt = runtime; goto success; error: if(self != NULL && self->cx != NULL) JS_EndRequest(self->cx); Py_XDECREF(self); self = NULL; success: if(self != NULL && self->cx != NULL) JS_EndRequest(self->cx); return (PyObject*) self; }
void ScriptInterface::SetCallbackData(void* cbdata) { JS_SetContextPrivate(m->m_cx, cbdata); }
ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime) : m_runtime(runtime) { JSBool ok; m_cx = JS_NewContext(m_runtime->m_rt, STACK_CHUNK_SIZE); ENSURE(m_cx); // For GC debugging: // JS_SetGCZeal(m_cx, 2); JS_SetContextPrivate(m_cx, NULL); JS_SetErrorReporter(m_cx, ErrorReporter); uint32 options = 0; options |= JSOPTION_STRICT; // "warn on dubious practice" options |= JSOPTION_XML; // "ECMAScript for XML support: parse <!-- --> as a token" options |= JSOPTION_VAROBJFIX; // "recommended" (fixes variable scoping) // Enable method JIT, unless script profiling/debugging is enabled (since profiling/debugging // hooks are incompatible with the JIT) // TODO: Verify what exactly is incompatible if (!g_ScriptProfilingEnabled && !g_JSDebuggerEnabled) { options |= JSOPTION_METHODJIT; // Some other JIT flags to experiment with: options |= JSOPTION_JIT; options |= JSOPTION_PROFILING; } JS_SetOptions(m_cx, options); JS_SetVersion(m_cx, JSVERSION_LATEST); // Threadsafe SpiderMonkey requires that we have a request before doing anything much JS_BeginRequest(m_cx); // We only want a single compartment per runtime if (m_runtime->m_compartmentGlobal) { m_call = JS_EnterCrossCompartmentCall(m_cx, m_runtime->m_compartmentGlobal); m_glob = JS_NewGlobalObject(m_cx, &global_class); } else { m_call = NULL; m_glob = JS_NewCompartmentAndGlobalObject(m_cx, &global_class, NULL); m_runtime->m_compartmentGlobal = m_glob; } ok = JS_InitStandardClasses(m_cx, m_glob); ENSURE(ok); JS_DefineProperty(m_cx, m_glob, "global", OBJECT_TO_JSVAL(m_glob), NULL, NULL, 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, m_glob, "print", ::print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "log", ::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "warn", ::warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineFunction(m_cx, m_glob, "deepcopy", ::deepcopy, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); Register("ProfileStart", ::ProfileStart, 1); Register("ProfileStop", ::ProfileStop, 0); }
int main(int argc, const char* argv[]) { JSRuntime* rt = NULL; JSContext* cx = NULL; JSObject* global = NULL; JSObject* klass = NULL; JSScript* script; JSString* scriptsrc; jschar* schars; size_t slen; jsval sroot; jsval result; int i; couch_args* args = couch_parse_args(argc, argv); rt = JS_NewRuntime(args->stack_size); if(rt == NULL) return 1; cx = JS_NewContext(rt, 8L * 1024L); if(cx == NULL) return 1; JS_SetErrorReporter(cx, couch_error); JS_ToggleOptions(cx, JSOPTION_XML); JS_SetContextPrivate(cx, args); SETUP_REQUEST(cx); global = JS_NewObject(cx, &global_class, NULL, NULL); if(global == NULL) return 1; JS_SetGlobalObject(cx, global); if(!JS_InitStandardClasses(cx, global)) return 1; if(couch_load_funcs(cx, global, global_functions) != JS_TRUE) return 1; if(args->use_http) { http_check_enabled(); klass = JS_InitClass( cx, global, NULL, &CouchHTTPClass, req_ctor, 0, CouchHTTPProperties, CouchHTTPFunctions, NULL, NULL ); if(!klass) { fprintf(stderr, "Failed to initialize CouchHTTP class.\n"); exit(2); } } for (i = 0 ; args->scripts[i] ; i++) { // Convert script source to jschars. scriptsrc = couch_readfile(cx, args->scripts[i]); if(!scriptsrc) return 1; schars = JS_GetStringChars(scriptsrc); slen = JS_GetStringLength(scriptsrc); // Root it so GC doesn't collect it. sroot = STRING_TO_JSVAL(scriptsrc); if(JS_AddRoot(cx, &sroot) != JS_TRUE) { fprintf(stderr, "Internal root error.\n"); return 1; } // Compile and run script = JS_CompileUCScript(cx, global, schars, slen, args->scripts[i], 1); if(!script) { fprintf(stderr, "Failed to compile script.\n"); return 1; } JS_ExecuteScript(cx, global, script, &result); // Warning message if we don't remove it. JS_RemoveRoot(cx, &sroot); } FINISH_REQUEST(cx); JS_DestroyContext(cx); JS_DestroyRuntime(rt); JS_ShutDown(); return 0; }
bool Engine::executeFile(FILE *file,HttpServerRequest &httpRequest,HttpServerResponse &httpResponse) { JSContext *cx = NULL; JSObject *obj = NULL; m_mutex.acquire_write(); // pop any available context if ( !m_contexts.empty() ) { cx = m_contexts.top(); m_contexts.pop(); } m_mutex.release(); if ( cx==NULL ) { // create new context cx = JS_NewContext(m_runtime,8192); if ( cx==NULL ) { LogManager::getInstance()->warning(LOGGER_CLASSNAME,"Could not create context. Engine is unavailable."); return false; } JS_SetErrorReporter(cx,reportError); if ( LogManager::getInstance()->isDebug() ) { LogManager::getInstance()->debug(LOGGER_CLASSNAME,"Created new context"); } } bool result = false; // begin request (requires js_threadsafe compilation) JS_SetContextThread(cx); JS_BeginRequest(cx); // create global object obj = JS_NewObject(cx,&globalClass,0,0); if ( obj==NULL ) { LogManager::getInstance()->warning(LOGGER_CLASSNAME,"Could not create global object"); } else { // initialize standard classes on global object if ( JS_InitStandardClasses(cx,obj)==JS_FALSE ) { LogManager::getInstance()->warning(LOGGER_CLASSNAME,"Could not init standard classes"); } else { // initialize custom classes on global object if ( !initCustomClasses(cx,obj) ) { LogManager::getInstance()->warning(LOGGER_CLASSNAME,"Could not init custom classes"); } else { // create predefined objects on global object createPredefinedObjects(cx,obj,httpRequest); // create context private ContextPrivate *cxPrivate = new ContextPrivate(this,httpRequest,httpResponse); JS_SetContextPrivate(cx,cxPrivate); // execute script in the context result = executeFile(file,cx,obj); // cleanup predefined objects on context object // note: this one might not be needed, remove later if ok cleanupPredefinedObjects(cx,obj); delete cxPrivate; } } } JS_GC(cx); // force garbage collection // end request (requires js_threadsafe) JS_EndRequest(cx); JS_ClearContextThread(cx); // return context to js engine m_mutex.acquire_write(); m_contexts.push(cx); m_mutex.release(); return result; }