| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index bbeee3f83911959a57dfa765edb5bde872cc8edd..99b5944c811d1d77199f44d5ffe7b069b9962b10 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -170,6 +170,17 @@ MaybeHandle<Object> Object::GetPropertyWithReceiver(
|
| }
|
|
|
|
|
| +MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
|
| + Name* name,
|
| + PropertyAttributes* attributes) {
|
| + LookupResult result(name->GetIsolate());
|
| + Lookup(name, &result);
|
| + MaybeObject* value = GetProperty(receiver, &result, name, attributes);
|
| + ASSERT(*attributes <= ABSENT);
|
| + return value;
|
| +}
|
| +
|
| +
|
| bool Object::ToInt32(int32_t* value) {
|
| if (IsSmi()) {
|
| *value = Smi::cast(this)->value();
|
| @@ -463,17 +474,69 @@ MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
|
| }
|
|
|
|
|
| -MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy,
|
| - Handle<Object> receiver,
|
| - Handle<Name> name) {
|
| - Isolate* isolate = proxy->GetIsolate();
|
| +MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw,
|
| + Name* name_raw) {
|
| + Isolate* isolate = GetIsolate();
|
| + HandleScope scope(isolate);
|
| + Handle<Object> receiver(receiver_raw, isolate);
|
| + Handle<Object> name(name_raw, isolate);
|
|
|
| // TODO(rossberg): adjust once there is a story for symbols vs proxies.
|
| - if (name->IsSymbol()) return isolate->factory()->undefined_value();
|
| + if (name->IsSymbol()) return isolate->heap()->undefined_value();
|
|
|
| Handle<Object> args[] = { receiver, name };
|
| - return CallTrap(
|
| - proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args);
|
| + Handle<Object> result;
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| + isolate, result,
|
| + CallTrap(handle(this),
|
| + "get",
|
| + isolate->derived_get_trap(),
|
| + ARRAY_SIZE(args),
|
| + args));
|
| + return *result;
|
| +}
|
| +
|
| +
|
| +MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
|
| + Handle<Name> name) {
|
| + uint32_t index;
|
| + Isolate* isolate = name->GetIsolate();
|
| + if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index);
|
| + return GetProperty(object, name);
|
| +}
|
| +
|
| +
|
| +Handle<Object> Object::GetProperty(Handle<Object> object,
|
| + Handle<Name> name) {
|
| + CALL_HEAP_FUNCTION(name->GetIsolate(), object->GetProperty(*name), Object);
|
| +}
|
| +
|
| +
|
| +MaybeObject* JSProxy::GetElementWithHandler(Object* receiver,
|
| + uint32_t index) {
|
| + String* name;
|
| + MaybeObject* maybe = GetHeap()->Uint32ToString(index);
|
| + if (!maybe->To<String>(&name)) return maybe;
|
| + return GetPropertyWithHandler(receiver, name);
|
| +}
|
| +
|
| +
|
| +MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
|
| + Handle<JSReceiver> receiver,
|
| + uint32_t index,
|
| + Handle<Object> value,
|
| + StrictMode strict_mode) {
|
| + Isolate* isolate = proxy->GetIsolate();
|
| + Handle<String> name = isolate->factory()->Uint32ToString(index);
|
| + return SetPropertyWithHandler(
|
| + proxy, receiver, name, value, NONE, strict_mode);
|
| +}
|
| +
|
| +
|
| +bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) {
|
| + Isolate* isolate = proxy->GetIsolate();
|
| + Handle<String> name = isolate->factory()->Uint32ToString(index);
|
| + return HasPropertyWithHandler(proxy, name);
|
| }
|
|
|
|
|
| @@ -773,10 +836,29 @@ bool JSObject::IsDirty() {
|
| MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
|
| Handle<Object> receiver,
|
| LookupResult* result,
|
| - Handle<Name> name,
|
| + Handle<Name> key,
|
| PropertyAttributes* attributes) {
|
| + Isolate* isolate = result->isolate();
|
| + CALL_HEAP_FUNCTION(
|
| + isolate,
|
| + object->GetProperty(*receiver, result, *key, attributes),
|
| + Object);
|
| +}
|
| +
|
| +
|
| +// TODO(yangguo): handlify this and get rid of.
|
| +MaybeObject* Object::GetProperty(Object* receiver,
|
| + LookupResult* result,
|
| + Name* name,
|
| + PropertyAttributes* attributes) {
|
| Isolate* isolate = name->GetIsolate();
|
| - Factory* factory = isolate->factory();
|
| + Heap* heap = isolate->heap();
|
| +
|
| +#ifdef DEBUG
|
| + // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon
|
| + // as this method has been fully handlified.
|
| + HandleScope scope(isolate);
|
| +#endif
|
|
|
| // Make sure that the top context does not change when doing
|
| // callbacks or interceptor calls.
|
| @@ -790,68 +872,93 @@ MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
|
| // holder in the prototype chain.
|
| // Proxy handlers do not use the proxy's prototype, so we can skip this.
|
| if (!result->IsHandler()) {
|
| - ASSERT(*object != object->GetPrototype(isolate));
|
| - Handle<Object> last = result->IsProperty()
|
| - ? Handle<Object>(result->holder(), isolate)
|
| - : Handle<Object>::cast(factory->null_value());
|
| - for (Handle<Object> current = object;
|
| + Object* last = result->IsProperty()
|
| + ? result->holder()
|
| + : Object::cast(heap->null_value());
|
| + ASSERT(this != this->GetPrototype(isolate));
|
| + for (Object* current = this;
|
| true;
|
| - current = Handle<Object>(current->GetPrototype(isolate), isolate)) {
|
| + current = current->GetPrototype(isolate)) {
|
| if (current->IsAccessCheckNeeded()) {
|
| // Check if we're allowed to read from the current object. Note
|
| // that even though we may not actually end up loading the named
|
| // property from the current object, we still check that we have
|
| // access to it.
|
| - Handle<JSObject> checked = Handle<JSObject>::cast(current);
|
| - if (!isolate->MayNamedAccessWrapper(checked, name, v8::ACCESS_GET)) {
|
| - return JSObject::GetPropertyWithFailedAccessCheck(
|
| - checked, receiver, result, name, attributes);
|
| + JSObject* checked = JSObject::cast(current);
|
| + if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
|
| + HandleScope scope(isolate);
|
| + Handle<Object> value;
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| + isolate, value,
|
| + JSObject::GetPropertyWithFailedAccessCheck(
|
| + handle(checked, isolate),
|
| + handle(receiver, isolate),
|
| + result,
|
| + handle(name, isolate),
|
| + attributes));
|
| + return *value;
|
| }
|
| }
|
| // Stop traversing the chain once we reach the last object in the
|
| // chain; either the holder of the result or null in case of an
|
| // absent property.
|
| - if (current.is_identical_to(last)) break;
|
| + if (current == last) break;
|
| }
|
| }
|
|
|
| if (!result->IsProperty()) {
|
| *attributes = ABSENT;
|
| - return factory->undefined_value();
|
| + return heap->undefined_value();
|
| }
|
| *attributes = result->GetAttributes();
|
| -
|
| - Handle<Object> value;
|
| - Handle<JSObject> holder(result->holder(), isolate);
|
| + Object* value;
|
| switch (result->type()) {
|
| - case NORMAL: {
|
| - DisallowHeapAllocation no_gc;
|
| - value = handle(holder->GetNormalizedProperty(result), isolate);
|
| - break;
|
| + case NORMAL:
|
| + value = result->holder()->GetNormalizedProperty(result);
|
| + ASSERT(!value->IsTheHole() || result->IsReadOnly());
|
| + return value->IsTheHole() ? heap->undefined_value() : value;
|
| + case FIELD: {
|
| + MaybeObject* maybe_result = result->holder()->FastPropertyAt(
|
| + result->representation(),
|
| + result->GetFieldIndex().field_index());
|
| + if (!maybe_result->To(&value)) return maybe_result;
|
| + ASSERT(!value->IsTheHole() || result->IsReadOnly());
|
| + return value->IsTheHole() ? heap->undefined_value() : value;
|
| }
|
| - case FIELD:
|
| - value = JSObject::FastPropertyAt(holder,
|
| - result->representation(),
|
| - result->GetFieldIndex().field_index());
|
| - break;
|
| case CONSTANT:
|
| - return handle(result->GetConstant(), isolate);
|
| - case CALLBACKS:
|
| - return JSObject::GetPropertyWithCallback(
|
| - holder, receiver, handle(result->GetCallbackObject(), isolate), name);
|
| + return result->GetConstant();
|
| + case CALLBACKS: {
|
| + HandleScope scope(isolate);
|
| + Handle<Object> value;
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| + isolate, value,
|
| + JSObject::GetPropertyWithCallback(
|
| + handle(result->holder(), isolate),
|
| + handle(receiver, isolate),
|
| + handle(result->GetCallbackObject(), isolate),
|
| + handle(name, isolate)));
|
| + return *value;
|
| + }
|
| case HANDLER:
|
| - return JSProxy::GetPropertyWithHandler(
|
| - handle(result->proxy(), isolate), receiver, name);
|
| - case INTERCEPTOR:
|
| - return JSObject::GetPropertyWithInterceptor(
|
| - holder, receiver, name, attributes);
|
| + return result->proxy()->GetPropertyWithHandler(receiver, name);
|
| + case INTERCEPTOR: {
|
| + HandleScope scope(isolate);
|
| + Handle<Object> value;
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| + isolate, value,
|
| + JSObject::GetPropertyWithInterceptor(
|
| + handle(result->holder(), isolate),
|
| + handle(receiver, isolate),
|
| + handle(name, isolate),
|
| + attributes));
|
| + return *value;
|
| + }
|
| case NONEXISTENT:
|
| UNREACHABLE();
|
| break;
|
| }
|
| - ASSERT(!value->IsTheHole() || result->IsReadOnly());
|
| - return value->IsTheHole() ? Handle<Object>::cast(factory->undefined_value())
|
| - : value;
|
| + UNREACHABLE();
|
| + return NULL;
|
| }
|
|
|
|
|
| @@ -881,8 +988,10 @@ MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
|
| holder = Handle<Object>(
|
| native_context->boolean_function()->instance_prototype(), isolate);
|
| } else if (holder->IsJSProxy()) {
|
| - return JSProxy::GetElementWithHandler(
|
| - Handle<JSProxy>::cast(holder), receiver, index);
|
| + CALL_HEAP_FUNCTION(isolate,
|
| + Handle<JSProxy>::cast(holder)->GetElementWithHandler(
|
| + *receiver, index),
|
| + Object);
|
| } else {
|
| // Undefined and null have no indexed properties.
|
| ASSERT(holder->IsUndefined() || holder->IsNull());
|
| @@ -3513,9 +3622,9 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
|
| Handle<String> configurable_name =
|
| isolate->factory()->InternalizeOneByteString(
|
| STATIC_ASCII_VECTOR("configurable_"));
|
| - Handle<Object> configurable =
|
| - Object::GetProperty(desc, configurable_name).ToHandleChecked();
|
| - ASSERT(configurable->IsBoolean());
|
| + Handle<Object> configurable = Object::GetProperty(desc, configurable_name);
|
| + ASSERT(!configurable.is_null());
|
| + ASSERT(configurable->IsTrue() || configurable->IsFalse());
|
| if (configurable->IsFalse()) {
|
| Handle<String> trap =
|
| isolate->factory()->InternalizeOneByteString(
|
| @@ -3531,16 +3640,16 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
|
| Handle<String> hasWritable_name =
|
| isolate->factory()->InternalizeOneByteString(
|
| STATIC_ASCII_VECTOR("hasWritable_"));
|
| - Handle<Object> hasWritable =
|
| - Object::GetProperty(desc, hasWritable_name).ToHandleChecked();
|
| - ASSERT(hasWritable->IsBoolean());
|
| + Handle<Object> hasWritable = Object::GetProperty(desc, hasWritable_name);
|
| + ASSERT(!hasWritable.is_null());
|
| + ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse());
|
| if (hasWritable->IsTrue()) {
|
| Handle<String> writable_name =
|
| isolate->factory()->InternalizeOneByteString(
|
| STATIC_ASCII_VECTOR("writable_"));
|
| - Handle<Object> writable =
|
| - Object::GetProperty(desc, writable_name).ToHandleChecked();
|
| - ASSERT(writable->IsBoolean());
|
| + Handle<Object> writable = Object::GetProperty(desc, writable_name);
|
| + ASSERT(!writable.is_null());
|
| + ASSERT(writable->IsTrue() || writable->IsFalse());
|
| *done = writable->IsFalse();
|
| if (!*done) return isolate->factory()->the_hole_value();
|
| if (strict_mode == SLOPPY) return value;
|
| @@ -3553,7 +3662,8 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
|
| // We have an AccessorDescriptor.
|
| Handle<String> set_name = isolate->factory()->InternalizeOneByteString(
|
| STATIC_ASCII_VECTOR("set_"));
|
| - Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked();
|
| + Handle<Object> setter = Object::GetProperty(desc, set_name);
|
| + ASSERT(!setter.is_null());
|
| if (!setter->IsUndefined()) {
|
| // TODO(rossberg): nicer would be to cast to some JSCallable here...
|
| return SetPropertyWithDefinedSetter(
|
| @@ -3645,25 +3755,21 @@ PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
|
| // Convert result to PropertyAttributes.
|
| Handle<String> enum_n = isolate->factory()->InternalizeOneByteString(
|
| STATIC_ASCII_VECTOR("enumerable_"));
|
| - Handle<Object> enumerable;
|
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| - isolate, enumerable, Object::GetProperty(desc, enum_n), NONE);
|
| + Handle<Object> enumerable = Object::GetProperty(desc, enum_n);
|
| + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, enumerable, NONE);
|
| Handle<String> conf_n = isolate->factory()->InternalizeOneByteString(
|
| STATIC_ASCII_VECTOR("configurable_"));
|
| - Handle<Object> configurable;
|
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| - isolate, configurable, Object::GetProperty(desc, conf_n), NONE);
|
| + Handle<Object> configurable = Object::GetProperty(desc, conf_n);
|
| + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, configurable, NONE);
|
| Handle<String> writ_n = isolate->factory()->InternalizeOneByteString(
|
| STATIC_ASCII_VECTOR("writable_"));
|
| - Handle<Object> writable;
|
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| - isolate, writable, Object::GetProperty(desc, writ_n), NONE);
|
| + Handle<Object> writable = Object::GetProperty(desc, writ_n);
|
| + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, writable, NONE);
|
| if (!writable->BooleanValue()) {
|
| Handle<String> set_n = isolate->factory()->InternalizeOneByteString(
|
| STATIC_ASCII_VECTOR("set_"));
|
| - Handle<Object> setter;
|
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| - isolate, setter, Object::GetProperty(desc, set_n), NONE);
|
| + Handle<Object> setter = Object::GetProperty(desc, set_n);
|
| + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, setter, NONE);
|
| writable = isolate->factory()->ToBoolean(!setter->IsUndefined());
|
| }
|
|
|
| @@ -5114,8 +5220,7 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object,
|
| if (!GetLocalElementAccessorPair(object, index).is_null()) {
|
| old_value = Handle<Object>::cast(factory->the_hole_value());
|
| } else {
|
| - old_value = Object::GetElement(
|
| - isolate, object, index).ToHandleChecked();
|
| + old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
|
| }
|
| }
|
| }
|
| @@ -5716,8 +5821,8 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
|
| // In particular, don't try to copy the length attribute of
|
| // an array.
|
| if (attributes != NONE) continue;
|
| - Handle<Object> value =
|
| - Object::GetProperty(copy, key_string).ToHandleChecked();
|
| + Handle<Object> value = Object::GetProperty(copy, key_string);
|
| + CHECK_NOT_EMPTY_HANDLE(isolate, value);
|
| if (value->IsJSObject()) {
|
| Handle<JSObject> result = VisitElementOrProperty(
|
| copy, Handle<JSObject>::cast(value));
|
| @@ -6280,8 +6385,7 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
|
| if (is_element) {
|
| preexists = HasLocalElement(object, index);
|
| if (preexists && GetLocalElementAccessorPair(object, index).is_null()) {
|
| - old_value =
|
| - Object::GetElement(isolate, object, index).ToHandleChecked();
|
| + old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
|
| }
|
| } else {
|
| LookupResult lookup(isolate);
|
| @@ -11189,7 +11293,7 @@ static bool GetOldValue(Isolate* isolate,
|
| if (!JSObject::GetLocalElementAccessorPair(object, index).is_null()) {
|
| value = Handle<Object>::cast(isolate->factory()->the_hole_value());
|
| } else {
|
| - value = Object::GetElement(isolate, object, index).ToHandleChecked();
|
| + value = Object::GetElementNoExceptionThrown(isolate, object, index);
|
| }
|
| old_values->Add(value);
|
| indices->Add(index);
|
| @@ -12440,7 +12544,7 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
|
|
|
| if (old_attributes != ABSENT) {
|
| if (GetLocalElementAccessorPair(object, index).is_null()) {
|
| - old_value = Object::GetElement(isolate, object, index).ToHandleChecked();
|
| + old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
|
| }
|
| } else if (object->IsJSArray()) {
|
| // Store old array length in case adding an element grows the array.
|
| @@ -12489,7 +12593,7 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
|
| EnqueueChangeRecord(object, "reconfigure", name, old_value);
|
| } else {
|
| Handle<Object> new_value =
|
| - Object::GetElement(isolate, object, index).ToHandleChecked();
|
| + Object::GetElementNoExceptionThrown(isolate, object, index);
|
| bool value_changed = !old_value->SameValue(*new_value);
|
| if (old_attributes != new_attributes) {
|
| if (!value_changed) old_value = isolate->factory()->the_hole_value();
|
|
|