// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

namespace reflect {

  const kCalledOnNonObject: constexpr MessageTemplate
  generates 'MessageTemplate::kCalledOnNonObject';

  // ES6 section 26.1.10 Reflect.isExtensible
  transitioning javascript builtin ReflectIsExtensible(
      js-implicit context: Context)(_receiver: Object, object: Object): Object {
    const objectJSReceiver = Cast<JSReceiver>(object)
        otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.isExtensible');
    return object::ObjectIsExtensible(objectJSReceiver);
  }

  // ES6 section 26.1.12 Reflect.preventExtensions
  transitioning javascript builtin ReflectPreventExtensions(
      js-implicit context: Context)(_receiver: Object, object: Object): Object {
    const objectJSReceiver = Cast<JSReceiver>(object)
        otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.preventExtensions');
    return object::ObjectPreventExtensionsDontThrow(objectJSReceiver);
  }

  // ES6 section 26.1.8 Reflect.getPrototypeOf
  transitioning javascript builtin ReflectGetPrototypeOf(
      js-implicit context: Context)(_receiver: Object, object: Object): Object {
    const objectJSReceiver = Cast<JSReceiver>(object)
        otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.getPrototypeOf');
    return object::JSReceiverGetPrototypeOf(objectJSReceiver);
  }

  // ES6 section 26.1.14 Reflect.setPrototypeOf
  transitioning javascript builtin ReflectSetPrototypeOf(
      js-implicit context:
          Context)(_receiver: Object, object: Object, proto: Object): Object {
    const objectJSReceiver = Cast<JSReceiver>(object)
        otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.setPrototypeOf');
    if (proto == Null || Is<JSReceiver>(proto)) {
      return object::ObjectSetPrototypeOfDontThrow(objectJSReceiver, proto);
    }
    ThrowTypeError(kProtoObjectOrNull, proto);
  }

  extern transitioning builtin ToName(implicit context: Context)(Object): Name;
  type OnNonExistent constexpr 'OnNonExistent';
  const kReturnUndefined: constexpr OnNonExistent
  generates 'OnNonExistent::kReturnUndefined';
  extern macro SmiConstant(constexpr OnNonExistent): Smi;
  extern transitioning builtin GetPropertyWithReceiver(
      implicit context: Context)(Object, Name, Object, Smi): Object;

  // ES6 section 26.1.6 Reflect.get
  transitioning javascript builtin
  ReflectGet(js-implicit context: Context)(...arguments): Object {
    const length = arguments.length;
    const object: Object = length > 0 ? arguments[0] : Undefined;
    const objectJSReceiver = Cast<JSReceiver>(object)
        otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.get');
    const propertyKey: Object = length > 1 ? arguments[1] : Undefined;
    const name: Name = ToName(propertyKey);
    const receiver: Object = length > 2 ? arguments[2] : objectJSReceiver;
    return GetPropertyWithReceiver(
        objectJSReceiver, name, receiver, SmiConstant(kReturnUndefined));
  }

  // ES6 section 26.1.4 Reflect.deleteProperty
  transitioning javascript builtin ReflectDeleteProperty(
      js-implicit context:
          Context)(_receiver: Object, object: Object, key: Object): Object {
    const objectJSReceiver = Cast<JSReceiver>(object)
        otherwise ThrowTypeError(kCalledOnNonObject, 'Reflect.deleteProperty');
    const name: Name = ToName(key);
    if (IsPrivateSymbol(name)) {
      return DeleteProperty(objectJSReceiver, name, kSloppy);
    }
    const proxy = Cast<JSProxy>(objectJSReceiver)
        otherwise return DeleteProperty(objectJSReceiver, name, kSloppy);
    return proxy::ProxyDeleteProperty(proxy, name, kSloppy);
  }
}  // namespace reflect
