11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/builtins/builtins-utils-inl.h"
61cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h"
71cb0ef41Sopenharmony_ci#include "src/logging/counters.h"
81cb0ef41Sopenharmony_ci#include "src/objects/keys.h"
91cb0ef41Sopenharmony_ci#include "src/objects/lookup.h"
101cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
111cb0ef41Sopenharmony_ci#include "src/objects/property-descriptor.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace internal {
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci// -----------------------------------------------------------------------------
171cb0ef41Sopenharmony_ci// ES6 section 26.1 The Reflect Object
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci// ES6 section 26.1.3 Reflect.defineProperty
201cb0ef41Sopenharmony_ciBUILTIN(ReflectDefineProperty) {
211cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
221cb0ef41Sopenharmony_ci  DCHECK_LE(4, args.length());
231cb0ef41Sopenharmony_ci  Handle<Object> target = args.at(1);
241cb0ef41Sopenharmony_ci  Handle<Object> key = args.at(2);
251cb0ef41Sopenharmony_ci  Handle<Object> attributes = args.at(3);
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci  if (!target->IsJSReceiver()) {
281cb0ef41Sopenharmony_ci    THROW_NEW_ERROR_RETURN_FAILURE(
291cb0ef41Sopenharmony_ci        isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
301cb0ef41Sopenharmony_ci                              isolate->factory()->NewStringFromAsciiChecked(
311cb0ef41Sopenharmony_ci                                  "Reflect.defineProperty")));
321cb0ef41Sopenharmony_ci  }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  Handle<Name> name;
351cb0ef41Sopenharmony_ci  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
361cb0ef41Sopenharmony_ci                                     Object::ToName(isolate, key));
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  PropertyDescriptor desc;
391cb0ef41Sopenharmony_ci  if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
401cb0ef41Sopenharmony_ci    return ReadOnlyRoots(isolate).exception();
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  Maybe<bool> result = JSReceiver::DefineOwnProperty(
441cb0ef41Sopenharmony_ci      isolate, Handle<JSReceiver>::cast(target), name, &desc, Just(kDontThrow));
451cb0ef41Sopenharmony_ci  MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
461cb0ef41Sopenharmony_ci  return *isolate->factory()->ToBoolean(result.FromJust());
471cb0ef41Sopenharmony_ci}
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci// ES6 section 26.1.7 Reflect.getOwnPropertyDescriptor
501cb0ef41Sopenharmony_ciBUILTIN(ReflectGetOwnPropertyDescriptor) {
511cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
521cb0ef41Sopenharmony_ci  DCHECK_LE(3, args.length());
531cb0ef41Sopenharmony_ci  Handle<Object> target = args.at(1);
541cb0ef41Sopenharmony_ci  Handle<Object> key = args.at(2);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  if (!target->IsJSReceiver()) {
571cb0ef41Sopenharmony_ci    THROW_NEW_ERROR_RETURN_FAILURE(
581cb0ef41Sopenharmony_ci        isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
591cb0ef41Sopenharmony_ci                              isolate->factory()->NewStringFromAsciiChecked(
601cb0ef41Sopenharmony_ci                                  "Reflect.getOwnPropertyDescriptor")));
611cb0ef41Sopenharmony_ci  }
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  Handle<Name> name;
641cb0ef41Sopenharmony_ci  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
651cb0ef41Sopenharmony_ci                                     Object::ToName(isolate, key));
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  PropertyDescriptor desc;
681cb0ef41Sopenharmony_ci  Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor(
691cb0ef41Sopenharmony_ci      isolate, Handle<JSReceiver>::cast(target), name, &desc);
701cb0ef41Sopenharmony_ci  MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
711cb0ef41Sopenharmony_ci  if (!found.FromJust()) return ReadOnlyRoots(isolate).undefined_value();
721cb0ef41Sopenharmony_ci  return *desc.ToObject(isolate);
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci// ES6 section 26.1.11 Reflect.ownKeys
761cb0ef41Sopenharmony_ciBUILTIN(ReflectOwnKeys) {
771cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
781cb0ef41Sopenharmony_ci  DCHECK_LE(2, args.length());
791cb0ef41Sopenharmony_ci  Handle<Object> target = args.at(1);
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  if (!target->IsJSReceiver()) {
821cb0ef41Sopenharmony_ci    THROW_NEW_ERROR_RETURN_FAILURE(
831cb0ef41Sopenharmony_ci        isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
841cb0ef41Sopenharmony_ci                              isolate->factory()->NewStringFromAsciiChecked(
851cb0ef41Sopenharmony_ci                                  "Reflect.ownKeys")));
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  Handle<FixedArray> keys;
891cb0ef41Sopenharmony_ci  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
901cb0ef41Sopenharmony_ci      isolate, keys,
911cb0ef41Sopenharmony_ci      KeyAccumulator::GetKeys(Handle<JSReceiver>::cast(target),
921cb0ef41Sopenharmony_ci                              KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
931cb0ef41Sopenharmony_ci                              GetKeysConversion::kConvertToString));
941cb0ef41Sopenharmony_ci  return *isolate->factory()->NewJSArrayWithElements(keys);
951cb0ef41Sopenharmony_ci}
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci// ES6 section 26.1.13 Reflect.set
981cb0ef41Sopenharmony_ciBUILTIN(ReflectSet) {
991cb0ef41Sopenharmony_ci  HandleScope scope(isolate);
1001cb0ef41Sopenharmony_ci  Handle<Object> target = args.atOrUndefined(isolate, 1);
1011cb0ef41Sopenharmony_ci  Handle<Object> key = args.atOrUndefined(isolate, 2);
1021cb0ef41Sopenharmony_ci  Handle<Object> value = args.atOrUndefined(isolate, 3);
1031cb0ef41Sopenharmony_ci  Handle<Object> receiver = args.length() > 4 ? args.at(4) : target;
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  if (!target->IsJSReceiver()) {
1061cb0ef41Sopenharmony_ci    THROW_NEW_ERROR_RETURN_FAILURE(
1071cb0ef41Sopenharmony_ci        isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
1081cb0ef41Sopenharmony_ci                              isolate->factory()->NewStringFromAsciiChecked(
1091cb0ef41Sopenharmony_ci                                  "Reflect.set")));
1101cb0ef41Sopenharmony_ci  }
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci  Handle<Name> name;
1131cb0ef41Sopenharmony_ci  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
1141cb0ef41Sopenharmony_ci                                     Object::ToName(isolate, key));
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci  PropertyKey lookup_key(isolate, name);
1171cb0ef41Sopenharmony_ci  LookupIterator it(isolate, receiver, lookup_key,
1181cb0ef41Sopenharmony_ci                    Handle<JSReceiver>::cast(target));
1191cb0ef41Sopenharmony_ci  Maybe<bool> result = Object::SetSuperProperty(
1201cb0ef41Sopenharmony_ci      &it, value, StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kDontThrow));
1211cb0ef41Sopenharmony_ci  MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
1221cb0ef41Sopenharmony_ci  return *isolate->factory()->ToBoolean(result.FromJust());
1231cb0ef41Sopenharmony_ci}
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci}  // namespace internal
1261cb0ef41Sopenharmony_ci}  // namespace v8
127