https://bugs.webkit.org/show_bug.cgi?id=63881
Need separate bytecodes for handling >, >= comparisons.
Reviewed by Oliver Hunt.
This clears the way to fix Bug#63880. We currently handle greater-than comparisons
as being using the corresponding op_less, etc opcodes. This is incorrect with
respect to evaluation ordering of the implicit conversions performed on operands -
we should be calling ToPrimitive on the LHS and RHS operands to the greater than,
but instead convert RHS then LHS.
This patch adds opcodes for greater-than comparisons mirroring existing ones used
for less-than.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dump):
* bytecode/Opcode.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitJumpIfTrue):
(JSC::BytecodeGenerator::emitJumpIfFalse):
* bytecompiler/NodesCodegen.cpp:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGNode.h:
* dfg/DFGNonSpeculativeJIT.cpp:
(JSC::DFG::NonSpeculativeJIT::compare):
(JSC::DFG::NonSpeculativeJIT::compile):
* dfg/DFGNonSpeculativeJIT.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT.h:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
(JSC::JIT::emit_op_loop_if_greater):
(JSC::JIT::emitSlow_op_loop_if_greater):
(JSC::JIT::emit_op_loop_if_greatereq):
(JSC::JIT::emitSlow_op_loop_if_greatereq):
* jit/JITArithmetic.cpp:
(JSC::JIT::emit_op_jgreater):
(JSC::JIT::emit_op_jgreatereq):
(JSC::JIT::emit_op_jngreater):
(JSC::JIT::emit_op_jngreatereq):
(JSC::JIT::emitSlow_op_jgreater):
(JSC::JIT::emitSlow_op_jgreatereq):
(JSC::JIT::emitSlow_op_jngreater):
(JSC::JIT::emitSlow_op_jngreatereq):
(JSC::JIT::emit_compareAndJumpSlow):
* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emitBinaryDoubleOp):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* jit/JITStubs.h:
* parser/NodeConstructors.h:
(JSC::GreaterNode::GreaterNode):
(JSC::GreaterEqNode::GreaterEqNode):
* parser/Nodes.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@90371 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 96de4f8..e8441e5 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -586,6 +586,14 @@
printBinaryOp(exec, location, it, "lesseq");
break;
}
+ case op_greater: {
+ printBinaryOp(exec, location, it, "greater");
+ break;
+ }
+ case op_greatereq: {
+ printBinaryOp(exec, location, it, "greatereq");
+ break;
+ }
case op_pre_inc: {
int r0 = (++it)->u.operand;
printf("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).data());
@@ -995,27 +1003,6 @@
printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
- case op_jnless: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- break;
- }
- case op_jnlesseq: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- break;
- }
- case op_loop_if_less: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- break;
- }
case op_jless: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
@@ -1030,6 +1017,55 @@
printf("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
+ case op_jgreater: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] jgreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
+ case op_jgreatereq: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] jgreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
+ case op_jnless: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
+ case op_jnlesseq: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
+ case op_jngreater: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] jngreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
+ case op_jngreatereq: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] jngreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
+ case op_loop_if_less: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
case op_loop_if_lesseq: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
@@ -1037,6 +1073,20 @@
printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
+ case op_loop_if_greater: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] loop_if_greater\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
+ case op_loop_if_greatereq: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+ break;
+ }
case op_switch_imm: {
int tableIndex = (++it)->u.operand;
int defaultTarget = (++it)->u.operand;