// 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;
}  // 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);
    return proxy::ProxyPreventExtensions(objectJSProxy, True);
  }

  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);
  }
}  // 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