Fix the 'in' operator so it works correctly for negative indices.
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@117 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
472ae34f9d
commit
d295ddd922
@ -285,6 +285,7 @@ class ArmCodeGenerator: public CodeGenerator {
|
|||||||
virtual void GenerateSquashFrame(ZoneList<Expression*>* args);
|
virtual void GenerateSquashFrame(ZoneList<Expression*>* args);
|
||||||
virtual void GenerateExpandFrame(ZoneList<Expression*>* args);
|
virtual void GenerateExpandFrame(ZoneList<Expression*>* args);
|
||||||
virtual void GenerateIsSmi(ZoneList<Expression*>* args);
|
virtual void GenerateIsSmi(ZoneList<Expression*>* args);
|
||||||
|
virtual void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
|
||||||
virtual void GenerateIsArray(ZoneList<Expression*>* args);
|
virtual void GenerateIsArray(ZoneList<Expression*>* args);
|
||||||
|
|
||||||
virtual void GenerateArgumentsLength(ZoneList<Expression*>* args);
|
virtual void GenerateArgumentsLength(ZoneList<Expression*>* args);
|
||||||
@ -3938,6 +3939,16 @@ void ArmCodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ArmCodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
|
||||||
|
ASSERT(args->length() == 1);
|
||||||
|
Load(args->at(0));
|
||||||
|
__ pop(r0);
|
||||||
|
__ tst(r0, Operand(kSmiTagMask | 0x80000000));
|
||||||
|
cc_reg_ = eq;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This should generate code that performs a charCodeAt() call or returns
|
// This should generate code that performs a charCodeAt() call or returns
|
||||||
// undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
|
// undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
|
||||||
// It is not yet implemented on ARM, so it always goes to the slow case.
|
// It is not yet implemented on ARM, so it always goes to the slow case.
|
||||||
|
@ -304,6 +304,7 @@ class Ia32CodeGenerator: public CodeGenerator {
|
|||||||
virtual void GenerateSquashFrame(ZoneList<Expression*>* args);
|
virtual void GenerateSquashFrame(ZoneList<Expression*>* args);
|
||||||
virtual void GenerateExpandFrame(ZoneList<Expression*>* args);
|
virtual void GenerateExpandFrame(ZoneList<Expression*>* args);
|
||||||
virtual void GenerateIsSmi(ZoneList<Expression*>* args);
|
virtual void GenerateIsSmi(ZoneList<Expression*>* args);
|
||||||
|
virtual void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
|
||||||
virtual void GenerateIsArray(ZoneList<Expression*>* args);
|
virtual void GenerateIsArray(ZoneList<Expression*>* args);
|
||||||
|
|
||||||
virtual void GenerateArgumentsLength(ZoneList<Expression*>* args);
|
virtual void GenerateArgumentsLength(ZoneList<Expression*>* args);
|
||||||
@ -4022,6 +4023,15 @@ void Ia32CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ia32CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
|
||||||
|
ASSERT(args->length() == 1);
|
||||||
|
Load(args->at(0));
|
||||||
|
__ pop(eax);
|
||||||
|
__ test(eax, Immediate(kSmiTagMask | 0x80000000));
|
||||||
|
cc_reg_ = zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This generates code that performs a charCodeAt() call or returns
|
// This generates code that performs a charCodeAt() call or returns
|
||||||
// undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
|
// undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
|
||||||
// It can handle flat and sliced strings, 8 and 16 bit characters and
|
// It can handle flat and sliced strings, 8 and 16 bit characters and
|
||||||
|
@ -243,6 +243,8 @@ bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) {
|
|||||||
"_ExpandFrame"},
|
"_ExpandFrame"},
|
||||||
{&v8::internal::CodeGenerator::GenerateIsSmi,
|
{&v8::internal::CodeGenerator::GenerateIsSmi,
|
||||||
"_IsSmi"},
|
"_IsSmi"},
|
||||||
|
{&v8::internal::CodeGenerator::GenerateIsNonNegativeSmi,
|
||||||
|
"_IsNonNegativeSmi"},
|
||||||
{&v8::internal::CodeGenerator::GenerateIsArray,
|
{&v8::internal::CodeGenerator::GenerateIsArray,
|
||||||
"_IsArray"},
|
"_IsArray"},
|
||||||
{&v8::internal::CodeGenerator::GenerateArgumentsLength,
|
{&v8::internal::CodeGenerator::GenerateArgumentsLength,
|
||||||
|
@ -159,6 +159,7 @@ class CodeGenerator: public Visitor {
|
|||||||
virtual void GenerateSquashFrame(ZoneList<Expression*>* args) = 0;
|
virtual void GenerateSquashFrame(ZoneList<Expression*>* args) = 0;
|
||||||
virtual void GenerateExpandFrame(ZoneList<Expression*>* args) = 0;
|
virtual void GenerateExpandFrame(ZoneList<Expression*>* args) = 0;
|
||||||
virtual void GenerateIsSmi(ZoneList<Expression*>* args) = 0;
|
virtual void GenerateIsSmi(ZoneList<Expression*>* args) = 0;
|
||||||
|
virtual void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) = 0;
|
||||||
virtual void GenerateIsArray(ZoneList<Expression*>* args) = 0;
|
virtual void GenerateIsArray(ZoneList<Expression*>* args) = 0;
|
||||||
|
|
||||||
// Support for arguments.length and arguments[?].
|
// Support for arguments.length and arguments[?].
|
||||||
|
@ -267,7 +267,7 @@ function IN(x) {
|
|||||||
if (x == null || (!IS_OBJECT(x) && !IS_FUNCTION(x))) {
|
if (x == null || (!IS_OBJECT(x) && !IS_FUNCTION(x))) {
|
||||||
throw %MakeTypeError('invalid_in_operator_use', [this, x]);
|
throw %MakeTypeError('invalid_in_operator_use', [this, x]);
|
||||||
}
|
}
|
||||||
return %_IsSmi(this) ? %HasElement(x, this) : %HasProperty(x, %ToString(this));
|
return %_IsNonNegativeSmi(this) ? %HasElement(x, this) : %HasProperty(x, %ToString(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,3 +156,10 @@ assertFalse(-Infinity in a,"-Infinity in a");
|
|||||||
assertFalse(-0 in a,"-0 in a");
|
assertFalse(-0 in a,"-0 in a");
|
||||||
assertFalse(+0 in a,"+0 in a");
|
assertFalse(+0 in a,"+0 in a");
|
||||||
assertTrue('toString' in a, "toString");
|
assertTrue('toString' in a, "toString");
|
||||||
|
|
||||||
|
// -------------
|
||||||
|
// Check negative indices in arrays.
|
||||||
|
var a = [];
|
||||||
|
assertFalse(-1 in a);
|
||||||
|
a[-1] = 43;
|
||||||
|
assertTrue(-1 in a);
|
||||||
|
Loading…
Reference in New Issue
Block a user