⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bytecodegenerator.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    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 + -