Implement for..in for FastDoubleArrays
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 20 Jul 2011 10:54:58 +0000 (10:54 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 20 Jul 2011 10:54:58 +0000 (10:54 +0000)
Also add tests for apply on FastDoubleArrays.

R=ager@chromium.org
BUG=none
TEST=unboxed-double-array.js

Review URL: http://codereview.chromium.org/7461018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8693 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects.cc
test/mjsunit/unbox-double-arrays.js

index f25078b..341f929 100644 (file)
@@ -8142,6 +8142,15 @@ bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
           !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
       break;
     }
+    case FAST_DOUBLE_ELEMENTS: {
+      uint32_t length = IsJSArray() ?
+          static_cast<uint32_t>
+              (Smi::cast(JSArray::cast(this)->length())->value()) :
+          static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
+      if ((index < length) &&
+          !FixedDoubleArray::cast(elements())->is_the_hole(index)) return true;
+      break;
+    }
     case EXTERNAL_PIXEL_ELEMENTS: {
       ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
       if (index < static_cast<uint32_t>(pixels->length())) {
@@ -8163,9 +8172,6 @@ bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
       }
       break;
     }
-    case FAST_DOUBLE_ELEMENTS:
-      UNREACHABLE();
-      break;
     case DICTIONARY_ELEMENTS: {
       if (element_dictionary()->FindEntry(index)
           != NumberDictionary::kNotFound) {
@@ -9603,6 +9609,21 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
       ASSERT(!storage || storage->length() >= counter);
       break;
     }
+    case FAST_DOUBLE_ELEMENTS: {
+      int length = IsJSArray() ?
+          Smi::cast(JSArray::cast(this)->length())->value() :
+          FixedDoubleArray::cast(elements())->length();
+      for (int i = 0; i < length; i++) {
+        if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) {
+          if (storage != NULL) {
+            storage->set(counter, Smi::FromInt(i));
+          }
+          counter++;
+        }
+      }
+      ASSERT(!storage || storage->length() >= counter);
+      break;
+    }
     case EXTERNAL_PIXEL_ELEMENTS: {
       int length = ExternalPixelArray::cast(elements())->length();
       while (counter < length) {
@@ -9632,9 +9653,6 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
       ASSERT(!storage || storage->length() >= counter);
       break;
     }
-    case FAST_DOUBLE_ELEMENTS:
-      UNREACHABLE();
-      break;
     case DICTIONARY_ELEMENTS: {
       if (storage != NULL) {
         element_dictionary()->CopyKeysTo(storage,
index 1149838..351765e 100644 (file)
@@ -417,3 +417,52 @@ assertEquals(undefined, large_array3[large_array3.length-1]);
 assertEquals(undefined, large_array3[large_array_size-1]);
 assertEquals(undefined, large_array3[-1]);
 gc();
+
+// Test apply on arrays backed by double elements.
+function called_by_apply(arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
+  assertEquals(expected_array_value(0), arg0);
+  assertEquals(NaN, arg1);
+  assertEquals(-NaN, arg2);
+  assertEquals(Infinity, arg3);
+  assertEquals(-Infinity, arg4);
+  assertEquals(expected_array_value(5), arg5);
+}
+
+large_array3[1] = NaN;
+large_array3[2] = -NaN;
+large_array3[3] = Infinity;
+large_array3[4] = -Infinity;
+
+function call_apply() {
+  assertTrue(%HasFastDoubleElements(large_array3));
+  called_by_apply.apply({}, large_array3);
+}
+
+call_apply();
+call_apply();
+call_apply();
+%OptimizeFunctionOnNextCall(call_apply);
+call_apply();
+call_apply();
+call_apply();
+
+function test_for_in() {
+  // Due to previous tests, keys 0..25 and 95 should be present.
+  next_expected = 0;
+  assertTrue(%HasFastDoubleElements(large_array3));
+  for (x in large_array3) {
+    assertTrue(next_expected++ == x);
+    if (next_expected == 25) {
+      next_expected = 95;
+    }
+  }
+  assertTrue(next_expected == 96);
+}
+
+test_for_in();
+test_for_in();
+test_for_in();
+%OptimizeFunctionOnNextCall(test_for_in);
+test_for_in();
+test_for_in();
+test_for_in();