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 |