+2013-04-25 Geoffrey Garen <ggaren@apple.com>
+
+ Cleaned up pre/post inc/dec in bytecode
+ https://bugs.webkit.org/show_bug.cgi?id=115222
+
+ Reviewed by Filip Pizlo.
+
+ * fast/js/const-expected.txt:
+ * fast/js/resources/const.js: Added tests for some const cases we used
+ to get wrong.
+
2013-04-26 Geoffrey Garen <ggaren@apple.com>
Re-landing <http://trac.webkit.org/changeset/148999>
PASS tryCatch2Result is 5
PASS with1Result is 5
PASS with2Result is 5
+PASS PASS: ++x should be 2 and is.
+PASS PASS: --x should be 0 and is.
+PASS PASS: x should be 1 and is.
+PASS PASS: x++ should be 1 and is.
+PASS PASS: x should be 1 and is.
+PASS PASS: ++x should be 2 and is.
+PASS PASS: x should be 1 and is.
+PASS PASS: x++ should be 1 and is.
+PASS PASS: x should be 1 and is.
PASS successfullyParsed is true
TEST COMPLETE
shouldBe("with1Result", "5");
with2Result = with2();
shouldBe("with2Result", "5");
+
+(function () {
+ function shouldBe(aDescription, a, b)
+ {
+ if (a === b) {
+ testPassed("PASS: " + aDescription + " should be " + b + " and is.");
+ return;
+ }
+
+ testFailed("FAIL: " + aDescription + " should be " + b + " but instead is " + a + ".");
+ }
+
+ (function() {
+ const x = "1";
+ shouldBe("++x", ++x, 2);
+ shouldBe("--x", --x, 0);
+ shouldBe("x", x, "1");
+ shouldBe("x++", x++, 1);
+ shouldBe("x", x, "1");
+ })();
+ (function() {
+ const x = 1;
+ shouldBe("++x", ++x, 2);
+ shouldBe("x", x, 1);
+ shouldBe("x++", x++, 1);
+ shouldBe("x", x, 1);
+ })();
+})();
+2013-04-25 Geoffrey Garen <ggaren@apple.com>
+
+ Cleaned up pre/post inc/dec in bytecode
+ https://bugs.webkit.org/show_bug.cgi?id=115222
+
+ Reviewed by Filip Pizlo.
+
+ A few related changes here:
+
+ (*) Removed post_inc and post_dec. The two-result form was awkward to
+ reason about. Being explicit about the intermediate mov and to_number
+ reduces DFG overhead, removes some fragile ASSERTs from the DFG, and
+ fixes a const bug. Plus, we get to blow away 262 lines of code.
+
+ (*) Renamed pre_inc and pre_dec to inc and dec, since there's only one
+ version now.
+
+ (*) Renamed to_jsnumber to to_number, to match the ECMA name.
+
+ (*) Tightened up the codegen and runtime support for to_number.
+
+
+ * JavaScriptCore.order: Order!
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecode/Opcode.h:
+ (JSC::padOpcodeName):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitInc):
+ (JSC::BytecodeGenerator::emitDec):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitToNumber):
+ (BytecodeGenerator): Removed post_inc and post_dec.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::emitPreIncOrDec): Updated for rename.
+
+ (JSC::emitPostIncOrDec): Issue an explicit mov and to_number when needed.
+ These are rare, and they boil away in the DFG.
+
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PrefixNode::emitResolve): For const, use an explicit mov instead
+ of any special forms. This fixes a bug where we would do string
+ add/subtract instead of number.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_inc):
+ (JSC::JIT::emitSlow_op_inc):
+ (JSC::JIT::emit_op_dec):
+ (JSC::JIT::emitSlow_op_dec):
+ * jit/JITArithmetic32_64.cpp:
+ (JSC::JIT::emit_op_inc):
+ (JSC::JIT::emitSlow_op_inc):
+ (JSC::JIT::emit_op_dec):
+ (JSC::JIT::emitSlow_op_dec): Removed post_inc/dec, and updated for renames.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_to_number):
+ (JSC::JIT::emitSlow_op_to_number): Removed a test for number cells. There's
+ no such thing!
+
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_to_number): Use LowestTag to avoid making assumptions
+ about the lowest valued tag.
+
+ (JSC::JIT::emitSlow_op_to_number): Updated for renames.
+
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LLIntSlowPaths.h:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * parser/NodeConstructors.h:
+ (JSC::UnaryPlusNode::UnaryPlusNode): Removed post_inc/dec, and updated for renames.
+
+ * runtime/Operations.cpp:
+ (JSC::jsIsObjectType): Removed a test for number cells. There's
+ no such thing!
+
2013-04-27 Julien Brianceau <jbrianceau@nds.com>
REGRESSION(r149114): cache flush for SH4 arch may flush an extra page.
__ZN3JSC3JIT18emit_op_get_by_valEPNS_11InstructionE
__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common19RelationalConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS5_13TrustedImmPtrE
__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii
-__ZN3JSC3JIT15emit_op_pre_incEPNS_11InstructionE
+__ZN3JSC3JIT15emit_op_incEPNS_11InstructionE
__ZN3JSC3JIT16emitTimeoutCheckEv
__ZN3JSC3JIT13emit_op_jlessEPNS_11InstructionE
__ZN3JSC3JIT22emitSlow_op_get_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3WTF9HashTableIPFN3JSC21MacroAssemblerCodePtrEPNS1_12VMEPNS1_14ExecutablePoolEESt4pairIS8_S2_ENS_18PairFirstExtractorISA_EENS_7PtrHashIS8_EENS_14PairHashTraitsINS_10HashTraitsIS8_EENSG_IS2_EEEESH_E6expandEv
__ZN3JSC3JIT27stringGetByValStubGeneratorEPNS_12VMEPNS_14ExecutablePoolE
__ZN3JSC21roundUpAllocationSizeEmm
-__ZN3JSC3JIT19emitSlow_op_pre_incEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT19emitSlow_op_incEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC3JIT17emitSlow_op_jlessEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC12X86Assembler7movq_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE
__ZN3JSC23MacroAssemblerX86Common12branchDoubleENS0_15DoubleConditionENS_12X86Registers13XMMRegisterIDES3_
_cti_op_load_varargs
__ZN3WTF13tryFastCallocEmm
__ZN3JSC17BytecodeGenerator10emitPreDecEPNS_10RegisterIDE
-__ZN3JSC3JIT15emit_op_pre_decEPNS_11InstructionE
-__ZN3JSC3JIT19emitSlow_op_pre_decEPNS_11InstructionERPNS_13SlowCaseEntryE
-_cti_op_pre_dec
+__ZN3JSC3JIT15emit_op_decEPNS_11InstructionE
+__ZN3JSC3JIT19emitSlow_op_decEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_dec
__ZN3WTF10StringImpl16findIgnoringCaseEPS0_j
__ZN3JSC5Lexer19getUnicodeCharacterEv
__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateE
__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainENS_16ReturnAddressPtrEb
_cti_op_put_by_id_fail
__ZN3JSC17BytecodeGenerator11emitPostIncEPNS_10RegisterIDES2_
-__ZN3JSC3JIT16emit_op_post_incEPNS_11InstructionE
-__ZN3JSC3JIT20emitSlow_op_post_incEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSCL23createPrototypePropertyERNS_12VMEPNS_14JSGlobalObjectEPNS_10JSFunctionE
__ZNK3JSC8NullNode6isNullEv
__ZN3JSC3JIT17emit_op_jneq_nullEPNS_11InstructionE
__ZN3JSC16globalFuncEscapeEPNS_9ExecStateE
__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC17BytecodeGenerator11emitPostDecEPNS_10RegisterIDES2_
-__ZN3JSC3JIT16emit_op_post_decEPNS_11InstructionE
-__ZN3JSC3JIT20emitSlow_op_post_decEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC7JSArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE
__ZN3JSC9ExecState19arrayPrototypeTableEPS0_
__ZNK3JSC18PropertyDescriptor10enumerableEv
__ZNK3JSC18PropertyDescriptor12configurableEv
__ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
-__ZN3JSC3JIT19emit_op_to_jsnumberEPNS_11InstructionE
-__ZN3JSC3JIT23emitSlow_op_to_jsnumberEPNS_11InstructionERPNS_13SlowCaseEntryE
-_cti_op_to_jsnumber
+__ZN3JSC3JIT19emit_op_to_numberEPNS_11InstructionE
+__ZN3JSC3JIT23emitSlow_op_to_numberEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_to_number
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE8toNumberEPNS_9ExecStateE
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE9classNameEv
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE8toStringEPNS_9ExecStateE
_cti_op_is_object
__ZN3JSC14jsIsObjectTypeENS_7JSValueE
__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateE
-_cti_op_pre_inc
+_cti_op_inc
__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateE
__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateE
__ZN3JSC7JSArray3popEv
__ZN3JSC15DateConstructor11getCallDataERNS_8CallDataE
__ZN3JSCL25numberConstructorMaxValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
__ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
-_cti_op_post_inc
-_cti_op_post_dec
__ZN3JSC10ASTBuilder18makeBitwiseNotNodeEPNS_14ExpressionNodeE
__ZN3JSC3JIT14emit_op_bitnotEPNS_11InstructionE
__ZN3JSC3JIT18emitSlow_op_bitnotEPNS_11InstructionERPNS_13SlowCaseEntryE
printBinaryOp(out, exec, location, it, "greatereq");
break;
}
- case op_pre_inc: {
+ case op_inc: {
int r0 = (++it)->u.operand;
out.printf("[%4d] pre_inc\t\t %s", location, registerName(exec, r0).data());
break;
}
- case op_pre_dec: {
+ case op_dec: {
int r0 = (++it)->u.operand;
out.printf("[%4d] pre_dec\t\t %s", location, registerName(exec, r0).data());
break;
}
- case op_post_inc: {
- printUnaryOp(out, exec, location, it, "post_inc");
- break;
- }
- case op_post_dec: {
- printUnaryOp(out, exec, location, it, "post_dec");
- break;
- }
- case op_to_jsnumber: {
- printUnaryOp(out, exec, location, it, "to_jsnumber");
+ case op_to_number: {
+ printUnaryOp(out, exec, location, it, "to_number");
break;
}
case op_negate: {
macro(op_greater, 4) \
macro(op_greatereq, 4) \
\
- macro(op_pre_inc, 2) \
- macro(op_pre_dec, 2) \
- macro(op_post_inc, 3) \
- macro(op_post_dec, 3) \
- macro(op_to_jsnumber, 3) \
+ macro(op_inc, 2) \
+ macro(op_dec, 2) \
+ macro(op_to_number, 3) \
macro(op_negate, 3) \
macro(op_add, 5) \
macro(op_mul, 5) \
return dst;
}
-RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
+RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
{
- emitOpcode(op_pre_inc);
+ emitOpcode(op_inc);
instructions().append(srcDst->index());
return srcDst;
}
-RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
+RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
{
- emitOpcode(op_pre_dec);
+ emitOpcode(op_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);
RegisterID* emitMove(RegisterID* dst, RegisterID* src);
- RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src); }
- RegisterID* emitPreInc(RegisterID* srcDst);
- RegisterID* emitPreDec(RegisterID* srcDst);
- RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst);
- RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst);
+ RegisterID* emitToNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_number, dst, src); }
+ RegisterID* emitInc(RegisterID* srcDst);
+ RegisterID* emitDec(RegisterID* srcDst);
void emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target);
RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype);
// ------------------------------ PostfixNode ----------------------------------
-static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
+static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
{
- return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
+ return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
}
static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
{
- if (srcDst == dst)
- return generator.emitToJSNumber(dst, srcDst);
- return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
+ if (dst == srcDst)
+ return generator.emitToNumber(generator.finalDestination(dst), srcDst);
+ RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
+ emitIncOrDec(generator, srcDst, oper);
+ return generator.moveToDestinationIfNeeded(dst, tmp.get());
}
RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
ResolveResult resolveResult = generator.resolve(ident);
- if (RegisterID* local = resolveResult.local()) {
+ if (RefPtr<RegisterID> local = resolveResult.local()) {
if (resolveResult.isReadOnly()) {
generator.emitReadOnlyExceptionIfNeeded();
- return generator.emitToJSNumber(generator.finalDestination(dst), local);
+ local = generator.emitMove(generator.tempDestination(dst), local.get());
}
- return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
+ return emitPostIncOrDec(generator, generator.finalDestination(dst), local.get(), m_operator);
}
if (resolveResult.isStatic() && !resolveResult.isReadOnly()) {
const Identifier& ident = resolve->identifier();
ResolveResult resolveResult = generator.resolve(ident);
- if (RegisterID* local = resolveResult.local()) {
+ if (RefPtr<RegisterID> local = resolveResult.local()) {
if (resolveResult.isReadOnly()) {
generator.emitReadOnlyExceptionIfNeeded();
- if (dst == generator.ignoredResult())
- return generator.emitToJSNumber(generator.newTemporary(), local);
- RefPtr<RegisterID> r0 = generator.emitLoad(generator.tempDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
- generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
- return generator.moveToDestinationIfNeeded(dst, r0.get());
+ local = generator.emitMove(generator.tempDestination(dst), local.get());
}
- emitPreIncOrDec(generator, local, m_operator);
- return generator.moveToDestinationIfNeeded(dst, local);
+ emitIncOrDec(generator, local.get(), m_operator);
+ return generator.moveToDestinationIfNeeded(dst, local.get());
}
if (resolveResult.isStatic() && !resolveResult.isReadOnly()) {
RefPtr<RegisterID> propDst = generator.emitGetStaticVar(generator.tempDestination(dst), resolveResult, ident);
- emitPreIncOrDec(generator, propDst.get(), m_operator);
+ emitIncOrDec(generator, propDst.get(), m_operator);
generator.emitPutStaticVar(resolveResult, ident, propDst.get());
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
RefPtr<RegisterID> propDst = generator.tempDestination(dst);
NonlocalResolveInfo resolveVerifier;
RefPtr<RegisterID> base = generator.emitResolveWithBaseForPut(generator.newTemporary(), propDst.get(), resolveResult, ident, resolveVerifier);
- emitPreIncOrDec(generator, propDst.get(), m_operator);
+ emitIncOrDec(generator, propDst.get(), m_operator);
generator.emitPutToBase(base.get(), ident, propDst.get(), resolveVerifier);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->startOffset(), bracketAccessor->endOffset());
RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
- emitPreIncOrDec(generator, value, m_operator);
+ emitIncOrDec(generator, value, m_operator);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutByVal(base.get(), property.get(), value);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->startOffset(), dotAccessor->endOffset());
RegisterID* value = generator.emitGetById(propDst.get(), base.get(), ident);
- emitPreIncOrDec(generator, value, m_operator);
+ emitIncOrDec(generator, value, m_operator);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutById(base.get(), ident, value);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
// === Increment/Decrement opcodes ===
- case op_pre_inc: {
+ case op_inc: {
unsigned srcDst = currentInstruction[1].u.operand;
Node* op = get(srcDst);
set(srcDst, makeSafe(addToGraph(ArithAdd, op, one())));
- NEXT_OPCODE(op_pre_inc);
+ NEXT_OPCODE(op_inc);
}
- case op_post_inc: {
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
- ASSERT(result != srcDst); // Required for assumptions we make during OSR.
- Node* op = get(srcDst);
- setPair(result, op, srcDst, makeSafe(addToGraph(ArithAdd, op, one())));
- NEXT_OPCODE(op_post_inc);
- }
-
- case op_pre_dec: {
+ case op_dec: {
unsigned srcDst = currentInstruction[1].u.operand;
Node* op = get(srcDst);
set(srcDst, makeSafe(addToGraph(ArithSub, op, one())));
- NEXT_OPCODE(op_pre_dec);
- }
-
- case op_post_dec: {
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
- Node* op = get(srcDst);
- setPair(result, op, srcDst, makeSafe(addToGraph(ArithSub, op, one())));
- NEXT_OPCODE(op_post_dec);
+ NEXT_OPCODE(op_dec);
}
// === Arithmetic operations ===
NEXT_OPCODE(op_typeof);
}
- case op_to_jsnumber: {
+ case op_to_number: {
set(currentInstruction[1].u.operand,
addToGraph(Identity, Edge(get(currentInstruction[2].u.operand), NumberUse)));
- NEXT_OPCODE(op_to_jsnumber);
+ NEXT_OPCODE(op_to_number);
}
default:
case op_rshift:
case op_lshift:
case op_urshift:
- case op_pre_inc:
- case op_post_inc:
- case op_pre_dec:
- case op_post_dec:
+ case op_inc:
+ case op_dec:
case op_add:
case op_sub:
case op_negate:
case op_put_to_base_variable:
case op_put_to_base:
case op_typeof:
- case op_to_jsnumber:
+ case op_to_number:
return CanCompile;
case op_call_varargs:
DEFINE_OP(op_not)
DEFINE_OP(op_nstricteq)
DEFINE_OP(op_pop_scope)
- DEFINE_OP(op_post_dec)
- DEFINE_OP(op_post_inc)
- DEFINE_OP(op_pre_dec)
- DEFINE_OP(op_pre_inc)
+ DEFINE_OP(op_dec)
+ DEFINE_OP(op_inc)
DEFINE_OP(op_profile_did_call)
DEFINE_OP(op_profile_will_call)
DEFINE_OP(op_push_name_scope)
DEFINE_OP(op_tear_off_arguments)
DEFINE_OP(op_throw)
DEFINE_OP(op_throw_static_error)
- DEFINE_OP(op_to_jsnumber)
+ DEFINE_OP(op_to_number)
DEFINE_OP(op_to_primitive)
DEFINE_OP(op_get_scoped_var)
DEFINE_SLOWCASE_OP(op_new_object)
DEFINE_SLOWCASE_OP(op_not)
DEFINE_SLOWCASE_OP(op_nstricteq)
- DEFINE_SLOWCASE_OP(op_post_dec)
- DEFINE_SLOWCASE_OP(op_post_inc)
- DEFINE_SLOWCASE_OP(op_pre_dec)
- DEFINE_SLOWCASE_OP(op_pre_inc)
+ DEFINE_SLOWCASE_OP(op_dec)
+ DEFINE_SLOWCASE_OP(op_inc)
case op_put_by_id_out_of_line:
case op_put_by_id_transition_direct:
case op_put_by_id_transition_normal:
DEFINE_SLOWCASE_OP(op_urshift)
DEFINE_SLOWCASE_OP(op_stricteq)
DEFINE_SLOWCASE_OP(op_sub)
- DEFINE_SLOWCASE_OP(op_to_jsnumber)
+ DEFINE_SLOWCASE_OP(op_to_number)
DEFINE_SLOWCASE_OP(op_to_primitive)
case op_resolve_global_property:
void emit_op_not(Instruction*);
void emit_op_nstricteq(Instruction*);
void emit_op_pop_scope(Instruction*);
- void emit_op_post_dec(Instruction*);
- void emit_op_post_inc(Instruction*);
- void emit_op_pre_dec(Instruction*);
- void emit_op_pre_inc(Instruction*);
+ void emit_op_dec(Instruction*);
+ void emit_op_inc(Instruction*);
void emit_op_profile_did_call(Instruction*);
void emit_op_profile_will_call(Instruction*);
void emit_op_push_name_scope(Instruction*);
void emit_op_tear_off_arguments(Instruction*);
void emit_op_throw(Instruction*);
void emit_op_throw_static_error(Instruction*);
- void emit_op_to_jsnumber(Instruction*);
+ void emit_op_to_number(Instruction*);
void emit_op_to_primitive(Instruction*);
void emit_op_unexpected_load(Instruction*);
void emit_op_urshift(Instruction*);
void emitSlow_op_new_object(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_not(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_nstricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_post_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_post_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_pre_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_pre_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_init_global_const_check(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_to_jsnumber(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_to_number(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
}
}
-void JIT::emit_op_post_inc(Instruction* currentInstruction)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- emitGetVirtualRegister(srcDst, regT0);
- move(regT0, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT1));
- emitFastArithIntToImmNoCheck(regT1, regT1);
- emitPutVirtualRegister(srcDst, regT1);
- emitPutVirtualRegister(result);
- if (canBeOptimizedOrInlined())
- killLastResultRegister();
-}
-
-void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- linkSlowCase(iter);
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_post_inc);
- stubCall.addArgument(regT0);
- stubCall.addArgument(Imm32(srcDst));
- stubCall.call(result);
-}
-
-void JIT::emit_op_post_dec(Instruction* currentInstruction)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- emitGetVirtualRegister(srcDst, regT0);
- move(regT0, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT1));
- emitFastArithIntToImmNoCheck(regT1, regT1);
- emitPutVirtualRegister(srcDst, regT1);
- emitPutVirtualRegister(result);
- if (canBeOptimizedOrInlined())
- killLastResultRegister();
-}
-
-void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- linkSlowCase(iter);
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_post_dec);
- stubCall.addArgument(regT0);
- stubCall.addArgument(Imm32(srcDst));
- stubCall.call(result);
-}
-
-void JIT::emit_op_pre_inc(Instruction* currentInstruction)
+void JIT::emit_op_inc(Instruction* currentInstruction)
{
unsigned srcDst = currentInstruction[1].u.operand;
emitPutVirtualRegister(srcDst);
}
-void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned srcDst = currentInstruction[1].u.operand;
linkSlowCase(iter);
emitGetVirtualRegister(srcDst, regT0);
notImm.link(this);
- JITStubCall stubCall(this, cti_op_pre_inc);
+ JITStubCall stubCall(this, cti_op_inc);
stubCall.addArgument(regT0);
stubCall.call(srcDst);
}
-void JIT::emit_op_pre_dec(Instruction* currentInstruction)
+void JIT::emit_op_dec(Instruction* currentInstruction)
{
unsigned srcDst = currentInstruction[1].u.operand;
emitPutVirtualRegister(srcDst);
}
-void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned srcDst = currentInstruction[1].u.operand;
linkSlowCase(iter);
emitGetVirtualRegister(srcDst, regT0);
notImm.link(this);
- JITStubCall stubCall(this, cti_op_pre_dec);
+ JITStubCall stubCall(this, cti_op_dec);
stubCall.addArgument(regT0);
stubCall.call(srcDst);
}
stubCall.call(dst);
}
-// PostInc (i++)
-
-void JIT::emit_op_post_inc(Instruction* currentInstruction)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- emitLoad(srcDst, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-
- if (dst == srcDst) // x = x++ is a noop for ints.
- return;
-
- move(regT0, regT2);
- addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT2));
- emitStoreInt32(srcDst, regT2, true);
-
- emitStoreAndMapInt32(dst, regT1, regT0, false, OPCODE_LENGTH(op_post_inc));
- if (canBeOptimizedOrInlined())
- unmap();
-}
-
-void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- linkSlowCase(iter); // int32 check
- if (dst != srcDst)
- linkSlowCase(iter); // overflow check
-
- JITStubCall stubCall(this, cti_op_post_inc);
- stubCall.addArgument(srcDst);
- stubCall.addArgument(TrustedImm32(srcDst));
- stubCall.call(dst);
-}
-
-// PostDec (i--)
-
-void JIT::emit_op_post_dec(Instruction* currentInstruction)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- emitLoad(srcDst, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-
- if (dst == srcDst) // x = x-- is a noop for ints.
- return;
-
- move(regT0, regT2);
- addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT2));
- emitStoreInt32(srcDst, regT2, true);
-
- emitStoreAndMapInt32(dst, regT1, regT0, false, OPCODE_LENGTH(op_post_dec));
- if (canBeOptimizedOrInlined())
- unmap();
-}
-
-void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- linkSlowCase(iter); // int32 check
- if (dst != srcDst)
- linkSlowCase(iter); // overflow check
-
- JITStubCall stubCall(this, cti_op_post_dec);
- stubCall.addArgument(srcDst);
- stubCall.addArgument(TrustedImm32(srcDst));
- stubCall.call(dst);
-}
-
-// PreInc (++i)
-
-void JIT::emit_op_pre_inc(Instruction* currentInstruction)
+void JIT::emit_op_inc(Instruction* currentInstruction)
{
unsigned srcDst = currentInstruction[1].u.operand;
addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT0));
- emitStoreAndMapInt32(srcDst, regT1, regT0, true, OPCODE_LENGTH(op_pre_inc));
+ emitStoreAndMapInt32(srcDst, regT1, regT0, true, OPCODE_LENGTH(op_inc));
}
-void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned srcDst = currentInstruction[1].u.operand;
linkSlowCase(iter); // int32 check
linkSlowCase(iter); // overflow check
- JITStubCall stubCall(this, cti_op_pre_inc);
+ JITStubCall stubCall(this, cti_op_inc);
stubCall.addArgument(srcDst);
stubCall.call(srcDst);
}
-// PreDec (--i)
-
-void JIT::emit_op_pre_dec(Instruction* currentInstruction)
+void JIT::emit_op_dec(Instruction* currentInstruction)
{
unsigned srcDst = currentInstruction[1].u.operand;
addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT0));
- emitStoreAndMapInt32(srcDst, regT1, regT0, true, OPCODE_LENGTH(op_pre_dec));
+ emitStoreAndMapInt32(srcDst, regT1, regT0, true, OPCODE_LENGTH(op_dec));
}
-void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned srcDst = currentInstruction[1].u.operand;
linkSlowCase(iter); // int32 check
linkSlowCase(iter); // overflow check
- JITStubCall stubCall(this, cti_op_pre_dec);
+ JITStubCall stubCall(this, cti_op_dec);
stubCall.addArgument(srcDst);
stubCall.call(srcDst);
}
compileOpStrictEq(currentInstruction, OpNStrictEq);
}
-void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
+void JIT::emit_op_to_number(Instruction* currentInstruction)
{
int srcVReg = currentInstruction[2].u.operand;
emitGetVirtualRegister(srcVReg, regT0);
- Jump wasImmediate = emitJumpIfImmediateInteger(regT0);
-
- emitJumpSlowCaseIfNotJSCell(regT0, srcVReg);
- loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
- addSlowCase(branch8(NotEqual, Address(regT2, Structure::typeInfoTypeOffset()), TrustedImm32(NumberType)));
-
- wasImmediate.link(this);
+ addSlowCase(emitJumpIfNotImmediateNumber(regT0));
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
compileOpCallSlowCase(op_construct, currentInstruction, iter, m_callLinkInfoIndex++);
}
-void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand);
linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_to_jsnumber);
+ JITStubCall stubCall(this, cti_op_to_number);
stubCall.addArgument(regT0);
stubCall.call(currentInstruction[1].u.operand);
}
JITStubCall(this, cti_op_pop_scope).call();
}
-void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
+void JIT::emit_op_to_number(Instruction* currentInstruction)
{
int dst = currentInstruction[1].u.operand;
int src = currentInstruction[2].u.operand;
emitLoad(src, regT1, regT0);
Jump isInt32 = branch32(Equal, regT1, TrustedImm32(JSValue::Int32Tag));
- addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
+ addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
isInt32.link(this);
if (src != dst)
emitStore(dst, regT1, regT0);
- map(m_bytecodeOffset + OPCODE_LENGTH(op_to_jsnumber), dst, regT1, regT0);
+ map(m_bytecodeOffset + OPCODE_LENGTH(op_to_number), dst, regT1, regT0);
}
-void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
int dst = currentInstruction[1].u.operand;
linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_to_jsnumber);
+ JITStubCall stubCall(this, cti_op_to_number);
stubCall.addArgument(regT1, regT0);
stubCall.call(dst);
}
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_inc)
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_inc)
{
STUB_INIT_STACK_FRAME(stackFrame);
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_dec)
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_dec)
{
STUB_INIT_STACK_FRAME(stackFrame);
return result;
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue v = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- double number = v.toNumber(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
-
- callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number + 1);
- return JSValue::encode(jsNumber(number));
-}
-
DEFINE_STUB_FUNCTION(int, op_eq)
{
STUB_INIT_STACK_FRAME(stackFrame);
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue v = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- double number = v.toNumber(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
-
- callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number - 1);
- return JSValue::encode(jsNumber(number));
-}
-
DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift)
{
STUB_INIT_STACK_FRAME(stackFrame);
return JSValue::encode(jsBoolean(result));
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_number)
{
STUB_INIT_STACK_FRAME(stackFrame);
EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
-EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION) WTF_INTERNAL;
-EncodedJSValue JIT_STUB cti_op_post_inc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
-EncodedJSValue JIT_STUB cti_op_pre_dec(STUB_ARGS_DECLARATION) WTF_INTERNAL;
-EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_dec(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_inc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_resolve_base_strict_put(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_sub(STUB_ARGS_DECLARATION) WTF_INTERNAL;
-EncodedJSValue JIT_STUB cti_op_to_jsnumber(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_to_number(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION) WTF_INTERNAL;
EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION) WTF_INTERNAL;
LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
}
-LLINT_SLOW_PATH_DECL(slow_path_post_inc)
-{
- LLINT_BEGIN();
- double result = LLINT_OP(2).jsValue().toNumber(exec);
- LLINT_OP(2) = jsNumber(result + 1);
- LLINT_RETURN(jsNumber(result));
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_post_dec)
-{
- LLINT_BEGIN();
- double result = LLINT_OP(2).jsValue().toNumber(exec);
- LLINT_OP(2) = jsNumber(result - 1);
- LLINT_RETURN(jsNumber(result));
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_to_jsnumber)
+LLINT_SLOW_PATH_DECL(slow_path_to_number)
{
LLINT_BEGIN();
LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_greatereq);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pre_inc);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pre_dec);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_post_inc);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_post_dec);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_jsnumber);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_number);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_negate);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_add);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_mul);
strictEq(macro (left, right, result) cineq left, right, result end, _llint_slow_path_nstricteq)
-_llint_op_pre_inc:
+_llint_op_inc:
traceExecution()
loadi 4[PC], t0
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreIncSlow
+ bineq TagOffset[cfr, t0, 8], Int32Tag, .opIncSlow
loadi PayloadOffset[cfr, t0, 8], t1
- baddio 1, t1, .opPreIncSlow
+ baddio 1, t1, .opIncSlow
storei t1, PayloadOffset[cfr, t0, 8]
dispatch(2)
-.opPreIncSlow:
+.opIncSlow:
callSlowPath(_llint_slow_path_pre_inc)
dispatch(2)
-_llint_op_pre_dec:
+_llint_op_dec:
traceExecution()
loadi 4[PC], t0
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreDecSlow
+ bineq TagOffset[cfr, t0, 8], Int32Tag, .opDecSlow
loadi PayloadOffset[cfr, t0, 8], t1
- bsubio 1, t1, .opPreDecSlow
+ bsubio 1, t1, .opDecSlow
storei t1, PayloadOffset[cfr, t0, 8]
dispatch(2)
-.opPreDecSlow:
+.opDecSlow:
callSlowPath(_llint_slow_path_pre_dec)
dispatch(2)
-_llint_op_post_inc:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t1
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostIncSlow
- bieq t0, t1, .opPostIncDone
- loadi PayloadOffset[cfr, t0, 8], t2
- move t2, t3
- baddio 1, t3, .opPostIncSlow
- storei Int32Tag, TagOffset[cfr, t1, 8]
- storei t2, PayloadOffset[cfr, t1, 8]
- storei t3, PayloadOffset[cfr, t0, 8]
-.opPostIncDone:
- dispatch(3)
-
-.opPostIncSlow:
- callSlowPath(_llint_slow_path_post_inc)
- dispatch(3)
-
-
-_llint_op_post_dec:
- traceExecution()
- loadi 8[PC], t0
- loadi 4[PC], t1
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPostDecSlow
- bieq t0, t1, .opPostDecDone
- loadi PayloadOffset[cfr, t0, 8], t2
- move t2, t3
- bsubio 1, t3, .opPostDecSlow
- storei Int32Tag, TagOffset[cfr, t1, 8]
- storei t2, PayloadOffset[cfr, t1, 8]
- storei t3, PayloadOffset[cfr, t0, 8]
-.opPostDecDone:
- dispatch(3)
-
-.opPostDecSlow:
- callSlowPath(_llint_slow_path_post_dec)
- dispatch(3)
-
-
-_llint_op_to_jsnumber:
+_llint_op_to_number:
traceExecution()
loadi 8[PC], t0
loadi 4[PC], t1
loadConstantOrVariable(t0, t2, t3)
- bieq t2, Int32Tag, .opToJsnumberIsInt
- biaeq t2, EmptyValueTag, .opToJsnumberSlow
-.opToJsnumberIsInt:
+ bieq t2, Int32Tag, .opToNumberIsInt
+ biaeq t2, LowestTag, .opToNumberSlow
+.opToNumberIsInt:
storei t2, TagOffset[cfr, t1, 8]
storei t3, PayloadOffset[cfr, t1, 8]
dispatch(3)
-.opToJsnumberSlow:
- callSlowPath(_llint_slow_path_to_jsnumber)
+.opToNumberSlow:
+ callSlowPath(_llint_slow_path_to_number)
dispatch(3)
dispatch(2)
end
-_llint_op_pre_inc:
+_llint_op_inc:
preOp(
macro (value, slow) baddio 1, value, slow end,
_llint_slow_path_pre_inc)
-_llint_op_pre_dec:
+_llint_op_dec:
preOp(
macro (value, slow) bsubio 1, value, slow end,
_llint_slow_path_pre_dec)
-macro postOp(arithmeticOperation, slowPath)
- traceExecution()
- loadisFromInstruction(2, t0)
- loadisFromInstruction(1, t1)
- loadq [cfr, t0, 8], t2
- bieq t0, t1, .done
- bqb t2, tagTypeNumber, .slow
- move t2, t3
- arithmeticOperation(t3, .slow)
- orq tagTypeNumber, t3
- storeq t2, [cfr, t1, 8]
- storeq t3, [cfr, t0, 8]
-.done:
- dispatch(3)
-
-.slow:
- callSlowPath(slowPath)
- dispatch(3)
-end
-
-_llint_op_post_inc:
- postOp(
- macro (value, slow) baddio 1, value, slow end,
- _llint_slow_path_post_inc)
-
-
-_llint_op_post_dec:
- postOp(
- macro (value, slow) bsubio 1, value, slow end,
- _llint_slow_path_post_dec)
-
-
-_llint_op_to_jsnumber:
+_llint_op_to_number:
traceExecution()
loadisFromInstruction(2, t0)
loadisFromInstruction(1, t1)
loadConstantOrVariable(t0, t2)
- bqaeq t2, tagTypeNumber, .opToJsnumberIsImmediate
- btqz t2, tagTypeNumber, .opToJsnumberSlow
-.opToJsnumberIsImmediate:
+ bqaeq t2, tagTypeNumber, .opToNumberIsImmediate
+ btqz t2, tagTypeNumber, .opToNumberSlow
+.opToNumberIsImmediate:
storeq t2, [cfr, t1, 8]
dispatch(3)
-.opToJsnumberSlow:
- callSlowPath(_llint_slow_path_to_jsnumber)
+.opToNumberSlow:
+ callSlowPath(_llint_slow_path_to_number)
dispatch(3)
}
inline UnaryPlusNode::UnaryPlusNode(const JSTokenLocation& location, ExpressionNode* expr)
- : UnaryOpNode(location, ResultType::numberType(), expr, op_to_jsnumber)
+ : UnaryOpNode(location, ResultType::numberType(), expr, op_to_number)
{
}
return v.isNull();
JSType type = v.asCell()->structure()->typeInfo().type();
- if (type == NumberType || type == StringType)
+ if (type == StringType)
return false;
if (type >= ObjectType) {
if (asObject(v)->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))