📄 interpreter.cpp
字号:
} 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_to_jsnumber) { /* to_jsnumber dst(r) src(r) Converts register src to number, and puts the result in register dst. */ int dst = (++vPC)->u.operand; int src = (++vPC)->u.operand; JSValuePtr srcVal = callFrame[src].jsValue(callFrame); if (LIKELY(srcVal.isNumber())) callFrame[dst] = callFrame[src]; else { JSValuePtr result = srcVal.toJSNumber(callFrame); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } ++vPC; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_negate) { /* negate dst(r) src(r) Converts register src to number, negates it, and puts the result in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame); ++vPC; double v; if (src.getNumber(v)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, -v)); else { JSValuePtr result = jsNumber(callFrame, -src.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_add) { /* add dst(r) src1(r) src2(r) Adds register src1 and register src2, and puts the result in register dst. (JS add may be string concatenation or numeric add, depending on the types of the operands.) */ int dst = (++vPC)->u.operand; JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame); if (JSFastMath::canDoFastAdditiveOperations(src1, src2)) callFrame[dst] = JSValuePtr(JSFastMath::addImmediateNumbers(src1, src2)); else { JSValuePtr result = jsAdd(callFrame, src1, src2); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } vPC += 2; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mul) { /* mul dst(r) src1(r) src2(r) Multiplies register src1 and register src2 (converted to numbers), and puts the product in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame); double left; double right; if (JSValuePtr::areBothInt32Fast(src1, src2)) { int32_t left = src1.getInt32Fast(); int32_t right = src2.getInt32Fast(); if ((left | right) >> 15 == 0) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left * right)); else callFrame[dst] = JSValuePtr(jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right))); } else if (src1.getNumber(left) && src2.getNumber(right)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left * right)); else { JSValuePtr result = jsNumber(callFrame, src1.toNumber(callFrame) * src2.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } vPC += 2; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_div) { /* div dst(r) dividend(r) divisor(r) Divides register dividend (converted to number) by the register divisor (converted to number), and puts the quotient in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr dividend = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr divisor = callFrame[(++vPC)->u.operand].jsValue(callFrame); double left; double right; if (dividend.getNumber(left) && divisor.getNumber(right)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left / right)); else { JSValuePtr result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } ++vPC; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_mod) { /* mod dst(r) dividend(r) divisor(r) Divides register dividend (converted to number) by register divisor (converted to number), and puts the remainder in register dst. */ int dst = (++vPC)->u.operand; int dividend = (++vPC)->u.operand; int divisor = (++vPC)->u.operand; JSValuePtr dividendValue = callFrame[dividend].jsValue(callFrame); JSValuePtr divisorValue = callFrame[divisor].jsValue(callFrame); if (JSValuePtr::areBothInt32Fast(dividendValue, divisorValue) && divisorValue != js0()) { // We expect the result of the modulus of a number that was representable as an int32 to also be representable // as an int32. JSValuePtr result = JSValuePtr::makeInt32Fast(dividendValue.getInt32Fast() % divisorValue.getInt32Fast()); ASSERT(result); callFrame[dst] = result; ++vPC; NEXT_INSTRUCTION(); } double d = dividendValue.toNumber(callFrame); JSValuePtr result = jsNumber(callFrame, fmod(d, divisorValue.toNumber(callFrame))); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; ++vPC; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_sub) { /* sub dst(r) src1(r) src2(r) Subtracts register src2 (converted to number) from register src1 (converted to number), and puts the difference in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame); double left; double right; if (JSFastMath::canDoFastAdditiveOperations(src1, src2)) callFrame[dst] = JSValuePtr(JSFastMath::subImmediateNumbers(src1, src2)); else if (src1.getNumber(left) && src2.getNumber(right)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left - right)); else { JSValuePtr result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } vPC += 2; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_lshift) { /* lshift dst(r) val(r) shift(r) Performs left shift of register val (converted to int32) by register shift (converted to uint32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame); int32_t left; uint32_t right; if (JSValuePtr::areBothInt32Fast(val, shift)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f))); else if (val.numberToInt32(left) && shift.numberToUInt32(right)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left << (right & 0x1f))); else { JSValuePtr result = jsNumber(callFrame, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } ++vPC; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_rshift) { /* rshift dst(r) val(r) shift(r) Performs arithmetic right shift of register val (converted to int32) by register shift (converted to uint32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame); int32_t left; uint32_t right; if (JSFastMath::canDoFastRshift(val, shift)) callFrame[dst] = JSValuePtr(JSFastMath::rightShiftImmediateNumbers(val, shift)); else if (val.numberToInt32(left) && shift.numberToUInt32(right)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left >> (right & 0x1f))); else { JSValuePtr result = jsNumber(callFrame, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } ++vPC; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_urshift) { /* rshift dst(r) val(r) shift(r) Performs logical right shift of register val (converted to uint32) by register shift (converted to uint32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame); if (JSFastMath::canDoFastUrshift(val, shift)) callFrame[dst] = JSValuePtr(JSFastMath::rightShiftImmediateNumbers(val, shift)); else { JSValuePtr result = jsNumber(callFrame, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } ++vPC; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitand) { /* bitand dst(r) src1(r) src2(r) Computes bitwise AND of register src1 (converted to int32) and register src2 (converted to int32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame); int32_t left; int32_t right; if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) callFrame[dst] = JSValuePtr(JSFastMath::andImmediateNumbers(src1, src2)); else if (src1.numberToInt32(left) && src2.numberToInt32(right)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left & right)); else { JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) & src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } vPC += 2; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitxor) { /* bitxor dst(r) src1(r) src2(r) Computes bitwise XOR of register src1 (converted to int32) and register src2 (converted to int32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame); int32_t left; int32_t right; if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) callFrame[dst] = JSValuePtr(JSFastMath::xorImmediateNumbers(src1, src2)); else if (src1.numberToInt32(left) && src2.numberToInt32(right)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left ^ right)); else { JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) ^ src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } vPC += 2; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitor) { /* bitor dst(r) src1(r) src2(r) Computes bitwise OR of register src1 (converted to int32) and register src2 (converted to int32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame); JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame); int32_t left; int32_t right; if (JSFastMath::canDoFastBitwiseOperations(src1, src2)) callFrame[dst] = JSValuePtr(JSFastMath::orImmediateNumbers(src1, src2)); else if (src1.numberToInt32(left) && src2.numberToInt32(right)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, left | right)); else { JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) | src2.toInt32(callFrame)); CHECK_FOR_EXCEPTION(); callFrame[dst] = result; } vPC += 2; NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_bitnot) { /* bitnot dst(r) src(r) Computes bitwise NOT of register src1 (converted to int32), and puts the result in register dst. */ int dst = (++vPC)->u.operand; JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame); int32_t value; if (src.numberToInt32(value)) callFrame[dst] = JSValuePtr(jsNumber(callFrame, ~value)); else { JSValuePtr result = jsNumber(callFrame, ~src.toInt32(callFrame)); CHECK_FOR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -