// Copyright 2020 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 function {

extern macro OrdinaryHasInstance(Context, Object, Object): JSAny;

// ES6 section 19.2.3.6 Function.prototype[@@hasInstance]
javascript builtin FunctionPrototypeHasInstance(
    js-implicit context: NativeContext, receiver: JSAny)(value: JSAny): JSAny {
  return OrdinaryHasInstance(context, receiver, value);
}

extern transitioning builtin
FunctionPrototypeBind(implicit context: Context)(
    JSFunction, JSAny, int32): JSAny;

const kLengthDescriptorIndex:
    constexpr int32 generates 'JSFunction::kLengthDescriptorIndex';
const kNameDescriptorIndex:
    constexpr int32 generates 'JSFunction::kNameDescriptorIndex';
const kMinDescriptorsForFastBind:
    constexpr int31 generates 'JSFunction::kMinDescriptorsForFastBind';

macro CheckAccessor(implicit context: Context)(
    array: DescriptorArray, index: constexpr int32, name: Name) labels Slow {
  const descriptor: DescriptorEntry = array.descriptors[index];
  const key: Name|Undefined = descriptor.key;
  if (!TaggedEqual(key, name)) goto Slow;

  // The descriptor value must be an AccessorInfo.
  Cast<AccessorInfo>(descriptor.value) otherwise goto Slow;
}

// ES6 section 19.2.3.2 Function.prototype.bind
transitioning javascript builtin
FastFunctionPrototypeBind(
    js-implicit context: NativeContext, receiver: JSAny, newTarget: JSAny,
    target: JSFunction)(...arguments): JSAny {
  const argc: intptr = arguments.length;
  try {
    typeswitch (receiver) {
      case (fn: JSFunction|JSBoundFunction): {
        // Disallow binding of slow-mode functions. We need to figure out
        // whether the length and name property are in the original state.
        Comment('Disallow binding of slow-mode functions');
        if (IsDictionaryMap(fn.map)) goto Slow;

        // Check whether the length and name properties are still present as
        // AccessorInfo objects. If so, their value can be recomputed even if
        // the actual value on the object changes.

        if (fn.map.bit_field3.number_of_own_descriptors <
            kMinDescriptorsForFastBind) {
          goto Slow;
        }

        const descriptors: DescriptorArray = fn.map.instance_descriptors;
        CheckAccessor(
            descriptors, kLengthDescriptorIndex, LengthStringConstant())
            otherwise Slow;
        CheckAccessor(descriptors, kNameDescriptorIndex, NameStringConstant())
            otherwise Slow;

        // Choose the right bound function map based on whether the target is
        // constructable.

        const boundFunctionMap: Map =
            IsConstructor(fn) ?
            *NativeContextSlot(
                ContextSlot::BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX) :
            *NativeContextSlot(ContextSlot::
                                    BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX);

        // Verify that prototype matches that of the target bound function.

        if (fn.map.prototype != boundFunctionMap.prototype) goto Slow;

        // Allocate the arguments array.

        const argumentsArray = arguments.length <= 1 ?
            kEmptyFixedArray :
            NewFixedArray(
                arguments.length - 1, ArgumentsIterator{arguments, current: 1});

        const boundReceiver: JSAny = arguments[0];

        const result = new JSBoundFunction{
          map: boundFunctionMap,
          properties_or_hash: kEmptyFixedArray,
          elements: kEmptyFixedArray,
          bound_target_function: fn,
          bound_this: boundReceiver,
          bound_arguments: argumentsArray
        };
        return result;
      }

      case (JSAny): {
        goto Slow;
      }
    }
  } label Slow {
    tail FunctionPrototypeBind(
        LoadTargetFromFrame(), newTarget, Convert<int32>(argc));
  }
}
}  // namespace function
