 Chromium Code Reviews
 Chromium Code Reviews Issue 1438233002:
  [proxies] Teach ToPropertyDescriptor to deal with Proxies  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1438233002:
  [proxies] Teach ToPropertyDescriptor to deal with Proxies  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| Index: src/property-descriptor.cc | 
| diff --git a/src/property-descriptor.cc b/src/property-descriptor.cc | 
| index 8c8dfa4f4ac74445c3336b095fe0c9cb26957439..c6d0101957a0153b75d29dc72e30c21274c1afcb 100644 | 
| --- a/src/property-descriptor.cc | 
| +++ b/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; | 
| @@ -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? | 
| 
Jakob Kummerow
2015/11/12 13:44:45
This is the same as old lines 167 through 253 with
 | 
| + 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, | 
| 
Jakob Kummerow
2015/11/12 13:44:45
I'm not using this yet, but my next CL is going to
 | 
| + 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 |