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

📄 interpreter.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            ASSERT(m_opcodeIDTable.size() == numOpcodeIDs);        #endif // HAVE(COMPUTED_GOTO)        return noValue();    }#if ENABLE(JIT)    // Currently with CTI enabled we never interpret functions    ASSERT_NOT_REACHED();#endif    JSGlobalData* globalData = &callFrame->globalData();    JSValuePtr exceptionValue = noValue();    HandlerInfo* handler = 0;    Instruction* vPC = callFrame->codeBlock()->instructions().begin();    Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();    unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck();#define CHECK_FOR_EXCEPTION() \    do { \        if (UNLIKELY(globalData->exception != noValue())) { \            exceptionValue = globalData->exception; \            goto vm_throw; \        } \    } while (0)#if ENABLE(OPCODE_STATS)    OpcodeStats::resetLastInstruction();#endif#define CHECK_FOR_TIMEOUT() \    if (!--tickCount) { \        if (globalData->timeoutChecker.didTimeOut(callFrame)) { \            exceptionValue = jsNull(); \            goto vm_throw; \        } \        tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \    }    #if ENABLE(OPCODE_SAMPLING)    #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)#else    #define SAMPLE(codeBlock, vPC)#endif#if HAVE(COMPUTED_GOTO)    #define NEXT_INSTRUCTION() SAMPLE(callFrame->codeBlock(), vPC); goto *vPC->u.opcode#if ENABLE(OPCODE_STATS)    #define DEFINE_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode);#else    #define DEFINE_OPCODE(opcode) opcode:#endif    NEXT_INSTRUCTION();#else    #define NEXT_INSTRUCTION() SAMPLE(callFrame->codeBlock(), vPC); goto interpreterLoopStart#if ENABLE(OPCODE_STATS)    #define DEFINE_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode);#else    #define DEFINE_OPCODE(opcode) case opcode:#endif    while (1) { // iterator loop begins    interpreterLoopStart:;    switch (vPC->u.opcode)#endif    {    DEFINE_OPCODE(op_new_object) {        /* new_object dst(r)           Constructs a new empty Object instance using the original           constructor, and puts the result in register dst.        */        int dst = (++vPC)->u.operand;        callFrame[dst] = JSValuePtr(constructEmptyObject(callFrame));        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_new_array) {        /* new_array dst(r) firstArg(r) argCount(n)           Constructs a new Array instance using the original           constructor, and puts the result in register dst.           The array will contain argCount elements with values           taken from registers starting at register firstArg.        */        int dst = (++vPC)->u.operand;        int firstArg = (++vPC)->u.operand;        int argCount = (++vPC)->u.operand;        ArgList args(callFrame->registers() + firstArg, argCount);        callFrame[dst] = JSValuePtr(constructArray(callFrame, args));        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_new_regexp) {        /* new_regexp dst(r) regExp(re)           Constructs a new RegExp instance using the original           constructor from regexp regExp, and puts the result in           register dst.        */        int dst = (++vPC)->u.operand;        int regExp = (++vPC)->u.operand;        callFrame[dst] = JSValuePtr(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_mov) {        /* mov dst(r) src(r)           Copies register src to register dst.        */        int dst = (++vPC)->u.operand;        int src = (++vPC)->u.operand;        callFrame[dst] = callFrame[src];        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_eq) {        /* eq dst(r) src1(r) src2(r)           Checks whether register src1 and register src2 are equal,           as with the ECMAScript '==' operator, and puts the result           as a boolean in register dst.        */        int dst = (++vPC)->u.operand;        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        if (JSFastMath::canDoFastBitwiseOperations(src1, src2))            callFrame[dst] = JSFastMath::equal(src1, src2);        else {            JSValuePtr result = jsBoolean(JSValuePtr::equalSlowCase(callFrame, src1, src2));            CHECK_FOR_EXCEPTION();            callFrame[dst] = result;        }        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_eq_null) {        /* eq_null dst(r) src(r)           Checks whether register src is null, as with the ECMAScript '!='           operator, and puts the result as a boolean in register dst.        */        int dst = (++vPC)->u.operand;        JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);        if (src.isUndefinedOrNull()) {            callFrame[dst] = jsBoolean(true);            ++vPC;            NEXT_INSTRUCTION();        }                callFrame[dst] = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_neq) {        /* neq dst(r) src1(r) src2(r)           Checks whether register src1 and register src2 are not           equal, as with the ECMAScript '!=' operator, and puts the           result as a boolean in register dst.        */        int dst = (++vPC)->u.operand;        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        if (JSFastMath::canDoFastBitwiseOperations(src1, src2))            callFrame[dst] = JSFastMath::notEqual(src1, src2);        else {            JSValuePtr result = jsBoolean(!JSValuePtr::equalSlowCase(callFrame, src1, src2));            CHECK_FOR_EXCEPTION();            callFrame[dst] = result;        }        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_neq_null) {        /* neq_null dst(r) src(r)           Checks whether register src is not null, as with the ECMAScript '!='           operator, and puts the result as a boolean in register dst.        */        int dst = (++vPC)->u.operand;        JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);        if (src.isUndefinedOrNull()) {            callFrame[dst] = jsBoolean(false);            ++vPC;            NEXT_INSTRUCTION();        }                callFrame[dst] = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined());        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_stricteq) {        /* stricteq dst(r) src1(r) src2(r)           Checks whether register src1 and register src2 are strictly           equal, as with the ECMAScript '===' operator, and puts the           result as a boolean in register dst.        */        int dst = (++vPC)->u.operand;        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        callFrame[dst] = jsBoolean(JSValuePtr::strictEqual(src1, src2));        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_nstricteq) {        /* nstricteq dst(r) src1(r) src2(r)           Checks whether register src1 and register src2 are not           strictly equal, as with the ECMAScript '!==' operator, and           puts the result as a boolean in register dst.        */        int dst = (++vPC)->u.operand;        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        callFrame[dst] = jsBoolean(!JSValuePtr::strictEqual(src1, src2));        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_less) {        /* less dst(r) src1(r) src2(r)           Checks whether register src1 is less than register src2, as           with the ECMAScript '<' operator, and puts the result as           a boolean in register dst.        */        int dst = (++vPC)->u.operand;        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        JSValuePtr result = jsBoolean(jsLess(callFrame, src1, src2));        CHECK_FOR_EXCEPTION();        callFrame[dst] = result;        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_lesseq) {        /* lesseq dst(r) src1(r) src2(r)           Checks whether register src1 is less than or equal to           register src2, as with the ECMAScript '<=' operator, and           puts the result as a boolean in register dst.        */        int dst = (++vPC)->u.operand;        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);        JSValuePtr result = jsBoolean(jsLessEq(callFrame, src1, src2));        CHECK_FOR_EXCEPTION();        callFrame[dst] = result;        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_pre_inc) {        /* pre_inc srcDst(r)           Converts register srcDst to number, adds one, and puts the result           back in register srcDst.        */        int srcDst = (++vPC)->u.operand;        JSValuePtr v = callFrame[srcDst].jsValue(callFrame);        if (JSFastMath::canDoFastAdditiveOperations(v))            callFrame[srcDst] = JSValuePtr(JSFastMath::incImmediateNumber(v));        else {            JSValuePtr result = jsNumber(callFrame, v.toNumber(callFrame) + 1);            CHECK_FOR_EXCEPTION();            callFrame[srcDst] = result;        }        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_pre_dec) {        /* pre_dec srcDst(r)           Converts register srcDst to number, subtracts one, and puts the result           back in register srcDst.        */        int srcDst = (++vPC)->u.operand;        JSValuePtr v = callFrame[srcDst].jsValue(callFrame);        if (JSFastMath::canDoFastAdditiveOperations(v))            callFrame[srcDst] = JSValuePtr(JSFastMath::decImmediateNumber(v));        else {            JSValuePtr result = jsNumber(callFrame, v.toNumber(callFrame) - 1);            CHECK_FOR_EXCEPTION();            callFrame[srcDst] = result;        }        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_post_inc) {        /* post_inc dst(r) srcDst(r)           Converts register srcDst to number. The number itself is           written to register dst, and the number plus one is written           back to register srcDst.        */        int dst = (++vPC)->u.operand;        int srcDst = (++vPC)->u.operand;        JSValuePtr v = callFrame[srcDst].jsValue(callFrame);        if (JSFastMath::canDoFastAdditiveOperations(v)) {            callFrame[dst] = v;            callFrame[srcDst] = JSValuePtr(JSFastMath::incImmediateNumber(v));        } else {            JSValuePtr number = callFrame[srcDst].jsValue(callFrame).toJSNumber(callFrame);            CHECK_FOR_EXCEPTION();            callFrame[dst] = number;            callFrame[srcDst] = JSValuePtr(jsNumber(callFrame, number.uncheckedGetNumber() + 1));        }        ++vPC;        NEXT_INSTRUCTION();    }    DEFINE_OPCODE(op_post_dec) {        /* post_dec dst(r) srcDst(r)           Converts register srcDst to number. The number itself is           written to register dst, and the number minus one is written           back to register srcDst.        */        int dst = (++vPC)->u.operand;        int srcDst = (++vPC)->u.operand;        JSValuePtr v = callFrame[srcDst].jsValue(callFrame);        if (JSFastMath::canDoFastAdditiveOperations(v)) {            callFrame[dst] = v;            callFrame[srcDst] = JSValuePtr(JSFastMath::decImmediateNumber(v));

⌨️ 快捷键说明

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