CJSRuntime::CJSRuntime(UI32 engineSize) { jsRuntime = JS_NewRuntime(engineSize); if (jsRuntime == NULL) Shutdown(FATAL_UOX3_JAVASCRIPT); jsContext = JS_NewContext(jsRuntime, 0x500000); if (jsContext == NULL) Shutdown(FATAL_UOX3_JAVASCRIPT); jsGlobal = JS_NewObject(jsContext, &global_class, NULL, NULL); if (jsGlobal == NULL) Shutdown(FATAL_UOX3_JAVASCRIPT); JS_LockGCThing(jsContext, jsGlobal); //JS_AddRoot(jsContext, &jsGlobal); JS_InitStandardClasses(jsContext, jsGlobal); objectList.resize(IUE_COUNT); InitializePrototypes(); }
void JsBuiltInEngineInterfaceExtensionObject::InjectJsBuiltInLibraryCode(ScriptContext * scriptContext) { JavascriptExceptionObject *pExceptionObject = nullptr; if (jsBuiltInByteCode != nullptr) { return; } try { EnsureJsBuiltInByteCode(scriptContext); Assert(jsBuiltInByteCode != nullptr); Js::ScriptFunction *functionGlobal = scriptContext->GetLibrary()->CreateScriptFunction(jsBuiltInByteCode); // If we are in the debugger and doing a GetProperty of arguments, then Js Builtins code will be injected on-demand // Since it is a cross site call, we marshall not only functionGlobal but also its entire prototype chain // The prototype of functionGlobal will be shared by a normal Js function, // so marshalling will inadvertantly transition the entrypoint of the prototype to a crosssite entrypoint // So we set the prototype to null here functionGlobal->SetPrototype(scriptContext->GetLibrary()->nullValue); #ifdef ENABLE_SCRIPT_PROFILING // If we are profiling, we need to register the script to the profiler callback, so the script compiled event will be sent. if (scriptContext->IsProfiling()) { scriptContext->RegisterScript(functionGlobal->GetFunctionProxy()); } #endif #ifdef ENABLE_SCRIPT_DEBUGGING // Mark we are profiling library code already, so that any initialization library code called here won't be reported to profiler. // Also tell the debugger not to record events during intialization so that we don't leak information about initialization. AutoInitLibraryCodeScope autoInitLibraryCodeScope(scriptContext); #endif Js::Var args[] = { scriptContext->GetLibrary()->GetUndefined(), scriptContext->GetLibrary()->GetEngineInterfaceObject() }; Js::CallInfo callInfo(Js::CallFlags_Value, _countof(args)); // Clear disable implicit call bit as initialization code doesn't have any side effect Js::ImplicitCallFlags saveImplicitCallFlags = scriptContext->GetThreadContext()->GetImplicitCallFlags(); scriptContext->GetThreadContext()->ClearDisableImplicitFlags(); JavascriptFunction::CallRootFunctionInScript(functionGlobal, Js::Arguments(callInfo, args)); scriptContext->GetThreadContext()->SetImplicitCallFlags((Js::ImplicitCallFlags)(saveImplicitCallFlags)); Js::ScriptFunction *functionBuiltins = scriptContext->GetLibrary()->CreateScriptFunction(jsBuiltInByteCode->GetNestedFunctionForExecution(0)); functionBuiltins->SetPrototype(scriptContext->GetLibrary()->nullValue); // Clear disable implicit call bit as initialization code doesn't have any side effect saveImplicitCallFlags = scriptContext->GetThreadContext()->GetImplicitCallFlags(); scriptContext->GetThreadContext()->ClearDisableImplicitFlags(); JavascriptFunction::CallRootFunctionInScript(functionBuiltins, Js::Arguments(callInfo, args)); scriptContext->GetThreadContext()->SetImplicitCallFlags((Js::ImplicitCallFlags)(saveImplicitCallFlags)); InitializePrototypes(scriptContext); #if DBG_DUMP if (PHASE_DUMP(Js::ByteCodePhase, functionGlobal->GetFunctionProxy()) && Js::Configuration::Global.flags.Verbose) { DumpByteCode(); } #endif } catch (const JavascriptException& err) { pExceptionObject = err.GetAndClear(); } if (pExceptionObject) { jsBuiltInByteCode = nullptr; if (pExceptionObject == ThreadContext::GetContextForCurrentThread()->GetPendingSOErrorObject()) { JavascriptExceptionOperators::DoThrowCheckClone(pExceptionObject, scriptContext); } Js::Throw::FatalJsBuiltInError(); } }