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:
ager@chromium.org 2008-09-03 07:34:21 +00:00
parent 472ae34f9d
commit d295ddd922
6 changed files with 32 additions and 1 deletions

View File

@ -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.

View File

@ -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

View File

@ -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,

View File

@ -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[?].

View File

@ -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));
}; };

View File

@ -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);