示例#1
0
    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();
        }
    }