// Copyright 2014 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/codegen/code-factory.h"

#include "src/builtins/builtins-descriptors.h"
#include "src/ic/ic.h"
#include "src/init/bootstrapper.h"
#include "src/objects/allocation-site-inl.h"
#include "src/objects/objects-inl.h"

namespace v8 {
namespace internal {

// static
Handle<Code> CodeFactory::RuntimeCEntry(Isolate* isolate, int result_size) {
  return CodeFactory::CEntry(isolate, result_size);
}

#define CENTRY_CODE(RS, SD, AM, BE) \
  BUILTIN_CODE(isolate, CEntry_##RS##_##SD##_##AM##_##BE)

// static
Handle<Code> CodeFactory::CEntry(Isolate* isolate, int result_size,
                                 SaveFPRegsMode save_doubles,
                                 ArgvMode argv_mode, bool builtin_exit_frame) {
  // Aliases for readability below.
  const int rs = result_size;
  const SaveFPRegsMode sd = save_doubles;
  const ArgvMode am = argv_mode;
  const bool be = builtin_exit_frame;

  if (rs == 1 && sd == kDontSaveFPRegs && am == kArgvOnStack && !be) {
    return CENTRY_CODE(Return1, DontSaveFPRegs, ArgvOnStack, NoBuiltinExit);
  } else if (rs == 1 && sd == kDontSaveFPRegs && am == kArgvOnStack && be) {
    return CENTRY_CODE(Return1, DontSaveFPRegs, ArgvOnStack, BuiltinExit);
  } else if (rs == 1 && sd == kDontSaveFPRegs && am == kArgvInRegister && !be) {
    return CENTRY_CODE(Return1, DontSaveFPRegs, ArgvInRegister, NoBuiltinExit);
  } else if (rs == 1 && sd == kSaveFPRegs && am == kArgvOnStack && !be) {
    return CENTRY_CODE(Return1, SaveFPRegs, ArgvOnStack, NoBuiltinExit);
  } else if (rs == 1 && sd == kSaveFPRegs && am == kArgvOnStack && be) {
    return CENTRY_CODE(Return1, SaveFPRegs, ArgvOnStack, BuiltinExit);
  } else if (rs == 2 && sd == kDontSaveFPRegs && am == kArgvOnStack && !be) {
    return CENTRY_CODE(Return2, DontSaveFPRegs, ArgvOnStack, NoBuiltinExit);
  } else if (rs == 2 && sd == kDontSaveFPRegs && am == kArgvOnStack && be) {
    return CENTRY_CODE(Return2, DontSaveFPRegs, ArgvOnStack, BuiltinExit);
  } else if (rs == 2 && sd == kDontSaveFPRegs && am == kArgvInRegister && !be) {
    return CENTRY_CODE(Return2, DontSaveFPRegs, ArgvInRegister, NoBuiltinExit);
  } else if (rs == 2 && sd == kSaveFPRegs && am == kArgvOnStack && !be) {
    return CENTRY_CODE(Return2, SaveFPRegs, ArgvOnStack, NoBuiltinExit);
  } else if (rs == 2 && sd == kSaveFPRegs && am == kArgvOnStack && be) {
    return CENTRY_CODE(Return2, SaveFPRegs, ArgvOnStack, BuiltinExit);
  }

  UNREACHABLE();
}

#undef CENTRY_CODE

// static
Callable CodeFactory::ApiGetter(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kCallApiGetter);
}

// static
Callable CodeFactory::CallApiCallback(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kCallApiCallback);
}

// static
Callable CodeFactory::LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode) {
  return typeof_mode == NOT_INSIDE_TYPEOF
             ? Builtins::CallableFor(isolate, Builtins::kLoadGlobalICTrampoline)
             : Builtins::CallableFor(
                   isolate, Builtins::kLoadGlobalICInsideTypeofTrampoline);
}

// static
Callable CodeFactory::LoadGlobalICInOptimizedCode(Isolate* isolate,
                                                  TypeofMode typeof_mode) {
  return typeof_mode == NOT_INSIDE_TYPEOF
             ? Builtins::CallableFor(isolate, Builtins::kLoadGlobalIC)
             : Builtins::CallableFor(isolate,
                                     Builtins::kLoadGlobalICInsideTypeof);
}

Callable CodeFactory::StoreOwnIC(Isolate* isolate) {
  // TODO(ishell): Currently we use StoreOwnIC only for storing properties that
  // already exist in the boilerplate therefore we can use StoreIC.
  return Builtins::CallableFor(isolate, Builtins::kStoreICTrampoline);
}

Callable CodeFactory::StoreOwnICInOptimizedCode(Isolate* isolate) {
  // TODO(ishell): Currently we use StoreOwnIC only for storing properties that
  // already exist in the boilerplate therefore we can use StoreIC.
  return Builtins::CallableFor(isolate, Builtins::kStoreIC);
}

Callable CodeFactory::KeyedStoreIC_SloppyArguments(Isolate* isolate,
                                                   KeyedAccessStoreMode mode) {
  Builtins::Name builtin_index;
  switch (mode) {
    case STANDARD_STORE:
      builtin_index = Builtins::kKeyedStoreIC_SloppyArguments_Standard;
      break;
    case STORE_AND_GROW_HANDLE_COW:
      builtin_index =
          Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW;
      break;
    case STORE_IGNORE_OUT_OF_BOUNDS:
      builtin_index =
          Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB;
      break;
    case STORE_HANDLE_COW:
      builtin_index =
          Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW;
      break;
    default:
      UNREACHABLE();
  }
  return isolate->builtins()->CallableFor(isolate, builtin_index);
}

Callable CodeFactory::KeyedStoreIC_Slow(Isolate* isolate,
                                        KeyedAccessStoreMode mode) {
  Builtins::Name builtin_index;
  switch (mode) {
    case STANDARD_STORE:
      builtin_index = Builtins::kKeyedStoreIC_Slow_Standard;
      break;
    case STORE_AND_GROW_HANDLE_COW:
      builtin_index = Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW;
      break;
    case STORE_IGNORE_OUT_OF_BOUNDS:
      builtin_index = Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB;
      break;
    case STORE_HANDLE_COW:
      builtin_index = Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW;
      break;
    default:
      UNREACHABLE();
  }
  return isolate->builtins()->CallableFor(isolate, builtin_index);
}

Callable CodeFactory::StoreInArrayLiteralIC_Slow(Isolate* isolate,
                                                 KeyedAccessStoreMode mode) {
  Builtins::Name builtin_index;
  switch (mode) {
    case STANDARD_STORE:
      builtin_index = Builtins::kStoreInArrayLiteralIC_Slow_Standard;
      break;
    case STORE_AND_GROW_HANDLE_COW:
      builtin_index =
          Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW;
      break;
    case STORE_IGNORE_OUT_OF_BOUNDS:
      builtin_index =
          Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB;
      break;
    case STORE_HANDLE_COW:
      builtin_index =
          Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW;
      break;
    default:
      UNREACHABLE();
  }
  return isolate->builtins()->CallableFor(isolate, builtin_index);
}

Callable CodeFactory::ElementsTransitionAndStore(Isolate* isolate,
                                                 KeyedAccessStoreMode mode) {
  Builtins::Name builtin_index;
  switch (mode) {
    case STANDARD_STORE:
      builtin_index = Builtins::kElementsTransitionAndStore_Standard;
      break;
    case STORE_AND_GROW_HANDLE_COW:
      builtin_index =
          Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW;
      break;
    case STORE_IGNORE_OUT_OF_BOUNDS:
      builtin_index =
          Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB;
      break;
    case STORE_HANDLE_COW:
      builtin_index =
          Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW;
      break;
    default:
      UNREACHABLE();
  }
  return isolate->builtins()->CallableFor(isolate, builtin_index);
}

Callable CodeFactory::StoreFastElementIC(Isolate* isolate,
                                         KeyedAccessStoreMode mode) {
  Builtins::Name builtin_index;
  switch (mode) {
    case STANDARD_STORE:
      builtin_index = Builtins::kStoreFastElementIC_Standard;
      break;
    case STORE_AND_GROW_HANDLE_COW:
      builtin_index = Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW;
      break;
    case STORE_IGNORE_OUT_OF_BOUNDS:
      builtin_index = Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB;
      break;
    case STORE_HANDLE_COW:
      builtin_index = Builtins::kStoreFastElementIC_NoTransitionHandleCOW;
      break;
    default:
      UNREACHABLE();
  }
  return isolate->builtins()->CallableFor(isolate, builtin_index);
}

// static
Callable CodeFactory::BinaryOperation(Isolate* isolate, Operation op) {
  switch (op) {
    case Operation::kShiftRight:
      return Builtins::CallableFor(isolate, Builtins::kShiftRight);
    case Operation::kShiftLeft:
      return Builtins::CallableFor(isolate, Builtins::kShiftLeft);
    case Operation::kShiftRightLogical:
      return Builtins::CallableFor(isolate, Builtins::kShiftRightLogical);
    case Operation::kAdd:
      return Builtins::CallableFor(isolate, Builtins::kAdd);
    case Operation::kSubtract:
      return Builtins::CallableFor(isolate, Builtins::kSubtract);
    case Operation::kMultiply:
      return Builtins::CallableFor(isolate, Builtins::kMultiply);
    case Operation::kDivide:
      return Builtins::CallableFor(isolate, Builtins::kDivide);
    case Operation::kModulus:
      return Builtins::CallableFor(isolate, Builtins::kModulus);
    case Operation::kBitwiseOr:
      return Builtins::CallableFor(isolate, Builtins::kBitwiseOr);
    case Operation::kBitwiseAnd:
      return Builtins::CallableFor(isolate, Builtins::kBitwiseAnd);
    case Operation::kBitwiseXor:
      return Builtins::CallableFor(isolate, Builtins::kBitwiseXor);
    default:
      break;
  }
  UNREACHABLE();
}

// static
Callable CodeFactory::NonPrimitiveToPrimitive(Isolate* isolate,
                                              ToPrimitiveHint hint) {
  return Callable(isolate->builtins()->NonPrimitiveToPrimitive(hint),
                  TypeConversionDescriptor{});
}

// static
Callable CodeFactory::OrdinaryToPrimitive(Isolate* isolate,
                                          OrdinaryToPrimitiveHint hint) {
  return Callable(isolate->builtins()->OrdinaryToPrimitive(hint),
                  TypeConversionDescriptor{});
}

// static
Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags) {
  switch (flags) {
    case STRING_ADD_CHECK_NONE:
      return Builtins::CallableFor(isolate, Builtins::kStringAdd_CheckNone);
    case STRING_ADD_CONVERT_LEFT:
      return Builtins::CallableFor(isolate, Builtins::kStringAdd_ConvertLeft);
    case STRING_ADD_CONVERT_RIGHT:
      return Builtins::CallableFor(isolate, Builtins::kStringAdd_ConvertRight);
  }
  UNREACHABLE();
}

// static
Callable CodeFactory::ResumeGenerator(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kResumeGeneratorTrampoline);
}

// static
Callable CodeFactory::FrameDropperTrampoline(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kFrameDropperTrampoline);
}

// static
Callable CodeFactory::HandleDebuggerStatement(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kHandleDebuggerStatement);
}

// static
Callable CodeFactory::FastNewFunctionContext(Isolate* isolate,
                                             ScopeType scope_type) {
  switch (scope_type) {
    case ScopeType::EVAL_SCOPE:
      return Builtins::CallableFor(isolate,
                                   Builtins::kFastNewFunctionContextEval);
    case ScopeType::FUNCTION_SCOPE:
      return Builtins::CallableFor(isolate,
                                   Builtins::kFastNewFunctionContextFunction);
    default:
      UNREACHABLE();
  }
}

// static
Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kArgumentsAdaptorTrampoline);
}

// static
Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode) {
  return Callable(isolate->builtins()->Call(mode), CallTrampolineDescriptor{});
}

// static
Callable CodeFactory::CallWithArrayLike(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kCallWithArrayLike);
}

// static
Callable CodeFactory::CallWithSpread(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kCallWithSpread);
}

// static
Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) {
  return Callable(isolate->builtins()->CallFunction(mode),
                  CallTrampolineDescriptor{});
}

// static
Callable CodeFactory::CallVarargs(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kCallVarargs);
}

// static
Callable CodeFactory::CallForwardVarargs(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kCallForwardVarargs);
}

// static
Callable CodeFactory::CallFunctionForwardVarargs(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kCallFunctionForwardVarargs);
}

// static
Callable CodeFactory::Construct(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kConstruct);
}

// static
Callable CodeFactory::ConstructWithSpread(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kConstructWithSpread);
}

// static
Callable CodeFactory::ConstructFunction(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kConstructFunction);
}

// static
Callable CodeFactory::ConstructVarargs(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kConstructVarargs);
}

// static
Callable CodeFactory::ConstructForwardVarargs(Isolate* isolate) {
  return Builtins::CallableFor(isolate, Builtins::kConstructForwardVarargs);
}

// static
Callable CodeFactory::ConstructFunctionForwardVarargs(Isolate* isolate) {
  return Builtins::CallableFor(isolate,
                               Builtins::kConstructFunctionForwardVarargs);
}

// static
Callable CodeFactory::InterpreterPushArgsThenCall(
    Isolate* isolate, ConvertReceiverMode receiver_mode,
    InterpreterPushArgsMode mode) {
  switch (mode) {
    case InterpreterPushArgsMode::kArrayFunction:
      // There is no special-case handling of calls to Array. They will all go
      // through the kOther case below.
      UNREACHABLE();
    case InterpreterPushArgsMode::kWithFinalSpread:
      return Builtins::CallableFor(
          isolate, Builtins::kInterpreterPushArgsThenCallWithFinalSpread);
    case InterpreterPushArgsMode::kOther:
      switch (receiver_mode) {
        case ConvertReceiverMode::kNullOrUndefined:
          return Builtins::CallableFor(
              isolate, Builtins::kInterpreterPushUndefinedAndArgsThenCall);
        case ConvertReceiverMode::kNotNullOrUndefined:
        case ConvertReceiverMode::kAny:
          return Builtins::CallableFor(isolate,
                                       Builtins::kInterpreterPushArgsThenCall);
      }
  }
  UNREACHABLE();
}

// static
Callable CodeFactory::InterpreterPushArgsThenConstruct(
    Isolate* isolate, InterpreterPushArgsMode mode) {
  switch (mode) {
    case InterpreterPushArgsMode::kArrayFunction:
      return Builtins::CallableFor(
          isolate, Builtins::kInterpreterPushArgsThenConstructArrayFunction);
    case InterpreterPushArgsMode::kWithFinalSpread:
      return Builtins::CallableFor(
          isolate, Builtins::kInterpreterPushArgsThenConstructWithFinalSpread);
    case InterpreterPushArgsMode::kOther:
      return Builtins::CallableFor(isolate,
                                   Builtins::kInterpreterPushArgsThenConstruct);
  }
  UNREACHABLE();
}

// static
Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) {
  // Note: If we ever use fpregs in the interpreter then we will need to
  // save fpregs too.
  Handle<Code> code = CodeFactory::CEntry(isolate, result_size, kDontSaveFPRegs,
                                          kArgvInRegister);
  if (result_size == 1) {
    return Callable(code, InterpreterCEntry1Descriptor{});
  } else {
    DCHECK_EQ(result_size, 2);
    return Callable(code, InterpreterCEntry2Descriptor{});
  }
}

// static
Callable CodeFactory::InterpreterOnStackReplacement(Isolate* isolate) {
  return Builtins::CallableFor(isolate,
                               Builtins::kInterpreterOnStackReplacement);
}

// static
Callable CodeFactory::ArrayNoArgumentConstructor(
    Isolate* isolate, ElementsKind kind,
    AllocationSiteOverrideMode override_mode) {
#define CASE(kind_caps, kind_camel, mode_camel) \
  case kind_caps:                               \
    return Builtins::CallableFor(               \
        isolate,                                \
        Builtins::kArrayNoArgumentConstructor_##kind_camel##_##mode_camel);
  if (override_mode == DONT_OVERRIDE && AllocationSite::ShouldTrack(kind)) {
    DCHECK(IsSmiElementsKind(kind));
    switch (kind) {
      CASE(PACKED_SMI_ELEMENTS, PackedSmi, DontOverride);
      CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DontOverride);
      default:
        UNREACHABLE();
    }
  } else {
    DCHECK(override_mode == DISABLE_ALLOCATION_SITES ||
           !AllocationSite::ShouldTrack(kind));
    switch (kind) {
      CASE(PACKED_SMI_ELEMENTS, PackedSmi, DisableAllocationSites);
      CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DisableAllocationSites);
      CASE(PACKED_ELEMENTS, Packed, DisableAllocationSites);
      CASE(HOLEY_ELEMENTS, Holey, DisableAllocationSites);
      CASE(PACKED_DOUBLE_ELEMENTS, PackedDouble, DisableAllocationSites);
      CASE(HOLEY_DOUBLE_ELEMENTS, HoleyDouble, DisableAllocationSites);
      default:
        UNREACHABLE();
    }
  }
#undef CASE
}

// static
Callable CodeFactory::ArraySingleArgumentConstructor(
    Isolate* isolate, ElementsKind kind,
    AllocationSiteOverrideMode override_mode) {
#define CASE(kind_caps, kind_camel, mode_camel) \
  case kind_caps:                               \
    return Builtins::CallableFor(               \
        isolate,                                \
        Builtins::kArraySingleArgumentConstructor_##kind_camel##_##mode_camel)
  if (override_mode == DONT_OVERRIDE && AllocationSite::ShouldTrack(kind)) {
    DCHECK(IsSmiElementsKind(kind));
    switch (kind) {
      CASE(PACKED_SMI_ELEMENTS, PackedSmi, DontOverride);
      CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DontOverride);
      default:
        UNREACHABLE();
    }
  } else {
    DCHECK(override_mode == DISABLE_ALLOCATION_SITES ||
           !AllocationSite::ShouldTrack(kind));
    switch (kind) {
      CASE(PACKED_SMI_ELEMENTS, PackedSmi, DisableAllocationSites);
      CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DisableAllocationSites);
      CASE(PACKED_ELEMENTS, Packed, DisableAllocationSites);
      CASE(HOLEY_ELEMENTS, Holey, DisableAllocationSites);
      CASE(PACKED_DOUBLE_ELEMENTS, PackedDouble, DisableAllocationSites);
      CASE(HOLEY_DOUBLE_ELEMENTS, HoleyDouble, DisableAllocationSites);
      default:
        UNREACHABLE();
    }
  }
#undef CASE
}

}  // namespace internal
}  // namespace v8
