/* static */ void ArgumentsObject::MaybeForwardToCallObject(ion::IonJSFrameLayout *frame, HandleObject callObj, JSObject *obj, ArgumentsData *data) { RawFunction callee = ion::CalleeTokenToFunction(frame->calleeToken()); RawScript script = callee->nonLazyScript(); if (callee->isHeavyweight() && script->argsObjAliasesFormals()) { JS_ASSERT(callObj && callObj->isCall()); obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(*callObj.get())); for (AliasedFormalIter fi(script); fi; fi++) data->args[fi.frameIndex()] = MagicValue(JS_FORWARD_TO_CALL_OBJECT); } }
bool TypeInferenceOracle::canEnterInlinedFunction(RawScript caller, jsbytecode *pc, RawFunction target) { RootedScript targetScript(cx, target->nonLazyScript()); // Make sure empty script has type information, to allow inlining in more cases. if (targetScript->length == 1) { if (!targetScript->ensureRanInference(cx)) return false; } if (!targetScript->hasAnalysis() || !targetScript->analysis()->ranInference() || !targetScript->analysis()->ranSSA()) { return false; } if (!targetScript->analysis()->ionInlineable()) return false; if (targetScript->needsArgsObj()) return false; if (!targetScript->compileAndGo) return false; if (targetScript->analysis()->usesScopeChain()) return false; types::TypeObject *targetType = target->getType(cx); if (!targetType || targetType->unknownProperties()) return false; JSOp op = JSOp(*pc); TypeSet *returnTypes = TypeScript::ReturnTypes(targetScript); TypeSet *callReturn = getCallReturn(caller, pc); if (op == JSOP_NEW) { if (!returnTypes->isSubsetIgnorePrimitives(callReturn)) return false; } else { if (!returnTypes->isSubset(callReturn)) return false; } // TI calls ObjectStateChange to trigger invalidation of the caller. HeapTypeSet::WatchObjectStateChange(cx, targetType); return true; }
bool TypeInferenceOracle::callArgsTypeSetIntersects(types::StackTypeSet *thisType, Vector<types::StackTypeSet *> &argvType, RawFunction callee) { RootedScript targetScript(cx, callee->nonLazyScript()); types::TypeSet *calleeType; size_t nargs = Min<size_t>(callee->nargs, argvType.length()); // This if (thisType) { calleeType = types::TypeScript::ThisTypes(targetScript); if (thisType->intersectionEmpty(calleeType)) return false; } // Arguments for (size_t i = 0; i < nargs; i++) { calleeType = types::TypeScript::ArgTypes(targetScript, i); if (argvType[i]->intersectionEmpty(calleeType)) return false; } // Arguments that weren't provided will be Undefined for (size_t i = nargs; i < callee->nargs; i++) { calleeType = types::TypeScript::ArgTypes(targetScript, i); if (calleeType->unknown() || !calleeType->hasType(types::Type::UndefinedType())) { return false; } } return true; }
bool TypeInferenceOracle::canEnterInlinedFunction(RawFunction target) { RootedScript targetScript(cx, target->nonLazyScript()); // Make sure empty script has type information, to allow inlining in more cases. if (targetScript->length == 1) { if (!targetScript->ensureRanInference(cx)) return false; } if (!targetScript->hasAnalysis() || !targetScript->analysis()->ranInference() || !targetScript->analysis()->ranSSA()) { return false; } if (!targetScript->analysis()->ionInlineable()) return false; if (targetScript->needsArgsObj()) return false; if (!targetScript->compileAndGo) return false; if (targetScript->analysis()->usesScopeChain()) return false; types::TypeObject *targetType = target->getType(cx); if (!targetType || targetType->unknownProperties()) return false; // TI calls ObjectStateChange to trigger invalidation of the caller. HeapTypeSet::WatchObjectStateChange(cx, targetType); return true; }
bool TypeInferenceOracle::callReturnTypeSetMatches(RawScript callerScript, jsbytecode *callerPc, RawFunction callee) { RootedScript targetScript(cx, callee->nonLazyScript()); JSOp op = JSOp(*callerPc); TypeSet *returnTypes = TypeScript::ReturnTypes(targetScript); TypeSet *callReturn = getCallReturn(callerScript, callerPc); if (op == JSOP_NEW) { if (!returnTypes->isSubsetIgnorePrimitives(callReturn)) return false; } else { if (!returnTypes->isSubset(callReturn)) return false; } return true; }