Var CrossSite::ProfileThunk(RecyclableObject* callable, CallInfo callInfo, ...) { JavascriptFunction* function = JavascriptFunction::FromVar(callable); Assert(function->GetTypeId() == TypeIds_Function); Assert(function->GetEntryPoint() == CrossSite::ProfileThunk); RUNTIME_ARGUMENTS(args, callInfo); ScriptContext * scriptContext = function->GetScriptContext(); // It is not safe to access the function body if the script context is not alive. scriptContext->VerifyAliveWithHostContext(!function->IsExternal(), scriptContext->GetThreadContext()->GetPreviousHostScriptContext()); JavascriptMethod entryPoint; FunctionInfo *funcInfo = function->GetFunctionInfo(); TTD_XSITE_LOG(callable->GetScriptContext(), "DefaultOrProfileThunk", callable); #ifdef ENABLE_WASM if (WasmScriptFunction::Is(function)) { AsmJsFunctionInfo* asmInfo = funcInfo->GetFunctionBody()->GetAsmJsFunctionInfo(); Assert(asmInfo); if (asmInfo->IsWasmDeferredParse()) { entryPoint = WasmLibrary::WasmDeferredParseExternalThunk; } else { entryPoint = Js::AsmJsExternalEntryPoint; } } else #endif if (funcInfo->HasBody()) { #if ENABLE_DEBUG_CONFIG_OPTIONS char16 debugStringBuffer[MAX_FUNCTION_BODY_DEBUG_STRING_SIZE]; #endif entryPoint = ScriptFunction::FromVar(function)->GetEntryPointInfo()->jsMethod; if (funcInfo->IsDeferred() && scriptContext->IsProfiling()) { // if the current entrypoint is deferred parse we need to update it appropriately for the profiler mode. entryPoint = Js::ScriptContext::GetProfileModeThunk(entryPoint); } OUTPUT_TRACE(Js::ScriptProfilerPhase, _u("CrossSite::ProfileThunk FunctionNumber : %s, Entrypoint : 0x%08X\n"), funcInfo->GetFunctionProxy()->GetDebugNumberSet(debugStringBuffer), entryPoint); } else { entryPoint = ProfileEntryThunk; } return CommonThunk(function, entryPoint, args); }
Var CrossSite::DefaultThunk(RecyclableObject* callable, CallInfo callInfo, ...) { JavascriptFunction* function = JavascriptFunction::FromVar(callable); Assert(function->GetTypeId() == TypeIds_Function); Assert(function->GetEntryPoint() == CrossSite::DefaultThunk); RUNTIME_ARGUMENTS(args, callInfo); // It is not safe to access the function body if the script context is not alive. function->GetScriptContext()->VerifyAliveWithHostContext(!function->IsExternal(), ThreadContext::GetContextForCurrentThread()->GetPreviousHostScriptContext()); JavascriptMethod entryPoint; FunctionInfo *funcInfo = function->GetFunctionInfo(); TTD_XSITE_LOG(callable->GetScriptContext(), "DefaultOrProfileThunk", callable); if (funcInfo->HasBody()) { #ifdef ASMJS_PLAT if (funcInfo->GetFunctionProxy()->IsFunctionBody() && funcInfo->GetFunctionBody()->GetIsAsmJsFunction()) { #ifdef ENABLE_WASM AsmJsFunctionInfo* asmInfo = funcInfo->GetFunctionBody()->GetAsmJsFunctionInfo(); if (asmInfo && asmInfo->IsWasmDeferredParse()) { entryPoint = WasmLibrary::WasmDeferredParseExternalThunk; } else #endif { entryPoint = Js::AsmJsExternalEntryPoint; } } else #endif { entryPoint = ScriptFunction::FromVar(function)->GetEntryPointInfo()->jsMethod; } } else { entryPoint = funcInfo->GetOriginalEntryPoint(); } return CommonThunk(function, entryPoint, args); }
void CrossSite::MarshalDynamicObject(ScriptContext * scriptContext, DynamicObject * object) { Assert(!object->IsExternal() && !object->IsCrossSiteObject()); TTD_XSITE_LOG(scriptContext, "MarshalDynamicObject", object); object->MarshalToScriptContext(scriptContext); if (object->GetTypeId() == TypeIds_Function) { AssertMsg(object != object->GetScriptContext()->GetLibrary()->GetDefaultAccessorFunction(), "default accessor marshalled"); JavascriptFunction * function = JavascriptFunction::FromVar(object); //TODO: this may be too aggressive and create x-site thunks that are't technically needed -- see uglify-2js test. // See if this function is one that the host needs to handle HostScriptContext * hostScriptContext = scriptContext->GetHostScriptContext(); if (!hostScriptContext || !hostScriptContext->SetCrossSiteForFunctionType(function)) { if (function->GetDynamicType()->GetIsLocked()) { TTD_XSITE_LOG(scriptContext, "SetCrossSiteForLockedFunctionType ", object); function->GetLibrary()->SetCrossSiteForLockedFunctionType(function); } else { TTD_XSITE_LOG(scriptContext, "setEntryPoint->CurrentCrossSiteThunk ", object); function->SetEntryPoint(function->GetScriptContext()->CurrentCrossSiteThunk); } } } else if (object->GetTypeId() == TypeIds_Proxy) { RecyclableObject * target = JavascriptProxy::FromVar(object)->GetTarget(); if (JavascriptConversion::IsCallable(target)) { Assert(JavascriptProxy::FunctionCallTrap == object->GetEntryPoint()); TTD_XSITE_LOG(scriptContext, "setEntryPoint->CrossSiteProxyCallTrap ", object); object->GetDynamicType()->SetEntryPoint(CrossSite::CrossSiteProxyCallTrap); } } }
void CrossSite::MarshalCrossSite_TTDInflate(DynamicObject* obj) { obj->MarshalCrossSite_TTDInflate(); if(obj->GetTypeId() == TypeIds_Function) { AssertMsg(obj != obj->GetScriptContext()->GetLibrary()->GetDefaultAccessorFunction(), "default accessor marshalled -- I don't think this should ever happen as it is marshalled in a special case?"); JavascriptFunction * function = JavascriptFunction::FromVar(obj); // //TODO: what happens if the gaurd in marshal (MarshalDynamicObject) isn't true? // if(function->GetTypeHandler()->GetIsLocked()) { function->GetLibrary()->SetCrossSiteForLockedFunctionType(function); } else { function->SetEntryPoint(function->GetScriptContext()->CurrentCrossSiteThunk); } } }