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; }
void InitGlobalObjectOptions(JS::CompartmentOptions& aOptions, nsIPrincipal* aPrincipal) { bool shouldDiscardSystemSource = ShouldDiscardSystemSource(); bool extraWarningsForSystemJS = ExtraWarningsForSystemJS(); bool isSystem = nsContentUtils::IsSystemPrincipal(aPrincipal); if (isSystem) { // Make sure [SecureContext] APIs are visible: aOptions.creationOptions().setSecureContext(true); #if 0 // TODO: Reenable in Bug 1288653 // Enable the ECMA-402 experimental formatToParts in any chrome page aOptions.creationOptions() .setExperimentalDateTimeFormatFormatToPartsEnabled(true); #endif } if (shouldDiscardSystemSource) { bool discardSource = isSystem; aOptions.behaviors().setDiscardSource(discardSource); } if (extraWarningsForSystemJS) { if (isSystem) aOptions.behaviors().extraWarningsOverride().set(true); } }
bool DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector) { mWorkerPrivate->AssertIsOnWorkerThread(); MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker()); JS::CompartmentOptions options; mWorkerPrivate->CopyJSCompartmentOptions(options); const bool usesSystemPrincipal = mWorkerPrivate->UsesSystemPrincipal(); // Note that xpc::ShouldDiscardSystemSource() and // xpc::ExtraWarningsForSystemJS() read prefs that are cached on the main // thread. This is benignly racey. const bool discardSource = (usesSystemPrincipal || mWorkerPrivate->IsInPrivilegedApp()) && xpc::ShouldDiscardSystemSource(); const bool extraWarnings = usesSystemPrincipal && xpc::ExtraWarningsForSystemJS(); options.setDiscardSource(discardSource) .extraWarningsOverride().set(extraWarnings); return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options, GetWorkerPrincipal(), true, aReflector); }
JSObject* createTestGlobal(bool preserveJitCode) { JS::CompartmentOptions options; options.creationOptions().setPreserveJitCode(preserveJitCode); return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options); }
bool DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector) { mWorkerPrivate->AssertIsOnWorkerThread(); MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker()); JS::CompartmentOptions options; mWorkerPrivate->CopyJSCompartmentOptions(options); const bool usesSystemPrincipal = mWorkerPrivate->UsesSystemPrincipal(); // Note that xpc::ShouldDiscardSystemSource() and // xpc::ExtraWarningsForSystemJS() read prefs that are cached on the main // thread. This is benignly racey. const bool discardSource = usesSystemPrincipal && xpc::ShouldDiscardSystemSource(); const bool extraWarnings = usesSystemPrincipal && xpc::ExtraWarningsForSystemJS(); JS::CompartmentBehaviors& behaviors = options.behaviors(); behaviors.setDiscardSource(discardSource) .extraWarningsOverride().set(extraWarnings); const bool sharedMemoryEnabled = xpc::SharedMemoryEnabled(); JS::CompartmentCreationOptions& creationOptions = options.creationOptions(); creationOptions.setSharedMemoryAndAtomicsEnabled(sharedMemoryEnabled); return DedicatedWorkerGlobalScopeBinding::Wrap(aCx, this, this, options, GetWorkerPrincipal(), true, aReflector); }
void InitGlobalObjectOptions(JS::CompartmentOptions& aOptions, nsIPrincipal* aPrincipal) { bool shouldDiscardSystemSource = ShouldDiscardSystemSource(); bool extraWarningsForSystemJS = ExtraWarningsForSystemJS(); bool isSystem = nsContentUtils::IsSystemPrincipal(aPrincipal); if (isSystem) { // Make sure [SecureContext] APIs are visible: aOptions.creationOptions().setSecureContext(true); } short status = aPrincipal->GetAppStatus(); // Enable the ECMA-402 experimental formatToParts in certified apps. if (status == nsIPrincipal::APP_STATUS_CERTIFIED) { aOptions.creationOptions() .setExperimentalDateTimeFormatFormatToPartsEnabled(true); } if (shouldDiscardSystemSource) { bool discardSource = isSystem || (status == nsIPrincipal::APP_STATUS_PRIVILEGED || status == nsIPrincipal::APP_STATUS_CERTIFIED); aOptions.behaviors().setDiscardSource(discardSource); } if (extraWarningsForSystemJS) { if (isSystem) aOptions.behaviors().extraWarningsOverride().set(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_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); }
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()); }
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions()) : creationOptions_(options.creationOptions()), behaviors_(options.behaviors()), zone_(zone), runtime_(zone->runtimeFromAnyThread()), principals_(nullptr), isSystem_(false), isAtomsCompartment_(false), isSelfHosting(false), marked(true), warnedAboutExprClosure(false), warnedAboutStringGenericsMethods(0), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), globalHolds(0), performanceMonitoring(runtime_), data(nullptr), realmData(nullptr), allocationMetadataBuilder(nullptr), lastAnimationTime(0), regExps(), arraySpeciesLookup(), globalWriteBarriered(0), detachedTypedObjects(0), objectMetadataState(ImmediateMetadata()), selfHostingScriptSource(nullptr), objectMetadataTable(nullptr), innerViews(zone), lazyArrayBuffers(nullptr), wasm(zone), nonSyntacticLexicalEnvironments_(nullptr), gcIncomingGrayPointers(nullptr), debugModeBits(0), validAccessPtr(nullptr), randomKeyGenerator_(runtime_->forkRandomKeyGenerator()), scriptCountsMap(nullptr), scriptNameMap(nullptr), debugScriptMap(nullptr), debugEnvs(nullptr), enumerators(nullptr), compartmentStats_(nullptr), scheduledForDestruction(false), maybeAlive(true), jitCompartment_(nullptr), mappedArgumentsTemplate_(nullptr), unmappedArgumentsTemplate_(nullptr), iterResultTemplate_(nullptr), lcovOutput() { PodArrayZero(sawDeprecatedLanguageExtension); runtime_->numCompartments++; MOZ_ASSERT_IF(creationOptions_.mergeable(), creationOptions_.invisibleToDebugger()); }
JSContext* XPCJSContextStack::GetSafeJSContext() { if (mSafeJSContext) return mSafeJSContext; // Start by getting the principal holder and principal for this // context. If we can't manage that, don't bother with the rest. nsRefPtr<nsNullPrincipal> principal = new nsNullPrincipal(); nsresult rv = principal->Init(); if (NS_FAILED(rv)) MOZ_CRASH(); nsXPConnect* xpc = nsXPConnect::XPConnect(); JSRuntime *rt = xpc->GetRuntime()->Runtime(); if (!rt) MOZ_CRASH(); mSafeJSContext = JS_NewContext(rt, 8192); if (!mSafeJSContext) MOZ_CRASH(); JSAutoRequest req(mSafeJSContext); JS::RootedObject glob(mSafeJSContext); JS_SetErrorReporter(mSafeJSContext, xpc::SystemErrorReporter); JS::CompartmentOptions options; options.setZone(JS::SystemZone); glob = xpc::CreateGlobalObject(mSafeJSContext, &SafeJSContextGlobalClass, principal, options); if (!glob) MOZ_CRASH(); // Make sure the context is associated with a proper compartment // and not the default compartment. js::SetDefaultObjectForContext(mSafeJSContext, glob); // Note: make sure to set the private before calling // InitClasses nsCOMPtr<nsIScriptObjectPrincipal> sop = new SandboxPrivate(principal, glob); JS_SetPrivate(glob, sop.forget().get()); // After this point either glob is null and the // nsIScriptObjectPrincipal ownership is either handled by the // nsCOMPtr or dealt with, or we'll release in the finalize // hook. if (NS_FAILED(xpc->InitClasses(mSafeJSContext, glob))) MOZ_CRASH(); JS_FireOnNewGlobalObject(mSafeJSContext, glob); // Save it off so we can destroy it later. mOwnSafeJSContext = mSafeJSContext; return mSafeJSContext; }
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; }
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); }
JSContext* XPCJSContextStack::InitSafeJSContext() { MOZ_ASSERT(!mSafeJSContext); // Start by getting the principal holder and principal for this // context. If we can't manage that, don't bother with the rest. nsRefPtr<nsNullPrincipal> principal = new nsNullPrincipal(); nsresult rv = principal->Init(); if (NS_FAILED(rv)) MOZ_CRASH(); nsXPConnect* xpc = nsXPConnect::XPConnect(); JSRuntime *rt = xpc->GetRuntime()->Runtime(); if (!rt) MOZ_CRASH(); mSafeJSContext = JS_NewContext(rt, 8192); if (!mSafeJSContext) MOZ_CRASH(); JSAutoRequest req(mSafeJSContext); ContextOptionsRef(mSafeJSContext).setNoDefaultCompartmentObject(true); JS_SetErrorReporter(mSafeJSContext, xpc::SystemErrorReporter); JS::CompartmentOptions options; options.setZone(JS::SystemZone) .setTrace(TraceXPCGlobal); mSafeJSContextGlobal = CreateGlobalObject(mSafeJSContext, &SafeJSContextGlobalClass, principal, options); if (!mSafeJSContextGlobal) MOZ_CRASH(); JS_AddNamedObjectRoot(mSafeJSContext, &mSafeJSContextGlobal, "SafeJSContext global"); // Note: make sure to set the private before calling // InitClasses nsRefPtr<SandboxPrivate> sp = new SandboxPrivate(principal, mSafeJSContextGlobal); JS_SetPrivate(mSafeJSContextGlobal, sp.forget().take()); // After this point either glob is null and the // nsIScriptObjectPrincipal ownership is either handled by the // nsCOMPtr or dealt with, or we'll release in the finalize // hook. if (NS_FAILED(xpc->InitClasses(mSafeJSContext, mSafeJSContextGlobal))) MOZ_CRASH(); JS::RootedObject glob(mSafeJSContext, mSafeJSContextGlobal); JS_FireOnNewGlobalObject(mSafeJSContext, glob); return mSafeJSContext; }
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions()) : creationOptions_(options.creationOptions()), behaviors_(options.behaviors()), zone_(zone), runtime_(zone->runtimeFromMainThread()), principals_(nullptr), isSystem_(false), isSelfHosting(false), marked(true), warnedAboutExprClosure(false), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), performanceMonitoring(runtime_), data(nullptr), allocationMetadataBuilder(nullptr), lastAnimationTime(0), regExps(runtime_), globalWriteBarriered(0), detachedTypedObjects(0), objectMetadataState(ImmediateMetadata()), propertyTree(thisForCtor()), baseShapes(zone, BaseShapeSet()), initialShapes(zone, InitialShapeSet()), selfHostingScriptSource(nullptr), objectMetadataTable(nullptr), lazyArrayBuffers(nullptr), wasmInstances(zone, WasmInstanceObjectSet()), nonSyntacticLexicalScopes_(nullptr), gcIncomingGrayPointers(nullptr), debugModeBits(0), watchpointMap(nullptr), scriptCountsMap(nullptr), debugScriptMap(nullptr), debugScopes(nullptr), enumerators(nullptr), compartmentStats_(nullptr), scheduledForDestruction(false), maybeAlive(true), jitCompartment_(nullptr), mappedArgumentsTemplate_(nullptr), unmappedArgumentsTemplate_(nullptr), lcovOutput() { PodArrayZero(sawDeprecatedLanguageExtension); runtime_->numCompartments++; MOZ_ASSERT_IF(creationOptions_.mergeable(), creationOptions_.invisibleToDebugger()); }
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions()) : options_(options), zone_(zone), runtime_(zone->runtimeFromMainThread()), principals_(nullptr), isSystem_(false), isSelfHosting(false), marked(true), warnedAboutNoSuchMethod(false), warnedAboutFlagsArgument(false), addonId(options.addonIdOrNull()), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), performanceMonitoring(runtime_), data(nullptr), objectMetadataCallback(nullptr), lastAnimationTime(0), regExps(runtime_), globalWriteBarriered(false), neuteredTypedObjects(0), objectMetadataState(ImmediateMetadata()), propertyTree(thisForCtor()), selfHostingScriptSource(nullptr), objectMetadataTable(nullptr), lazyArrayBuffers(nullptr), nonSyntacticLexicalScopes_(nullptr), gcIncomingGrayPointers(nullptr), gcPreserveJitCode(options.preserveJitCode()), debugModeBits(0), rngState(0), watchpointMap(nullptr), scriptCountsMap(nullptr), debugScriptMap(nullptr), debugScopes(nullptr), enumerators(nullptr), compartmentStats(nullptr), scheduledForDestruction(false), maybeAlive(true), jitCompartment_(nullptr), mappedArgumentsTemplate_(nullptr), unmappedArgumentsTemplate_(nullptr), lcovOutput() { PodArrayZero(sawDeprecatedLanguageExtension); runtime_->numCompartments++; MOZ_ASSERT_IF(options.mergeable(), options.invisibleToDebugger()); }
JSContext* XPCJSContextStack::InitSafeJSContext() { MOZ_ASSERT(!mSafeJSContext); // Start by getting the principal holder and principal for this // context. If we can't manage that, don't bother with the rest. nsRefPtr<nsNullPrincipal> principal = new nsNullPrincipal(); nsresult rv = principal->Init(); if (NS_FAILED(rv)) MOZ_CRASH(); nsXPConnect* xpc = nsXPConnect::XPConnect(); JSRuntime *rt = xpc->GetRuntime()->Runtime(); if (!rt) MOZ_CRASH(); mSafeJSContext = JS_NewContext(rt, 8192); if (!mSafeJSContext) MOZ_CRASH(); JSAutoRequest req(mSafeJSContext); ContextOptionsRef(mSafeJSContext).setNoDefaultCompartmentObject(true); JS_SetErrorReporter(mSafeJSContext, xpc::SystemErrorReporter); // Note - We intentionally avoid firing OnNewGlobalObject while // simultaneously skipping the call to setInvisibleToDebugger(true) here. // This lets us piggy-back on the assertions in the JS engine (which make // sure that, for non-invisible globals, we always fire onNewGlobalObject // before creating scripts), to assert that we never create scripts with // the SafeJSContextGlobal. This is all happening way before anyone could be // listening for debugger notifications anyway. JS::CompartmentOptions options; options.setZone(JS::SystemZone) .setTrace(TraceXPCGlobal); mSafeJSContextGlobal = CreateGlobalObject(mSafeJSContext, &SafeJSContextGlobalClass, principal, options); if (!mSafeJSContextGlobal) MOZ_CRASH(); nsRefPtr<SandboxPrivate> sp = new SandboxPrivate(principal, mSafeJSContextGlobal); JS_SetPrivate(mSafeJSContextGlobal, sp.forget().take()); return mSafeJSContext; }
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) { if (!JS_Init()) return 1; JSContext* cx = checkPtr(JS_NewContext(1024 * 1024)); JS_SetGCParameter(cx, JSGC_MAX_BYTES, 0xffffffff); JS_SetNativeStackQuota(cx, 5000000); checkBool(JS::InitSelfHostedCode(cx)); JS::SetWarningReporter(cx, reportWarning); JSAutoRequest ar(cx); /* Create the global object. */ JS::CompartmentOptions options; options.behaviors().setVersion(JSVERSION_LATEST); RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook, options))); 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; }
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; }
JSCompartment::JSCompartment(Zone *zone, const JS::CompartmentOptions &options = JS::CompartmentOptions()) : options_(options), zone_(zone), runtime_(zone->runtimeFromMainThread()), principals(nullptr), isSystem(false), isSelfHosting(false), marked(true), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), data(nullptr), objectMetadataCallback(nullptr), lastAnimationTime(0), regExps(runtime_), typeReprs(runtime_), globalWriteBarriered(false), propertyTree(thisForCtor()), selfHostingScriptSource(nullptr), gcIncomingGrayPointers(nullptr), gcLiveArrayBuffers(nullptr), gcWeakMapList(nullptr), debugModeBits(runtime_->debugMode ? DebugFromC : 0), rngState(0), watchpointMap(nullptr), scriptCountsMap(nullptr), debugScriptMap(nullptr), debugScopes(nullptr), enumerators(nullptr), compartmentStats(nullptr) #ifdef JS_ION , jitCompartment_(nullptr) #endif { runtime_->numCompartments++; JS_ASSERT_IF(options.mergeable(), options.invisibleToDebugger()); }
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; }
GlobalObject * JSRuntime::createSelfHostingGlobal(JSContext *cx) { MOZ_ASSERT(!cx->isExceptionPending()); MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); JS::CompartmentOptions options; options.setDiscardSource(true); options.setZone(JS::FreshZone); JSCompartment *compartment = NewCompartment(cx, nullptr, nullptr, options); if (!compartment) return nullptr; static const Class shgClass = { "self-hosting-global", JSCLASS_GLOBAL_FLAGS, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook }; AutoCompartment ac(cx, compartment); Rooted<GlobalObject*> shg(cx, GlobalObject::createInternal(cx, &shgClass)); if (!shg) return nullptr; cx->runtime()->selfHostingGlobal_ = shg; compartment->isSelfHosting = true; compartment->isSystem = true; if (!GlobalObject::initSelfHostingBuiltins(cx, shg, intrinsic_functions)) return nullptr; JS_FireOnNewGlobalObject(cx, shg); return shg; }
nsresult Init() { mRuntime = JS_NewRuntime(sRuntimeHeapSize, JS_NO_HELPER_THREADS); NS_ENSURE_TRUE(mRuntime, NS_ERROR_OUT_OF_MEMORY); /* * Not setting this will cause JS_CHECK_RECURSION to report false * positives */ JS_SetNativeStackQuota(mRuntime, 128 * sizeof(size_t) * 1024); mContext = JS_NewContext(mRuntime, 0); NS_ENSURE_TRUE(mContext, NS_ERROR_OUT_OF_MEMORY); JSAutoRequest ar(mContext); JS::CompartmentOptions options; options.setZone(JS::SystemZone) .setVersion(JSVERSION_LATEST); mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr, JS::DontFireOnNewGlobalHook, options); NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY); JS::Rooted<JSObject*> global(mContext, mGlobal); JSAutoCompartment ac(mContext, global); js::SetDefaultObjectForContext(mContext, global); JS_InitStandardClasses(mContext, global); JS_SetErrorReporter(mContext, PACErrorReporter); if (!JS_DefineFunctions(mContext, global, PACGlobalFunctions)) return NS_ERROR_FAILURE; JS_FireOnNewGlobalObject(mContext, global); return NS_OK; }
bool XPCShellEnvironment::Init() { nsresult rv; // unbuffer stdout so that output is in the correct order; note that stderr // is unbuffered by default setbuf(stdout, 0); nsCOMPtr<nsIJSRuntimeService> rtsvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1"); if (!rtsvc) { NS_ERROR("failed to get nsJSRuntimeService!"); return false; } JSRuntime *rt; if (NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) { NS_ERROR("failed to get JSRuntime from nsJSRuntimeService!"); return false; } if (!mGlobalHolder.Hold(rt)) { NS_ERROR("Can't protect global object!"); return false; } AutoSafeJSContext cx; JS_SetContextPrivate(cx, this); nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID()); if (!xpc) { NS_ERROR("failed to get nsXPConnect service!"); return false; } nsCOMPtr<nsIPrincipal> principal; nsCOMPtr<nsIScriptSecurityManager> securityManager = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); if (NS_SUCCEEDED(rv) && securityManager) { rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal)); if (NS_FAILED(rv)) { fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n"); } } else { fprintf(stderr, "+++ Failed to get ScriptSecurityManager service, running without principals"); } nsRefPtr<BackstagePass> backstagePass; rv = NS_NewBackstagePass(getter_AddRefs(backstagePass)); if (NS_FAILED(rv)) { NS_ERROR("Failed to create backstage pass!"); return false; } JS::CompartmentOptions options; options.setZone(JS::SystemZone) .setVersion(JSVERSION_LATEST); nsCOMPtr<nsIXPConnectJSObjectHolder> holder; rv = xpc->InitClassesWithNewWrappedGlobal(cx, static_cast<nsIGlobalObject *>(backstagePass), principal, 0, options, getter_AddRefs(holder)); if (NS_FAILED(rv)) { NS_ERROR("InitClassesWithNewWrappedGlobal failed!"); return false; } JS::Rooted<JSObject*> globalObj(cx, holder->GetJSObject()); if (!globalObj) { NS_ERROR("Failed to get global JSObject!"); return false; } JSAutoCompartment ac(cx, globalObj); backstagePass->SetGlobalObject(globalObj); if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment", PRIVATE_TO_JSVAL(this), JS_PropertyStub, JS_StrictPropertyStub, JSPROP_READONLY | JSPROP_PERMANENT) || !JS_DefineFunctions(cx, globalObj, gGlobalFunctions) || !JS_DefineProfilingFunctions(cx, globalObj)) { NS_ERROR("JS_DefineFunctions failed!"); return false; } mGlobalHolder = globalObj; FILE* runtimeScriptFile = fopen(kDefaultRuntimeScriptFilename, "r"); if (runtimeScriptFile) { fprintf(stdout, "[loading '%s'...]\n", kDefaultRuntimeScriptFilename); ProcessFile(cx, globalObj, kDefaultRuntimeScriptFilename, runtimeScriptFile, false); fclose(runtimeScriptFile); } return 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; } 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; }
bool JSRuntime::initSelfHosting(JSContext *cx) { JS_ASSERT(!selfHostingGlobal_); if (cx->runtime()->parentRuntime) { selfHostingGlobal_ = cx->runtime()->parentRuntime->selfHostingGlobal_; return true; } /* * Self hosted state can be accessed from threads for other runtimes * parented to this one, so cannot include state in the nursery. */ JS::AutoDisableGenerationalGC disable(cx->runtime()); JS::CompartmentOptions compartmentOptions; compartmentOptions.setDiscardSource(true); if (!(selfHostingGlobal_ = JS_NewGlobalObject(cx, &self_hosting_global_class, nullptr, JS::DontFireOnNewGlobalHook, compartmentOptions))) return false; JSAutoCompartment ac(cx, selfHostingGlobal_); Rooted<GlobalObject*> shg(cx, &selfHostingGlobal_->as<GlobalObject>()); selfHostingGlobal_->compartment()->isSelfHosting = true; selfHostingGlobal_->compartment()->isSystem = true; /* * During initialization of standard classes for the self-hosting global, * all self-hosted functions are ignored. Thus, we don't create cyclic * dependencies in the order of initialization. */ if (!GlobalObject::initStandardClasses(cx, shg)) return false; if (!JS_DefineFunctions(cx, shg, intrinsic_functions)) return false; JS_FireOnNewGlobalObject(cx, shg); CompileOptions options(cx); FillSelfHostingCompileOptions(options); /* * Set a temporary error reporter printing to stderr because it is too * early in the startup process for any other reporter to be registered * and we don't want errors in self-hosted code to be silently swallowed. */ JSErrorReporter oldReporter = JS_SetErrorReporter(cx->runtime(), selfHosting_ErrorReporter); RootedValue rv(cx); bool ok = false; char *filename = getenv("MOZ_SELFHOSTEDJS"); if (filename) { RootedScript script(cx); if (Compile(cx, shg, options, filename, &script)) ok = Execute(cx, script, *shg.get(), rv.address()); } else { uint32_t srcLen = GetRawScriptsSize(); const unsigned char *compressed = compressedSources; uint32_t compressedLen = GetCompressedSize(); ScopedJSFreePtr<char> src(selfHostingGlobal_->zone()->pod_malloc<char>(srcLen)); if (!src || !DecompressString(compressed, compressedLen, reinterpret_cast<unsigned char *>(src.get()), srcLen)) { return false; } ok = Evaluate(cx, shg, options, src, srcLen, &rv); } JS_SetErrorReporter(cx->runtime(), oldReporter); return ok; }
JSObject *createTestGlobal() { JS::CompartmentOptions options; options.setVersion(JSVERSION_LATEST); return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options); }
bool XPCShellEnvironment::Init() { nsresult rv; // unbuffer stdout so that output is in the correct order; note that stderr // is unbuffered by default setbuf(stdout, 0); AutoSafeJSContext cx; mGlobalHolder.init(cx); nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID()); if (!xpc) { NS_ERROR("failed to get nsXPConnect service!"); return false; } nsCOMPtr<nsIPrincipal> principal; nsCOMPtr<nsIScriptSecurityManager> securityManager = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); if (NS_SUCCEEDED(rv) && securityManager) { rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal)); if (NS_FAILED(rv)) { fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n"); } } else { fprintf(stderr, "+++ Failed to get ScriptSecurityManager service, running without principals"); } RefPtr<BackstagePass> backstagePass; rv = NS_NewBackstagePass(getter_AddRefs(backstagePass)); if (NS_FAILED(rv)) { NS_ERROR("Failed to create backstage pass!"); return false; } JS::CompartmentOptions options; options.creationOptions().setSystemZone(); options.behaviors().setVersion(JSVERSION_LATEST); if (xpc::SharedMemoryEnabled()) options.creationOptions().setSharedMemoryAndAtomicsEnabled(true); nsCOMPtr<nsIXPConnectJSObjectHolder> holder; rv = xpc->InitClassesWithNewWrappedGlobal(cx, static_cast<nsIGlobalObject *>(backstagePass), principal, 0, options, getter_AddRefs(holder)); if (NS_FAILED(rv)) { NS_ERROR("InitClassesWithNewWrappedGlobal failed!"); return false; } JS::Rooted<JSObject*> globalObj(cx, holder->GetJSObject()); if (!globalObj) { NS_ERROR("Failed to get global JSObject!"); return false; } JSAutoCompartment ac(cx, globalObj); backstagePass->SetGlobalObject(globalObj); JS::Rooted<Value> privateVal(cx, PrivateValue(this)); if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment", privateVal, JSPROP_READONLY | JSPROP_PERMANENT, JS_STUBGETTER, JS_STUBSETTER) || !JS_DefineFunctions(cx, globalObj, gGlobalFunctions) || !JS_DefineProfilingFunctions(cx, globalObj)) { NS_ERROR("JS_DefineFunctions failed!"); return false; } mGlobalHolder = globalObj; FILE* runtimeScriptFile = fopen(kDefaultRuntimeScriptFilename, "r"); if (runtimeScriptFile) { fprintf(stdout, "[loading '%s'...]\n", kDefaultRuntimeScriptFilename); ProcessFile(cx, kDefaultRuntimeScriptFilename, runtimeScriptFile, false); fclose(runtimeScriptFile); } return true; }