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); }
bool ASMLink::CheckMathLibraryMethod(ScriptContext* scriptContext, const Var asmMathObject, const AsmJSMathBuiltinFunction mathLibMethod) { Var mathFuncObj; switch (mathLibMethod) { case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_sin: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::sin, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Sin)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_cos: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::cos, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Cos)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_tan: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::tan, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Tan)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_asin: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::asin, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Asin)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_acos: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::acos, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Acos)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_atan: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::atan, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Atan)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_ceil: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::ceil, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Ceil)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_floor: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::floor, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Floor)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_exp: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::exp, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Exp)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_log: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::log, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Log)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_pow: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::pow, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Pow)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_sqrt: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::sqrt, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Sqrt)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_abs: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::abs, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Abs)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_atan2: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::atan2, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Atan2)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_imul: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::imul, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Imul)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_clz32: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::clz32, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Clz32)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_min: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::min, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Min)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_max: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::max, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Max)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_fround: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::fround, scriptContext); if (JavascriptFunction::Is(mathFuncObj)) { JavascriptFunction* mathLibFunc = (JavascriptFunction*)mathFuncObj; if (mathLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Math::EntryInfo::Fround)->GetOriginalEntryPoint()) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_e: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::E, scriptContext); if (JavascriptNumber::Is(mathFuncObj)) { JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj; if (JavascriptNumber::GetValue(mathConstNumber) == (Math::E)) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_ln10: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::LN10, scriptContext); if (JavascriptNumber::Is(mathFuncObj)) { JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj; if (JavascriptNumber::GetValue(mathConstNumber) == (Math::LN10)) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_ln2: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::LN2, scriptContext); if (JavascriptNumber::Is(mathFuncObj)) { JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj; if (JavascriptNumber::GetValue(mathConstNumber) == (Math::LN2)) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_log2e: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::LOG2E, scriptContext); if (JavascriptNumber::Is(mathFuncObj)) { JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj; if (JavascriptNumber::GetValue(mathConstNumber) == (Math::LOG2E)) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_log10e: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::LOG10E, scriptContext); if (JavascriptNumber::Is(mathFuncObj)) { JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj; if (JavascriptNumber::GetValue(mathConstNumber) == (Math::LOG10E)) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_pi: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::PI, scriptContext); if (JavascriptNumber::Is(mathFuncObj)) { JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj; if (JavascriptNumber::GetValue(mathConstNumber) == (Math::PI)) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_sqrt1_2: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::SQRT1_2, scriptContext); if (JavascriptNumber::Is(mathFuncObj)) { JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj; if (JavascriptNumber::GetValue(mathConstNumber) == (Math::SQRT1_2)) { return true; } } break; case AsmJSMathBuiltinFunction::AsmJSMathBuiltin_sqrt2: mathFuncObj = JavascriptOperators::OP_GetProperty(asmMathObject, PropertyIds::SQRT2, scriptContext); if (JavascriptNumber::Is(mathFuncObj)) { JavascriptNumber* mathConstNumber = (JavascriptNumber*)mathFuncObj; if (JavascriptNumber::GetValue(mathConstNumber) == (Math::SQRT2)) { return true; } } break; default: Assume(UNREACHED); } return false; }
bool ASMLink::CheckArrayLibraryMethod(ScriptContext* scriptContext, const Var stdlib, const AsmJSTypedArrayBuiltinFunction arrayLibMethod) { Var arrayFuncObj; switch (arrayLibMethod) { case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_byteLength: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::byteLength, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; if (arrayLibFunc->IsBoundFunction()) { BoundFunction* boundFunc = (BoundFunction*)arrayLibFunc; RecyclableObject* thisObj = boundFunc->GetBoundThis(); if (JavascriptFunction::Is(thisObj)) { JavascriptFunction * thisFunc = (JavascriptFunction*)thisObj; if (thisFunc->GetFunctionInfo()->GetOriginalEntryPoint() != (&ArrayBuffer::EntryInfo::GetterByteLength)->GetOriginalEntryPoint()) { return false; } } JavascriptFunction* targetFunc = boundFunc->GetTargetFunction(); return targetFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&JavascriptFunction::EntryInfo::Call)->GetOriginalEntryPoint(); } } break; case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Int8Array: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Int8Array, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Int8Array::EntryInfo::NewInstance)->GetOriginalEntryPoint(); } break; case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Uint8Array: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Uint8Array, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Uint8Array::EntryInfo::NewInstance)->GetOriginalEntryPoint(); } break; case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Int16Array: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Int16Array, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Int16Array::EntryInfo::NewInstance)->GetOriginalEntryPoint(); } break; case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Uint16Array: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Uint16Array, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Uint16Array::EntryInfo::NewInstance)->GetOriginalEntryPoint(); } break; case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Int32Array: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Int32Array, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Int32Array::EntryInfo::NewInstance)->GetOriginalEntryPoint(); } break; case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Uint32Array: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Uint32Array, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Uint32Array::EntryInfo::NewInstance)->GetOriginalEntryPoint(); } break; case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Float32Array: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Float32Array, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Float32Array::EntryInfo::NewInstance)->GetOriginalEntryPoint(); } break; case AsmJSTypedArrayBuiltinFunction::AsmJSTypedArrayBuiltin_Float64Array: arrayFuncObj = JavascriptOperators::OP_GetProperty(stdlib, PropertyIds::Float64Array, scriptContext); if (JavascriptFunction::Is(arrayFuncObj)) { JavascriptFunction* arrayLibFunc = (JavascriptFunction*)arrayFuncObj; return arrayLibFunc->GetFunctionInfo()->GetOriginalEntryPoint() == (&Float64Array::EntryInfo::NewInstance)->GetOriginalEntryPoint(); } break; default: Assume(UNREACHED); } return false; }