📄 jitstubs.cpp
字号:
JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) * src2.toNumber(callFrame)); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSObject* JITStubs::cti_op_new_func(STUB_ARGS){ BEGIN_STUB_FUNCTION(); return ARG_func1->makeFunction(ARG_callFrame, ARG_callFrame->scopeChain());}void* JITStubs::cti_op_call_JSFunction(STUB_ARGS){ BEGIN_STUB_FUNCTION();#ifndef NDEBUG CallData callData; ASSERT(ARG_src1.getCallData(callData) == CallTypeJS);#endif ScopeChainNode* callDataScopeChain = asFunction(ARG_src1)->scope().node(); CodeBlock* newCodeBlock = &asFunction(ARG_src1)->body()->bytecode(callDataScopeChain); if (!newCodeBlock->jitCode()) JIT::compile(ARG_globalData, newCodeBlock); return newCodeBlock;}VoidPtrPair JITStubs::cti_op_call_arityCheck(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; CodeBlock* newCodeBlock = ARG_codeBlock4; int argCount = ARG_int3; ASSERT(argCount != newCodeBlock->m_numParameters); CallFrame* oldCallFrame = callFrame->callerFrame(); if (argCount > newCodeBlock->m_numParameters) { size_t numParameters = newCodeBlock->m_numParameters; Register* r = callFrame->registers() + numParameters; Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount; for (size_t i = 0; i < numParameters; ++i) argv[i + argCount] = argv[i]; callFrame = CallFrame::create(r); callFrame->setCallerFrame(oldCallFrame); } else { size_t omittedArgCount = newCodeBlock->m_numParameters - argCount; Register* r = callFrame->registers() + omittedArgCount; Register* newEnd = r + newCodeBlock->m_numCalleeRegisters; if (!ARG_registerFile->grow(newEnd)) { // Rewind to the previous call frame because op_call already optimistically // moved the call frame forward. ARG_setCallFrame(oldCallFrame); throwStackOverflowError(oldCallFrame, ARG_globalData, ARG_returnAddress2, STUB_RETURN_ADDRESS); RETURN_PAIR(0, 0); } Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount; for (size_t i = 0; i < omittedArgCount; ++i) argv[i] = jsUndefined(); callFrame = CallFrame::create(r); callFrame->setCallerFrame(oldCallFrame); } RETURN_PAIR(newCodeBlock, callFrame);}void* JITStubs::cti_vm_dontLazyLinkCall(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSGlobalData* globalData = ARG_globalData; JSFunction* callee = asFunction(ARG_src1); CodeBlock* codeBlock = &callee->body()->bytecode(callee->scope().node()); if (!codeBlock->jitCode()) JIT::compile(globalData, codeBlock); ctiPatchNearCallByReturnAddress(ARG_returnAddress2, globalData->jitStubs.ctiVirtualCallLink()); return codeBlock->jitCode().addressForCall();}void* JITStubs::cti_vm_lazyLinkCall(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSFunction* callee = asFunction(ARG_src1); CodeBlock* codeBlock = &callee->body()->bytecode(callee->scope().node()); if (!codeBlock->jitCode()) JIT::compile(ARG_globalData, codeBlock); CallLinkInfo* callLinkInfo = &ARG_callFrame->callerFrame()->codeBlock()->getCallLinkInfo(ARG_returnAddress2); JIT::linkCall(callee, codeBlock, codeBlock->jitCode(), callLinkInfo, ARG_int3); return codeBlock->jitCode().addressForCall();}JSObject* JITStubs::cti_op_push_activation(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSActivation* activation = new (ARG_globalData) JSActivation(ARG_callFrame, static_cast<FunctionBodyNode*>(ARG_callFrame->codeBlock()->ownerNode())); ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->copy()->push(activation)); return activation;}JSValueEncodedAsPointer* JITStubs::cti_op_call_NotJSFunction(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSValuePtr funcVal = ARG_src1; CallData callData; CallType callType = funcVal.getCallData(callData); ASSERT(callType != CallTypeJS); if (callType == CallTypeHost) { int registerOffset = ARG_int2; int argCount = ARG_int3; CallFrame* previousCallFrame = ARG_callFrame; CallFrame* callFrame = CallFrame::create(previousCallFrame->registers() + registerOffset); callFrame->init(0, static_cast<Instruction*>(STUB_RETURN_ADDRESS), previousCallFrame->scopeChain(), previousCallFrame, 0, argCount, 0); ARG_setCallFrame(callFrame); Register* argv = ARG_callFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount; ArgList argList(argv + 1, argCount - 1); JSValuePtr returnValue; { SamplingTool::HostCallRecord callRecord(CTI_SAMPLER); // FIXME: All host methods should be calling toThisObject, but this is not presently the case. JSValuePtr thisValue = argv[0].jsValue(callFrame); if (thisValue == jsNull()) thisValue = callFrame->globalThisValue(); returnValue = callData.native.function(callFrame, asObject(funcVal), thisValue, argList); } ARG_setCallFrame(previousCallFrame); CHECK_FOR_EXCEPTION(); return JSValuePtr::encode(returnValue); } ASSERT(callType == CallTypeNone); CallFrame* callFrame = ARG_callFrame; CodeBlock* codeBlock = callFrame->codeBlock(); unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS); ARG_globalData->exception = createNotAFunctionError(ARG_callFrame, funcVal, vPCIndex, codeBlock); VM_THROW_EXCEPTION();}void JITStubs::cti_op_create_arguments(STUB_ARGS){ BEGIN_STUB_FUNCTION(); Arguments* arguments = new (ARG_globalData) Arguments(ARG_callFrame); ARG_callFrame->setCalleeArguments(arguments); ARG_callFrame[RegisterFile::ArgumentsRegister] = arguments;}void JITStubs::cti_op_create_arguments_no_params(STUB_ARGS){ BEGIN_STUB_FUNCTION(); Arguments* arguments = new (ARG_globalData) Arguments(ARG_callFrame, Arguments::NoParameters); ARG_callFrame->setCalleeArguments(arguments); ARG_callFrame[RegisterFile::ArgumentsRegister] = arguments;}void JITStubs::cti_op_tear_off_activation(STUB_ARGS){ BEGIN_STUB_FUNCTION(); ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain()); asActivation(ARG_src1)->copyRegisters(ARG_callFrame->optionalCalleeArguments());}void JITStubs::cti_op_tear_off_arguments(STUB_ARGS){ BEGIN_STUB_FUNCTION(); ASSERT(ARG_callFrame->codeBlock()->usesArguments() && !ARG_callFrame->codeBlock()->needsFullScopeChain()); ARG_callFrame->optionalCalleeArguments()->copyRegisters();}void JITStubs::cti_op_profile_will_call(STUB_ARGS){ BEGIN_STUB_FUNCTION(); ASSERT(*ARG_profilerReference); (*ARG_profilerReference)->willExecute(ARG_callFrame, ARG_src1);}void JITStubs::cti_op_profile_did_call(STUB_ARGS){ BEGIN_STUB_FUNCTION(); ASSERT(*ARG_profilerReference); (*ARG_profilerReference)->didExecute(ARG_callFrame, ARG_src1);}void JITStubs::cti_op_ret_scopeChain(STUB_ARGS){ BEGIN_STUB_FUNCTION(); ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain()); ARG_callFrame->scopeChain()->deref();}JSObject* JITStubs::cti_op_new_array(STUB_ARGS){ BEGIN_STUB_FUNCTION(); ArgList argList(&ARG_callFrame->registers()[ARG_int1], ARG_int2); return constructArray(ARG_callFrame, argList);}JSValueEncodedAsPointer* JITStubs::cti_op_resolve(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); ScopeChainIterator end = scopeChain->end(); ASSERT(iter != end); Identifier& ident = *ARG_id1; do { JSObject* o = *iter; PropertySlot slot(o); if (o->getPropertySlot(callFrame, ident, slot)) { JSValuePtr result = slot.getValue(callFrame, ident); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result); } } while (++iter != end); CodeBlock* codeBlock = callFrame->codeBlock(); unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS); ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock); VM_THROW_EXCEPTION();}JSObject* JITStubs::cti_op_construct_JSConstruct(STUB_ARGS){ BEGIN_STUB_FUNCTION();#ifndef NDEBUG ConstructData constructData; ASSERT(asFunction(ARG_src1)->getConstructData(constructData) == ConstructTypeJS);#endif Structure* structure; if (ARG_src4.isObject()) structure = asObject(ARG_src4)->inheritorID(); else structure = asFunction(ARG_src1)->scope().node()->globalObject()->emptyObjectStructure(); return new (ARG_globalData) JSObject(structure);}JSValueEncodedAsPointer* JITStubs::cti_op_construct_NotJSConstruct(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; JSValuePtr constrVal = ARG_src1; int argCount = ARG_int3; int thisRegister = ARG_int5; ConstructData constructData; ConstructType constructType = constrVal.getConstructData(constructData); if (constructType == ConstructTypeHost) { ArgList argList(callFrame->registers() + thisRegister + 1, argCount - 1); JSValuePtr returnValue; { SamplingTool::HostCallRecord callRecord(CTI_SAMPLER); returnValue = constructData.native.function(callFrame, asObject(constrVal), argList); } CHECK_FOR_EXCEPTION(); return JSValuePtr::encode(returnValue); } ASSERT(constructType == ConstructTypeNone); CodeBlock* codeBlock = callFrame->codeBlock(); unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS); ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, vPCIndex, codeBlock); VM_THROW_EXCEPTION();}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_val(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; JSGlobalData* globalData = ARG_globalData; JSValuePtr baseValue = ARG_src1; JSValuePtr subscript = ARG_src2; JSValuePtr result; if (LIKELY(subscript.isUInt32Fast())) { uint32_t i = subscript.getUInt32Fast(); if (isJSArray(globalData, baseValue)) { JSArray* jsArray = asArray(baseValue); if (jsArray->canGetIndex(i)) result = jsArray->getIndex(i); else result = jsArray->JSArray::get(callFrame, i); } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) result = asString(baseValue)->getIndex(ARG_globalData, i); else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) { // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks. ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_val_byte_array)); return JSValuePtr::encode(asByteArray(baseValue)->getIndex(callFrame, i)); } else result = baseValue.get(callFrame, i); } else { Identifier property(callFrame, subscript.toString(callFrame)); result = baseValue.get(callFrame, property); } CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_val_byte_array(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; JSGlobalData* globalData = ARG_globalData; JSValuePtr baseValue = ARG_src1; JSValuePtr subscript = ARG_src2; JSValuePtr result; if (LIKELY(subscript.isUInt32Fast())) { uint32_t i = subscript.getUInt32Fast(); if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) { // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks. return JSValuePtr::encode(asByteArray(baseValue)->getIndex(callFrame, i)); } result = baseValue.get(callFrame, i); if (!isJSByteArray(globalData, baseValue)) ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_val)); } else { Identifier property(callFrame, subscript.toString(callFrame)); result = baseValue.get(callFrame, property); } CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}VoidPtrPair JITStubs::cti_op_resolve_func(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); ScopeChainIterator end = scopeChain->end(); // FIXME: add scopeDepthIsZero optimization ASSERT(iter != end); Identifier& ident = *ARG_id1; JSObject* base; do { base = *iter; PropertySlot slot(base); if (base->getPropertySlot(callFrame, ident, slot)) { // ECMA 11.2.3 says that if we hit an activation the this value should be null. // However, section 10.2.3 says that in the case where the value provided
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -