inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (UNLIKELY(!calleeAsFunctionCell)) return handleHostCall(execCallee, calleeAsValue, kind); JSFunction* function = asFunction(calleeAsFunctionCell); execCallee->setScopeChain(function->scopeUnchecked()); ExecutableBase* executable = function->executable(); if (UNLIKELY(!executable->hasJITCodeFor(kind))) { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind); if (error) { exec->globalData().exception = error; return 0; } } return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress(); }
inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (!calleeAsFunctionCell) return handleHostCall(execCallee, calleeAsValue, kind); JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell); execCallee->setScopeChain(callee->scopeUnchecked()); ExecutableBase* executable = callee->executable(); MacroAssemblerCodePtr codePtr; CodeBlock* codeBlock = 0; if (executable->isHostFunction()) codePtr = executable->generatedJITCodeFor(kind).addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind); if (error) { globalData->exception = createStackOverflowError(exec); return 0; } codeBlock = &functionExecutable->generatedBytecodeFor(kind); if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())) codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind); else codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall(); } CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress); if (!callLinkInfo.seenOnce()) callLinkInfo.setSeen(); else dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind); return codePtr.executableAddress(); }