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

    try {
      // 2. Let handler be O.[[ProxyHandler]].
      // 3. If handler is null, throw a TypeError exception.
      // 4. Assert: Type(handler) is Object.
      assert(proxy.handler == Null || Is<JSReceiver>(proxy.handler));
      const handler =
          Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked;

      // 5. Let target be O.[[ProxyTarget]].
      const target = UnsafeCast<JSReceiver>(proxy.target);

      // 6. Let trap be ? GetMethod(handler, "set").
      // 7. If trap is undefined, then (see 7.a below).
      const trap: Callable = GetMethod(handler, '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, handler, target, name, value, receiverValue);
      if (BranchIfToBooleanIsTrue(trapResult)) {
        CheckGetSetTrapResult(target, proxy, name, value, kProxySet);
        return value;
      }
      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 {
      ThrowTypeError(kProxyRevoked, 'set');
    }
  }
}
