| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 89ebdd7675d15231a601e285b7bfaed19e52013b..f5ad23396b9dd5c6d531c585f9be4ec938a093c9 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -6717,14 +6717,16 @@ bool JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
|
| // TODO(jkummerow): Any chance to unify this with
|
| // "MaybeHandle<Object> GetOwnProperty()" in runtime-object.cc?
|
|
|
| -// TODO(jkummerow/verwaest): Proxy support: call getOwnPropertyDescriptor trap
|
| -// and convert the result (if it's an object) with ToPropertyDescriptor.
|
| -
|
| // ES6 9.1.5.1
|
| // Returns true on success; false if there was an exception or no property.
|
| // static
|
| bool JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it,
|
| PropertyDescriptor* desc) {
|
| + // "Virtual" dispatch.
|
| + if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) {
|
| + return JSProxy::GetOwnPropertyDescriptor(it, desc);
|
| + }
|
| +
|
| Isolate* isolate = it->isolate();
|
| // 1. (Assert)
|
| // 2. If O does not have an own property with key P, return undefined.
|
| @@ -6772,6 +6774,122 @@ bool JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it,
|
| }
|
|
|
|
|
| +// ES6 9.5.5
|
| +// static
|
| +bool JSProxy::GetOwnPropertyDescriptor(LookupIterator* it,
|
| + PropertyDescriptor* desc) {
|
| + DCHECK(it->GetHolder<Object>()->IsJSProxy());
|
| + Isolate* isolate = it->isolate();
|
| + Handle<Name> property_name = it->GetName();
|
| + // 1. (Assert)
|
| + // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O.
|
| + Handle<Object> handler(it->GetHolder<JSProxy>()->handler(), isolate);
|
| + // 3. If handler is null, throw a TypeError exception.
|
| + if (handler->IsNull()) {
|
| + isolate->Throw(*isolate->factory()->NewTypeError(
|
| + MessageTemplate::kProxyHandlerNonObject));
|
| + return false;
|
| + }
|
| + // 4. Assert: Type(handler) is Object.
|
| + DCHECK(handler->IsSpecObject());
|
| + // If the handler is not null, the target can't be null either.
|
| + DCHECK(it->GetHolder<JSProxy>()->target()->IsSpecObject());
|
| + // 5. Let target be the value of the [[ProxyTarget]] internal slot of O.
|
| + Handle<JSReceiver> target(
|
| + JSReceiver::cast(it->GetHolder<JSProxy>()->target()), isolate);
|
| + // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
|
| + Handle<Object> trap;
|
| + ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| + isolate, trap,
|
| + Object::GetMethod(Handle<JSReceiver>::cast(handler),
|
| + isolate->factory()->getOwnPropertyDescriptor_string()),
|
| + false);
|
| + // 7. If trap is undefined, then
|
| + if (trap->IsUndefined()) {
|
| + // 7a. Return target.[[GetOwnProperty]](P).
|
| + return JSReceiver::GetOwnPropertyDescriptor(isolate, target, property_name,
|
| + desc);
|
| + }
|
| + // 8. Let trapResultObj be ? Call(trap, handler, «target, P»).
|
| + Handle<Object> trap_result_obj;
|
| + Handle<Object> args[] = {target, property_name};
|
| + ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| + isolate, trap_result_obj,
|
| + Execution::Call(isolate, trap, handler, arraysize(args), args), false);
|
| + // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a
|
| + // TypeError exception.
|
| + if (!trap_result_obj->IsSpecObject() && !trap_result_obj->IsUndefined()) {
|
| + isolate->Throw(*isolate->factory()->NewTypeError(
|
| + MessageTemplate::kProxyHandlerReturned, handler, trap_result_obj,
|
| + property_name));
|
| + return false;
|
| + }
|
| + // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
|
| + PropertyDescriptor target_desc;
|
| + JSReceiver::GetOwnPropertyDescriptor(isolate, target, property_name,
|
| + &target_desc);
|
| + if (isolate->has_pending_exception()) return false;
|
| + // 11. If trapResultObj is undefined, then
|
| + if (trap_result_obj->IsUndefined()) {
|
| + // 11a. If targetDesc is undefined, return undefined.
|
| + if (target_desc.is_empty()) return false;
|
| + // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError
|
| + // exception.
|
| + if (!target_desc.configurable()) {
|
| + isolate->Throw(*isolate->factory()->NewTypeError(
|
| + MessageTemplate::kProxyTargetPropNotConfigurable, property_name));
|
| + return false;
|
| + }
|
| + // 11c. Let extensibleTarget be ? IsExtensible(target).
|
| + Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
|
| + if (maybe_extensible.IsNothing()) return false;
|
| + bool extensible_target = maybe_extensible.FromJust();
|
| + // 11d. (Assert)
|
| + // 11e. If extensibleTarget is false, throw a TypeError exception.
|
| + if (!extensible_target) {
|
| + isolate->Throw(*isolate->factory()->NewTypeError(
|
| + MessageTemplate::kProxyTargetNotExtensible));
|
| + return false;
|
| + }
|
| + // 11f. Return undefined.
|
| + return false; // |desc->is_empty()| is what JavaScript calls "undefined".
|
| + }
|
| + // 12. Let extensibleTarget be ? IsExtensible(target).
|
| + Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
|
| + if (maybe_extensible.IsNothing()) return false;
|
| + bool extensible_target = maybe_extensible.FromJust();
|
| + // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
|
| + if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj,
|
| + desc)) {
|
| + DCHECK(isolate->has_pending_exception());
|
| + return false;
|
| + }
|
| + // 14. Call CompletePropertyDescriptor(resultDesc).
|
| + PropertyDescriptor::CompletePropertyDescriptor(isolate, desc);
|
| + // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget,
|
| + // resultDesc, targetDesc).
|
| + bool valid = IsCompatiblePropertyDescriptor(extensible_target, desc,
|
| + &target_desc, property_name);
|
| + // 16. If valid is false, throw a TypeError exception.
|
| + if (!valid) {
|
| + DCHECK(isolate->has_pending_exception());
|
| + return false;
|
| + }
|
| + // 17. If resultDesc.[[Configurable]] is false, then
|
| + if (!desc->configurable()) {
|
| + // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true:
|
| + if (target_desc.is_empty() || target_desc.configurable()) {
|
| + // 17a i. Throw a TypeError exception.
|
| + isolate->Throw(*isolate->factory()->NewTypeError(
|
| + MessageTemplate::kRedefineDisallowed, property_name));
|
| + return false;
|
| + }
|
| + }
|
| + // 18. Return resultDesc.
|
| + return true;
|
| +}
|
| +
|
| +
|
| bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
|
| ElementsKind kind,
|
| Object* object) {
|
|
|