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

📄 bytecodegenerator.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        instructions().append(m_thisRegister.index());    }        for (size_t i = 0; i < parameterCount; ++i)        addParameter(parameters[i]);    allocateConstants(functionBody->neededConstants());}BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)    : m_shouldEmitDebugHooks(!!debugger)    , m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())    , m_scopeChain(&scopeChain)    , m_symbolTable(symbolTable)    , m_scopeNode(evalNode)    , m_codeBlock(codeBlock)    , m_thisRegister(RegisterFile::ProgramCodeThisRegister)    , m_finallyDepth(0)    , m_dynamicScopeDepth(0)    , m_baseScopeDepth(codeBlock->baseScopeDepth())    , m_codeType(EvalCode)    , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())    , m_lastOpcodeID(op_end)    , m_emitNodeDepth(0)    , m_regeneratingForExceptionInfo(false)    , m_codeBlockBeingRegeneratedFrom(0){    if (m_shouldEmitDebugHooks || m_baseScopeDepth)        m_codeBlock->setNeedsFullScopeChain(true);    emitOpcode(op_enter);    codeBlock->setGlobalData(m_globalData);    m_codeBlock->m_numParameters = 1; // Allocate space for "this"    allocateConstants(evalNode->neededConstants());}RegisterID* BytecodeGenerator::addParameter(const Identifier& ident){    // Parameters overwrite var declarations, but not function declarations.    RegisterID* result = 0;    UString::Rep* rep = ident.ustring().rep();    if (!m_functions.contains(rep)) {        symbolTable().set(rep, m_nextParameterIndex);        RegisterID& parameter = registerFor(m_nextParameterIndex);        parameter.setIndex(m_nextParameterIndex);        result = &parameter;    }    // To maintain the calling convention, we have to allocate unique space for    // each parameter, even if the parameter doesn't make it into the symbol table.    ++m_nextParameterIndex;    ++m_codeBlock->m_numParameters;    return result;}RegisterID* BytecodeGenerator::registerFor(const Identifier& ident){    if (ident == propertyNames().thisIdentifier)        return &m_thisRegister;    if (!shouldOptimizeLocals())        return 0;    SymbolTableEntry entry = symbolTable().get(ident.ustring().rep());    if (entry.isNull())        return 0;    return &registerFor(entry.getIndex());}RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident){    if (m_codeType == EvalCode)        return 0;    SymbolTableEntry entry = symbolTable().get(ident.ustring().rep());    ASSERT(!entry.isNull());    return &registerFor(entry.getIndex());}bool BytecodeGenerator::isLocal(const Identifier& ident){    if (ident == propertyNames().thisIdentifier)        return true;        return shouldOptimizeLocals() && symbolTable().contains(ident.ustring().rep());}bool BytecodeGenerator::isLocalConstant(const Identifier& ident){    return symbolTable().get(ident.ustring().rep()).isReadOnly();}RegisterID* BytecodeGenerator::newRegister(){    m_calleeRegisters.append(m_calleeRegisters.size());    m_codeBlock->m_numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size());    return &m_calleeRegisters.last();}RegisterID* BytecodeGenerator::newTemporary(){    // Reclaim free register IDs.    while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount())        m_calleeRegisters.removeLast();            RegisterID* result = newRegister();    result->setTemporary();    return result;}RegisterID* BytecodeGenerator::highestUsedRegister(){    size_t count = m_codeBlock->m_numCalleeRegisters;    while (m_calleeRegisters.size() < count)        newRegister();    return &m_calleeRegisters.last();}PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name){    // Reclaim free label scopes.    while (m_labelScopes.size() && !m_labelScopes.last().refCount())        m_labelScopes.removeLast();    // Allocate new label scope.    LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : 0); // Only loops have continue targets.    m_labelScopes.append(scope);    return &m_labelScopes.last();}PassRefPtr<Label> BytecodeGenerator::newLabel(){    // Reclaim free label IDs.    while (m_labels.size() && !m_labels.last().refCount())        m_labels.removeLast();    // Allocate new label ID.    m_labels.append(m_codeBlock);    return &m_labels.last();}PassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0){    unsigned newLabelIndex = instructions().size();    l0->setLocation(newLabelIndex);    if (m_codeBlock->numberOfJumpTargets()) {        unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();        ASSERT(lastLabelIndex <= newLabelIndex);        if (newLabelIndex == lastLabelIndex) {            // Peephole optimizations have already been disabled by emitting the last label            return l0;        }    }    m_codeBlock->addJumpTarget(newLabelIndex);    // This disables peephole optimizations when an instruction is a jump target    m_lastOpcodeID = op_end;    return l0;}void BytecodeGenerator::emitOpcode(OpcodeID opcodeID){    instructions().append(globalData()->interpreter->getOpcode(opcodeID));    m_lastOpcodeID = opcodeID;}void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index){    ASSERT(instructions().size() >= 4);    size_t size = instructions().size();    dstIndex = instructions().at(size - 3).u.operand;    src1Index = instructions().at(size - 2).u.operand;    src2Index = instructions().at(size - 1).u.operand;}void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex){    ASSERT(instructions().size() >= 3);    size_t size = instructions().size();    dstIndex = instructions().at(size - 2).u.operand;    srcIndex = instructions().at(size - 1).u.operand;}void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp(){    ASSERT(instructions().size() >= 4);    instructions().shrink(instructions().size() - 4);}void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp(){    ASSERT(instructions().size() >= 3);    instructions().shrink(instructions().size() - 3);}PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target){    emitOpcode(target->isForward() ? op_jmp : op_loop);    instructions().append(target->offsetFrom(instructions().size()));    return target;}PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target){    if (m_lastOpcodeID == op_less && !target->isForward()) {        int dstIndex;        int src1Index;        int src2Index;        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {            rewindBinaryOp();            emitOpcode(op_loop_if_less);            instructions().append(src1Index);            instructions().append(src2Index);            instructions().append(target->offsetFrom(instructions().size()));            return target;        }    } else if (m_lastOpcodeID == op_lesseq && !target->isForward()) {        int dstIndex;        int src1Index;        int src2Index;        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {            rewindBinaryOp();            emitOpcode(op_loop_if_lesseq);            instructions().append(src1Index);            instructions().append(src2Index);            instructions().append(target->offsetFrom(instructions().size()));            return target;        }    } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {        int dstIndex;        int srcIndex;        retrieveLastUnaryOp(dstIndex, srcIndex);        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {            rewindUnaryOp();            emitOpcode(op_jeq_null);            instructions().append(srcIndex);            instructions().append(target->offsetFrom(instructions().size()));            return target;        }    } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {        int dstIndex;        int srcIndex;        retrieveLastUnaryOp(dstIndex, srcIndex);        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {            rewindUnaryOp();            emitOpcode(op_jneq_null);            instructions().append(srcIndex);            instructions().append(target->offsetFrom(instructions().size()));            return target;        }    }    emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);    instructions().append(cond->index());    instructions().append(target->offsetFrom(instructions().size()));    return target;}PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target){    ASSERT(target->isForward());    if (m_lastOpcodeID == op_less) {        int dstIndex;        int src1Index;        int src2Index;        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {            rewindBinaryOp();            emitOpcode(op_jnless);            instructions().append(src1Index);            instructions().append(src2Index);            instructions().append(target->offsetFrom(instructions().size()));            return target;        }    } else if (m_lastOpcodeID == op_not) {        int dstIndex;        int srcIndex;        retrieveLastUnaryOp(dstIndex, srcIndex);        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {            rewindUnaryOp();            emitOpcode(op_jtrue);            instructions().append(srcIndex);            instructions().append(target->offsetFrom(instructions().size()));            return target;        }    } else if (m_lastOpcodeID == op_eq_null) {        int dstIndex;        int srcIndex;        retrieveLastUnaryOp(dstIndex, srcIndex);        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {            rewindUnaryOp();            emitOpcode(op_jneq_null);            instructions().append(srcIndex);            instructions().append(target->offsetFrom(instructions().size()));            return target;        }    } else if (m_lastOpcodeID == op_neq_null) {        int dstIndex;        int srcIndex;        retrieveLastUnaryOp(dstIndex, srcIndex);        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {            rewindUnaryOp();            emitOpcode(op_jeq_null);            instructions().append(srcIndex);            instructions().append(target->offsetFrom(instructions().size()));            return target;        }    }    emitOpcode(op_jfalse);    instructions().append(cond->index());    instructions().append(target->offsetFrom(instructions().size()));    return target;}unsigned BytecodeGenerator::addConstant(FuncDeclNode* n){    // No need to explicitly unique function body nodes -- they're unique already.    return m_codeBlock->addFunction(n);}unsigned BytecodeGenerator::addConstant(FuncExprNode* n){    // No need to explicitly unique function expression nodes -- they're unique already.    return m_codeBlock->addFunctionExpression(n);}unsigned BytecodeGenerator::addConstant(const Identifier& ident){    UString::Rep* rep = ident.ustring().rep();    pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());    if (result.second) // new entry        m_codeBlock->addIdentifier(Identifier(m_globalData, rep));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -