[es6] When comparing two symbols we may need to throw a TypeError

When comparing a symbol to istself using <, <=, > or >= we need to
throw a TypeError. This is correctly handled in the runtime function
so if we are comparing a symbol fall back to use the runtime.

BUG=v8:4073
LOG=Y
R=rossberg@chromium.org

Review URL: https://codereview.chromium.org/1125783002

Cr-Commit-Position: refs/heads/master@{#28226}
This commit is contained in:
arv 2015-05-05 07:11:49 -07:00 committed by Commit bot
parent f6d632bd4d
commit d26f5d3923
9 changed files with 48 additions and 0 deletions

View File

@ -253,6 +253,8 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm,
if (cond == lt || cond == gt) {
__ CompareObjectType(r0, r4, r4, FIRST_SPEC_OBJECT_TYPE);
__ b(ge, slow);
__ CompareObjectType(r0, r4, r4, SYMBOL_TYPE);
__ b(eq, slow);
} else {
__ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
__ b(eq, &heap_number);

View File

@ -224,6 +224,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm,
if ((cond == lt) || (cond == gt)) {
__ JumpIfObjectType(right, scratch, scratch, FIRST_SPEC_OBJECT_TYPE, slow,
ge);
__ JumpIfObjectType(right, scratch, scratch, SYMBOL_TYPE, slow, eq);
} else if (cond == eq) {
__ JumpIfHeapNumber(right, &heap_number);
} else {

View File

@ -1710,6 +1710,9 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
// Call runtime on identical JSObjects. Otherwise return equal.
__ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(above_equal, &not_identical);
// Call runtime on identical symbols since we need to throw a TypeError.
__ CmpObjectType(eax, SYMBOL_TYPE, ecx);
__ j(equal, &not_identical);
}
__ Move(eax, Immediate(Smi::FromInt(EQUAL)));
__ ret(0);

View File

@ -294,6 +294,8 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm,
if (cc == less || cc == greater) {
__ GetObjectType(a0, t4, t4);
__ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
__ GetObjectType(a0, t4, t4);
__ Branch(slow, eq, t4, Operand(SYMBOL_TYPE));
} else {
__ GetObjectType(a0, t4, t4);
__ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE));

View File

@ -290,6 +290,8 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm,
if (cc == less || cc == greater) {
__ GetObjectType(a0, t0, t0);
__ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
__ GetObjectType(a0, t0, t0);
__ Branch(slow, eq, t0, Operand(SYMBOL_TYPE));
} else {
__ GetObjectType(a0, t0, t0);
__ Branch(&heap_number, eq, t0, Operand(HEAP_NUMBER_TYPE));

View File

@ -262,6 +262,8 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
if (cond == lt || cond == gt) {
__ CompareObjectType(r3, r7, r7, FIRST_SPEC_OBJECT_TYPE);
__ bge(slow);
__ CompareObjectType(r3, r7, r7, SYMBOL_TYPE);
__ beq(slow);
} else {
__ CompareObjectType(r3, r7, r7, HEAP_NUMBER_TYPE);
__ beq(&heap_number);

View File

@ -1578,6 +1578,9 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
// Call runtime on identical objects. Otherwise return equal.
__ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(above_equal, &not_identical, Label::kNear);
// Call runtime on identical symbols since we need to throw a TypeError.
__ CmpObjectType(rax, SYMBOL_TYPE, rcx);
__ j(equal, &not_identical, Label::kNear);
}
__ Set(rax, EQUAL);
__ ret(0);

View File

@ -1385,6 +1385,9 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
// Call runtime on identical JSObjects. Otherwise return equal.
__ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(above_equal, &not_identical);
// Call runtime on identical symbols since we need to throw a TypeError.
__ CmpObjectType(eax, SYMBOL_TYPE, ecx);
__ j(equal, &not_identical);
}
__ Move(eax, Immediate(Smi::FromInt(EQUAL)));
__ ret(0);

View File

@ -504,3 +504,33 @@ function TestGetOwnPropertySymbolsOnPrimitives() {
assertEquals(Object.getOwnPropertySymbols("OK"), []);
}
TestGetOwnPropertySymbolsOnPrimitives();
function TestComparison() {
function f() {
var a = Symbol();
a < a;
a > a;
a <= a;
a >= a;
}
assertThrows(f, TypeError);
%OptimizeFunctionOnNextCall(f);
assertThrows(f, TypeError);
assertThrows(f, TypeError);
function g() {
var a = Symbol();
var b = Symbol();
a < b;
a > b;
a <= b;
a >= b;
}
assertThrows(g, TypeError);
%OptimizeFunctionOnNextCall(g);
assertThrows(g, TypeError);
assertThrows(g, TypeError);
}
TestComparison();