diff --git a/src/builtins.cc b/src/builtins.cc index a79df97f1e..b48de7f2cd 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -548,18 +548,6 @@ static Handle ElementsAccessorGetWrapper( } -// TODO(ishell): Temporary wrapper until handlified. -static Handle ElementsAccessorSetLengthWrapper( - Isolate* isolate, - ElementsAccessor* accessor, - Handle array, - int new_length) { - CALL_HEAP_FUNCTION(isolate, - accessor->SetLength(*array, Smi::FromInt(new_length)), - Object); -} - - BUILTIN(ArrayPop) { HandleScope scope(isolate); Handle 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; } diff --git a/src/elements.cc b/src/elements.cc index 2e9bc3266f..d935fb1b9c 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -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(NULL, 0))); +static Handle ThrowArrayLengthRangeError(Isolate* isolate) { + isolate->Throw( + *isolate->factory()->NewRangeError("invalid_array_length", + HandleVector(NULL, 0))); + return Handle(); } @@ -737,25 +737,18 @@ class ElementsAccessorBase : public ElementsAccessor { return NULL; } - // TODO(ishell): Temporary wrapper until handlified. MUST_USE_RESULT virtual Handle SetLength( Handle array, Handle 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 SetLengthImpl( + Handle obj, + Handle length, + Handle 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 SetLengthWithoutNormalize( + Handle backing_store, + Handle array, + Handle 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 SetLengthImpl( + Handle obj, + Handle length, + Handle 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 SetLengthWithoutNormalize( + Handle store, + Handle array, + Handle 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 SetLengthImpl( + Handle obj, + Handle length, + Handle 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 -MUST_USE_RESULT MaybeObject* ElementsAccessorBase:: - SetLengthImpl(JSObject* obj, - Object* length, - FixedArrayBase* backing_store) { - JSArray* array = JSArray::cast(obj); +MUST_USE_RESULT Handle ElementsAccessorBase:: + SetLengthImpl(Handle obj, + Handle length, + Handle backing_store) { + Isolate* isolate = obj->GetIsolate(); + Handle array = Handle::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 smi_length = Object::ToSmi(isolate, length); + + if (!smi_length.is_null() && smi_length->IsSmi()) { + const int value = Handle::cast(smi_length)->value(); if (value >= 0) { - Object* new_length; - MaybeObject* result = ElementsAccessorSubclass:: + Handle 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* ElementsAccessorBaseIsSmi() || new_length->IsHeapNumber() || new_length->IsUndefined()); if (new_length->IsSmi()) { - array->set_length(Smi::cast(new_length)); + array->set_length(*Handle::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* ElementsAccessorBaseIsNumber()) { 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 dictionary = + JSObject::NormalizeElements(array); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, dictionary, dictionary); + + Handle 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 new_backing_store = factory->NewFixedArray(1); + new_backing_store->set(0, *length); + factory->SetContent(array, new_backing_store); return array; } diff --git a/src/elements.h b/src/elements.h index 135e091a6f..1353869052 100644 --- a/src/elements.h +++ b/src/elements.h @@ -112,8 +112,6 @@ class ElementsAccessor { MUST_USE_RESULT virtual Handle SetLength( Handle holder, Handle 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 diff --git a/src/objects-inl.h b/src/objects-inl.h index 618cf30f76..83f11e7f16 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1031,6 +1031,21 @@ bool Object::IsNaN() { } +// static +Handle Object::ToSmi(Isolate* isolate, Handle object) { + if (object->IsSmi()) return object; + if (object->IsHeapNumber()) { + double value = Handle::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(); +} + + +// TODO(ishell): Use handlified version instead. MaybeObject* Object::ToSmi() { if (IsSmi()) return this; if (IsHeapNumber()) { diff --git a/src/objects.h b/src/objects.h index 41c0d2a3d4..cbe9553e11 100644 --- a/src/objects.h +++ b/src/objects.h @@ -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 ToSmi(Isolate* isolate, + Handle object); MUST_USE_RESULT inline MaybeObject* ToSmi(); void Lookup(Name* name, LookupResult* result);