Var JsBuiltInEngineInterfaceExtensionObject::EntryJsBuiltIn_RegisterChakraLibraryFunction(RecyclableObject* function, CallInfo callInfo, ...)
    {
        EngineInterfaceObject_CommonFunctionProlog(function, callInfo);

        AssertOrFailFast(args.Info.Count >= 3 && JavascriptString::Is(args.Values[1]) && JavascriptFunction::Is(args.Values[2]));

        JavascriptLibrary * library = scriptContext->GetLibrary();

        // retrieves arguments
        JavascriptString* methodName = JavascriptString::FromVar(args.Values[1]);
        JavascriptFunction* func = JavascriptFunction::FromVar(args.Values[2]);

        // Set the function's display name, as the function we pass in argument are anonym.
        func->GetFunctionProxy()->SetIsPublicLibraryCode();
        func->GetFunctionProxy()->EnsureDeserialized()->SetDisplayName(methodName->GetString(), methodName->GetLength(), 0);

        DynamicObject* chakraLibraryObject = GetPrototypeFromName(PropertyIds::__chakraLibrary, scriptContext);
        PropertyIds functionIdentifier = JavascriptOperators::GetPropertyId(methodName, scriptContext);

        // Link the function to __chakraLibrary.
        ScriptFunction* scriptFunction = library->CreateScriptFunction(func->GetFunctionProxy());
        scriptFunction->GetFunctionProxy()->SetIsJsBuiltInCode();

        Assert(scriptFunction->HasFunctionBody());
        scriptFunction->GetFunctionBody()->SetJsBuiltInForceInline();

        scriptFunction->SetPropertyWithAttributes(PropertyIds::name, methodName, PropertyConfigurable, nullptr);

        library->AddMember(chakraLibraryObject, functionIdentifier, scriptFunction);

        //Don't need to return anything
        return library->GetUndefined();
    }
    Var EngineInterfaceObject::Entry_TagPublicLibraryCode(RecyclableObject *function, CallInfo callInfo, ...)
    {
        EngineInterfaceObject_CommonFunctionProlog(function, callInfo);

        if (callInfo.Count >= 2 && JavascriptFunction::Is(args.Values[1]))
        {
            JavascriptFunction* func = JavascriptFunction::FromVar(args.Values[1]);
            func->GetFunctionProxy()->SetIsPublicLibraryCode();

            if (callInfo.Count >= 3 && JavascriptString::Is(args.Values[2]))
            {
                JavascriptString* customFunctionName = JavascriptString::FromVar(args.Values[2]);
                // tagPublicFunction("Intl.Collator", Collator); in Intl.js calls TagPublicLibraryCode the expected name is Collator so we need to calculate the offset
                const wchar_t * shortName = wcsrchr(customFunctionName->GetString(), L'.');
                uint shortNameOffset = 0;
                if (shortName != nullptr)
                {
                    // JavascriptString length is bounded by uint max
                    shortName++;
                    shortNameOffset = static_cast<uint>(shortName - customFunctionName->GetString());
                }
                func->GetFunctionProxy()->EnsureDeserialized()->SetDisplayName(customFunctionName->GetString(), customFunctionName->GetLength(), shortNameOffset);
            }

            return func;
        }

        return scriptContext->GetLibrary()->GetUndefined();
    }
示例#3
0
    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);
            }
        }
    }
示例#4
0
    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);
            }
        }
    }
示例#5
0
    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);
    }
示例#6
0
    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 JavascriptExternalFunction::PrepareExternalCall(Js::Arguments * args)
    {
        ScriptContext * scriptContext = this->type->GetScriptContext();
        Assert(!scriptContext->GetThreadContext()->IsDisableImplicitException());
        scriptContext->VerifyAlive();

        Assert(scriptContext->GetThreadContext()->IsScriptActive());

        if (args->Info.Count == 0)
        {
            JavascriptError::ThrowTypeError(scriptContext, JSERR_This_NullOrUndefined);
        }

        Var &thisVar = args->Values[0];

        Js::TypeId typeId = Js::JavascriptOperators::GetTypeId(thisVar);

        this->callCount++;
        if (IS_JS_ETW(EventEnabledJSCRIPT_HOSTING_EXTERNAL_FUNCTION_CALL_START()))
        {
            JavascriptFunction* caller = nullptr;

            // Lot the caller function if the call count of the external function pass certain threshold (randomly pick 256)
            // we don't want to call stackwalk too often. The threshold can be adjusted as needed.
            if (callCount >= ETW_MIN_COUNT_FOR_CALLER && ((callCount % ETW_MIN_COUNT_FOR_CALLER) == 0))
            {
                Js::JavascriptStackWalker stackWalker(scriptContext);
                bool foundScriptCaller = false;
                while(stackWalker.GetCaller(&caller))
                {
                    if(caller != nullptr && Js::ScriptFunction::Is(caller))
                    {
                        foundScriptCaller = true;
                        break;
                    }
                }
                if(foundScriptCaller)
                {
                    Var sourceString = caller->EnsureSourceString();
                    Assert(JavascriptString::Is(sourceString));
                    const char16* callerString = Js::JavascriptString::FromVar(sourceString)->GetSz();
                    char16* outString = (char16*)callerString;
                    int length = 0;
                    if (wcschr(callerString, _u('\n')) != NULL || wcschr(callerString, _u('\n')) != NULL)
                    {
                        length = Js::JavascriptString::FromVar(sourceString)->GetLength();
                        outString = HeapNewArray(char16, length+1);
                        int j = 0;
                        for (int i = 0; i < length; i++)
                        {
                            if (callerString[i] != _u('\n') && callerString[i] != L'\r')
                            {
                                outString[j++] = callerString[i];
                            }
                        }
                        outString[j] = L'\0';
                    }
                    JS_ETW(EventWriteJSCRIPT_HOSTING_CALLER_TO_EXTERNAL(scriptContext, this, typeId, outString, callCount));
                    if (outString != callerString)
                    {
                        HeapDeleteArray(length+1, outString);
                    }
#if DBG_DUMP
                    if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::HostPhase))
                    {
                        Output::Print(_u("Large number of Call to trampoline: methodAddr= %p, Object typeid= %d, caller method= %s, callcount= %d\n"),
                            this, typeId, callerString, callCount);
                    }
#endif
                }
            }
            JS_ETW(EventWriteJSCRIPT_HOSTING_EXTERNAL_FUNCTION_CALL_START(scriptContext, this, typeId));
#if DBG_DUMP
            if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::HostPhase))
            {
                Output::Print(_u("Call to trampoline: methodAddr= %p, Object typeid= %d\n"), this, typeId);
            }
#endif
        }

        Js::RecyclableObject* directHostObject = nullptr;
        switch(typeId)
        {
        case TypeIds_Integer:
#if FLOATVAR
        case TypeIds_Number:
#endif // FLOATVAR
            Assert(!Js::RecyclableObject::Is(thisVar));
            break;
        default:
            {
                Assert(Js::RecyclableObject::Is(thisVar));

                ScriptContext* scriptContextThisVar = Js::RecyclableObject::FromVar(thisVar)->GetScriptContext();
                // We need to verify "this" pointer is active as well. The problem is that DOM prototype functions are
                // the same across multiple frames, and caller can do function.call(closedthis)
                Assert(!scriptContext->GetThreadContext()->IsDisableImplicitException());
                scriptContextThisVar->VerifyAlive();

                // translate direct host for fastDOM.
                switch(typeId)
                {
                case Js::TypeIds_GlobalObject:
                    {
                        Js::GlobalObject* srcGlobalObject = static_cast<Js::GlobalObject*>(thisVar);
                        directHostObject = srcGlobalObject->GetDirectHostObject();
                        // For jsrt, direct host object can be null. If thats the case don't change it.
                        if (directHostObject != nullptr)
                        {
                            thisVar = directHostObject;
                        }

                    }
                    break;
                case Js::TypeIds_Undefined:
                case Js::TypeIds_Null:
                    {
                        // Call to DOM function with this as "undefined" or "null"
                        // This should be converted to Global object
                        Js::GlobalObject* srcGlobalObject = scriptContextThisVar->GetGlobalObject() ;
                        directHostObject = srcGlobalObject->GetDirectHostObject();
                        // For jsrt, direct host object can be null. If thats the case don't change it.
                        if (directHostObject != nullptr)
                        {
                            thisVar = directHostObject;
                        }
                    }
                    break;
                }
            }
            break;
        }
    }
    Var JsBuiltInEngineInterfaceExtensionObject::EntryJsBuiltIn_RegisterFunction(RecyclableObject* function, CallInfo callInfo, ...)
    {
        EngineInterfaceObject_CommonFunctionProlog(function, callInfo);

        AssertOrFailFast(args.Info.Count >= 3 && JavascriptObject::Is(args.Values[1]) && JavascriptFunction::Is(args.Values[2]));

        JavascriptLibrary * library = scriptContext->GetLibrary();

        // retrieves arguments
        RecyclableObject* funcInfo = nullptr;
        if (!JavascriptConversion::ToObject(args.Values[1], scriptContext, &funcInfo))
        {
            JavascriptError::ThrowTypeError(scriptContext, JSERR_FunctionArgument_NeedObject, _u("Object.assign"));
        }

        Var classNameProperty = JavascriptOperators::OP_GetProperty(funcInfo, Js::PropertyIds::className, scriptContext);
        Var methodNameProperty = JavascriptOperators::OP_GetProperty(funcInfo, Js::PropertyIds::methodName, scriptContext);
        Var argumentsCountProperty = JavascriptOperators::OP_GetProperty(funcInfo, Js::PropertyIds::argumentsCount, scriptContext);
        Var forceInlineProperty = JavascriptOperators::OP_GetProperty(funcInfo, Js::PropertyIds::forceInline, scriptContext);
        Var aliasProperty = JavascriptOperators::OP_GetProperty(funcInfo, Js::PropertyIds::alias, scriptContext);

        Assert(JavascriptString::Is(classNameProperty));
        Assert(JavascriptString::Is(methodNameProperty));
        Assert(TaggedInt::Is(argumentsCountProperty));

        JavascriptString* className = JavascriptString::FromVar(classNameProperty);
        JavascriptString* methodName = JavascriptString::FromVar(methodNameProperty);
        int argumentsCount = TaggedInt::ToInt32(argumentsCountProperty);

        BOOL forceInline = JavascriptConversion::ToBoolean(forceInlineProperty, scriptContext);

        JavascriptFunction* func = JavascriptFunction::FromVar(args.Values[2]);

        // Set the function's display name, as the function we pass in argument are anonym.
        func->GetFunctionProxy()->SetIsPublicLibraryCode();
        func->GetFunctionProxy()->EnsureDeserialized()->SetDisplayName(methodName->GetString(), methodName->GetLength(), 0);

        DynamicObject* prototype = GetPrototypeFromName(JavascriptOperators::GetPropertyId(className, scriptContext), scriptContext);
        PropertyIds functionIdentifier = methodName->BufferEquals(_u("Symbol.iterator"), 15)? PropertyIds::_symbolIterator :
            JavascriptOperators::GetPropertyId(methodName, scriptContext);

        // Link the function to the prototype.
        ScriptFunction* scriptFunction = library->CreateScriptFunction(func->GetFunctionProxy());
        scriptFunction->GetFunctionProxy()->SetIsJsBuiltInCode();

        if (forceInline)
        {
            Assert(scriptFunction->HasFunctionBody());
            scriptFunction->GetFunctionBody()->SetJsBuiltInForceInline();
        }
        scriptFunction->SetPropertyWithAttributes(PropertyIds::length, TaggedInt::ToVarUnchecked(argumentsCount), PropertyConfigurable, nullptr);

        scriptFunction->SetConfigurable(PropertyIds::prototype, true);
        scriptFunction->DeleteProperty(PropertyIds::prototype, Js::PropertyOperationFlags::PropertyOperation_None);

        scriptFunction->SetPropertyWithAttributes(PropertyIds::name, methodName, PropertyConfigurable, nullptr);

        library->AddMember(prototype, functionIdentifier, scriptFunction);

        RecordCommonNativeInterfaceBuiltIns(functionIdentifier, scriptContext, scriptFunction);

        if (!JavascriptOperators::IsUndefinedOrNull(aliasProperty))
        {
            JavascriptString * alias = JavascriptConversion::ToString(aliasProperty, scriptContext);
            // Cannot do a string to property id search here, Symbol.* have different hashing mechanism, so resort to this str compare
            PropertyIds aliasFunctionIdentifier = alias->BufferEquals(_u("Symbol.iterator"), 15) ? PropertyIds::_symbolIterator :
                JavascriptOperators::GetPropertyId(alias, scriptContext);
            library->AddMember(prototype, aliasFunctionIdentifier, scriptFunction);
        }

        if (prototype == library->arrayPrototype)
        {
            RecordDefaultIteratorFunctions(functionIdentifier, scriptContext, scriptFunction);
        }

        //Don't need to return anything
        return library->GetUndefined();
    }
示例#9
0
    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;
    }
示例#10
0
 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;
 }