static void CreateGlobalAndRunTest(JSRuntime* rt, JSContext* cx) { static const JSClass GlobalClass = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); JS::RootedObject global(cx); global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options); ASSERT_TRUE(global != nullptr); JS_AddNamedObjectRoot(cx, global.address(), "test-global"); JSCompartment *oldCompartment = JS_EnterCompartment(cx, global); RunTest(rt, cx); JS_LeaveCompartment(cx, oldCompartment); JS_RemoveObjectRoot(cx, global.address()); }
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); }
JSObject *newDelegate() { static const JSClass delegateClass = { "delegate", JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_RESERVED_SLOTS(1), JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; /* Create the global object. */ JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); JS::RootedObject global(cx); global = JS_NewGlobalObject(cx, &delegateClass, nullptr, JS::FireOnNewGlobalHook, options); JS_SetReservedSlot(global, 0, JS::Int32Value(42)); /* * Ensure the delegate is not in the nursery because for the purpose of this * test we're going to put it in a private slot where it won't get updated. */ JS_GC(rt); return global; }
JSObject* createTestGlobal(bool preserveJitCode) { JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); options.setPreserveJitCode(preserveJitCode); return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options); }
void JavaScriptInterpreter::ReadEvalPrintLoop() { JSAutoRequest ar(cx); JS::CompartmentOptions compartmentOptions; compartmentOptions.setVersion(JSVERSION_DEFAULT); JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook, compartmentOptions)); if (!global) return; JS::RootedValue rval(cx); JSAutoCompartment ac(cx, global); if (!JS_InitStandardClasses(cx, global)) return; v = JS_GetVersion(cx); actionJSVersion->setDisabled(false); ///////////////////////////////////////////////////////////// int lineno = 1; int startline = lineno; errno = 1; u16string source = TextEdit_input->toPlainText().toStdU16String(); if (source.empty()) { if (errno) { char buffer[80]; strerror_s(buffer, 80, errno); JS_ReportError(cx, buffer); return; } return; } lineno++; QString output = EvalAndPrint(source.c_str(), source.length(), startline); if (output.isEmpty()) { JS_ReportPendingException(cx); } if (checkBox->isChecked()) { TextEdit_output->setPlainText(output); } else { TextEdit_output->insertPlainText(output + "\n"); } }
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); }
bool JSAudioContext::createContext() { if (m_JsRt != NULL) return false; if ((m_JsRt = JS_NewRuntime(JS::DefaultHeapMaxBytes, JS::DefaultNurseryBytes)) == NULL) { fprintf(stderr, "Failed to init JS runtime"); return false; } NidiumJS::SetJSRuntimeOptions(m_JsRt); JS_SetGCParameter(m_JsRt, JSGC_MAX_BYTES, 0xffffffff); JS_SetGCParameter(m_JsRt, JSGC_SLICE_TIME_BUDGET, 15); if ((m_JsTcx = JS_NewContext(m_JsRt, 8192)) == NULL) { fprintf(stderr, "Failed to init JS context"); return false; } NidiumLocalContext::InitJSThread(m_JsRt, m_JsTcx); JSAutoRequest ar(m_JsTcx); // JS_SetGCParameterForThread(this->tcx, JSGC_MAX_CODE_CACHE_BYTES, 16 * // 1024 * 1024); JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); JS::RootedObject global( m_JsTcx, JS_NewGlobalObject(m_JsTcx, &Global_AudioThread_class, nullptr, JS::DontFireOnNewGlobalHook, options)); JSAutoCompartment ac(m_JsTcx, global); m_JsGlobalObj = global; // We don't actually needs to root a global object, but we // need to store a reference to the global object in a // JS::Heap and this reference needs to be traced. NidiumLocalContext::RootObjectUntilShutdown(m_JsGlobalObj); if (!JS_InitStandardClasses(m_JsTcx, global)) { fprintf(stderr, "Failed to init std class"); return false; } JS_SetErrorReporter(m_JsRt, reportError); JS_FireOnNewGlobalObject(m_JsTcx, global); JSConsole::RegisterObject(m_JsTcx); JSAudioNodeThreaded::RegisterObject(m_JsTcx); return true; }
static void CreateGlobalAndRunTest(JSRuntime* rt, JSContext* cx) { static const JSClass GlobalClass = { "global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); JS::PersistentRootedObject global(cx); global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options); ASSERT_TRUE(global != nullptr); JSCompartment *oldCompartment = JS_EnterCompartment(cx, global); typedef Heap<JSObject*> ElementT; { nsTArray<ElementT>* array = new nsTArray<ElementT>(InitialElements); RunTest(rt, cx, array); delete array; } { FallibleTArray<ElementT>* array = new FallibleTArray<ElementT>(InitialElements); RunTest(rt, cx, array); delete array; } { nsAutoTArray<ElementT, InitialElements> array; RunTest(rt, cx, &array); } { AutoFallibleTArray<ElementT, InitialElements> array; RunTest(rt, cx, &array); } JS_LeaveCompartment(cx, oldCompartment); }
int main (int argc, const char **argv) { JSRuntime *runtime = checkPtr(JS_NewRuntime(1024 * 1024, JS_USE_HELPER_THREADS)); JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff); JS_SetNativeStackQuota(runtime, 5000000); JSContext *cx = checkPtr(JS_NewContext(runtime, 8192)); JS_SetErrorReporter(cx, reportError); JSAutoRequest ar(cx); /* Create the global object. */ JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class, NULL, JS::FireOnNewGlobalHook, options))); js::SetDefaultObjectForContext(cx, global); JSAutoCompartment ac(cx, global); /* Populate the global object with the standard globals, like Object and Array. */ checkBool(JS_InitStandardClasses(cx, global)); argv++; while (*argv) { const char *name = *argv++; GDBFragment *fragment; for (fragment = GDBFragment::allFragments; fragment; fragment = fragment->next) { if (strcmp(fragment->name(), name) == 0) { fragment->run(cx, argv); break; } } if (!fragment) { fprintf(stderr, "Unrecognized fragment name: %s\n", name); exit(1); } } return 0; }
JSObject * JSAPITest::createGlobal(JSPrincipals *principals) { /* Create the global object. */ JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); global = JS_NewGlobalObject(cx, getGlobalClass(), principals, options); if (!global) return NULL; JS_AddNamedObjectRoot(cx, &global, "test-global"); JS::HandleObject globalHandle = JS::HandleObject::fromMarkedLocation(&global); JSAutoCompartment ac(cx, globalHandle); /* Populate the global object with the standard globals, like Object and Array. */ if (!JS_InitStandardClasses(cx, globalHandle)) return NULL; return global; }
JSObject* newDelegate() { static const js::Class delegateClass = { "delegate", JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_RESERVED_SLOTS(1), nullptr, /* addProperty */ nullptr, /* delProperty */ nullptr, /* getProperty */ nullptr, /* setProperty */ nullptr, /* enumerate */ nullptr, /* resolve */ nullptr, /* mayResolve */ nullptr, /* convert */ nullptr, /* finalize */ nullptr, /* call */ nullptr, /* hasInstance */ nullptr, /* construct */ JS_GlobalObjectTraceHook, JS_NULL_CLASS_SPEC, { nullptr, nullptr, false, nullptr, DelegateObjectMoved }, JS_NULL_OBJECT_OPS }; /* Create the global object. */ JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); JS::RootedObject global(cx); global = JS_NewGlobalObject(cx, Jsvalify(&delegateClass), nullptr, JS::FireOnNewGlobalHook, options); JS_SetReservedSlot(global, 0, JS::Int32Value(42)); return global; }
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; } if (!JS_Init()) return false; std::cout << "Input file: " << inputFilePath << std::endl; JSRuntime * runtime = JS_NewRuntime(10 * 1024 * 1024, JS_NO_HELPER_THREADS); JSContext *cx = JS_NewContext(runtime, 10240); JS_SetOptions(cx, JSOPTION_TYPE_INFERENCE); JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); JS::RootedObject global(cx, JS_NewGlobalObject(cx, &GlobalClass, NULL, JS::DontFireOnNewGlobalHook, options)); JS_SetErrorReporter(cx, &ReportError); { JSAutoCompartment ac(cx, global); if (JS_InitStandardClasses(cx, global)) { JS_InitReflect(cx, global); JS_FireOnNewGlobalObject(cx, global); JS::CompileOptions options(cx); options.setUTF8(true); options.setSourcePolicy(JS::CompileOptions::NO_SOURCE); std::cout << "Compiling ..." << std::endl; JS::RootedScript script(cx, JS::Compile(cx, global, options, inputFilePath.c_str())); if (script) { void *data = NULL; uint32_t length = 0; std::cout << "Encoding ..." << std::endl; data = JS_EncodeScript(cx, script, &length); if (data) { if (WriteFile(ofp, data, length)) { std::cout << "Done! " << "Output file: " << ofp << std::endl; result = true; } } } else { std::cout << "Compiled " << inputFilePath << " fails!" << std::endl; } } else { std::cout << "JS_InitStandardClasses failed! " << std::endl; } } if (cx) { JS_DestroyContext(cx); cx = NULL; } if (runtime) { JS_DestroyRuntime(runtime); runtime = NULL; } JS_ShutDown(); return result; }