From d295ddd92292a16ef44262e31d3b4f60dc1da09e Mon Sep 17 00:00:00 2001 From: "ager@chromium.org" Date: Wed, 3 Sep 2008 07:34:21 +0000 Subject: [PATCH] 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 --- src/codegen-arm.cc | 11 +++++++++++ src/codegen-ia32.cc | 10 ++++++++++ src/codegen.cc | 2 ++ src/codegen.h | 1 + src/runtime.js | 2 +- test/mjsunit/in.js | 7 +++++++ 6 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc index 19dc9a8..c4d3f38 100644 --- a/src/codegen-arm.cc +++ b/src/codegen-arm.cc @@ -285,6 +285,7 @@ class ArmCodeGenerator: public CodeGenerator { virtual void GenerateSquashFrame(ZoneList* args); virtual void GenerateExpandFrame(ZoneList* args); virtual void GenerateIsSmi(ZoneList* args); + virtual void GenerateIsNonNegativeSmi(ZoneList* args); virtual void GenerateIsArray(ZoneList* args); virtual void GenerateArgumentsLength(ZoneList* args); @@ -3938,6 +3939,16 @@ void ArmCodeGenerator::GenerateIsSmi(ZoneList* args) { } +void ArmCodeGenerator::GenerateIsNonNegativeSmi(ZoneList* 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 // 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. diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc index e60ba39..6d38136 100644 --- a/src/codegen-ia32.cc +++ b/src/codegen-ia32.cc @@ -304,6 +304,7 @@ class Ia32CodeGenerator: public CodeGenerator { virtual void GenerateSquashFrame(ZoneList* args); virtual void GenerateExpandFrame(ZoneList* args); virtual void GenerateIsSmi(ZoneList* args); + virtual void GenerateIsNonNegativeSmi(ZoneList* args); virtual void GenerateIsArray(ZoneList* args); virtual void GenerateArgumentsLength(ZoneList* args); @@ -4022,6 +4023,15 @@ void Ia32CodeGenerator::GenerateIsSmi(ZoneList* args) { } +void Ia32CodeGenerator::GenerateIsNonNegativeSmi(ZoneList* 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 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt. // It can handle flat and sliced strings, 8 and 16 bit characters and diff --git a/src/codegen.cc b/src/codegen.cc index d450595..14ab511 100644 --- a/src/codegen.cc +++ b/src/codegen.cc @@ -243,6 +243,8 @@ bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) { "_ExpandFrame"}, {&v8::internal::CodeGenerator::GenerateIsSmi, "_IsSmi"}, + {&v8::internal::CodeGenerator::GenerateIsNonNegativeSmi, + "_IsNonNegativeSmi"}, {&v8::internal::CodeGenerator::GenerateIsArray, "_IsArray"}, {&v8::internal::CodeGenerator::GenerateArgumentsLength, diff --git a/src/codegen.h b/src/codegen.h index ed03dd2..9833445 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -159,6 +159,7 @@ class CodeGenerator: public Visitor { virtual void GenerateSquashFrame(ZoneList* args) = 0; virtual void GenerateExpandFrame(ZoneList* args) = 0; virtual void GenerateIsSmi(ZoneList* args) = 0; + virtual void GenerateIsNonNegativeSmi(ZoneList* args) = 0; virtual void GenerateIsArray(ZoneList* args) = 0; // Support for arguments.length and arguments[?]. diff --git a/src/runtime.js b/src/runtime.js index aa624a7..78c20c1 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -267,7 +267,7 @@ function IN(x) { if (x == null || (!IS_OBJECT(x) && !IS_FUNCTION(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)); }; diff --git a/test/mjsunit/in.js b/test/mjsunit/in.js index b2b6cd5..06adb71 100644 --- a/test/mjsunit/in.js +++ b/test/mjsunit/in.js @@ -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"); assertTrue('toString' in a, "toString"); + +// ------------- +// Check negative indices in arrays. +var a = []; +assertFalse(-1 in a); +a[-1] = 43; +assertTrue(-1 in a); -- 2.7.4