ElementsAccessor::SetLength() handlified.
authorishell@chromium.org <ishell@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 19 Mar 2014 16:29:19 +0000 (16:29 +0000)
committerishell@chromium.org <ishell@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 19 Mar 2014 16:29:19 +0000 (16:29 +0000)
R=yangguo@chromium.org

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

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

src/builtins.cc
src/elements.cc
src/elements.h
src/objects-inl.h
src/objects.h

index a79df97..b48de7f 100644 (file)
@@ -548,18 +548,6 @@ static Handle<Object> ElementsAccessorGetWrapper(
 }
 
 
-// TODO(ishell): Temporary wrapper until handlified.
-static Handle<Object> ElementsAccessorSetLengthWrapper(
-    Isolate* isolate,
-    ElementsAccessor* accessor,
-    Handle<JSArray> array,
-    int new_length) {
-  CALL_HEAP_FUNCTION(isolate,
-                     accessor->SetLength(*array, Smi::FromInt(new_length)),
-                     Object);
-}
-
-
 BUILTIN(ArrayPop) {
   HandleScope scope(isolate);
   Handle<Object> receiver = args.receiver();
@@ -588,8 +576,8 @@ BUILTIN(ArrayPop) {
   }
   RETURN_IF_EMPTY_HANDLE(isolate, element);
   RETURN_IF_EMPTY_HANDLE(isolate,
-                         ElementsAccessorSetLengthWrapper(
-                             isolate, accessor, array, new_length));
+                         accessor->SetLength(
+                             array, handle(Smi::FromInt(new_length), isolate)));
   return *element;
 }
 
index 2e9bc32..d935fb1 100644 (file)
@@ -160,11 +160,11 @@ static bool HasKey(FixedArray* array, Object* key) {
 }
 
 
-static Failure* ThrowArrayLengthRangeError(Heap* heap) {
-  HandleScope scope(heap->isolate());
-  return heap->isolate()->Throw(
-      *heap->isolate()->factory()->NewRangeError("invalid_array_length",
-          HandleVector<Object>(NULL, 0)));
+static Handle<Object> ThrowArrayLengthRangeError(Isolate* isolate) {
+  isolate->Throw(
+      *isolate->factory()->NewRangeError("invalid_array_length",
+                                         HandleVector<Object>(NULL, 0)));
+  return Handle<Object>();
 }
 
 
@@ -737,25 +737,18 @@ class ElementsAccessorBase : public ElementsAccessor {
     return NULL;
   }
 
-  // TODO(ishell): Temporary wrapper until handlified.
   MUST_USE_RESULT virtual Handle<Object> SetLength(
       Handle<JSArray> array,
       Handle<Object> length) {
-    CALL_HEAP_FUNCTION(array->GetIsolate(),
-                       SetLength(*array, *length),
-                       Object);
-  }
-
-  MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* array,
-                                                 Object* length) {
+    Isolate* isolate = array->GetIsolate();
     return ElementsAccessorSubclass::SetLengthImpl(
-        array, length, array->elements());
+        array, length, handle(array->elements(), isolate));
   }
 
-  MUST_USE_RESULT static MaybeObject* SetLengthImpl(
-      JSObject* obj,
-      Object* length,
-      FixedArrayBase* backing_store);
+  MUST_USE_RESULT static Handle<Object> SetLengthImpl(
+      Handle<JSObject> obj,
+      Handle<Object> length,
+      Handle<FixedArrayBase> backing_store);
 
   MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength(
       JSArray* array,
@@ -994,6 +987,18 @@ class FastElementsAccessor
     return array->GetHeap()->undefined_value();
   }
 
+  // TODO(ishell): Temporary wrapper until handlified.
+  static Handle<Object> SetLengthWithoutNormalize(
+      Handle<FixedArrayBase> backing_store,
+      Handle<JSArray> array,
+      Handle<Object> length_object,
+      uint32_t length) {
+    CALL_HEAP_FUNCTION(array->GetIsolate(),
+                       SetLengthWithoutNormalize(
+                           *backing_store, *array, *length_object, length),
+                       Object);
+  }
+
   static MaybeObject* DeleteCommon(JSObject* obj,
                                    uint32_t key,
                                    JSReceiver::DeleteMode mode) {
@@ -1382,10 +1387,10 @@ class TypedElementsAccessor
           ? FIELD : NONEXISTENT;
   }
 
-  MUST_USE_RESULT static MaybeObject* SetLengthImpl(
-      JSObject* obj,
-      Object* length,
-      FixedArrayBase* backing_store) {
+  MUST_USE_RESULT static Handle<Object> SetLengthImpl(
+      Handle<JSObject> obj,
+      Handle<Object> length,
+      Handle<FixedArrayBase> backing_store) {
     // External arrays do not support changing their length.
     UNREACHABLE();
     return obj;
@@ -1493,6 +1498,18 @@ class DictionaryElementsAccessor
     return length_object;
   }
 
+  // TODO(ishell): Temporary wrapper until handlified.
+  MUST_USE_RESULT static Handle<Object> SetLengthWithoutNormalize(
+      Handle<FixedArrayBase> store,
+      Handle<JSArray> array,
+      Handle<Object> length_object,
+      uint32_t length) {
+    CALL_HEAP_FUNCTION(array->GetIsolate(),
+                       SetLengthWithoutNormalize(
+                             *store, *array, *length_object, length),
+                       Object);
+  }
+
   MUST_USE_RESULT static MaybeObject* DeleteCommon(
       JSObject* obj,
       uint32_t key,
@@ -1736,10 +1753,10 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
     }
   }
 
-  MUST_USE_RESULT static MaybeObject* SetLengthImpl(
-      JSObject* obj,
-      Object* length,
-      FixedArrayBase* parameter_map) {
+  MUST_USE_RESULT static Handle<Object> SetLengthImpl(
+      Handle<JSObject> obj,
+      Handle<Object> length,
+      Handle<FixedArrayBase> parameter_map) {
     // TODO(mstarzinger): This was never implemented but will be used once we
     // correctly implement [[DefineOwnProperty]] on arrays.
     UNIMPLEMENTED();
@@ -1851,23 +1868,24 @@ void ElementsAccessor::TearDown() {
 
 
 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
-MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
-                                                  ElementsKindTraits>::
-    SetLengthImpl(JSObject* obj,
-                  Object* length,
-                  FixedArrayBase* backing_store) {
-  JSArray* array = JSArray::cast(obj);
+MUST_USE_RESULT Handle<Object> ElementsAccessorBase<ElementsAccessorSubclass,
+                                                    ElementsKindTraits>::
+    SetLengthImpl(Handle<JSObject> obj,
+                  Handle<Object> length,
+                  Handle<FixedArrayBase> backing_store) {
+  Isolate* isolate = obj->GetIsolate();
+  Handle<JSArray> array = Handle<JSArray>::cast(obj);
 
   // Fast case: The new length fits into a Smi.
-  MaybeObject* maybe_smi_length = length->ToSmi();
-  Object* smi_length = Smi::FromInt(0);
-  if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
-    const int value = Smi::cast(smi_length)->value();
+  Handle<Object> smi_length = Object::ToSmi(isolate, length);
+
+  if (!smi_length.is_null() && smi_length->IsSmi()) {
+    const int value = Handle<Smi>::cast(smi_length)->value();
     if (value >= 0) {
-      Object* new_length;
-      MaybeObject* result = ElementsAccessorSubclass::
+      Handle<Object> new_length = ElementsAccessorSubclass::
           SetLengthWithoutNormalize(backing_store, array, smi_length, value);
-      if (!result->ToObject(&new_length)) return result;
+      RETURN_IF_EMPTY_HANDLE_VALUE(isolate, new_length, new_length);
+
       // even though the proposed length was a smi, new_length could
       // still be a heap number because SetLengthWithoutNormalize doesn't
       // allow the array length property to drop below the index of
@@ -1875,14 +1893,14 @@ MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
       ASSERT(new_length->IsSmi() || new_length->IsHeapNumber() ||
              new_length->IsUndefined());
       if (new_length->IsSmi()) {
-        array->set_length(Smi::cast(new_length));
+        array->set_length(*Handle<Smi>::cast(new_length));
         return array;
       } else if (new_length->IsHeapNumber()) {
-        array->set_length(new_length);
+        array->set_length(*new_length);
         return array;
       }
     } else {
-      return ThrowArrayLengthRangeError(array->GetHeap());
+      return ThrowArrayLengthRangeError(isolate);
     }
   }
 
@@ -1891,30 +1909,28 @@ MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
   if (length->IsNumber()) {
     uint32_t value;
     if (length->ToArrayIndex(&value)) {
-      SeededNumberDictionary* dictionary;
-      MaybeObject* maybe_object = array->NormalizeElements();
-      if (!maybe_object->To(&dictionary)) return maybe_object;
-      Object* new_length;
-      MaybeObject* result = DictionaryElementsAccessor::
+      Handle<SeededNumberDictionary> dictionary =
+          JSObject::NormalizeElements(array);
+      RETURN_IF_EMPTY_HANDLE_VALUE(isolate, dictionary, dictionary);
+
+      Handle<Object> new_length = DictionaryElementsAccessor::
           SetLengthWithoutNormalize(dictionary, array, length, value);
-      if (!result->ToObject(&new_length)) return result;
+      RETURN_IF_EMPTY_HANDLE_VALUE(isolate, new_length, new_length);
+
       ASSERT(new_length->IsNumber());
-      array->set_length(new_length);
+      array->set_length(*new_length);
       return array;
     } else {
-      return ThrowArrayLengthRangeError(array->GetHeap());
+      return ThrowArrayLengthRangeError(isolate);
     }
   }
 
+  Factory* factory = isolate->factory();
   // Fall-back case: The new length is not a number so make the array
   // size one and set only element to length.
-  FixedArray* new_backing_store;
-  MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1);
-  if (!maybe_obj->To(&new_backing_store)) return maybe_obj;
-  new_backing_store->set(0, length);
-  { MaybeObject* result = array->SetContent(new_backing_store);
-    if (result->IsFailure()) return result;
-  }
+  Handle<FixedArray> new_backing_store = factory->NewFixedArray(1);
+  new_backing_store->set(0, *length);
+  factory->SetContent(array, new_backing_store);
   return array;
 }
 
index 135e091..1353869 100644 (file)
@@ -112,8 +112,6 @@ class ElementsAccessor {
   MUST_USE_RESULT virtual Handle<Object> SetLength(
       Handle<JSArray> holder,
       Handle<Object> new_length) = 0;
-  MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* holder,
-                                                 Object* new_length) = 0;
 
   // Modifies both the length and capacity of a JSArray, resizing the underlying
   // backing store as necessary. This method does NOT honor the semantics of
index 618cf30..83f11e7 100644 (file)
@@ -1031,6 +1031,21 @@ bool Object::IsNaN() {
 }
 
 
+// static
+Handle<Object> Object::ToSmi(Isolate* isolate, Handle<Object> object) {
+  if (object->IsSmi()) return object;
+  if (object->IsHeapNumber()) {
+    double value = Handle<HeapNumber>::cast(object)->value();
+    int int_value = FastD2I(value);
+    if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
+      return handle(Smi::FromInt(int_value), isolate);
+    }
+  }
+  return Handle<Object>();
+}
+
+
+// TODO(ishell): Use handlified version instead.
 MaybeObject* Object::ToSmi() {
   if (IsSmi()) return this;
   if (IsHeapNumber()) {
index 41c0d2a..cbe9553 100644 (file)
@@ -1536,6 +1536,8 @@ class Object : public MaybeObject {
 
   // Converts this to a Smi if possible.
   // Failure is returned otherwise.
+  static MUST_USE_RESULT inline Handle<Object> ToSmi(Isolate* isolate,
+                                                     Handle<Object> object);
   MUST_USE_RESULT inline MaybeObject* ToSmi();
 
   void Lookup(Name* name, LookupResult* result);