diff options
Diffstat (limited to 'deps/v8/src/property-descriptor.cc')
-rw-r--r-- | deps/v8/src/property-descriptor.cc | 232 |
1 files changed, 132 insertions, 100 deletions
diff --git a/deps/v8/src/property-descriptor.cc b/deps/v8/src/property-descriptor.cc index 8c8dfa4f4a..243a9faac3 100644 --- a/deps/v8/src/property-descriptor.cc +++ b/deps/v8/src/property-descriptor.cc @@ -20,11 +20,11 @@ bool GetPropertyIfPresent(Handle<Object> obj, Handle<String> name, Handle<Object>* value) { LookupIterator it(obj, name); // 4. Let hasEnumerable be HasProperty(Obj, "enumerable"). - Maybe<PropertyAttributes> maybe_attr = JSReceiver::GetPropertyAttributes(&it); + Maybe<bool> has_property = JSReceiver::HasProperty(&it); // 5. ReturnIfAbrupt(hasEnumerable). - if (!maybe_attr.IsJust()) return false; + if (has_property.IsNothing()) return false; // 6. If hasEnumerable is true, then - if (maybe_attr.FromJust() != ABSENT) { + if (has_property.FromJust() == true) { // 6a. Let enum be ToBoolean(Get(Obj, "enumerable")). // 6b. ReturnIfAbrupt(enum). if (!JSObject::GetProperty(&it).ToHandle(value)) return false; @@ -103,7 +103,7 @@ bool ToPropertyDescriptorFastPath(Isolate* isolate, Handle<Object> obj, static void CreateDataProperty(Isolate* isolate, Handle<JSObject> object, Handle<String> name, Handle<Object> value) { - LookupIterator it(object, name); + LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); Maybe<bool> result = JSObject::CreateDataProperty(&it, value); CHECK(result.IsJust() && result.FromJust()); } @@ -148,7 +148,7 @@ bool PropertyDescriptor::ToPropertyDescriptor(Isolate* isolate, PropertyDescriptor* desc) { // 1. ReturnIfAbrupt(Obj). // 2. If Type(Obj) is not Object, throw a TypeError exception. - if (!obj->IsSpecObject()) { + if (!obj->IsJSReceiver()) { isolate->Throw(*isolate->factory()->NewTypeError( MessageTemplate::kPropertyDescObject, obj)); return false; @@ -160,109 +160,141 @@ bool PropertyDescriptor::ToPropertyDescriptor(Isolate* isolate, return true; } - // TODO(jkummerow): Implement JSProxy support. - // Specifically, instead of taking the attributes != ABSENT shortcut, we - // have to implement proper HasProperty for proxies. - if (!obj->IsJSProxy()) { - { // enumerable? - Handle<Object> enumerable; - // 4 through 6b. - if (!GetPropertyIfPresent(obj, isolate->factory()->enumerable_string(), - &enumerable)) { - return false; - } - // 6c. Set the [[Enumerable]] field of desc to enum. - if (!enumerable.is_null()) { - desc->set_enumerable(enumerable->BooleanValue()); - } - } - { // configurable? - Handle<Object> configurable; - // 7 through 9b. - if (!GetPropertyIfPresent(obj, isolate->factory()->configurable_string(), - &configurable)) { - return false; - } - // 9c. Set the [[Configurable]] field of desc to conf. - if (!configurable.is_null()) { - desc->set_configurable(configurable->BooleanValue()); - } - } - { // value? - Handle<Object> value; - // 10 through 12b. - if (!GetPropertyIfPresent(obj, isolate->factory()->value_string(), - &value)) - return false; - // 12c. Set the [[Value]] field of desc to value. - if (!value.is_null()) desc->set_value(value); - } - { // writable? - Handle<Object> writable; - // 13 through 15b. - if (!GetPropertyIfPresent(obj, isolate->factory()->writable_string(), - &writable)) { - return false; - } - // 15c. Set the [[Writable]] field of desc to writable. - if (!writable.is_null()) desc->set_writable(writable->BooleanValue()); + // enumerable? + Handle<Object> enumerable; + // 4 through 6b. + if (!GetPropertyIfPresent(obj, isolate->factory()->enumerable_string(), + &enumerable)) { + return false; + } + // 6c. Set the [[Enumerable]] field of desc to enum. + if (!enumerable.is_null()) { + desc->set_enumerable(enumerable->BooleanValue()); + } + + // configurable? + Handle<Object> configurable; + // 7 through 9b. + if (!GetPropertyIfPresent(obj, isolate->factory()->configurable_string(), + &configurable)) { + return false; + } + // 9c. Set the [[Configurable]] field of desc to conf. + if (!configurable.is_null()) { + desc->set_configurable(configurable->BooleanValue()); + } + + // value? + Handle<Object> value; + // 10 through 12b. + if (!GetPropertyIfPresent(obj, isolate->factory()->value_string(), &value)) { + return false; + } + // 12c. Set the [[Value]] field of desc to value. + if (!value.is_null()) desc->set_value(value); + + // writable? + Handle<Object> writable; + // 13 through 15b. + if (!GetPropertyIfPresent(obj, isolate->factory()->writable_string(), + &writable)) { + return false; + } + // 15c. Set the [[Writable]] field of desc to writable. + if (!writable.is_null()) desc->set_writable(writable->BooleanValue()); + + // getter? + Handle<Object> getter; + // 16 through 18b. + if (!GetPropertyIfPresent(obj, isolate->factory()->get_string(), &getter)) { + return false; + } + if (!getter.is_null()) { + // 18c. If IsCallable(getter) is false and getter is not undefined, + // throw a TypeError exception. + if (!getter->IsCallable() && !getter->IsUndefined()) { + isolate->Throw(*isolate->factory()->NewTypeError( + MessageTemplate::kObjectGetterCallable, getter)); + return false; } - { // getter? - Handle<Object> getter; - // 16 through 18b. - if (!GetPropertyIfPresent(obj, isolate->factory()->get_string(), &getter)) - return false; - if (!getter.is_null()) { - // 18c. If IsCallable(getter) is false and getter is not undefined, - // throw a TypeError exception. - if (!getter->IsCallable() && !getter->IsUndefined()) { - isolate->Throw(*isolate->factory()->NewTypeError( - MessageTemplate::kObjectGetterCallable, getter)); - return false; - } - // 18d. Set the [[Get]] field of desc to getter. - desc->set_get(getter); - } - { // setter? - Handle<Object> setter; - // 19 through 21b. - if (!GetPropertyIfPresent(obj, isolate->factory()->set_string(), - &setter)) - return false; - if (!setter.is_null()) { - // 21c. If IsCallable(setter) is false and setter is not undefined, - // throw a TypeError exception. - if (!setter->IsCallable() && !setter->IsUndefined()) { - isolate->Throw(*isolate->factory()->NewTypeError( - MessageTemplate::kObjectSetterCallable, setter)); - return false; - } - // 21d. Set the [[Set]] field of desc to setter. - desc->set_set(setter); - } - } - // 22. If either desc.[[Get]] or desc.[[Set]] is present, then - // 22a. If either desc.[[Value]] or desc.[[Writable]] is present, - // throw a TypeError exception. - if ((desc->has_get() || desc->has_set()) && - (desc->has_value() || desc->has_writable())) { - isolate->Throw(*isolate->factory()->NewTypeError( - MessageTemplate::kValueAndAccessor, obj)); - return false; - } + // 18d. Set the [[Get]] field of desc to getter. + desc->set_get(getter); + } + // setter? + Handle<Object> setter; + // 19 through 21b. + if (!GetPropertyIfPresent(obj, isolate->factory()->set_string(), &setter)) { + return false; + } + if (!setter.is_null()) { + // 21c. If IsCallable(setter) is false and setter is not undefined, + // throw a TypeError exception. + if (!setter->IsCallable() && !setter->IsUndefined()) { + isolate->Throw(*isolate->factory()->NewTypeError( + MessageTemplate::kObjectSetterCallable, setter)); + return false; } - } else { - DCHECK(obj->IsJSProxy()); - // Having an UNIMPLEMENTED() here would upset ClusterFuzz, because - // --harmony-proxies makes it possible to reach this branch. - isolate->Throw( - *isolate->factory()->NewTypeError(MessageTemplate::kUnsupported)); + // 21d. Set the [[Set]] field of desc to setter. + desc->set_set(setter); + } + + // 22. If either desc.[[Get]] or desc.[[Set]] is present, then + // 22a. If either desc.[[Value]] or desc.[[Writable]] is present, + // throw a TypeError exception. + if ((desc->has_get() || desc->has_set()) && + (desc->has_value() || desc->has_writable())) { + isolate->Throw(*isolate->factory()->NewTypeError( + MessageTemplate::kValueAndAccessor, obj)); return false; } + // 23. Return desc. return true; } +// ES6 6.2.4.6 +// static +void PropertyDescriptor::CompletePropertyDescriptor(Isolate* isolate, + PropertyDescriptor* desc) { + // 1. ReturnIfAbrupt(Desc). + // 2. Assert: Desc is a Property Descriptor. + // 3. Let like be Record{ + // [[Value]]: undefined, [[Writable]]: false, + // [[Get]]: undefined, [[Set]]: undefined, + // [[Enumerable]]: false, [[Configurable]]: false}. + // 4. If either IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, + // then: + if (!IsAccessorDescriptor(desc)) { + // 4a. If Desc does not have a [[Value]] field, set Desc.[[Value]] to + // like.[[Value]]. + if (!desc->has_value()) { + desc->set_value(isolate->factory()->undefined_value()); + } + // 4b. If Desc does not have a [[Writable]] field, set Desc.[[Writable]] + // to like.[[Writable]]. + if (!desc->has_writable()) desc->set_writable(false); + } else { + // 5. Else, + // 5a. If Desc does not have a [[Get]] field, set Desc.[[Get]] to + // like.[[Get]]. + if (!desc->has_get()) { + desc->set_get(isolate->factory()->undefined_value()); + } + // 5b. If Desc does not have a [[Set]] field, set Desc.[[Set]] to + // like.[[Set]]. + if (!desc->has_set()) { + desc->set_set(isolate->factory()->undefined_value()); + } + } + // 6. If Desc does not have an [[Enumerable]] field, set + // Desc.[[Enumerable]] to like.[[Enumerable]]. + if (!desc->has_enumerable()) desc->set_enumerable(false); + // 7. If Desc does not have a [[Configurable]] field, set + // Desc.[[Configurable]] to like.[[Configurable]]. + if (!desc->has_configurable()) desc->set_configurable(false); + // 8. Return Desc. +} + } // namespace internal } // namespace v8 |