// 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.

#include 'src/builtins/builtins-proxy-gen.h'

namespace proxy {

  extern transitioning runtime
  SetPropertyWithReceiver(implicit context:
                              Context)(Object, Name, Object, Object): void;

  transitioning macro CallThrowTypeErrorIfStrict(implicit context: Context)(
      message: constexpr MessageTemplate) {
    ThrowTypeErrorIfStrict(SmiConstant(message), Null, Null);
  }

  // ES #sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
  // https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
  transitioning builtin
  ProxySetProperty(implicit context: Context)(
      proxy: JSProxy, name: Name, value: Object,
      receiverValue: Object): Object {
    // 1. Assert: IsPropertyKey(P) is true.
    assert(TaggedIsNotSmi(name));
    assert(IsName(name));

    if (IsPrivateSymbol(name)) {
      CallThrowTypeErrorIfStrict(kProxyPrivate);
      return Undefined;
    }

    // 2. Let handler be O.[[ProxyHandler]].
    const handler: Object = proxy.handler;

    try {
      // 3. If handler is null, throw a TypeError exception.
      // 4. Assert: Type(handler) is Object.
      const handlerJSReceiver =
          Cast<JSReceiver>(handler) otherwise ThrowProxyHandlerRevoked;

      // 5. Let target be O.[[ProxyTarget]].
      const target = proxy.target;

      // 6. Let trap be ? GetMethod(handler, "set").
      // 7. If trap is undefined, then (see 7.a below).
      const trap: Callable = GetMethod(handlerJSReceiver, 'set')
          otherwise goto TrapUndefined(target);

      // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler,
      // « target, P, V, Receiver »)).
      // 9. If booleanTrapResult is false, return false.
      // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
      // 11. If targetDesc is not undefined and targetDesc.[[Configurable]] is
      // false, then
      //    a. If IsDataDescriptor(targetDesc) is true and
      //    targetDesc.[[Writable]] is false, then
      //      i. If SameValue(V, targetDesc.[[Value]]) is false, throw a
      //      TypeError exception.
      //    b. If IsAccessorDescriptor(targetDesc) is true, then
      //      i. If targetDesc.[[Set]] is undefined, throw a TypeError
      //      exception.
      // 12. Return true.
      const trapResult = Call(
          context, trap, handlerJSReceiver, target, name, value, receiverValue);
      if (BranchIfToBooleanIsTrue(trapResult)) {
        return CheckGetSetTrapResult(
            target, proxy, name, trapResult, kProxySet);
      }
      ThrowTypeErrorIfStrict(
          SmiConstant(kProxyTrapReturnedFalsishFor), 'set', name);
      return value;
    }
    label TrapUndefined(target: Object) {
      // 7.a. Return ? target.[[Set]](P, V, Receiver).
      SetPropertyWithReceiver(target, name, value, receiverValue);
      return value;
    }
    label ThrowProxyHandlerRevoked deferred {
      assert(handler == Null);
      ThrowTypeError(kProxyRevoked, 'set');
    }
  }
}
