// 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 runtime {
extern transitioning runtime ToString(Context, BigInt): String;
}

extern enum OrdinaryToPrimitiveHint { kString, kNumber }

extern macro OrdinaryToPrimitive(implicit context: Context)(
    JSAny, constexpr OrdinaryToPrimitiveHint): JSPrimitive;

namespace conversion {

builtin StringToNumber(implicit context: Context)(input: String): Number {
  return ::StringToNumber(input);
}

transitioning builtin NonNumberToNumber(implicit context: Context)(
    input: JSAnyNotNumber): Number {
  return ::NonNumberToNumber(input);
}

transitioning builtin NonNumberToNumeric(implicit context: Context)(
    input: JSAnyNotNumber): Numeric {
  return ::NonNumberToNumeric(input);
}

transitioning builtin ToNumeric(implicit context: Context)(input: JSAny):
    Numeric {
  typeswitch (input) {
    case (n: Number): {
      return n;
    }
    case (h: JSAnyNotNumber): {
      return conversion::NonNumberToNumeric(h);
    }
  }
}

// ES section #sec-tostring-applied-to-the-number-type
builtin NumberToString(implicit context: Context)(input: Number): String {
  return ::NumberToString(input);
}

// ES6 section 7.1.2 ToBoolean ( argument )
builtin ToBoolean(implicit context: Context)(input: JSAny): Boolean {
  BranchIfToBooleanIsTrue(input) otherwise return TrueConstant(),
      return FalseConstant();
}

transitioning builtin ToLength(implicit context: Context)(input: JSAny):
    Number {
  // We might need to loop once for ToNumber conversion.
  let x: JSAny = input;
  while (true) {
    typeswitch (x) {
      case (s: Smi): {
        if (s < 0) return 0;
        return s;
      }
      case (h: HeapNumber): {
        let value: float64 = Convert<float64>(h);
        // The sense of this test is important for the NaN and -0 cases.
        if (!(value > 0)) return 0;
        if (value > kMaxSafeInteger) return kMaxSafeInteger;
        value = math::Float64Floor(value);
        return ChangeFloat64ToTagged(value);
      }
      case (h: JSAnyNotNumber): {
        x = ::NonNumberToNumber(h);
      }
    }
  }
  VerifiedUnreachable();
}

transitioning builtin ToName(implicit context: Context)(input: JSAny): Name {
  // We might need to loop once for ToNumber conversion.
  let x: JSAny = input;
  while (true) {
    typeswitch (x) {
      case (n: Name): {
        return n;
      }
      case (n: Number): {
        return ::NumberToString(n);
      }
      case (b: BigInt): {
        // We don't have a fast-path for BigInt currently, so just
        // tail call to the %ToString runtime function here for now.
        tail runtime::ToString(context, b);
      }
      case (o: Oddball): {
        return o.to_string;
      }
      case (o: JSReceiver): {
        x = NonPrimitiveToPrimitive_String(o);
      }
    }
  }
  VerifiedUnreachable();
}

const kNoConstructorFunctionIndex:
    constexpr int31 generates 'Map::kNoConstructorFunctionIndex';

// ES6 section 7.1.13 ToObject (argument)
transitioning builtin ToObject(implicit context: Context)(input: JSAny):
    JSReceiver {
  try {
    typeswitch (input) {
      case (Smi): {
        goto WrapPrimitive(ContextSlot::NUMBER_FUNCTION_INDEX);
      }
      case (o: JSReceiver): {
        return o;
      }
      case (o: JSAnyNotSmi): {
        const index: intptr = Convert<intptr>(
            o.map.in_object_properties_start_or_constructor_function_index);
        if (index != kNoConstructorFunctionIndex)
          goto WrapPrimitive(
              %RawDownCast<Slot<NativeContext, JSFunction>>(index));
        ThrowTypeError(MessageTemplate::kUndefinedOrNullToObject, 'ToObject');
      }
    }
  } label WrapPrimitive(constructorIndex: Slot<NativeContext, JSFunction>) {
    const constructor = *NativeContextSlot(constructorIndex);
    const map: Map = UnsafeCast<Map>(constructor.prototype_or_initial_map);
    const wrapper =
        UnsafeCast<JSPrimitiveWrapper>(AllocateFastOrSlowJSObjectFromMap(map));
    wrapper.value = input;
    return wrapper;
  }
}

// ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] )

transitioning macro TryGetExoticToPrimitive(implicit context: Context)(
    input: JSAny): JSAny labels OrdinaryToPrimitive {
  // Look up the @@toPrimitive property.
  const exoticToPrimitive: JSAny =
      GetProperty(input, ToPrimitiveSymbolConstant());
  if (IsNullOrUndefined(exoticToPrimitive)) goto OrdinaryToPrimitive;
  return exoticToPrimitive;
}

transitioning macro CallExoticToPrimitive(implicit context: Context)(
    input: JSAny, exoticToPrimitive: JSAny, hint: String): JSPrimitive {
  // Invoke the exoticToPrimitive method on the input with a string
  // representation of the hint.
  const result: JSAny = Call(context, exoticToPrimitive, input, hint);

  // Verify that the result is primitive.
  typeswitch (result) {
    case (o: JSPrimitive): {
      return o;
    }
    case (JSReceiver): {
      // Somehow the @@toPrimitive method on input didn't yield a primitive.
      ThrowTypeError(MessageTemplate::kCannotConvertToPrimitive);
    }
  }
}

transitioning builtin NonPrimitiveToPrimitive_Default(
    implicit context: Context)(input: JSReceiver): JSPrimitive {
  const exoticToPrimitive: JSAny = TryGetExoticToPrimitive(input)
      otherwise return OrdinaryToPrimitive_Number(input);
  return CallExoticToPrimitive(
      input, exoticToPrimitive, DefaultStringConstant());
}

transitioning builtin NonPrimitiveToPrimitive_Number(implicit context: Context)(
    input: JSReceiver): JSPrimitive {
  const exoticToPrimitive: JSAny = TryGetExoticToPrimitive(input)
      otherwise return OrdinaryToPrimitive_Number(input);
  return CallExoticToPrimitive(
      input, exoticToPrimitive, NumberStringConstant());
}

transitioning builtin NonPrimitiveToPrimitive_String(implicit context: Context)(
    input: JSReceiver): JSPrimitive {
  const exoticToPrimitive: JSAny = TryGetExoticToPrimitive(input)
      otherwise return OrdinaryToPrimitive_String(input);
  return CallExoticToPrimitive(
      input, exoticToPrimitive, StringStringConstant());
}

// 7.1.1.1 OrdinaryToPrimitive ( O, hint )

transitioning macro TryToPrimitiveMethod(implicit context: Context)(
    input: JSAny, name: String): JSPrimitive labels Continue {
  const method: JSAny = GetProperty(input, name);
  typeswitch (method) {
    case (Callable): {
      const value: JSAny = Call(context, method, input);
      return Cast<JSPrimitive>(value) otherwise Continue;
    }
    case (JSAny): {
      goto Continue;
    }
  }
}

transitioning builtin OrdinaryToPrimitive_Number(implicit context: Context)(
    input: JSAny): JSPrimitive {
  try {
    return TryToPrimitiveMethod(input, ValueOfStringConstant())
        otherwise String;
  } label String {
    return TryToPrimitiveMethod(input, ToStringStringConstant())
        otherwise Throw;
  } label Throw {
    ThrowTypeError(MessageTemplate::kCannotConvertToPrimitive);
  }
}

transitioning builtin OrdinaryToPrimitive_String(implicit context: Context)(
    input: JSAny): JSPrimitive {
  try {
    return TryToPrimitiveMethod(input, ToStringStringConstant())
        otherwise String;
  } label String {
    return TryToPrimitiveMethod(input, ValueOfStringConstant()) otherwise Throw;
  } label Throw {
    ThrowTypeError(MessageTemplate::kCannotConvertToPrimitive);
  }
}

}  // namespace conversion
