blob: 0194099e8c1de05b7663e16c600802c62548c26e [file] [log] [blame]
// Copyright 2023 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.
#ifndef V8_BUILTINS_BUILTINS_INL_H_
#define V8_BUILTINS_BUILTINS_INL_H_
#include "src/builtins/builtins.h"
#include "src/execution/isolate.h"
namespace v8 {
namespace internal {
// static
constexpr Builtin Builtins::RecordWrite(SaveFPRegsMode fp_mode) {
switch (fp_mode) {
case SaveFPRegsMode::kIgnore:
return Builtin::kRecordWriteIgnoreFP;
case SaveFPRegsMode::kSave:
return Builtin::kRecordWriteSaveFP;
}
}
// static
constexpr Builtin Builtins::IndirectPointerBarrier(SaveFPRegsMode fp_mode) {
switch (fp_mode) {
case SaveFPRegsMode::kIgnore:
return Builtin::kIndirectPointerBarrierIgnoreFP;
case SaveFPRegsMode::kSave:
return Builtin::kIndirectPointerBarrierSaveFP;
}
}
// static
constexpr Builtin Builtins::EphemeronKeyBarrier(SaveFPRegsMode fp_mode) {
switch (fp_mode) {
case SaveFPRegsMode::kIgnore:
return Builtin::kEphemeronKeyBarrierIgnoreFP;
case SaveFPRegsMode::kSave:
return Builtin::kEphemeronKeyBarrierSaveFP;
}
}
// static
constexpr Builtin Builtins::AdaptorWithBuiltinExitFrame(
int formal_parameter_count) {
switch (formal_parameter_count) {
case kDontAdaptArgumentsSentinel:
case JSParameterCount(0):
return Builtin::kAdaptorWithBuiltinExitFrame0;
case JSParameterCount(1):
return Builtin::kAdaptorWithBuiltinExitFrame1;
case JSParameterCount(2):
return Builtin::kAdaptorWithBuiltinExitFrame2;
case JSParameterCount(3):
return Builtin::kAdaptorWithBuiltinExitFrame3;
case JSParameterCount(4):
return Builtin::kAdaptorWithBuiltinExitFrame4;
case JSParameterCount(5):
return Builtin::kAdaptorWithBuiltinExitFrame5;
}
UNREACHABLE();
}
// static
constexpr Builtin Builtins::CallFunction(ConvertReceiverMode mode) {
switch (mode) {
case ConvertReceiverMode::kNullOrUndefined:
return Builtin::kCallFunction_ReceiverIsNullOrUndefined;
case ConvertReceiverMode::kNotNullOrUndefined:
return Builtin::kCallFunction_ReceiverIsNotNullOrUndefined;
case ConvertReceiverMode::kAny:
return Builtin::kCallFunction_ReceiverIsAny;
}
UNREACHABLE();
}
// static
constexpr Builtin Builtins::Call(ConvertReceiverMode mode) {
switch (mode) {
case ConvertReceiverMode::kNullOrUndefined:
return Builtin::kCall_ReceiverIsNullOrUndefined;
case ConvertReceiverMode::kNotNullOrUndefined:
return Builtin::kCall_ReceiverIsNotNullOrUndefined;
case ConvertReceiverMode::kAny:
return Builtin::kCall_ReceiverIsAny;
}
UNREACHABLE();
}
// static
constexpr bool Builtins::IsAnyCall(Builtin builtin) {
switch (builtin) {
case Builtin::kCallFunction_ReceiverIsNullOrUndefined:
case Builtin::kCallFunction_ReceiverIsNotNullOrUndefined:
case Builtin::kCallFunction_ReceiverIsAny:
case Builtin::kCall_ReceiverIsNullOrUndefined:
case Builtin::kCall_ReceiverIsNotNullOrUndefined:
case Builtin::kCall_ReceiverIsAny:
return true;
default:
return false;
}
}
// static
constexpr Builtin Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) {
switch (hint) {
case ToPrimitiveHint::kDefault:
return Builtin::kNonPrimitiveToPrimitive_Default;
case ToPrimitiveHint::kNumber:
return Builtin::kNonPrimitiveToPrimitive_Number;
case ToPrimitiveHint::kString:
return Builtin::kNonPrimitiveToPrimitive_String;
}
UNREACHABLE();
}
// static
constexpr Builtin Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) {
switch (hint) {
case OrdinaryToPrimitiveHint::kNumber:
return Builtin::kOrdinaryToPrimitive_Number;
case OrdinaryToPrimitiveHint::kString:
return Builtin::kOrdinaryToPrimitive_String;
}
UNREACHABLE();
}
// static
constexpr Builtin Builtins::StringAdd(StringAddFlags flags) {
switch (flags) {
case STRING_ADD_CHECK_NONE:
return Builtin::kStringAdd_CheckNone;
case STRING_ADD_CONVERT_LEFT:
return Builtin::kStringAddConvertLeft;
case STRING_ADD_CONVERT_RIGHT:
return Builtin::kStringAddConvertRight;
}
UNREACHABLE();
}
// static
constexpr Builtin Builtins::LoadGlobalIC(TypeofMode typeof_mode) {
return typeof_mode == TypeofMode::kNotInside
? Builtin::kLoadGlobalICTrampoline
: Builtin::kLoadGlobalICInsideTypeofTrampoline;
}
// static
constexpr Builtin Builtins::LoadGlobalICInOptimizedCode(
TypeofMode typeof_mode) {
return typeof_mode == TypeofMode::kNotInside
? Builtin::kLoadGlobalIC
: Builtin::kLoadGlobalICInsideTypeof;
}
// static
constexpr Builtin Builtins::CEntry(int result_size, ArgvMode argv_mode,
bool builtin_exit_frame,
bool switch_to_central_stack) {
// Aliases for readability below.
const int rs = result_size;
const ArgvMode am = argv_mode;
const bool be = builtin_exit_frame;
if (switch_to_central_stack) {
DCHECK_EQ(result_size, 1);
DCHECK_EQ(argv_mode, ArgvMode::kStack);
DCHECK_EQ(builtin_exit_frame, false);
return Builtin::kWasmCEntry;
}
if (rs == 1 && am == ArgvMode::kStack && !be) {
return Builtin::kCEntry_Return1_ArgvOnStack_NoBuiltinExit;
} else if (rs == 1 && am == ArgvMode::kStack && be) {
return Builtin::kCEntry_Return1_ArgvOnStack_BuiltinExit;
} else if (rs == 1 && am == ArgvMode::kRegister && !be) {
return Builtin::kCEntry_Return1_ArgvInRegister_NoBuiltinExit;
} else if (rs == 2 && am == ArgvMode::kStack && !be) {
return Builtin::kCEntry_Return2_ArgvOnStack_NoBuiltinExit;
} else if (rs == 2 && am == ArgvMode::kStack && be) {
return Builtin::kCEntry_Return2_ArgvOnStack_BuiltinExit;
} else if (rs == 2 && am == ArgvMode::kRegister && !be) {
return Builtin::kCEntry_Return2_ArgvInRegister_NoBuiltinExit;
}
UNREACHABLE();
}
// static
constexpr Builtin Builtins::RuntimeCEntry(int result_size,
bool switch_to_central_stack) {
return CEntry(result_size, ArgvMode::kStack, false, switch_to_central_stack);
}
// static
constexpr Builtin Builtins::InterpreterCEntry(int result_size) {
return CEntry(result_size, ArgvMode::kRegister);
}
// static
constexpr Builtin Builtins::InterpreterPushArgsThenCall(
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 Builtin::kInterpreterPushArgsThenCallWithFinalSpread;
case InterpreterPushArgsMode::kOther:
switch (receiver_mode) {
case ConvertReceiverMode::kNullOrUndefined:
return Builtin::kInterpreterPushUndefinedAndArgsThenCall;
case ConvertReceiverMode::kNotNullOrUndefined:
case ConvertReceiverMode::kAny:
return Builtin::kInterpreterPushArgsThenCall;
}
}
UNREACHABLE();
}
// static
constexpr Builtin Builtins::InterpreterPushArgsThenConstruct(
InterpreterPushArgsMode mode) {
switch (mode) {
case InterpreterPushArgsMode::kArrayFunction:
return Builtin::kInterpreterPushArgsThenConstructArrayFunction;
case InterpreterPushArgsMode::kWithFinalSpread:
return Builtin::kInterpreterPushArgsThenConstructWithFinalSpread;
case InterpreterPushArgsMode::kOther:
return Builtin::kInterpreterPushArgsThenConstruct;
}
UNREACHABLE();
}
// static
Address Builtins::EntryOf(Builtin builtin, Isolate* isolate) {
return isolate->builtin_entry_table()[Builtins::ToInt(builtin)];
}
// static
constexpr bool Builtins::IsJSEntryVariant(Builtin builtin) {
switch (builtin) {
case Builtin::kJSEntry:
case Builtin::kJSConstructEntry:
case Builtin::kJSRunMicrotasksEntry:
return true;
default:
return false;
}
UNREACHABLE();
}
// static
int Builtins::GetFormalParameterCount(Builtin builtin) {
CHECK(HasJSLinkage(builtin));
// TODO(saelo): consider merging GetFormalParameterCount and
// GetStackParameterCount into a single function.
if (Builtins::KindOf(builtin) == TSJ || Builtins::KindOf(builtin) == TFJ) {
return Builtins::GetStackParameterCount(builtin);
} else if (Builtins::KindOf(builtin) == ASM ||
Builtins::KindOf(builtin) == TFC) {
// At the moment, all ASM builtins are varargs builtins. This is verified
// in CheckFormalParameterCount.
return kDontAdaptArgumentsSentinel;
} else if (Builtins::KindOf(builtin) == CPP) {
#define CPP_BUILTIN(Name, Argc) \
case Builtin::k##Name: \
return Argc;
switch (builtin) {
BUILTIN_LIST_C(CPP_BUILTIN)
default:
UNREACHABLE();
}
#undef CPP_BUILTIN
} else {
UNREACHABLE();
}
}
} // namespace internal
} // namespace v8
#endif // V8_BUILTINS_BUILTINS_INL_H_