// 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 runtime {
  extern transitioning runtime
  ObjectIsExtensible(implicit context: Context)(Object): Object;

  extern transitioning runtime
  JSReceiverPreventExtensionsThrow(implicit context: Context)(JSReceiver):
      Object;

  extern transitioning runtime
  JSReceiverPreventExtensionsDontThrow(implicit context: Context)(JSReceiver):
      Object;

  extern transitioning runtime
  JSReceiverGetPrototypeOf(implicit context: Context)(JSReceiver): Object;

  extern transitioning runtime
  JSReceiverSetPrototypeOfThrow(implicit context: Context)(JSReceiver, Object):
      Object;

  extern transitioning runtime
  JSReceiverSetPrototypeOfDontThrow(implicit context:
                                        Context)(JSReceiver, Object): Object;
}  // namespace runtime

namespace object {
  transitioning macro
  ObjectIsExtensible(implicit context: Context)(object: Object): Object {
    const objectJSReceiver = Cast<JSReceiver>(object) otherwise return False;
    const objectJSProxy = Cast<JSProxy>(objectJSReceiver)
        otherwise return runtime::ObjectIsExtensible(objectJSReceiver);
    return proxy::ProxyIsExtensible(objectJSProxy);
  }

  transitioning macro
  ObjectPreventExtensionsThrow(implicit context: Context)(object: Object):
      Object {
    const objectJSReceiver = Cast<JSReceiver>(object) otherwise return object;
    const objectJSProxy = Cast<JSProxy>(objectJSReceiver)
        otherwise return runtime::JSReceiverPreventExtensionsThrow(
        objectJSReceiver);
    proxy::ProxyPreventExtensions(objectJSProxy, True);
    return objectJSReceiver;
  }

  transitioning macro
  ObjectPreventExtensionsDontThrow(implicit context: Context)(object: Object):
      Object {
    const objectJSReceiver = Cast<JSReceiver>(object) otherwise return False;
    const objectJSProxy = Cast<JSProxy>(objectJSReceiver)
        otherwise return runtime::JSReceiverPreventExtensionsDontThrow(
        objectJSReceiver);
    return proxy::ProxyPreventExtensions(objectJSProxy, False);
  }

  transitioning macro
  ObjectGetPrototypeOf(implicit context: Context)(object: Object): Object {
    const objectJSReceiver: JSReceiver = ToObject_Inline(context, object);
    return object::JSReceiverGetPrototypeOf(objectJSReceiver);
  }

  transitioning macro
  JSReceiverGetPrototypeOf(implicit context: Context)(object: JSReceiver):
      Object {
    const objectJSProxy = Cast<JSProxy>(object)
        otherwise return runtime::JSReceiverGetPrototypeOf(object);
    return proxy::ProxyGetPrototypeOf(objectJSProxy);
  }

  transitioning macro
  ObjectSetPrototypeOfThrow(implicit context: Context)(
      object: Object, proto: Object): Object {
    const objectJSReceiver = Cast<JSReceiver>(object) otherwise return object;
    const objectJSProxy = Cast<JSProxy>(objectJSReceiver)
        otherwise return runtime::JSReceiverSetPrototypeOfThrow(
        objectJSReceiver, proto);
    proxy::ProxySetPrototypeOf(objectJSProxy, proto, True);
    return objectJSReceiver;
  }

  transitioning macro
  ObjectSetPrototypeOfDontThrow(implicit context: Context)(
      object: Object, proto: Object): Object {
    const objectJSReceiver = Cast<JSReceiver>(object) otherwise return False;
    const objectJSProxy = Cast<JSProxy>(objectJSReceiver)
        otherwise return runtime::JSReceiverSetPrototypeOfDontThrow(
        objectJSReceiver, proto);
    return proxy::ProxySetPrototypeOf(objectJSProxy, proto, False);
  }
}  // namespace object

namespace object_isextensible {
  // ES6 section 19.1.2.11 Object.isExtensible ( O )
  transitioning javascript builtin ObjectIsExtensible(
      js-implicit context: Context)(_receiver: Object, object: Object): Object {
    return object::ObjectIsExtensible(object);
  }
}  // namespace object_isextensible

namespace object_preventextensions {
  // ES6 section 19.1.2.11 Object.isExtensible ( O )
  transitioning javascript builtin ObjectPreventExtensions(
      js-implicit context: Context)(_receiver: Object, object: Object): Object {
    return object::ObjectPreventExtensionsThrow(object);
  }
}  // namespace object_preventextensions

namespace object_getprototypeof {
  // ES6 section 19.1.2.9 Object.getPrototypeOf ( O )
  transitioning javascript builtin ObjectGetPrototypeOf(
      js-implicit context: Context)(_receiver: Object, object: Object): Object {
    return object::ObjectGetPrototypeOf(object);
  }
}  // namespace object_getprototypeof

namespace object_setprototypeof {
  // ES6 section 19.1.2.21 Object.setPrototypeOf ( O, proto )
  transitioning javascript builtin ObjectSetPrototypeOf(
      js-implicit context:
          Context)(_receiver: Object, object: Object, proto: Object): Object {
    // 1. Set O to ? RequireObjectCoercible(O).
    RequireObjectCoercible(object, 'Object.setPrototypeOf');

    // 2. If Type(proto) is neither Object nor Null, throw a TypeError
    // exception.
    // 3. If Type(O) is not Object, return O.
    // 4. Let status be ? O.[[SetPrototypeOf]](proto).
    // 5. If status is false, throw a TypeError exception.
    // 6. Return O.
    if (proto == Null || Is<JSReceiver>(proto)) {
      return object::ObjectSetPrototypeOfThrow(object, proto);
    }
    ThrowTypeError(kProtoObjectOrNull, proto);
  }
}  // namespace object_setprototypeof
