Closed
Bug 640052
Opened 14 years ago
Closed 6 years ago
Relational operators > and >= incorrectly use AvmCore::compare()
Categories
(Tamarin Graveyard :: Virtual Machine, defect, P3)
Tamarin Graveyard
Virtual Machine
Tracking
(Not tracked)
RESOLVED
WONTFIX
Q2 12 - Cyril
People
(Reporter: edwsmith, Unassigned)
References
Details
ECMAScript requires left-to-right evaluation. Side effects from calling ToPrimitive on the left and right arguments must be observed in order.
Both the Interpreter and CodegenLIR implement the symmetric relational operators by swapping arguments, then calling a helper. Eventually, the call to AvmCore::compare() occurs, which always calls ToPrimitive in the same order.
Interpreter only ever calls AvmCore::compare(), either with the arguments in the correct order, or swapped. These opcodes have them swapped:
lessequals, greaterthan, ifle, ifnle, ifgt, ifngt
CodegenLIR uses two helpers:
cmpLt(a,b) calls compare(a,b)
cmpLt(b,a) calls compare(b,a) <-- swapped
cmpLe(a,b) calls compare(b,a) <-- swapped
cmpLe(b,a) calls compare(a,b)
So, the broken opcodes are the ones that call cmpLt(b,a) or cmpLe(a,b):
greaterthan, ifgt, ifngt call cmpLt(b,a)
lessequals, ifle, ifnle call cmpLe(a,b)
So, while wrong, it seems the interpreter and jit agree.
Reporter | ||
Comment 1•14 years ago
|
||
We need to make sure we have good coverage of these paths, to make sure ongoing jit/interpreter work don't accedentially break when side effects are visible. (marking in-testsuite).
Blocks: ecma-incompatibility
Flags: in-testsuite?
Reporter | ||
Comment 2•14 years ago
|
||
No matter what, this bug should stay open until the bytecode docs are clarified.
Testing/doc should be required prior to Halfmoon. Targeting to Cyril.
Assignee: nobody → edwsmith
Flags: flashplayer-qrb+
Flags: flashplayer-needsversioning+
Priority: -- → P3
Target Milestone: --- → Q2 12 - Cyril
Comment 5•13 years ago
|
||
What am I currently missing here, my understanding of the spec seems to agree with how the following code runs.
function MyObject(value)
{
this.value = value;
this.valueOf = function(){var v = ++this.value; return v};
}
var foo = new MyObject(0); // increments value every time valueOf is called
print(foo<foo); // (1<2), LeftFirst true (expressions 8.4.1.2)
print(foo>foo); // (4>3), LeftFirst false (expressions 8.4.2.2)
print(foo<=foo); // (6<=5), LeftFirst false (expressions 8.4.3.2)
print(foo>=foo); // (7>=8), LeftFirst true (expressions 8.4.4.2)
This code produces results that iI would expect (true, true, false, false). This is with both -Dinterp and -Ojit
Comment 6•13 years ago
|
||
I believe the spec is "wrong" because it reflects the reality of this bug, see the comment to that effect following the definition of the relational comparison algorithm (Defn 8.4) about how leftFirst is ignored. The "right" spec is Ecma-262.
Comment 7•13 years ago
|
||
(In reply to Lars T Hansen from comment #6)
> I believe the spec is "wrong" because it reflects the reality of this bug,
> see the comment to that effect following the definition of the relational
> comparison algorithm (Defn 8.4) about how leftFirst is ignored. The "right"
> spec is Ecma-262.
But ecma 262 changes the LeftFirst value depending on the operator as well (11.8.2 and 11.8.3 set the LeftFirst to false)
***Ah, but this is the big difference between the AS Expressions spec and the ECMA spec:
11.8.2: Greater-than (>)
11.8.2.5: Let r be the result of performing abstract relational comparison rval < lval with LeftFirst equal to false. (see 11.8.5).
So this is how it should behave:
print(foo>foo);
--> foo_left > foo_right
--> foo_right < foo_left with LeftFirst false
--> 2 < 1
-> false
Reporter | ||
Updated•13 years ago
|
Assignee: edwsmith → nobody
Updated•6 years ago
|
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → WONTFIX
You need to log in
before you can comment on or make changes to this bug.
Description
•