bool test(const char *bytes) { jsval v; JS_SetOptions(cx, JS_GetOptions(cx) & ~(JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS)); sRemain = 0; CHECK(!evaluate(bytes, __FILE__, __LINE__, &v)); CHECK(!JS_IsExceptionPending(cx)); sRemain = 1000; CHECK(!evaluate(bytes, __FILE__, __LINE__, &v)); CHECK(!JS_IsExceptionPending(cx)); JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS); sRemain = 0; CHECK(!evaluate(bytes, __FILE__, __LINE__, &v)); CHECK(!JS_IsExceptionPending(cx)); sRemain = 1000; CHECK(!evaluate(bytes, __FILE__, __LINE__, &v)); CHECK(!JS_IsExceptionPending(cx)); return true; }
static JSBool vm_jit_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { if (gpsee_isFalsy(cx, *vp)) JS_SetOptions(cx, JS_GetOptions(cx) & ~JSOPTION_JIT); else JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT); return JS_TRUE; }
bool CompileFile(const std::string &inputFilePath, const std::string &outputFilePath) { bool result = false; std::string ofp; if (!outputFilePath.empty()) { ofp = outputFilePath; } else { ofp = RemoveFileExt(inputFilePath) + BYTE_CODE_FILE_EXT; } std::cout << "Input file: " << inputFilePath << std::endl; JSRuntime * runtime = JS_NewRuntime(10 * 1024 * 1024, JS_NO_HELPER_THREADS); JSContext *context = JS_NewContext(runtime, 10240); JS_SetOptions(context, JSOPTION_TYPE_INFERENCE); JS_SetVersion(context, JSVERSION_LATEST); JS_SetOptions(context, JS_GetOptions(context) & ~JSOPTION_METHODJIT); JS_SetOptions(context, JS_GetOptions(context) & ~JSOPTION_METHODJIT_ALWAYS); JSObject* global = JS_NewGlobalObject(context, &GlobalClass, NULL); JS_SetErrorReporter(context, &ReportError); if (JS_InitStandardClasses(context, global)) { JS::CompileOptions options(context); options.setUTF8(true); options.setSourcePolicy(JS::CompileOptions::NO_SOURCE); js::RootedObject rootedObject(context, global); std::cout << "Compiling ..." << std::endl; JSScript *script = JS::Compile(context, rootedObject, options, inputFilePath.c_str()); if (script) { void *data = NULL; uint32_t length = 0; std::cout << "Encoding ..." << std::endl; data = JS_EncodeScript(context, script, &length); if (data) { if (WriteFile(ofp, data, length)) { std::cout << "Done! " << "Output file: " << ofp << std::endl; result = true; } } } } if (context) { JS_DestroyContext(context); context = NULL; } if (runtime) { JS_DestroyRuntime(runtime); runtime = NULL; } return result; }
// Not strictly necessary, but part of the test attempts to check // whether these callbacks still trigger when traced, so force // JSOPTION_JIT just to be sure. Once the method jit and tracing jit // are integrated, this'll probably have to change (and we'll probably // want to test in all modes.) virtual JSContext *createContext() { JSContext *cx = JSAPITest::createContext(); if (cx) JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_METHODJIT | JSOPTION_PCCOUNT); return cx; }
// Make sure that the method jit is enabled. // We'll probably want to test in all modes. virtual JSContext *createContext() { JSContext *cx = JSAPITest::createContext(); if (cx) JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_BASELINE | JSOPTION_ION); return cx; }
AutoDontReportUncaught(JSContext* aContext) : mContext(aContext) { MOZ_ASSERT(aContext); uint32_t oldOptions = JS_GetOptions(mContext); mWasSet = oldOptions & JSOPTION_DONT_REPORT_UNCAUGHT; if (!mWasSet) { JS_SetOptions(mContext, oldOptions | JSOPTION_DONT_REPORT_UNCAUGHT); } }
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; }
static JSBool Load(JSContext *cx, uintN argc, jsval *vp) { SG_context *pCtx = NULL; JSObject *thisobj = JS_THIS_OBJECT(cx, vp); jsval *argv = JS_ARGV(cx, vp); uintN i; if (!thisobj) return JS_FALSE; SG_context__alloc(&pCtx); if (pCtx==NULL) return JS_FALSE; for (i = 0; i < argc; i++) { JSString *str = JS_ValueToString(cx, argv[i]); char *filename = NULL; uint32 oldopts; JSObject *scriptObj; if (!str) { SG_CONTEXT_NULLFREE(pCtx); return JS_FALSE; } argv[i] = STRING_TO_JSVAL(str); sg_jsglue__jsstring_to_sz(pCtx, cx, str, &filename); if (SG_context__has_err(pCtx)) { SG_CONTEXT_NULLFREE(pCtx); return JS_FALSE; } errno = 0; oldopts = JS_GetOptions(cx); JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL); scriptObj = JS_CompileFile(cx, thisobj, filename); SG_NULLFREE(pCtx, filename); JS_SetOptions(cx, oldopts); if (!scriptObj) { SG_CONTEXT_NULLFREE(pCtx); return JS_FALSE; } if (!compileOnly && !JS_ExecuteScript(cx, thisobj, scriptObj, NULL)) { SG_CONTEXT_NULLFREE(pCtx); return JS_FALSE; } } SG_CONTEXT_NULLFREE(pCtx); return JS_TRUE; }
/*----------------------------------------------------------------------------* * Scripter descriptor * *----------------------------------------------------------------------------*/ static void * _egueb_script_js_sm_scripter_new(void) { Egueb_Script_Js_Sm_Scripter *thiz; thiz = calloc(1, sizeof(Egueb_Script_Js_Sm_Scripter)); /* Create an instance of the engine */ thiz->rt = JS_NewRuntime(1024 * 1024); JS_SetRuntimePrivate(thiz->rt, thiz); /* Create an execution context */ thiz->cx = JS_NewContext(thiz->rt, 8192); JS_SetOptions(thiz->cx, JS_GetOptions(thiz->cx) | JSOPTION_VAROBJFIX); JS_SetErrorReporter(thiz->cx, _egueb_script_js_sm_scripter_report_error); _egueb_script_js_sm_init_global_object(thiz); return thiz; }
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; }
NS_IMETHODIMP nsDOMWorkerScriptLoader::ScriptCompiler::Run() { NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); if (mRevoked) { return NS_OK; } NS_ASSERTION(!mScriptObj.ToJSObject(), "Already have a script object?!"); NS_ASSERTION(mScriptObj.IsHeld(), "Not held?!"); NS_ASSERTION(!mScriptText.IsEmpty(), "Shouldn't have empty source here!"); JSContext* cx = nsDOMThreadService::GetCurrentContext(); NS_ENSURE_STATE(cx); JSAutoRequest ar(cx); JSObject* global = JS_GetGlobalObject(cx); NS_ENSURE_STATE(global); // Because we may have nested calls to this function we don't want the // execution to automatically report errors. We let them propagate instead. uint32 oldOpts = JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT); JSPrincipals* principal = nsDOMWorkerSecurityManager::WorkerPrincipal(); JSScript* script = JS_CompileUCScriptForPrincipals(cx, global, principal, reinterpret_cast<const jschar*> (mScriptText.BeginReading()), mScriptText.Length(), mFilename.get(), 1); JS_SetOptions(cx, oldOpts); if (!script) { return NS_ERROR_FAILURE; } mScriptObj = JS_NewScriptObject(cx, script); NS_ENSURE_STATE(mScriptObj.ToJSObject()); return NS_OK; }
/* * 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"); }
SafeCallGuard(JSContext *cx, nsIPrincipal *principal) : cx(cx) { nsIScriptSecurityManager_1_9_2 *ssm = XPCWrapper::GetSecurityManager(); if (ssm) { // Note: We pass null as the target frame pointer because we know that // we're about to set aside the frame chain. nsresult rv = ssm->PushContextPrincipal(cx, nsnull, principal); if (NS_FAILED(rv)) { NS_WARNING("Not allowing call because we're out of memory"); JS_ReportOutOfMemory(cx); this->cx = nsnull; return; } } js_SaveAndClearRegExpStatics(cx, &statics, &tvr, &tvr2); fp = JS_SaveFrameChain(cx); options = JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT); }
void DEBUG_CheckForComponentsInScope(JSContext* cx, JSObject* obj, JSObject* startingObj, JSBool OKIfNotInitialized, XPCJSRuntime* runtime) { if(OKIfNotInitialized) return; if(!(JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS)) return; const char* name = runtime->GetStringName(XPCJSRuntime::IDX_COMPONENTS); jsval prop; if(JS_LookupProperty(cx, obj, name, &prop) && !JSVAL_IS_PRIMITIVE(prop)) return; // This is pretty much always bad. It usually means that native code is // making a callback to an interface implemented in JavaScript, but the // document where the JS object was created has already been cleared and the // global properties of that document's window are *gone*. Generally this // indicates a problem that should be addressed in the design and use of the // callback code. NS_ERROR("XPConnect is being called on a scope without a 'Components' property! (stack and details follow)"); printf("The current JS stack is:\n"); xpc_DumpJSStack(cx, JS_TRUE, JS_TRUE, JS_TRUE); printf("And the object whose scope lacks a 'Components' property is:\n"); js_DumpObject(startingObj); JSObject *p = startingObj; while(p->isWrapper()) { p = p->getProxyPrivate().toObjectOrNull(); if(!p) break; printf("which is a wrapper for:\n"); js_DumpObject(p); } }
nsresult nsDOMWorkerScriptLoader::ExecuteScripts(JSContext* aCx) { NS_ASSERTION(aCx, "Shouldn't be null!"); // Now execute all the scripts. for (PRUint32 index = 0; index < mScriptCount; index++) { ScriptLoadInfo& loadInfo = mLoadInfos[index]; JSAutoRequest ar(aCx); JSScript* script = static_cast<JSScript*>(JS_GetPrivate(aCx, loadInfo.scriptObj.ToJSObject())); NS_ASSERTION(script, "This shouldn't ever be null!"); JSObject* global = mWorker->mGlobal ? mWorker->mGlobal : JS_GetGlobalObject(aCx); NS_ENSURE_STATE(global); // Because we may have nested calls to this function we don't want the // execution to automatically report errors. We let them propagate instead. uint32 oldOpts = JS_SetOptions(aCx, JS_GetOptions(aCx) | JSOPTION_DONT_REPORT_UNCAUGHT); jsval val; PRBool success = JS_ExecuteScript(aCx, global, script, &val); JS_SetOptions(aCx, oldOpts); if (!success) { return NS_ERROR_FAILURE; } } return NS_OK; }
static JSDContext* _newJSDContext(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user, JSObject* scopeobj) { JSDContext* jsdc = NULL; JSCrossCompartmentCall *call = 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) | JSOPTION_ALLOW_XML); jsdc->glob = JS_NewCompartmentAndGlobalObject(jsdc->dumbContext, &global_class, NULL); if( ! jsdc->glob ) goto label_newJSDContext_failure; call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, jsdc->glob); if( ! call ) goto label_newJSDContext_failure; if ( ! JS_AddNamedObjectRoot(jsdc->dumbContext, &jsdc->glob, "JSD context global") ) goto label_newJSDContext_failure; ok = JS_InitStandardClasses(jsdc->dumbContext, jsdc->glob); JS_LeaveCrossCompartmentCall(call); 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; }
PyObject* Context_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) { Context* self = NULL; Runtime* runtime = NULL; PyObject* global = NULL; PyObject* access = NULL; int strict = 0; uint32_t jsopts; char* keywords[] = {"runtime", "glbl", "access", "strict", NULL}; if(!PyArg_ParseTupleAndKeywords( args, kwargs, "O!|OOI", keywords, RuntimeType, &runtime, &global, &access, &strict )) goto error; if(global == Py_None) global = NULL; if(access == Py_None) access = NULL; strict &= 1; /* clamp at 1 */ 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; } 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; // 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); jsopts = JS_GetOptions(self->cx); jsopts |= JSOPTION_VAROBJFIX; if (strict) { jsopts |= JSOPTION_STRICT; } else { jsopts &= ~JSOPTION_STRICT; } JS_SetOptions(self->cx, jsopts); 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; }
PRIntn prmain(PRIntn argc, char **argv) { void *stackBasePtr; gpsee_interpreter_t *jsi; /* Handle describing a GPSEE/JavaScript Interpreter */ gpsee_realm_t *realm; /* Interpreter's primordial realm */ JSContext *cx; /* A context in realm */ const char *scriptCode = NULL; /* String with JavaScript program in it */ const char *scriptFilename = NULL; /* Filename with JavaScript program in it */ char * const *script_argv; /* Becomes arguments array in JS program */ char * const *script_environ = NULL; /* Environment to pass to script */ char *flags = malloc(8); /* Flags found on command line */ int noRunScript = 0; /* !0 = compile but do not run */ int fiArg = 0; int skipSheBang = 0; int exitCode; int verbosity; /* Verbosity to use before flags are processed */ #ifdef GPSEE_DEBUGGER JSDContext *jsdc; #endif #if defined(__SURELYNX__) permanent_pool = apr_initRuntime(); #endif gpsee_setVerbosity(isatty(STDERR_FILENO) ? GSR_PREPROGRAM_TTY_VERBOSITY : GSR_PREPROGRAM_NOTTY_VERBOSITY); gpsee_openlog(gpsee_basename(argv[0])); /* Print usage and exit if no arguments were given */ if (argc < 2) usage(argv[0]); flags[0] = (char)0; fiArg = findFileToInterpret(argc, argv); if (fiArg == 0) /* Not a script file interpreter (shebang) */ { int c; char *flag_p = flags; while ((c = getopt(argc, argv, whenSureLynx("D:r:","") "v:c:hHnf:F:aCRxSUWdeJz")) != -1) { switch(c) { #if defined(__SURELYNX__) case 'D': redirect_output(permanent_pool, optarg); break; case 'r': /* handled by cfg_openfile() */ break; #endif case 'c': scriptCode = optarg; break; case 'h': usage(argv[0]); break; case 'H': moreHelp(argv[0]); break; case 'n': noRunScript = 1; break; case 'F': skipSheBang = 1; case 'f': scriptFilename = optarg; break; case 'a': case 'C': case 'd': case 'e': case 'J': case 'S': case 'R': case 'U': case 'W': case 'x': case 'z': { char *flags_storage = realloc(flags, (flag_p - flags) + 1 + 1); if (flags_storage != flags) { flag_p = (flag_p - flags) + flags_storage; flags = flags_storage; } *flag_p++ = c; *flag_p = '\0'; } break; case '?': { char buf[32]; snprintf(buf, sizeof(buf), "Invalid option: %c\n", optopt); fatal(buf); } case ':': { char buf[32]; snprintf(buf, sizeof(buf), "Missing parameter to option '%c'\n", optopt); fatal(buf); } } } /* getopt wend */ /* Create the script's argument vector with the script name as arguments[0] */ { char **nc_script_argv = malloc(sizeof(argv[0]) * (2 + (argc - optind))); nc_script_argv[0] = (char *)scriptFilename; memcpy(nc_script_argv + 1, argv + optind, sizeof(argv[0]) * ((1 + argc) - optind)); script_argv = nc_script_argv; } *flag_p = (char)0; } else { scriptFilename = argv[fiArg]; if (fiArg == 2) { if (argv[1][0] != '-') fatal("Invalid syntax for file-interpreter flags! (Must begin with '-')"); flags = realloc(flags, strlen(argv[1]) + 1); strcpy(flags, argv[1] + 1); } /* This is a file interpreter; script_argv is correct at offset fiArg. */ script_argv = argv + fiArg; } if (strchr(flags, 'a')) { #if defined(GPSEE_DARWIN_SYSTEM) script_environ = (char * const *)_NSGetEnviron(); #else extern char **environ; script_environ = (char * const *)environ; #endif } loadRuntimeConfig(scriptFilename, flags, argc, argv); if (strchr(flags, 'U') || (cfg_bool_value(cfg, "gpsee_force_no_utf8_c_strings") == cfg_true) || getenv("GPSEE_NO_UTF8_C_STRINGS")) { JS_DestroyRuntime(JS_NewRuntime(1024)); putenv((char *)"GPSEE_NO_UTF8_C_STRINGS=1"); } jsi = gpsee_createInterpreter(); realm = jsi->realm; cx = jsi->cx; #if defined(GPSEE_DEBUGGER) jsdc = gpsee_initDebugger(cx, realm, DEBUGGER_JS); #endif gpsee_setThreadStackLimit(cx, &stackBasePtr, strtol(cfg_default_value(cfg, "gpsee_thread_stack_limit_bytes", "0x80000"), NULL, 0)); processFlags(cx, flags, &verbosity); free(flags); #if defined(__SURELYNX__) sl_set_debugLevel(gpsee_verbosity(0)); /* enableTerminalLogs(permanent_pool, gpsee_verbosity(0) > 0, NULL); */ #else if (verbosity < GSR_MIN_TTY_VERBOSITY && isatty(STDERR_FILENO)) verbosity = GSR_MIN_TTY_VERBOSITY; #endif if (gpsee_verbosity(0) < verbosity) gpsee_setVerbosity(verbosity); /* Run JavaScript specified with -c */ if (scriptCode) { jsval v; if (JS_EvaluateScript(cx, realm->globalObject, scriptCode, strlen(scriptCode), "command_line", 1, &v) == JS_FALSE) { v = JSVAL_NULL; goto out; } v = JSVAL_NULL; } if ((argv[0][0] == '/') #if defined(SYSTEM_GSR) && (strcmp(argv[0], SYSTEM_GSR) != 0) #endif && cfg_bool_value(cfg, "no_gsr_preload_script") != cfg_true) { char preloadScriptFilename[FILENAME_MAX]; char mydir[FILENAME_MAX]; int i; jsi->grt->exitType = et_unknown; i = snprintf(preloadScriptFilename, sizeof(preloadScriptFilename), "%s/.%s_preload", gpsee_dirname(argv[0], mydir, sizeof(mydir)), gpsee_basename(argv[0])); if ((i == 0) || (i == (sizeof(preloadScriptFilename) -1))) gpsee_log(cx, GLOG_EMERG, PRODUCT_SHORTNAME ": Unable to create preload script filename!"); else errno = 0; if (access(preloadScriptFilename, F_OK) == 0) { jsval v; JSScript *script; JSObject *scrobj; if (!gpsee_compileScript(cx, preloadScriptFilename, NULL, NULL, &script, realm->globalObject, &scrobj)) { jsi->grt->exitType = et_compileFailure; gpsee_log(cx, GLOG_EMERG, PRODUCT_SHORTNAME ": Unable to compile preload script '%s'", preloadScriptFilename); goto out; } if (!script || !scrobj) goto out; if (!noRunScript) { JS_AddNamedObjectRoot(cx, &scrobj, "preload_scrobj"); jsi->grt->exitType = et_execFailure; if (JS_ExecuteScript(cx, realm->globalObject, script, &v) == JS_TRUE) jsi->grt->exitType = et_finished; else jsi->grt->exitType = et_exception; JS_RemoveObjectRoot(cx, &scrobj); v = JSVAL_NULL; } } if (jsi->grt->exitType & et_errorMask) goto out; } /* Setup for main-script running -- cancel preprogram verbosity and use our own error reporting system in gsr that does not use error reporter */ gpsee_setVerbosity(verbosity); JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT); if (!scriptFilename) { if (!scriptCode) /* Command-line options did not include code to run */ usage(argv[0]); if (jsi->grt->exitType == et_unknown) jsi->grt->exitType = et_finished; } else { FILE *scriptFile = openScriptFile(cx, scriptFilename, skipSheBang || (fiArg != 0)); if (!scriptFile) { gpsee_log(cx, GLOG_NOTICE, PRODUCT_SHORTNAME ": Unable to open' script '%s'! (%m)", scriptFilename); jsi->grt->exitType = et_compileFailure; goto out; } processInlineFlags(cx, scriptFile, &verbosity); gpsee_setVerbosity(verbosity); /* Just compile and exit? */ if (noRunScript) { JSScript *script; JSObject *scrobj; if (!gpsee_compileScript(cx, scriptFilename, scriptFile, NULL, &script, realm->globalObject, &scrobj)) { jsi->grt->exitType = et_exception; gpsee_reportUncaughtException(cx, JSVAL_NULL, (gpsee_verbosity(0) >= GSR_FORCE_STACK_DUMP_VERBOSITY) || ((gpsee_verbosity(0) >= GPSEE_ERROR_OUTPUT_VERBOSITY) && isatty(STDERR_FILENO))); } else { jsi->grt->exitType = et_finished; } } else /* noRunScript is false; run the program */ { jsi->grt->exitType = et_execFailure; if (gpsee_runProgramModule(cx, scriptFilename, NULL, scriptFile, script_argv, script_environ) == JS_TRUE) { jsi->grt->exitType = et_finished; } else { int code; code = gpsee_getExceptionExitCode(cx); if (code >= 0) /** e.g. throw 6 */ { jsi->grt->exitType = et_requested; jsi->grt->exitCode = code; } else { if (JS_IsExceptionPending(cx)) { jsi->grt->exitType = et_exception; gpsee_reportUncaughtException(cx, JSVAL_NULL, (gpsee_verbosity(0) >= GSR_FORCE_STACK_DUMP_VERBOSITY) || ((gpsee_verbosity(0) >= GPSEE_ERROR_OUTPUT_VERBOSITY) && isatty(STDERR_FILENO))); } } } } fclose(scriptFile); goto out; } out: #ifdef GPSEE_DEBUGGER gpsee_finiDebugger(jsdc); #endif if (jsi->grt->exitType & et_successMask) { exitCode = jsi->grt->exitCode; } else { const char *reason; exitCode = 1; switch(jsi->grt->exitType) { case et_successMask: case et_errorMask: case et_requested: case et_finished: case et_dummy: default: GPSEE_NOT_REACHED("impossible"); reason = NULL; /* quell compiler warning below */ break; case et_execFailure: reason = "execFailure - probable native module error, returning JS_FALSE without setting exception"; break; case et_compileFailure: reason = "script could not be compiled"; break; case et_unknown: reason = "unknown - probable native module error, returning JS_FALSE without setting exception"; break; case et_exception: reason = NULL; break; } if (reason) { gpsee_log(cx, GLOG_NOTICE, "Unexpected interpreter shutdown: %s (%m)", reason); if (gpsee_verbosity(0) == 0) { /* not gpsee_ */ fprintf(stderr, "*** Unexpected interpreter shutdown: %s", reason); if (errno) fprintf(stderr, " (%s)\n", strerror(errno)); else fputs("\n", stderr); } } } gpsee_destroyInterpreter(jsi); JS_ShutDown(); return exitCode; }
void* vm_run(void* arg) { vm_ptr vm = (vm_ptr) arg; JSContext* cx; JSObject* gl; job_ptr job; ENTERM resp; int flags; cx = JS_NewContext(vm->runtime, vm->stack_size); if(cx == NULL) { fprintf(stderr, "Failed to create context.\n"); goto done; } JS_BeginRequest(cx); flags = 0; flags |= JSOPTION_VAROBJFIX; flags |= JSOPTION_STRICT; flags |= JSVERSION_LATEST; flags |= JSOPTION_COMPILE_N_GO; flags |= JSOPTION_XML; JS_SetOptions(cx, JS_GetOptions(cx) | flags); gl = JS_NewObject(cx, &global_class, NULL, NULL); if(gl == NULL) { fprintf(stderr, "Failed to create global object.\n"); goto done; } if(!JS_InitStandardClasses(cx, gl)) { fprintf(stderr, "Failed to initialize classes.\n"); goto done; } if(!install_jserl(cx, gl)) { fprintf(stderr, "Failed to install erlang object."); goto done; } JS_SetErrorReporter(cx, vm_report_error); JS_SetContextPrivate(cx, (void*) vm); JS_EndRequest(cx); while(1) { job = queue_pop(vm->jobs); if(job->type == job_close) { job_destroy(job); break; } JS_BeginRequest(cx); assert(vm->curr_job == NULL && "vm already has a job set."); vm->curr_job = job; if(job->type == job_eval) { resp = vm_eval(cx, gl, job); } else if(job->type == job_call) { resp = vm_call(cx, gl, job); } else { assert(0 && "Invalid job type."); } vm->curr_job = NULL; JS_EndRequest(cx); JS_MaybeGC(cx); // XXX: If pid is not alive, we just ignore it. enif_send(NULL, &(job->pid), job->env, resp); job_destroy(job); } done: JS_BeginRequest(cx); if(cx != NULL) JS_DestroyContext(cx); return NULL; }
nsresult mozJSComponentLoader::ReallyInit() { nsresult rv; /* * Get the JSRuntime from the runtime svc, if possible. * We keep a reference around, because it's a Bad Thing if the runtime * service gets shut down before we're done. Bad! */ mRuntimeService = do_GetService(kJSRuntimeServiceContractID, &rv); if (NS_FAILED(rv) || NS_FAILED(rv = mRuntimeService->GetRuntime(&mRuntime))) return rv; // Create our compilation context. mContext = JS_NewContext(mRuntime, 256); if (!mContext) return NS_ERROR_OUT_OF_MEMORY; uint32 options = JS_GetOptions(mContext); JS_SetOptions(mContext, options | JSOPTION_XML); // Always use the latest js version JS_SetVersion(mContext, JSVERSION_LATEST); // Limit C stack consumption to a reasonable 512K int stackDummy; const jsuword kStackSize = 0x80000; jsuword stackLimit, currentStackAddr = (jsuword)&stackDummy; #if JS_STACK_GROWTH_DIRECTION < 0 stackLimit = (currentStackAddr > kStackSize) ? currentStackAddr - kStackSize : 0; #else stackLimit = (currentStackAddr + kStackSize > currentStackAddr) ? currentStackAddr + kStackSize : (jsuword) -1; #endif JS_SetThreadStackLimit(mContext, stackLimit); #ifndef XPCONNECT_STANDALONE nsCOMPtr<nsIScriptSecurityManager> secman = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); if (!secman) return NS_ERROR_FAILURE; rv = secman->GetSystemPrincipal(getter_AddRefs(mSystemPrincipal)); if (NS_FAILED(rv) || !mSystemPrincipal) return NS_ERROR_FAILURE; #endif if (!mModules.Init(32)) return NS_ERROR_OUT_OF_MEMORY; if (!mImports.Init(32)) return NS_ERROR_OUT_OF_MEMORY; if (!mInProgressImports.Init(32)) return NS_ERROR_OUT_OF_MEMORY; // Set up our fastload file nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv); if (NS_SUCCEEDED(rv)) rv = flSvc->NewFastLoadFile("XPC", getter_AddRefs(mFastLoadFile)); if (NS_FAILED(rv)) { LOG(("Could not get fastload file location\n")); } // Listen for xpcom-shutdown so that we can close out our fastload file // at that point (after that we can no longer create an input stream). nsCOMPtr<nsIObserverService> obsSvc = do_GetService(kObserverServiceContractID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = obsSvc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); rv = obsSvc->AddObserver(this, "xpcom-shutdown-loaders", PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); #ifdef DEBUG_shaver_off fprintf(stderr, "mJCL: ReallyInit success!\n"); #endif mInitialized = PR_TRUE; return NS_OK; }
static JSBool vm_jit_getter(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { *vp = (JS_GetOptions(cx) & JSOPTION_JIT) ? JSVAL_TRUE : JSVAL_FALSE; return JS_TRUE; }
static GObject* gjs_context_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_params) { GObject *object; GjsContext *js_context; guint32 options_flags; JSVersion js_version; object = (* G_OBJECT_CLASS (gjs_context_parent_class)->constructor) (type, n_construct_properties, construct_params); js_context = GJS_CONTEXT(object); if (js_context->runtime == NULL) { js_context->runtime = JS_NewRuntime(32*1024*1024 /* max bytes */); if (js_context->runtime == NULL) gjs_fatal("Failed to create javascript runtime"); JS_SetGCParameter(js_context->runtime, JSGC_MAX_BYTES, 0xffffffff); js_context->we_own_runtime = TRUE; gjs_runtime_init(js_context->runtime); } js_context->context = JS_NewContext(js_context->runtime, 8192 /* stack chunk size */); if (js_context->context == NULL) gjs_fatal("Failed to create javascript context"); JS_BeginRequest(js_context->context); /* same as firefox, see discussion at * https://bugzilla.mozilla.org/show_bug.cgi?id=420869 */ JS_SetScriptStackQuota(js_context->context, 100*1024*1024); /* JSOPTION_DONT_REPORT_UNCAUGHT: Don't send exceptions to our * error report handler; instead leave them set. This allows us * to get at the exception object. * * JSOPTION_STRICT: Report warnings to error reporter function. */ options_flags = JSOPTION_DONT_REPORT_UNCAUGHT | JSOPTION_STRICT; if (!g_getenv("GJS_DISABLE_JIT")) { gjs_debug(GJS_DEBUG_CONTEXT, "Enabling JIT"); options_flags |= JSOPTION_METHODJIT; } JS_SetOptions(js_context->context, JS_GetOptions(js_context->context) | options_flags); JS_SetLocaleCallbacks(js_context->context, &gjs_locale_callbacks); JS_SetErrorReporter(js_context->context, gjs_error_reporter); /* set ourselves as the private data */ JS_SetContextPrivate(js_context->context, js_context); js_version = JS_StringToVersion(js_context->jsversion_string); /* It doesn't make sense to throw here; just use the default if we * don't know. */ if (js_version == JSVERSION_UNKNOWN) js_version = JSVERSION_DEFAULT; /* Set the version if we need to. */ if (js_version != JSVERSION_DEFAULT && JS_GetVersion(js_context->context) != js_version) { gjs_debug(GJS_DEBUG_CONTEXT, "Changing JavaScript version to %s from %s", JS_VersionToString(js_version), JS_VersionToString(JS_GetVersion(js_context->context))); JS_SetVersion(js_context->context, js_version); } if (!gjs_init_context_standard(js_context->context)) gjs_fatal("Failed to initialize context"); js_context->global = JS_GetGlobalObject(js_context->context); if (!JS_DefineProperty(js_context->context, js_context->global, "window", OBJECT_TO_JSVAL(js_context->global), NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT)) gjs_fatal("No memory to export global object as 'window'"); /* Define a global function called log() */ if (!JS_DefineFunction(js_context->context, js_context->global, "log", (JSNative)gjs_log, 1, GJS_MODULE_PROP_FLAGS)) gjs_fatal("Failed to define log function"); if (!JS_DefineFunction(js_context->context, js_context->global, "logError", (JSNative)gjs_log_error, 2, GJS_MODULE_PROP_FLAGS)) gjs_fatal("Failed to define logError function"); /* Define global functions called print() and printerr() */ if (!JS_DefineFunction(js_context->context, js_context->global, "print", (JSNative)gjs_print, 3, GJS_MODULE_PROP_FLAGS)) gjs_fatal("Failed to define print function"); if (!JS_DefineFunction(js_context->context, js_context->global, "printerr", (JSNative)gjs_printerr, 4, GJS_MODULE_PROP_FLAGS)) gjs_fatal("Failed to define printerr function"); /* We need to know what the default context is, since it's the context whose * global object is used to load imported JS modules. We currently say that * it's the context of the runtime's owner, but if we needed to support * externally created runtimes, we could define it in some other fashion. */ if (js_context->we_own_runtime) { gjs_runtime_set_default_context(js_context->runtime, js_context->context); } else { if (gjs_runtime_get_default_context(js_context->runtime) == NULL) gjs_fatal("GjsContext created for a runtime not owned by GJS"); } /* We create the global-to-runtime root importer with the * passed-in search path. If someone else already created * the root importer, this is a no-op. */ if (!gjs_create_root_importer(js_context->context, js_context->search_path ? (const char**) js_context->search_path : NULL, TRUE)) gjs_fatal("Failed to create root importer"); /* Now copy the global root importer (which we just created, * if it didn't exist) to our global object */ if (!gjs_define_root_importer(js_context->context, js_context->global, "imports")) gjs_fatal("Failed to point 'imports' property at root importer"); if (js_context->we_own_runtime) { js_context->profiler = gjs_profiler_new(js_context->runtime); } if (!gjs_is_registered_native_module(js_context->context, NULL, "gi")) gjs_register_native_module("gi", gjs_define_gi_stuff, GJS_NATIVE_SUPPLIES_MODULE_OBJ); /* For GjsDBus */ { char *priv_typelib_dir = g_build_filename (PKGLIBDIR, "girepository-1.0", NULL); g_irepository_prepend_search_path(priv_typelib_dir); g_free (priv_typelib_dir); } if (js_context->gc_notifications_enabled) JS_SetGCCallback(js_context->context, gjs_on_context_gc); JS_EndRequest(js_context->context); g_static_mutex_lock (&contexts_lock); all_contexts = g_list_prepend(all_contexts, object); g_static_mutex_unlock (&contexts_lock); return object; }
NS_IMETHODIMP nsJSSh::Init() { nsCOMPtr<nsIScriptSecurityManager> ssm = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); if (!ssm) { NS_ERROR("failed to get script security manager"); return NS_ERROR_FAILURE; } ssm->GetSystemPrincipal(getter_AddRefs(mPrincipal)); if (!mPrincipal) { NS_ERROR("failed to get system principal"); return NS_ERROR_FAILURE; } nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID()); if (!xpc) { NS_ERROR("failed to get xpconnect service"); return NS_ERROR_FAILURE; } nsCOMPtr<nsIJSRuntimeService> rtsvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1"); // get the JSRuntime from the runtime svc if (!rtsvc) { NS_ERROR("failed to get nsJSRuntimeService"); return NS_ERROR_FAILURE; } JSRuntime *rt = nsnull; if (NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) { NS_ERROR("failed to get JSRuntime from nsJSRuntimeService"); return NS_ERROR_FAILURE; } mJSContext = JS_NewContext(rt, 8192); if (!mJSContext) { NS_ERROR("JS_NewContext failed"); return NS_ERROR_FAILURE; } JSAutoRequest ar(mJSContext); // Enable e4x: JS_SetOptions(mJSContext, JS_GetOptions(mJSContext) | JSOPTION_XML); // Always use the latest js version JS_SetVersion(mJSContext, JSVERSION_LATEST); mContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); if (!mContextStack) { NS_ERROR("failed to get the nsThreadJSContextStack service"); return NS_ERROR_FAILURE; } JS_SetErrorReporter(mJSContext, my_ErrorReporter); nsCOMPtr<nsIXPConnectJSObjectHolder> holder; xpc->InitClassesWithNewWrappedGlobal(mJSContext, (nsIJSSh*)this, NS_GET_IID(nsISupports), PR_TRUE, getter_AddRefs(holder)); if (!holder) { NS_ERROR("global initialization failed"); return NS_ERROR_FAILURE; } holder->GetJSObject(&mGlobal); if (!mGlobal) { NS_ERROR("bad global object"); return NS_ERROR_FAILURE; } mContextObj = mGlobal; if (!JS_DefineFunctions(mJSContext, mGlobal, global_functions)) { NS_ERROR("failed to initialise global functions"); return NS_ERROR_FAILURE; } if (!mStartupURI.IsEmpty()) LoadURL(mStartupURI.get()); return NS_OK; }
~AutoDontReportUncaught() { if (!mWasSet) { JS_SetOptions(mContext, JS_GetOptions(mContext) & ~JSOPTION_DONT_REPORT_UNCAUGHT); } }
/* * See: * https://bugzilla.mozilla.org/show_bug.cgi?id=166436 * https://bugzilla.mozilla.org/show_bug.cgi?id=215173 * * Very surprisingly, jsapi.h lacks any way to "throw new Error()" * * So here is an awful hack inspired by * http://egachine.berlios.de/embedding-sm-best-practice/embedding-sm-best-practice.html#error-handling */ static void gjs_throw_valist(JSContext *context, const char *format, va_list args) { char *s; jsval retval; jsval argv[1]; JSFunction *func; const char *body; JSBool result; const char *names[] = { "message" }; guint options; s = g_strdup_vprintf(format, args); JS_BeginRequest(context); if (JS_IsExceptionPending(context)) { /* Often it's unclear whether a given jsapi.h function * will throw an exception, so we will throw ourselves * "just in case"; in those cases, we don't want to * overwrite an exception that already exists. * (Do log in case our second exception adds more info, * but don't log as topic ERROR because if the exception is * caught we don't want an ERROR in the logs.) */ gjs_debug(GJS_DEBUG_CONTEXT, "Ignoring second exception: '%s'", s); g_free(s); return; } result = JS_FALSE; JS_EnterLocalRootScope(context); if (!gjs_string_from_utf8(context, s, -1, &argv[0])) { JS_ReportError(context, "Failed to copy exception string"); goto out; } body = "throw new Error(message);"; func = JS_CompileFunction(context, JS_GetGlobalObject(context), /* parent object (scope chain) */ NULL, /* name of function if we wanted to define it in parent */ 1, /* nargs */ &names[0], /* array of arg names if we had args */ body, strlen(body), "gjs_throw", /* file */ 0); /* line */ if (func == NULL) { JS_ReportError(context, "Failed to compile function"); goto out; } /* we need JS_CallFunctionValue() to leave the exception set */ options = JS_GetOptions(context); if (!(options & JSOPTION_DONT_REPORT_UNCAUGHT)) { JS_SetOptions(context, options | JSOPTION_DONT_REPORT_UNCAUGHT); } retval = JSVAL_VOID; /* note the return value is whether function succeeded, which it shouldn't, since it * throws... */ JS_CallFunctionValue(context, JS_GetGlobalObject(context), OBJECT_TO_JSVAL(JS_GetFunctionObject(func)), 1, &argv[0], &retval); if (!(options & JSOPTION_DONT_REPORT_UNCAUGHT)) { JS_SetOptions(context, options); } if (!JS_IsExceptionPending(context)) { JS_ReportError(context, "Failed to set exception by calling our exception-setting function"); goto out; } result = JS_TRUE; out: JS_LeaveLocalRootScope(context); if (!result) { /* try just reporting it to error handler? should not * happen though pretty much */ JS_ReportError(context, "Failed to throw exception '%s'", s); } g_free(s); JS_EndRequest(context); }
/** Process the script interpreter flags. * * @param flags An array of flags, in no particular order. */ static void processFlags(JSContext *cx, const char *flags, signed int *verbosity_p) { int gcZeal = 0; int jsOptions; const char *f; gpsee_runtime_t *grt = JS_GetRuntimePrivate(JS_GetRuntime(cx)); jsOptions = JS_GetOptions(cx) | JSOPTION_ANONFUNFIX | JSOPTION_STRICT | JSOPTION_RELIMIT | JSOPTION_JIT; *verbosity_p = 0; /* Iterate over each flag */ for (f=flags; *f; f++) { switch(*f) { /* 'C' flag disables compiler cache */ case 'C': grt->useCompilerCache = 0; break; case 'a': /* Handled in prmain() */ case 'R': /* Handled in loadRuntimeConfig() */ case 'U': /* Must be handled before 1st JS runtime */ break; case 'x': /* Parse <!-- comments --> as E4X tokens */ jsOptions |= JSOPTION_XML; break; case 'S': /* Disable Strict JS */ jsOptions &= ~JSOPTION_STRICT; break; case 'W': /* Suppress JS Warnings */ grt->errorReport |= er_noWarnings; break; case 'e': /* Allow regexps that are more than O(n^3) */ jsOptions &= ~JSOPTION_RELIMIT; break; case 'J': /* Disable Nanojit */ jsOptions &= ~JSOPTION_JIT; break; case 'z': /* GC Zeal */ gcZeal++; break; case 'd': /* increase debug level */ (*verbosity_p)++;; break; default: gpsee_log(cx, GLOG_WARNING, "Error: Unrecognized option flag %c!", *f); break; } } #ifdef JSFEATURE_GC_ZEAL if (JS_HasFeature(JSFEATURE_GC_ZEAL) == JS_TRUE) JS_SetGCZeal(cx, gcZeal); #else # ifdef JS_GC_ZEAL JS_SetGCZeal(cx, gcZeal); # else # warning JS_SetGCZeal not available when building with this version of SpiderMonkey (try a debug build?) # endif #endif JS_SetOptions(cx, jsOptions); }
/* void CompileFile (in nsILocalFile aFile, in PRBool strict); */ NS_IMETHODIMP nsXPCToolsCompiler::CompileFile(nsILocalFile *aFile, PRBool strict) { // use the xpccallcontext stuff to get the current JSContext // get the xpconnect service nsresult rv; nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); if(NS_FAILED(rv)) return NS_ERROR_FAILURE; // get the xpconnect native call context nsCOMPtr<nsIXPCNativeCallContext> callContext; xpc->GetCurrentNativeCallContext(getter_AddRefs(callContext)); if(!callContext) return NS_ERROR_FAILURE; // verify that we are being called from JS (i.e. the current call is // to this object - though we don't verify that it is to this exact method) nsCOMPtr<nsISupports> callee; callContext->GetCallee(getter_AddRefs(callee)); if(!callee || callee.get() != (nsISupports*)this) return NS_ERROR_FAILURE; // Get JSContext of current call JSContext* cx; rv = callContext->GetJSContext(&cx); if(NS_FAILED(rv) || !cx) return NS_ERROR_FAILURE; FILE* handle; if(NS_FAILED(aFile->OpenANSIFileDesc("r", &handle))) return NS_ERROR_FAILURE; JSObject* glob = JS_NewObject(cx, &global_class, NULL, NULL); if (!glob) return NS_ERROR_FAILURE; if (!JS_InitStandardClasses(cx, glob)) return NS_ERROR_FAILURE; nsCAutoString path; if(NS_FAILED(aFile->GetNativePath(path))) return NS_ERROR_FAILURE; uint32 oldoptions = JS_GetOptions(cx); JS_SetOptions(cx, JSOPTION_WERROR | (strict ? JSOPTION_STRICT : 0)); JSErrorReporter older = JS_SetErrorReporter(cx, ErrorReporter); JSExceptionState *es =JS_SaveExceptionState(cx); if(!JS_CompileFileHandle(cx, glob, path.get(), handle)) { jsval v; JSErrorReport* report; if(JS_GetPendingException(cx, &v) && nsnull != (report = JS_ErrorFromException(cx, v))) { JSString* str; const char* msg = "Error"; str = JS_ValueToString(cx, v); if(str) msg = JS_GetStringBytes(str); printf("%s [%s,%d]\n\n", msg, report->filename, (int)report->lineno); } else { printf("no script and no error report!\n"); } } JS_RestoreExceptionState(cx, es); JS_SetErrorReporter(cx, older); JS_SetOptions(cx, oldoptions); return NS_OK; }
/** * Create a new GPSEE Realm. New realm will be initialized to have all members NULL, except * - the context and name provided (name only present in debug build) * - an initialized module system (and hence module data store) * - an initialized I/O hooks data store * - an initialized global object * - a prototype for the module object * * @param grt The GPSEE runtime to which the new realm will belong * @param name A symbolic name, for use in debugging, to describe this realm. Does not need to be unique. * * @returns The new realm, or NULL if we threw an exception. */ gpsee_realm_t *gpsee_createRealm(gpsee_runtime_t *grt, const char *name) { gpsee_realm_t *realm = NULL; JSContext *cx; cx = JS_NewContext(grt->rt, 8192); if (!cx) return NULL; JS_BeginRequest(cx); JS_SetOptions(cx, JS_GetOptions(grt->coreCx)); gpsee_enterAutoMonitor(cx, &grt->monitors.realms); realm = JS_malloc(cx, sizeof(*realm)); if (!realm) goto err_out; memset(realm, 0, sizeof(*realm)); realm->grt = grt; #ifdef GPSEE_DEBUG_BUILD realm->name = JS_strdup(cx, name); if (!realm->name) goto err_out; #endif realm->user_io_pendingWrites = gpsee_ds_create(grt, GPSEE_DS_OTM_KEYS, 0); if (!realm->user_io_pendingWrites) return JS_FALSE; #if defined(JSRESERVED_GLOBAL_COMPARTMENT) realm->globalObject = JS_NewCompartmentAndGlobalObject(cx, gpsee_getGlobalClass(), NULL); #else realm->globalObject = JS_NewGlobalObject(cx, gpsee_getGlobalClass()); #endif if (!realm->globalObject) goto err_out; { static JSClass moduleObjectClass = { GPSEE_GLOBAL_NAMESPACE_NAME ".Module", 0, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub }; #undef JS_InitClass moduleObjectClass.name += sizeof(GPSEE_GLOBAL_NAMESPACE_NAME); realm->moduleObjectProto = JS_InitClass(cx, realm->globalObject, NULL, &moduleObjectClass, ModuleObject, 0, NULL, NULL, NULL, NULL); moduleObjectClass.name -= sizeof(GPSEE_GLOBAL_NAMESPACE_NAME); realm->moduleObjectClass = &moduleObjectClass; #define JS_InitClass poison } if (!realm->moduleObjectProto) goto err_out; JS_AddNamedObjectRoot(cx, &realm->globalObject, "super-global"); if (gpsee_ds_put(grt->realms, realm, NULL) == JS_FALSE) goto err_out; if (gpsee_initializeModuleSystem(cx, realm) == JS_FALSE) panic("Unable to initialize module system"); if (gpsee_initGlobalObject(cx, realm, realm->globalObject) == JS_FALSE) goto err_out; realm->cachedCx = cx; goto out; err_out: if (realm) { JS_free(cx, realm); #ifdef GPSEE_DEBUG_BUILD if (realm->name) JS_free(cx, (char *)realm->name); #endif realm = NULL; } if (cx) { JS_DestroyContext(cx); cx = NULL; } out: gpsee_leaveAutoMonitor(grt->monitors.realms); if (cx) JS_EndRequest(cx); return realm; }
JLThreadFuncDecl TaskThreadProc( void *threadArg ) { TaskPrivate *pv = NULL; jl::ChunkedBuffer<char> errBuffer; JSContext *cx = CreateHost((uint32_t)-1, (uint32_t)-1, 0); if ( cx == NULL ) // out of memory JLThreadExit(0); jl::Host& hpv; hpv = jl::Host::getJLHost(cx); // allocator must be threadsafe ! hpv->alloc.malloc = jl_malloc; hpv->alloc.calloc = jl_calloc; hpv->alloc.memalign = jl_memalign; hpv->alloc.realloc = jl_realloc; hpv->alloc.msize = jl_msize; hpv->alloc.free = jl_free; JL_CHK( InitHost(cx, _unsafeMode != 0, NULL, NULL, TaskStdErrHostOutput, &errBuffer) ); JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT); pv = (TaskPrivate*)threadArg; ASSERT( pv ); bool ok; ok = TheTask(cx, pv); if ( !ok ) { // handle fatal error jsval ex; if ( JL_IsExceptionPending(cx) ) { ok = JS_GetPendingException(cx, &ex); JS_ClearPendingException(cx); JL_CHK( ok ); } else { JL_CHK( JL_NativeToJsval(cx, errBuffer.GetData(), errBuffer.Length(), &ex) ); } SerializedData * serializedException; SerializerCreate(&serializedException); if ( !SerializeJsval(cx, serializedException, &ex) ) { ASSERT( false ); JLSemaphoreRelease(pv->responseSem); // +1 JL_ERR( E_JSLIBS, E_STR("serializer"), E_INTERNAL ); } JLMutexAcquire(pv->mutex); // -- pv->end = true; QueuePush(&pv->exceptionList, serializedException); JLMutexRelease(pv->mutex); // ++ JLSemaphoreRelease(pv->responseSem); // +1 } good: bad: // These queues must be destroyed before cx because SerializedData * *ser hold a reference to the context that created the value. JLMutexAcquire(pv->mutex); // -- while ( !QueueIsEmpty(&pv->exceptionList) ) { SerializedData * ser = (SerializedData *)QueueShift(&pv->exceptionList); SerializerFree(&ser); } while ( !QueueIsEmpty(&pv->responseList) ) { SerializedData * ser = (SerializedData *)QueueShift(&pv->responseList); SerializerFree(&ser); } JLMutexRelease(pv->mutex); // ++ if ( cx ) DestroyHost(cx, false); // no skip cleanup, else memory leaks. JLThreadExit(0); return 0; }