📄 bytecodegenerator.cpp
字号:
emitOpcode(op_resolve_base); instructions().append(dst->index()); instructions().append(addConstant(property)); return dst;}RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property){ emitOpcode(op_resolve_with_base); instructions().append(baseDst->index()); instructions().append(propDst->index()); instructions().append(addConstant(property)); return baseDst;}RegisterID* BytecodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property){ emitOpcode(op_resolve_func); instructions().append(baseDst->index()); instructions().append(funcDst->index()); instructions().append(addConstant(property)); return baseDst;}RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property){#if ENABLE(JIT) m_codeBlock->addStructureStubInfo(StructureStubInfo(op_get_by_id));#else m_codeBlock->addPropertyAccessInstruction(instructions().size());#endif emitOpcode(op_get_by_id); instructions().append(dst->index()); instructions().append(base->index()); instructions().append(addConstant(property)); instructions().append(0); instructions().append(0); instructions().append(0); instructions().append(0); return dst;}RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value){#if ENABLE(JIT) m_codeBlock->addStructureStubInfo(StructureStubInfo(op_put_by_id));#else m_codeBlock->addPropertyAccessInstruction(instructions().size());#endif emitOpcode(op_put_by_id); instructions().append(base->index()); instructions().append(addConstant(property)); instructions().append(value->index()); instructions().append(0); instructions().append(0); instructions().append(0); instructions().append(0); return value;}RegisterID* BytecodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value){ emitOpcode(op_put_getter); instructions().append(base->index()); instructions().append(addConstant(property)); instructions().append(value->index()); return value;}RegisterID* BytecodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value){ emitOpcode(op_put_setter); instructions().append(base->index()); instructions().append(addConstant(property)); instructions().append(value->index()); return value;}RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property){ emitOpcode(op_del_by_id); instructions().append(dst->index()); instructions().append(base->index()); instructions().append(addConstant(property)); return dst;}RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property){ emitOpcode(op_get_by_val); instructions().append(dst->index()); instructions().append(base->index()); instructions().append(property->index()); return dst;}RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value){ emitOpcode(op_put_by_val); instructions().append(base->index()); instructions().append(property->index()); instructions().append(value->index()); return value;}RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property){ emitOpcode(op_del_by_val); instructions().append(dst->index()); instructions().append(base->index()); instructions().append(property->index()); return dst;}RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value){ emitOpcode(op_put_by_index); instructions().append(base->index()); instructions().append(index); instructions().append(value->index()); return value;}RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst){ emitOpcode(op_new_object); instructions().append(dst->index()); return dst;}RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements){ Vector<RefPtr<RegisterID>, 16> argv; for (ElementNode* n = elements; n; n = n->next()) { if (n->elision()) break; argv.append(newTemporary()); // op_new_array requires the initial values to be a sequential range of registers ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1); emitNode(argv.last().get(), n->value()); } emitOpcode(op_new_array); instructions().append(dst->index()); instructions().append(argv.size() ? argv[0]->index() : 0); // argv instructions().append(argv.size()); // argc return dst;}RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FuncDeclNode* n){ emitOpcode(op_new_func); instructions().append(dst->index()); instructions().append(addConstant(n)); return dst;}RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp){ emitOpcode(op_new_regexp); instructions().append(dst->index()); instructions().append(addRegExp(regExp)); return dst;}RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n){ emitOpcode(op_new_func_exp); instructions().append(r0->index()); instructions().append(addConstant(n)); return r0;}RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset){ return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);}RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset){ return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);}RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset){ ASSERT(opcodeID == op_call || opcodeID == op_call_eval); ASSERT(func->refCount()); ASSERT(thisRegister->refCount()); RegisterID* originalFunc = func; if (m_shouldEmitProfileHooks) { // If codegen decided to recycle func as this call's destination register, // we need to undo that optimization here so that func will still be around // for the sake of op_profile_did_call. if (dst == func) { RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), thisRegister); RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func); thisRegister = movedThisRegister.release().releaseRef(); func = movedFunc.release().releaseRef(); } } // Generate code for arguments. Vector<RefPtr<RegisterID>, 16> argv; argv.append(thisRegister); for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) { argv.append(newTemporary()); // op_call requires the arguments to be a sequential range of registers ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1); emitNode(argv.last().get(), n); } // Reserve space for call frame. Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame; for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i) callFrame.append(newTemporary()); if (m_shouldEmitProfileHooks) { emitOpcode(op_profile_will_call); instructions().append(func->index());#if ENABLE(JIT) m_codeBlock->addFunctionRegisterInfo(instructions().size(), func->index());#endif } emitExpressionInfo(divot, startOffset, endOffset);#if ENABLE(JIT) m_codeBlock->addCallLinkInfo();#endif // Emit call. emitOpcode(opcodeID); instructions().append(dst->index()); // dst instructions().append(func->index()); // func instructions().append(argv.size()); // argCount instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset if (m_shouldEmitProfileHooks) { emitOpcode(op_profile_did_call); instructions().append(func->index()); if (dst == originalFunc) { thisRegister->deref(); func->deref(); } } return dst;}RegisterID* BytecodeGenerator::emitReturn(RegisterID* src){ if (m_codeBlock->needsFullScopeChain()) { emitOpcode(op_tear_off_activation); instructions().append(m_activationRegisterIndex); } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1) emitOpcode(op_tear_off_arguments); return emitUnaryNoDstOp(op_ret, src);}RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src){ emitOpcode(opcodeID); instructions().append(src->index()); return src;}RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset){ ASSERT(func->refCount()); RegisterID* originalFunc = func; if (m_shouldEmitProfileHooks) { // If codegen decided to recycle func as this call's destination register, // we need to undo that optimization here so that func will still be around // for the sake of op_profile_did_call. if (dst == func) { RefPtr<RegisterID> movedFunc = emitMove(newTemporary(), func); func = movedFunc.release().releaseRef(); } } RefPtr<RegisterID> funcProto = newTemporary(); // Generate code for arguments. Vector<RefPtr<RegisterID>, 16> argv; argv.append(newTemporary()); // reserve space for "this" for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) { argv.append(newTemporary()); // op_construct requires the arguments to be a sequential range of registers ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1); emitNode(argv.last().get(), n); } if (m_shouldEmitProfileHooks) { emitOpcode(op_profile_will_call); instructions().append(func->index()); } // Load prototype. emitExpressionInfo(divot, startOffset, endOffset); emitGetByIdExceptionInfo(op_construct); emitGetById(funcProto.get(), func, globalData()->propertyNames->prototype); // Reserve space for call frame. Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame; for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i) callFrame.append(newTemporary()); emitExpressionInfo(divot, startOffset, endOffset);#if ENABLE(JIT) m_codeBlock->addCallLinkInfo();#endif emitOpcode(op_construct); instructions().append(dst->index()); // dst instructions().append(func->index()); // func instructions().append(argv.size()); // argCount instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset instructions().append(funcProto->index()); // proto instructions().append(argv[0]->index()); // thisRegister emitOpcode(op_construct_verify); instructions().append(dst->index()); instructions().append(argv[0]->index()); if (m_shouldEmitProfileHooks) { emitOpcode(op_profile_did_call); instructions().append(func->index()); if (dst == originalFunc) func->deref(); } return dst;}RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope){ ASSERT(scope->isTemporary()); ControlFlowContext context; context.isFinallyBlock = false; m_scopeContextStack.append(context); m_dynamicScopeDepth++; return emitUnaryNoDstOp(op_push_scope, scope);}void BytecodeGenerator::emitPopScope(){ ASSERT(m_scopeContextStack.size());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -