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

📄 bytecodegenerator.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    return result.first->second;}RegisterID* BytecodeGenerator::addConstant(JSValuePtr v){    pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValuePtr::encode(v), m_nextConstantIndex);    if (result.second) {        RegisterID& constant = m_calleeRegisters[m_nextConstantIndex];                ++m_nextConstantIndex;        m_codeBlock->addConstantRegister(JSValuePtr(v));        return &constant;    }    return &registerFor(result.first->second);}unsigned BytecodeGenerator::addUnexpectedConstant(JSValuePtr v){    return m_codeBlock->addUnexpectedConstant(v);}unsigned BytecodeGenerator::addRegExp(RegExp* r){    return m_codeBlock->addRegExp(r);}RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src){    emitOpcode(op_mov);    instructions().append(dst->index());    instructions().append(src->index());    return dst;}RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src){    emitOpcode(opcodeID);    instructions().append(dst->index());    instructions().append(src->index());    return dst;}RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst){    emitOpcode(op_pre_inc);    instructions().append(srcDst->index());    return srcDst;}RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst){    emitOpcode(op_pre_dec);    instructions().append(srcDst->index());    return srcDst;}RegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst){    emitOpcode(op_post_inc);    instructions().append(dst->index());    instructions().append(srcDst->index());    return dst;}RegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst){    emitOpcode(op_post_dec);    instructions().append(dst->index());    instructions().append(srcDst->index());    return dst;}RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types){    emitOpcode(opcodeID);    instructions().append(dst->index());    instructions().append(src1->index());    instructions().append(src2->index());    if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||        opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub) {        instructions().append(types.toInt());    }    return dst;}RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2){    if (m_lastOpcodeID == op_typeof) {        int dstIndex;        int srcIndex;        retrieveLastUnaryOp(dstIndex, srcIndex);        if (src1->index() == dstIndex            && src1->isTemporary()            && m_codeBlock->isConstantRegisterIndex(src2->index())            && m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()).isString()) {            const UString& value = asString(m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()))->value();            if (value == "undefined") {                rewindUnaryOp();                emitOpcode(op_is_undefined);                instructions().append(dst->index());                instructions().append(srcIndex);                return dst;            }            if (value == "boolean") {                rewindUnaryOp();                emitOpcode(op_is_boolean);                instructions().append(dst->index());                instructions().append(srcIndex);                return dst;            }            if (value == "number") {                rewindUnaryOp();                emitOpcode(op_is_number);                instructions().append(dst->index());                instructions().append(srcIndex);                return dst;            }            if (value == "string") {                rewindUnaryOp();                emitOpcode(op_is_string);                instructions().append(dst->index());                instructions().append(srcIndex);                return dst;            }            if (value == "object") {                rewindUnaryOp();                emitOpcode(op_is_object);                instructions().append(dst->index());                instructions().append(srcIndex);                return dst;            }            if (value == "function") {                rewindUnaryOp();                emitOpcode(op_is_function);                instructions().append(dst->index());                instructions().append(srcIndex);                return dst;            }        }    }    emitOpcode(opcodeID);    instructions().append(dst->index());    instructions().append(src1->index());    instructions().append(src2->index());    return dst;}RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b){    return emitLoad(dst, jsBoolean(b));}RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number){    // FIXME: Our hash tables won't hold infinity, so we make a new JSNumberCell each time.    // Later we can do the extra work to handle that like the other cases.    if (number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))        return emitLoad(dst, jsNumber(globalData(), number));    JSValuePtr& valueInMap = m_numberMap.add(number, noValue()).first->second;    if (!valueInMap)        valueInMap = jsNumber(globalData(), number);    return emitLoad(dst, valueInMap);}RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier){    JSString*& stringInMap = m_stringMap.add(identifier.ustring().rep(), 0).first->second;    if (!stringInMap)        stringInMap = jsOwnedString(globalData(), identifier.ustring());    return emitLoad(dst, JSValuePtr(stringInMap));}RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValuePtr v){    RegisterID* constantID = addConstant(v);    if (dst)        return emitMove(dst, constantID);    return constantID;}RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, bool b){    emitOpcode(op_unexpected_load);    instructions().append(dst->index());    instructions().append(addUnexpectedConstant(jsBoolean(b)));    return dst;}RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d){    emitOpcode(op_unexpected_load);    instructions().append(dst->index());    instructions().append(addUnexpectedConstant(jsNumber(globalData(), d)));    return dst;}bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject){    // Cases where we cannot statically optimize the lookup.    if (property == propertyNames().arguments || !canOptimizeNonLocals()) {        stackDepth = 0;        index = missingSymbolMarker();        if (shouldOptimizeLocals() && m_codeType == GlobalCode) {            ScopeChainIterator iter = m_scopeChain->begin();            globalObject = *iter;            ASSERT((++iter) == m_scopeChain->end());        }        return false;    }    size_t depth = 0;        ScopeChainIterator iter = m_scopeChain->begin();    ScopeChainIterator end = m_scopeChain->end();    for (; iter != end; ++iter, ++depth) {        JSObject* currentScope = *iter;        if (!currentScope->isVariableObject())            break;        JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);        SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.ustring().rep());        // Found the property        if (!entry.isNull()) {            if (entry.isReadOnly() && forWriting) {                stackDepth = 0;                index = missingSymbolMarker();                if (++iter == end)                    globalObject = currentVariableObject;                return false;            }            stackDepth = depth;            index = entry.getIndex();            if (++iter == end)                globalObject = currentVariableObject;            return true;        }        if (currentVariableObject->isDynamicScope())            break;    }    // Can't locate the property but we're able to avoid a few lookups.    stackDepth = depth;    index = missingSymbolMarker();    JSObject* scope = *iter;    if (++iter == end)        globalObject = scope;    return true;}RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype){     emitOpcode(op_instanceof);    instructions().append(dst->index());    instructions().append(value->index());    instructions().append(base->index());    instructions().append(basePrototype->index());    return dst;}RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& property){    size_t depth = 0;    int index = 0;    JSObject* globalObject = 0;    if (!findScopedProperty(property, index, depth, false, globalObject) && !globalObject) {        // We can't optimise at all :-(        emitOpcode(op_resolve);        instructions().append(dst->index());        instructions().append(addConstant(property));        return dst;    }    if (globalObject) {        bool forceGlobalResolve = false;        if (m_regeneratingForExceptionInfo) {#if ENABLE(JIT)            forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInfoAtBytecodeOffset(instructions().size());#else            forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInstructionAtBytecodeOffset(instructions().size());#endif        }        if (index != missingSymbolMarker() && !forceGlobalResolve) {            // Directly index the property lookup across multiple scopes.            return emitGetScopedVar(dst, depth, index, globalObject);        }#if ENABLE(JIT)        m_codeBlock->addGlobalResolveInfo(instructions().size());#else        m_codeBlock->addGlobalResolveInstruction(instructions().size());#endif        emitOpcode(op_resolve_global);        instructions().append(dst->index());        instructions().append(globalObject);        instructions().append(addConstant(property));        instructions().append(0);        instructions().append(0);        return dst;    }    if (index != missingSymbolMarker()) {        // Directly index the property lookup across multiple scopes.        return emitGetScopedVar(dst, depth, index, globalObject);    }    // In this case we are at least able to drop a few scope chains from the    // lookup chain, although we still need to hash from then on.    emitOpcode(op_resolve_skip);    instructions().append(dst->index());    instructions().append(addConstant(property));    instructions().append(depth);    return dst;}RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValuePtr globalObject){    if (globalObject) {        emitOpcode(op_get_global_var);        instructions().append(dst->index());        instructions().append(asCell(globalObject));        instructions().append(index);        return dst;    }    emitOpcode(op_get_scoped_var);    instructions().append(dst->index());    instructions().append(index);    instructions().append(depth);    return dst;}RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValuePtr globalObject){    if (globalObject) {        emitOpcode(op_put_global_var);        instructions().append(asCell(globalObject));        instructions().append(index);        instructions().append(value->index());        return value;    }    emitOpcode(op_put_scoped_var);    instructions().append(index);    instructions().append(depth);    instructions().append(value->index());    return value;}RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property){

⌨️ 快捷键说明

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