Revert "[fastcall] Enable float support on arm64 simulator"

This reverts commit b9ddcbc86f.

Reason for revert: Hits unreachable on MSAN, see https://bugs.chromium.org/p/chromium/issues/detail?id=1267854

Original change's description:
> [fastcall] Enable float support on arm64 simulator
>
> This CL adds support for handling calls to C functions with arbitrary
> signatures on the arm64 simulator. It adds infrastructure for
> encoding the signature data from CallDescriptor and FunctionInfo
> classes into a compact representation, stored in the simulator and
> called EncodedCSignature.
>
> Design doc:
> https://docs.google.com/document/d/1ZxOF3GSyNmtU0C0YJvrsydPJj35W_tTJZymeXwfDxoI/edit
>
> This CL is a follow up on the native support added in
> https://chromium-review.googlesource.com/c/v8/v8/+/3182232
> and is partially based on the previous attempt:
> https://chromium-review.googlesource.com/c/v8/v8/+/2343072
>
> Bug: chromium:1052746
> Change-Id: I0991b47bd644b2fc2244c5eb923b085261f04765
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3060486
> Commit-Queue: Maya Lekova <mslekova@chromium.org>
> Reviewed-by: Camillo Bruni <cbruni@chromium.org>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#77744}

Bug: chromium:1052746, chromium:1267854, chromium:1267841
Change-Id: If3d5aaab6b5f4309ce90add614d674aaa86b43c7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3268910
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77788}
This commit is contained in:
Maya Lekova 2021-11-09 12:06:01 +01:00 committed by V8 LUCI CQ
parent 47501f907e
commit 741b8d4071
23 changed files with 518 additions and 1424 deletions

View File

@ -2872,7 +2872,6 @@ v8_header_set("v8_internal_headers") {
"src/diagnostics/unwinder.h",
"src/execution/arguments-inl.h",
"src/execution/arguments.h",
"src/execution/encoded-c-signature.h",
"src/execution/execution.h",
"src/execution/frame-constants.h",
"src/execution/frames-inl.h",
@ -4087,7 +4086,6 @@ v8_source_set("v8_base_without_compiler") {
"src/diagnostics/perf-jit.cc",
"src/diagnostics/unwinder.cc",
"src/execution/arguments.cc",
"src/execution/encoded-c-signature.cc",
"src/execution/execution.cc",
"src/execution/frames.cc",
"src/execution/futex-emulation.cc",

View File

@ -249,15 +249,6 @@ class CTypeInfo {
kV8Value,
kApiObject, // This will be deprecated once all users have
// migrated from v8::ApiObject to v8::Local<v8::Value>.
kAny, // This is added to enable untyped representation of fast
// call arguments for test purposes. It can represent any of
// the other types stored in the same memory as a union (see
// the AnyCType struct declared below). This allows for
// uniform passing of arguments w.r.t. their location
// (in a register or on the stack), independent of their
// actual type. It's currently used by the arm64 simulator
// and can be added to the other simulators as well when fast
// calls having both GP and FP params need to be supported.
};
// kCallbackOptionsType is not part of the Type enum
@ -413,37 +404,6 @@ class V8_EXPORT CFunctionInfo {
const CTypeInfo* arg_info_;
};
struct FastApiCallbackOptions;
// Provided for testing.
struct AnyCType {
AnyCType() : int64_value(0) {}
union {
bool bool_value;
int32_t int32_value;
uint32_t uint32_value;
int64_t int64_value;
uint64_t uint64_value;
float float_value;
double double_value;
Local<Object> object_value;
Local<Array> sequence_value;
const FastApiTypedArray<int32_t>* int32_ta_value;
const FastApiTypedArray<uint32_t>* uint32_ta_value;
const FastApiTypedArray<int64_t>* int64_ta_value;
const FastApiTypedArray<uint64_t>* uint64_ta_value;
const FastApiTypedArray<float>* float_ta_value;
const FastApiTypedArray<double>* double_ta_value;
FastApiCallbackOptions* options_value;
};
};
static_assert(
sizeof(AnyCType) == 8,
"The AnyCType struct should have size == 64 bits, as this is assumed "
"by EffectControlLinearizer.");
class V8_EXPORT CFunction {
public:
constexpr CFunction() : address_(nullptr), type_info_(nullptr) {}
@ -500,19 +460,6 @@ class V8_EXPORT CFunction {
return ArgUnwrap<F*>::Make(func);
}
// Provided for testing purposes.
template <typename R, typename... Args, typename R_Patch,
typename... Args_Patch>
static CFunction Make(R (*func)(Args...),
R_Patch (*patching_func)(Args_Patch...)) {
CFunction c_func = ArgUnwrap<R (*)(Args...)>::Make(func);
static_assert(
sizeof...(Args_Patch) == sizeof...(Args),
"The patching function must have the same number of arguments.");
c_func.address_ = reinterpret_cast<void*>(patching_func);
return c_func;
}
CFunction(const void* address, const CFunctionInfo* type_info);
private:
@ -608,8 +555,7 @@ class CFunctionInfoImpl : public CFunctionInfo {
kReturnType == CTypeInfo::Type::kInt32 ||
kReturnType == CTypeInfo::Type::kUint32 ||
kReturnType == CTypeInfo::Type::kFloat32 ||
kReturnType == CTypeInfo::Type::kFloat64 ||
kReturnType == CTypeInfo::Type::kAny,
kReturnType == CTypeInfo::Type::kFloat64,
"64-bit int and api object values are not currently "
"supported return types.");
}
@ -660,8 +606,7 @@ struct CTypeInfoTraits {};
V(void, kVoid) \
V(v8::Local<v8::Value>, kV8Value) \
V(v8::Local<v8::Object>, kV8Value) \
V(ApiObject, kApiObject) \
V(AnyCType, kAny)
V(ApiObject, kApiObject)
// ApiObject was a temporary solution to wrap the pointer to the v8::Value.
// Please use v8::Local<v8::Value> in new code for the arguments and

View File

@ -4,7 +4,6 @@
#include "src/codegen/external-reference.h"
#include "include/v8-fast-api-calls.h"
#include "src/api/api.h"
#include "src/base/ieee754.h"
#include "src/codegen/cpu-features.h"
@ -12,11 +11,10 @@
#include "src/date/date.h"
#include "src/debug/debug.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/encoded-c-signature.h"
#include "src/execution/isolate-utils.h"
#include "src/execution/isolate.h"
#include "src/execution/microtask-queue.h"
#include "src/execution/simulator.h"
#include "src/execution/simulator-base.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
#include "src/ic/stub-cache.h"
@ -174,19 +172,9 @@ static ExternalReference::Type BuiltinCallTypeForResultSize(int result_size) {
UNREACHABLE();
}
// static
ExternalReference ExternalReference::Create(ApiFunction* fun, Type type) {
return ExternalReference(Redirect(fun->address(), type));
}
// static
ExternalReference ExternalReference::Create(
Isolate* isolate, ApiFunction* fun, Type type, Address* c_functions,
const CFunctionInfo* const* c_signatures, unsigned num_functions) {
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Simulator::current(isolate)->RegisterFunctionsAndSignatures(
c_functions, c_signatures, num_functions);
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
ApiFunction* fun, Type type = ExternalReference::BUILTIN_CALL) {
return ExternalReference(Redirect(fun->address(), type));
}

View File

@ -11,7 +11,6 @@
namespace v8 {
class ApiFunction;
class CFunctionInfo;
namespace internal {
@ -407,15 +406,6 @@ class ExternalReference {
static ExternalReference Create(StatsCounter* counter);
static V8_EXPORT_PRIVATE ExternalReference Create(ApiFunction* ptr,
Type type);
// The following version is used by JSCallReducer in the compiler
// to create a reference for a fast API call, with one or more
// overloads. In simulator builds, it additionally "registers"
// the overloads with the simulator to ensure it maintains a
// mapping of callable Address'es to a function signature, encoding
// GP and FP arguments.
static V8_EXPORT_PRIVATE ExternalReference
Create(Isolate* isolate, ApiFunction* ptr, Type type, Address* c_functions,
const CFunctionInfo* const* c_signatures, unsigned num_functions);
static ExternalReference Create(const Runtime::Function* f);
static ExternalReference Create(IsolateAddressId id, Isolate* isolate);
static ExternalReference Create(Runtime::FunctionId id);

View File

@ -90,13 +90,6 @@ constexpr int64_t TB = static_cast<int64_t>(GB) * 1024;
#define V8_DEFAULT_STACK_SIZE_KB 984
#endif
#if defined(USE_SIMULATOR) && defined(V8_TARGET_ARCH_ARM64)
#define USE_SIMULATOR_WITH_GENERIC_C_CALLS
#define IF_USE_SIMULATOR(V) , V
#else
#define IF_USE_SIMULATOR(V)
#endif
// Minimum stack size in KB required by compilers.
constexpr int kStackSpaceRequiredForCompilation = 40;

View File

@ -4985,10 +4985,6 @@ MachineType MachineTypeFor(CTypeInfo::Type type) {
return MachineType::Uint32();
case CTypeInfo::Type::kInt64:
return MachineType::Int64();
case CTypeInfo::Type::kAny:
static_assert(sizeof(AnyCType) == 8,
"CTypeInfo::Type::kAny is assumed to be of size 64 bits.");
return MachineType::Int64();
case CTypeInfo::Type::kUint64:
return MachineType::Uint64();
case CTypeInfo::Type::kFloat32:
@ -5333,7 +5329,7 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier),
stack_slot,
static_cast<int>(offsetof(v8::FastApiCallbackOptions, fallback)),
__ Int32Constant(0));
__ ZeroConstant());
__ Store(StoreRepresentation(MachineType::PointerRepresentation(),
kNoWriteBarrier),
stack_slot,
@ -5470,11 +5466,6 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kApiObject:
UNREACHABLE();
case CTypeInfo::Type::kAny:
fast_call_result =
ChangeFloat64ToTagged(__ ChangeInt64ToFloat64(c_call_result),
CheckForMinusZeroMode::kCheckForMinusZero);
break;
}
auto merge = __ MakeLabel(MachineRepresentation::kTagged);

View File

@ -27,7 +27,6 @@ ElementsKind GetTypedArrayElementsKind(CTypeInfo::Type type) {
case CTypeInfo::Type::kBool:
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kApiObject:
case CTypeInfo::Type::kAny:
UNREACHABLE();
}
}

View File

@ -92,8 +92,8 @@ const int kMaxFastLiteralProperties = JSObject::kMaxInObjectProperties;
// to add support for IA32, because it has a totally different approach
// (using FP stack). As support is added to more platforms, please make sure
// to list them here in order to enable tests of this functionality.
// Make sure to sync the following with src/d8/d8-test.cc.
#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM64)
#if defined(V8_TARGET_ARCH_X64) || \
(defined(V8_TARGET_ARCH_ARM64) && !defined(USE_SIMULATOR))
#define V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
#endif

View File

@ -956,10 +956,7 @@ class FastApiCallReducerAssembler : public JSCallReducerAssembler {
CallDescriptor::kNeedsFrameState);
ApiFunction api_function(call_handler_info.callback());
ExternalReference function_reference = ExternalReference::Create(
isolate(), &api_function, ExternalReference::DIRECT_API_CALL,
function_template_info_.c_functions().data(),
function_template_info_.c_signatures().data(),
static_cast<unsigned>(function_template_info_.c_functions().size()));
&api_function, ExternalReference::DIRECT_API_CALL);
Node* continuation_frame_state =
CreateGenericLazyDeoptContinuationFrameState(

View File

@ -208,25 +208,6 @@ int CallDescriptor::CalculateFixedFrameSize(CodeKind code_kind) const {
UNREACHABLE();
}
EncodedCSignature CallDescriptor::ToEncodedCSignature() const {
int parameter_count = static_cast<int>(ParameterCount());
EncodedCSignature sig(parameter_count);
CHECK_LT(parameter_count, EncodedCSignature::kInvalidParamCount);
for (int i = 0; i < parameter_count; ++i) {
if (IsFloatingPoint(GetParameterType(i).representation())) {
sig.SetFloat(i);
}
}
if (ReturnCount() > 0) {
DCHECK_EQ(1, ReturnCount());
if (IsFloatingPoint(GetReturnType(0).representation())) {
sig.SetFloat(EncodedCSignature::kReturnIndex);
}
}
return sig;
}
void CallDescriptor::ComputeParamCounts() const {
gp_param_count_ = 0;
fp_param_count_ = 0;

View File

@ -15,7 +15,6 @@
#include "src/common/globals.h"
#include "src/compiler/frame.h"
#include "src/compiler/operator.h"
#include "src/execution/encoded-c-signature.h"
#include "src/runtime/runtime.h"
#include "src/zone/zone.h"
@ -435,8 +434,6 @@ class V8_EXPORT_PRIVATE CallDescriptor final
return allocatable_registers_ != 0;
}
EncodedCSignature ToEncodedCSignature() const;
private:
void ComputeParamCounts() const;

View File

@ -1821,7 +1821,6 @@ class RepresentationSelector {
// path.
case CTypeInfo::Type::kInt64:
case CTypeInfo::Type::kUint64:
case CTypeInfo::Type::kAny:
return UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, feedback);
case CTypeInfo::Type::kFloat32:
case CTypeInfo::Type::kFloat64:

View File

@ -17,7 +17,8 @@
// and resetting these counters.
// Make sure to sync the following with src/compiler/globals.h.
#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM64)
#if defined(V8_TARGET_ARCH_X64) || \
(defined(V8_TARGET_ARCH_ARM64) && !defined(USE_SIMULATOR))
#define V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
#endif
@ -39,22 +40,6 @@ namespace {
class FastCApiObject {
public:
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
static AnyCType AddAllFastCallbackPatch(AnyCType receiver,
AnyCType should_fallback,
AnyCType arg_i32, AnyCType arg_u32,
AnyCType arg_i64, AnyCType arg_u64,
AnyCType arg_f32, AnyCType arg_f64,
AnyCType options) {
AnyCType ret;
ret.double_value = AddAllFastCallback(
receiver.object_value, should_fallback.bool_value, arg_i32.int32_value,
arg_u32.uint32_value, arg_i64.int64_value, arg_u64.uint64_value,
arg_f32.float_value, arg_f64.double_value, *options.options_value);
return ret;
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
static double AddAllFastCallback(Local<Object> receiver, bool should_fallback,
int32_t arg_i32, uint32_t arg_u32,
int64_t arg_i64, uint64_t arg_u64,
@ -67,8 +52,6 @@ class FastCApiObject {
if (should_fallback) {
options.fallback = 1;
return 0;
} else {
options.fallback = 0;
}
return static_cast<double>(arg_i32) + static_cast<double>(arg_u32) +
@ -116,24 +99,6 @@ class FastCApiObject {
#else
typedef int32_t Type;
#endif // V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
static AnyCType AddAllSequenceFastCallbackPatch(AnyCType receiver,
AnyCType should_fallback,
AnyCType seq_arg,
AnyCType options) {
AnyCType ret;
#ifdef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
ret.double_value = AddAllSequenceFastCallback(
receiver.object_value, should_fallback.bool_value,
seq_arg.sequence_value, *options.options_value);
#else
ret.int32_value = AddAllSequenceFastCallback(
receiver.object_value, should_fallback.bool_value,
seq_arg.sequence_value, *options.options_value);
#endif // V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
return ret;
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
static Type AddAllSequenceFastCallback(Local<Object> receiver,
bool should_fallback,
Local<Array> seq_arg,
@ -227,57 +192,6 @@ class FastCApiObject {
}
args.GetReturnValue().Set(Number::New(isolate, sum));
}
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
template <typename T>
static const FastApiTypedArray<T>* AnyCTypeToTypedArray(AnyCType arg);
template <>
const FastApiTypedArray<int32_t>* AnyCTypeToTypedArray<int32_t>(
AnyCType arg) {
return arg.int32_ta_value;
}
template <>
const FastApiTypedArray<uint32_t>* AnyCTypeToTypedArray<uint32_t>(
AnyCType arg) {
return arg.uint32_ta_value;
}
template <>
const FastApiTypedArray<int64_t>* AnyCTypeToTypedArray<int64_t>(
AnyCType arg) {
return arg.int64_ta_value;
}
template <>
const FastApiTypedArray<uint64_t>* AnyCTypeToTypedArray<uint64_t>(
AnyCType arg) {
return arg.uint64_ta_value;
}
template <>
const FastApiTypedArray<float>* AnyCTypeToTypedArray<float>(AnyCType arg) {
return arg.float_ta_value;
}
template <>
const FastApiTypedArray<double>* AnyCTypeToTypedArray<double>(AnyCType arg) {
return arg.double_ta_value;
}
template <typename T>
static AnyCType AddAllTypedArrayFastCallbackPatch(AnyCType receiver,
AnyCType should_fallback,
AnyCType typed_array_arg,
AnyCType options) {
AnyCType ret;
#ifdef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
ret.double_value = AddAllTypedArrayFastCallback(
receiver.object_value, should_fallback.bool_value,
*AnyCTypeToTypedArray<T>(typed_array_arg), *options.options_value);
#else
ret.int32_value = AddAllTypedArrayFastCallback(
receiver.object_value, should_fallback.bool_value,
*AnyCTypeToTypedArray<T>(typed_array_arg), *options.options_value);
#endif // V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
return ret;
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
template <typename T>
static Type AddAllTypedArrayFastCallback(
Local<Object> receiver, bool should_fallback,
@ -362,20 +276,6 @@ class FastCApiObject {
UNREACHABLE();
}
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
static AnyCType Add32BitIntFastCallbackPatch(AnyCType receiver,
AnyCType should_fallback,
AnyCType arg_i32,
AnyCType arg_u32,
AnyCType options) {
AnyCType ret;
ret.int32_value = Add32BitIntFastCallback(
receiver.object_value, should_fallback.bool_value, arg_i32.int32_value,
arg_u32.uint32_value, *options.options_value);
return ret;
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
static int Add32BitIntFastCallback(v8::Local<v8::Object> receiver,
bool should_fallback, int32_t arg_i32,
uint32_t arg_u32,
@ -411,30 +311,6 @@ class FastCApiObject {
args.GetReturnValue().Set(Number::New(isolate, sum));
}
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
static AnyCType AddAll32BitIntFastCallback_6ArgsPatch(
AnyCType receiver, AnyCType should_fallback, AnyCType arg1_i32,
AnyCType arg2_i32, AnyCType arg3_i32, AnyCType arg4_u32,
AnyCType arg5_u32, AnyCType arg6_u32, AnyCType options) {
AnyCType ret;
ret.int32_value = AddAll32BitIntFastCallback_6Args(
receiver.object_value, should_fallback.bool_value, arg1_i32.int32_value,
arg2_i32.int32_value, arg3_i32.int32_value, arg4_u32.uint32_value,
arg5_u32.uint32_value, arg6_u32.uint32_value, *options.options_value);
return ret;
}
static AnyCType AddAll32BitIntFastCallback_5ArgsPatch(
AnyCType receiver, AnyCType should_fallback, AnyCType arg1_i32,
AnyCType arg2_i32, AnyCType arg3_i32, AnyCType arg4_u32,
AnyCType arg5_u32, AnyCType options) {
AnyCType arg6;
arg6.uint32_value = 0;
return AddAll32BitIntFastCallback_6ArgsPatch(
receiver, should_fallback, arg1_i32, arg2_i32, arg3_i32, arg4_u32,
arg5_u32, arg6, options);
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
static int AddAll32BitIntFastCallback_6Args(
Local<Object> receiver, bool should_fallback, int32_t arg1_i32,
int32_t arg2_i32, int32_t arg3_i32, uint32_t arg4_u32, uint32_t arg5_u32,
@ -644,8 +520,7 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
Local<Signature> signature = Signature::New(isolate, api_obj_ctor);
{
CFunction add_all_c_func =
CFunction::Make(FastCApiObject::AddAllFastCallback IF_USE_SIMULATOR(
FastCApiObject::AddAllFastCallbackPatch));
CFunction::Make(FastCApiObject::AddAllFastCallback);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all",
FunctionTemplate::New(isolate, FastCApiObject::AddAllSlowCallback,
@ -653,9 +528,8 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &add_all_c_func));
CFunction add_all_seq_c_func = CFunction::Make(
FastCApiObject::AddAllSequenceFastCallback IF_USE_SIMULATOR(
FastCApiObject::AddAllSequenceFastCallbackPatch));
CFunction add_all_seq_c_func =
CFunction::Make(FastCApiObject::AddAllSequenceFastCallback);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_sequence",
FunctionTemplate::New(
@ -663,10 +537,8 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &add_all_seq_c_func));
CFunction add_all_int32_typed_array_c_func = CFunction::Make(
FastCApiObject::AddAllTypedArrayFastCallback<int32_t> IF_USE_SIMULATOR(
FastCApiObject::AddAllTypedArrayFastCallbackPatch<int32_t>));
CFunction add_all_int32_typed_array_c_func =
CFunction::Make(FastCApiObject::AddAllTypedArrayFastCallback<int32_t>);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_int32_typed_array",
FunctionTemplate::New(
@ -674,9 +546,8 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
Local<Value>(), signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &add_all_int32_typed_array_c_func));
CFunction add_all_int64_typed_array_c_func = CFunction::Make(
FastCApiObject::AddAllTypedArrayFastCallback<int64_t> IF_USE_SIMULATOR(
FastCApiObject::AddAllTypedArrayFastCallbackPatch<int64_t>));
CFunction add_all_int64_typed_array_c_func =
CFunction::Make(FastCApiObject::AddAllTypedArrayFastCallback<int64_t>);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_int64_typed_array",
FunctionTemplate::New(
@ -684,9 +555,8 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
Local<Value>(), signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &add_all_int64_typed_array_c_func));
CFunction add_all_uint64_typed_array_c_func = CFunction::Make(
FastCApiObject::AddAllTypedArrayFastCallback<uint64_t> IF_USE_SIMULATOR(
FastCApiObject::AddAllTypedArrayFastCallbackPatch<uint64_t>));
CFunction add_all_uint64_typed_array_c_func =
CFunction::Make(FastCApiObject::AddAllTypedArrayFastCallback<uint64_t>);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_uint64_typed_array",
FunctionTemplate::New(
@ -695,9 +565,8 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
SideEffectType::kHasSideEffect,
&add_all_uint64_typed_array_c_func));
CFunction add_all_uint32_typed_array_c_func = CFunction::Make(
FastCApiObject::AddAllTypedArrayFastCallback<uint32_t> IF_USE_SIMULATOR(
FastCApiObject::AddAllTypedArrayFastCallbackPatch<uint32_t>));
CFunction add_all_uint32_typed_array_c_func =
CFunction::Make(FastCApiObject::AddAllTypedArrayFastCallback<uint32_t>);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_uint32_typed_array",
FunctionTemplate::New(
@ -706,9 +575,8 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
SideEffectType::kHasSideEffect,
&add_all_uint32_typed_array_c_func));
CFunction add_all_float32_typed_array_c_func = CFunction::Make(
FastCApiObject::AddAllTypedArrayFastCallback<float> IF_USE_SIMULATOR(
FastCApiObject::AddAllTypedArrayFastCallbackPatch<float>));
CFunction add_all_float32_typed_array_c_func =
CFunction::Make(FastCApiObject::AddAllTypedArrayFastCallback<float>);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_float32_typed_array",
FunctionTemplate::New(
@ -717,9 +585,8 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
SideEffectType::kHasSideEffect,
&add_all_float32_typed_array_c_func));
CFunction add_all_float64_typed_array_c_func = CFunction::Make(
FastCApiObject::AddAllTypedArrayFastCallback<double> IF_USE_SIMULATOR(
FastCApiObject::AddAllTypedArrayFastCallbackPatch<double>));
CFunction add_all_float64_typed_array_c_func =
CFunction::Make(FastCApiObject::AddAllTypedArrayFastCallback<double>);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_float64_typed_array",
FunctionTemplate::New(
@ -752,12 +619,10 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, {add_all_invalid_overloads, 2}));
CFunction add_all_32bit_int_6args_c_func = CFunction::Make(
FastCApiObject::AddAll32BitIntFastCallback_6Args IF_USE_SIMULATOR(
FastCApiObject::AddAll32BitIntFastCallback_6ArgsPatch));
CFunction add_all_32bit_int_5args_c_func = CFunction::Make(
FastCApiObject::AddAll32BitIntFastCallback_5Args IF_USE_SIMULATOR(
FastCApiObject::AddAll32BitIntFastCallback_5ArgsPatch));
CFunction add_all_32bit_int_6args_c_func =
CFunction::Make(FastCApiObject::AddAll32BitIntFastCallback_6Args);
CFunction add_all_32bit_int_5args_c_func =
CFunction::Make(FastCApiObject::AddAll32BitIntFastCallback_5Args);
const CFunction c_function_overloads[] = {add_all_32bit_int_6args_c_func,
add_all_32bit_int_5args_c_func};
api_obj_ctor->PrototypeTemplate()->Set(
@ -767,9 +632,8 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, {c_function_overloads, 2}));
CFunction add_32bit_int_c_func = CFunction::Make(
FastCApiObject::Add32BitIntFastCallback IF_USE_SIMULATOR(
FastCApiObject::Add32BitIntFastCallbackPatch));
CFunction add_32bit_int_c_func =
CFunction::Make(FastCApiObject::Add32BitIntFastCallback);
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_32bit_int",
FunctionTemplate::New(

View File

@ -14,6 +14,7 @@
#include <cstdarg>
#include <type_traits>
#include "src/base/lazy-instance.h"
#include "src/base/overflowing-math.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/wrappers.h"
@ -502,126 +503,6 @@ void UnsafeDirectGetterCall(int64_t function, int64_t arg0, int64_t arg1) {
target(arg0, arg1);
}
using MixedRuntimeCall_0 = AnyCType (*)();
#define BRACKETS(ident, N) ident[N]
#define REP_0(expr, FMT)
#define REP_1(expr, FMT) FMT(expr, 0)
#define REP_2(expr, FMT) REP_1(expr, FMT), FMT(expr, 1)
#define REP_3(expr, FMT) REP_2(expr, FMT), FMT(expr, 2)
#define REP_4(expr, FMT) REP_3(expr, FMT), FMT(expr, 3)
#define REP_5(expr, FMT) REP_4(expr, FMT), FMT(expr, 4)
#define REP_6(expr, FMT) REP_5(expr, FMT), FMT(expr, 5)
#define REP_7(expr, FMT) REP_6(expr, FMT), FMT(expr, 6)
#define REP_8(expr, FMT) REP_7(expr, FMT), FMT(expr, 7)
#define REP_9(expr, FMT) REP_8(expr, FMT), FMT(expr, 8)
#define REP_10(expr, FMT) REP_9(expr, FMT), FMT(expr, 9)
#define REP_11(expr, FMT) REP_10(expr, FMT), FMT(expr, 10)
#define REP_12(expr, FMT) REP_11(expr, FMT), FMT(expr, 11)
#define REP_13(expr, FMT) REP_12(expr, FMT), FMT(expr, 12)
#define REP_14(expr, FMT) REP_13(expr, FMT), FMT(expr, 13)
#define REP_15(expr, FMT) REP_14(expr, FMT), FMT(expr, 14)
#define REP_16(expr, FMT) REP_15(expr, FMT), FMT(expr, 15)
#define REP_17(expr, FMT) REP_16(expr, FMT), FMT(expr, 16)
#define REP_18(expr, FMT) REP_17(expr, FMT), FMT(expr, 17)
#define REP_19(expr, FMT) REP_18(expr, FMT), FMT(expr, 18)
#define REP_20(expr, FMT) REP_19(expr, FMT), FMT(expr, 19)
#define GEN_MAX_PARAM_COUNT(V) \
V(0) \
V(1) \
V(2) \
V(3) \
V(4) \
V(5) \
V(6) \
V(7) \
V(8) \
V(9) \
V(10) \
V(11) \
V(12) \
V(13) \
V(14) \
V(15) \
V(16) \
V(17) \
V(18) \
V(19) \
V(20)
#define MIXED_RUNTIME_CALL(N) \
using MixedRuntimeCall_##N = AnyCType (*)(REP_##N(AnyCType arg, CONCAT));
GEN_MAX_PARAM_COUNT(MIXED_RUNTIME_CALL)
#undef MIXED_RUNTIME_CALL
#define CALL_ARGS(N) REP_##N(args, BRACKETS)
#define CALL_TARGET_VARARG(N) \
if (signature.ParameterCount() == N) { /* NOLINT */ \
MixedRuntimeCall_##N target = \
reinterpret_cast<MixedRuntimeCall_##N>(target_address); \
result = target(CALL_ARGS(N)); \
} else /* NOLINT */
void Simulator::CallAnyCTypeFunction(Address target_address,
const EncodedCSignature& signature) {
TraceSim("Type: mixed types BUILTIN_CALL\n");
const int64_t* stack_pointer = reinterpret_cast<int64_t*>(sp());
const double* double_stack_pointer = reinterpret_cast<double*>(sp());
int num_gp_params = 0, num_fp_params = 0, num_stack_params = 0;
CHECK_LE(signature.ParameterCount(), kMaxCParameters);
static_assert(sizeof(AnyCType) == 8, "AnyCType is assumed to be 64-bit.");
AnyCType args[kMaxCParameters];
// The first 8 parameters of each type (GP or FP) are placed in corresponding
// registers. The rest are expected to be on the stack, where each parameter
// type counts on its own. For example a function like:
// foo(int i1, ..., int i9, float f1, float f2) will use up all 8 GP
// registers, place i9 on the stack, and place f1 and f2 in FP registers.
// Source: https://developer.arm.com/documentation/ihi0055/d/, section
// "Parameter Passing".
for (int i = 0; i < signature.ParameterCount(); ++i) {
if (signature.IsFloat(i)) {
if (num_fp_params < 8) {
args[i].double_value = dreg(num_fp_params++);
} else {
args[i].double_value = double_stack_pointer[num_stack_params++];
}
} else {
if (num_gp_params < 8) {
args[i].int64_value = xreg(num_gp_params++);
} else {
args[i].int64_value = stack_pointer[num_stack_params++];
}
}
}
AnyCType result;
GEN_MAX_PARAM_COUNT(CALL_TARGET_VARARG)
/* else */ {
UNREACHABLE();
}
static_assert(20 == kMaxCParameters,
"If you've changed kMaxCParameters, please change the "
"GEN_MAX_PARAM_COUNT macro.");
#undef CALL_TARGET_VARARG
#undef CALL_ARGS
#undef GEN_MAX_PARAM_COUNT
#ifdef DEBUG
CorruptAllCallerSavedCPURegisters();
#endif
if (signature.IsReturnFloat()) {
set_dreg(0, result.double_value);
} else {
set_xreg(0, result.int64_value);
}
}
void Simulator::DoRuntimeCall(Instruction* instr) {
Redirection* redirection = Redirection::FromInstruction(instr);
@ -642,17 +523,6 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
FATAL("ALIGNMENT EXCEPTION");
}
Address func_addr =
reinterpret_cast<Address>(redirection->external_function());
const EncodedCSignature& signature = GetSignatureForTarget(func_addr);
if (signature.IsValid()) {
CHECK(redirection->type() == ExternalReference::FAST_C_CALL);
CallAnyCTypeFunction(external, signature);
set_lr(return_address);
set_pc(return_address);
return;
}
int64_t* stack_pointer = reinterpret_cast<int64_t*>(sp());
const int64_t arg0 = xreg(0);
@ -682,6 +552,17 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
TraceSim("Type: Unknown.\n");
UNREACHABLE();
// FAST_C_CALL is temporarily handled here as well, because we lack
// proper support for direct C calls with FP params in the simulator.
// The generic BUILTIN_CALL path assumes all parameters are passed in
// the GP registers, thus supporting calling the slow callback without
// crashing. The reason for that is that in the mjsunit tests we check
// the `fast_c_api.supports_fp_params` (which is false on non-simulator
// builds for arm/arm64), thus we expect that the slow path will be
// called. And since the slow path passes the arguments as a `const
// FunctionCallbackInfo<Value>&` (which is a GP argument), the call is
// made correctly.
case ExternalReference::FAST_C_CALL:
case ExternalReference::BUILTIN_CALL:
#if defined(V8_OS_WIN)
{
@ -6341,31 +6222,6 @@ void Simulator::GlobalMonitor::RemoveProcessor(Processor* processor) {
processor->next_ = nullptr;
}
void Simulator::RegisterFunctionsAndSignatures(
Address* c_functions, const CFunctionInfo* const* c_signatures,
unsigned num_functions) {
base::MutexGuard guard(&signature_map_mutex_);
for (unsigned i = 0; i < num_functions; ++i) {
EncodedCSignature sig(c_signatures[i]);
AddSignatureForTarget(c_functions[i], sig);
}
}
void Simulator::AddSignatureForTarget(Address target,
const EncodedCSignature& signature) {
target_to_signature_table_[target] = signature;
}
const EncodedCSignature& Simulator::GetSignatureForTarget(Address target) {
base::MutexGuard guard(&signature_map_mutex_);
auto entry = target_to_signature_table_.find(target);
if (entry != target_to_signature_table_.end()) {
const EncodedCSignature& sig = entry->second;
return sig;
}
return EncodedCSignature::Invalid();
}
#undef SScanF
#undef COLOUR
#undef COLOUR_BOLD
@ -6408,6 +6264,4 @@ V8_EXPORT_PRIVATE extern bool _v8_internal_Simulator_ExecDebugCommand(
return simulator->ExecDebugCommand(std::move(command_copy));
}
#undef BRACKETS
#endif // USE_SIMULATOR

View File

@ -20,7 +20,6 @@
#include "src/codegen/arm64/decoder-arm64.h"
#include "src/codegen/assembler.h"
#include "src/diagnostics/arm64/disasm-arm64.h"
#include "src/execution/encoded-c-signature.h"
#include "src/execution/simulator-base.h"
#include "src/utils/allocation.h"
#include "src/utils/utils.h"
@ -1439,28 +1438,6 @@ class Simulator : public DecoderVisitor, public SimulatorBase {
PACKey key, PointerType type);
V8_EXPORT_PRIVATE static uint64_t StripPAC(uint64_t ptr, PointerType type);
// Calls AddSignatureForTarget for each function and signature, registering
// an encoded version of the signature within a mapping maintained by the
// simulator (from function address -> encoded signature). The function
// is supposed to be called whenever one compiles a fast API function with
// possibly multiple overloads.
// Note that this function is called from one or more compiler threads,
// while the main thread might be reading at the same time from the map, so
// both Register* and Get* are guarded with a single mutex.
void RegisterFunctionsAndSignatures(Address* c_functions,
const CFunctionInfo* const* c_signatures,
unsigned num_functions);
// The following method is used by the simulator itself to query
// whether a signature is registered for the call target and use this
// information to address arguments correctly (load them from either GP or
// FP registers, or from the stack).
const EncodedCSignature& GetSignatureForTarget(Address target);
// This method is exposed only for tests, which don't need synchronisation.
void AddSignatureForTargetForTesting(Address target,
const EncodedCSignature& signature) {
AddSignatureForTarget(target, signature);
}
protected:
// Simulation helpers ------------------------------------
bool ConditionPassed(Condition cond) {
@ -2472,9 +2449,6 @@ class Simulator : public DecoderVisitor, public SimulatorBase {
V8_EXPORT_PRIVATE void CallImpl(Address entry, CallArgument* args);
void CallAnyCTypeFunction(Address target_address,
const EncodedCSignature& signature);
// Read floating point return values.
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
@ -2536,17 +2510,10 @@ class Simulator : public DecoderVisitor, public SimulatorBase {
}
}
void AddSignatureForTarget(Address target,
const EncodedCSignature& signature);
int log_parameters_;
// Instruction counter only valid if FLAG_stop_sim_at isn't 0.
int icount_for_stop_sim_at_;
Isolate* isolate_;
v8::base::Mutex signature_map_mutex_;
typedef std::unordered_map<Address, EncodedCSignature> TargetToSignatureTable;
TargetToSignatureTable target_to_signature_table_;
};
template <>

View File

@ -1,41 +0,0 @@
// Copyright 2021 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/execution/encoded-c-signature.h"
#include "include/v8-fast-api-calls.h"
#include "src/base/bits.h"
#include "src/base/logging.h"
namespace v8 {
namespace internal {
int EncodedCSignature::FPParameterCount() const {
CHECK(IsValid());
return base::bits::CountPopulation(bitfield_ & ~(1 << kReturnIndex));
}
EncodedCSignature::EncodedCSignature(const CFunctionInfo* signature) {
parameter_count_ = static_cast<int>(signature->ArgumentCount());
for (int i = 0; i < parameter_count_; ++i) {
if (signature->ArgumentInfo(i).GetSequenceType() ==
CTypeInfo::SequenceType::kScalar &&
CTypeInfo::IsFloatingPointType(signature->ArgumentInfo(i).GetType())) {
SetFloat(i);
}
}
// The struct holding the options of the CFunction (e.g. callback) is not
// included in the number of regular parameters, so we add it manually here.
if (signature->HasOptions()) {
parameter_count_++;
}
if (signature->ReturnInfo().GetSequenceType() ==
CTypeInfo::SequenceType::kScalar &&
CTypeInfo::IsFloatingPointType(signature->ReturnInfo().GetType())) {
SetFloat(EncodedCSignature::kReturnIndex);
}
}
} // namespace internal
} // namespace v8

View File

@ -1,60 +0,0 @@
// Copyright 2021 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_EXECUTION_ENCODED_C_SIGNATURE_H_
#define V8_EXECUTION_ENCODED_C_SIGNATURE_H_
#include <stdint.h>
namespace v8 {
class CFunctionInfo;
namespace internal {
namespace compiler {
class CallDescriptor;
} // namespace compiler
// This structure represents whether the parameters for a given function
// should be read from general purpose or FP registers. parameter_count =
// kInvalidParamCount represents "invalid" signature, a placeholder for
// non-existing elements in the mapping.
struct EncodedCSignature {
public:
EncodedCSignature() = default;
EncodedCSignature(uint32_t bitfield, int parameter_count)
: bitfield_(bitfield), parameter_count_(parameter_count) {}
explicit EncodedCSignature(int parameter_count)
: parameter_count_(parameter_count) {}
explicit EncodedCSignature(const CFunctionInfo* signature);
bool IsFloat(int index) const {
return (bitfield_ & (static_cast<uint32_t>(1) << index)) != 0;
}
bool IsReturnFloat() const { return IsFloat(kReturnIndex); }
void SetFloat(int index) { bitfield_ |= (static_cast<uint32_t>(1) << index); }
bool IsValid() const { return parameter_count_ < kInvalidParamCount; }
int ParameterCount() const { return parameter_count_; }
int FPParameterCount() const;
static const EncodedCSignature& Invalid() {
static EncodedCSignature kInvalid = {0, kInvalidParamCount};
return kInvalid;
}
static const int kReturnIndex = 31;
static const int kInvalidParamCount = kReturnIndex + 1;
private:
uint32_t bitfield_ = 0; // Bit i is set if floating point, unset if not.
int parameter_count_ = kInvalidParamCount;
};
} // namespace internal
} // namespace v8
#endif // V8_EXECUTION_ENCODED_C_SIGNATURE_H_

View File

@ -7,9 +7,6 @@
#include <type_traits>
#ifdef V8_TARGET_ARCH_ARM64
#include "include/v8-fast-api-calls.h"
#endif // V8_TARGET_ARCH_ARM64
#include "src/base/hashmap.h"
#include "src/common/globals.h"
#include "src/execution/isolate.h"
@ -71,16 +68,6 @@ class SimulatorBase {
return Object(ret);
}
#ifdef V8_TARGET_ARCH_ARM64
template <typename T>
static typename std::enable_if<std::is_same<T, v8::AnyCType>::value, T>::type
ConvertReturn(intptr_t ret) {
v8::AnyCType result;
result.int64_value = static_cast<int64_t>(ret);
return result;
}
#endif // V8_TARGET_ARCH_ARM64
// Convert back void return type (i.e. no return).
template <typename T>
static typename std::enable_if<std::is_void<T>::value, T>::type ConvertReturn(
@ -119,13 +106,6 @@ class SimulatorBase {
ConvertArg(T arg) {
return reinterpret_cast<intptr_t>(arg);
}
template <typename T>
static
typename std::enable_if<std::is_floating_point<T>::value, intptr_t>::type
ConvertArg(T arg) {
UNREACHABLE();
}
};
// When the generated code calls an external reference we need to catch that in

View File

@ -122,13 +122,9 @@ class GeneratedCode {
// Starboard is a platform abstraction interface that also include Windows
// platforms like UWP.
#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) && \
!defined(V8_OS_STARBOARD) && !defined(V8_TARGET_ARCH_ARM)
FATAL(
"Generated code execution not possible during cross-compilation."
"Also, generic C function calls are not implemented on 32-bit arm "
"yet.");
#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) &&
// !defined(V8_OS_STARBOARD) && !defined(V8_TARGET_ARCH_ARM)
!defined(V8_OS_STARBOARD)
FATAL("Generated code execution not possible during cross-compilation.");
#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN)
return Simulator::current(isolate_)->template Call<Return>(
reinterpret_cast<Address>(fn_ptr_), args...);
}

View File

@ -5,10 +5,6 @@
#ifndef V8_COMPILER_C_SIGNATURE_H_
#define V8_COMPILER_C_SIGNATURE_H_
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
#include "include/v8-fast-api-calls.h"
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
#include "src/codegen/machine-type.h"
namespace v8 {
@ -46,12 +42,6 @@ inline constexpr MachineType MachineTypeForC() {
FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
#undef DECLARE_TEMPLATE_SPECIALIZATION
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
template <>
inline MachineType constexpr MachineTypeForC<v8::AnyCType>() {
return MachineType::Int64();
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
// Helper for building machine signatures from C types.
class CSignature : public MachineSignature {
protected:

View File

@ -381,12 +381,7 @@ TEST(RunCallFloat64Pow) {
template <typename T>
MachineType MachineTypeForCType() {
return MachineType::AnyTagged();
}
template <>
MachineType MachineTypeForCType<int64_t>() {
return MachineType::Int64();
UNREACHABLE();
}
template <>
@ -399,176 +394,93 @@ MachineType MachineTypeForCType<double>() {
return MachineType::Float64();
}
#define SIGNATURE_TYPES(TYPE, IDX, VALUE) MachineTypeForCType<TYPE>()
template <>
MachineType MachineTypeForCType<float>() {
return MachineType::Float32();
}
#define PARAM_PAIRS(TYPE, IDX, VALUE) \
#define SIGNATURE_TYPES_END(TYPE, IDX, VALUE) MachineTypeForCType<TYPE>()
#define SIGNATURE_TYPES(TYPE, IDX, VALUE) SIGNATURE_TYPES_END(TYPE, IDX, VALUE),
#define PARAM_PAIRS_END(TYPE, IDX, VALUE) \
std::make_pair(MachineTypeForCType<TYPE>(), m.Parameter(IDX))
#define CALL_ARGS(TYPE, IDX, VALUE) static_cast<TYPE>(VALUE)
#define PARAM_PAIRS(TYPE, IDX, VALUE) PARAM_PAIRS_END(TYPE, IDX, VALUE),
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
union Int64OrDoubleUnion {
int64_t int64_t_value;
double double_value;
};
#define CALL_ARGS_END(TYPE, IDX, VALUE) static_cast<TYPE>(VALUE)
#define CALL_ARGS(TYPE, IDX, VALUE) CALL_ARGS_END(TYPE, IDX, VALUE),
#define CHECK_ARG_I(TYPE, IDX, VALUE) \
(result = result && (arg##IDX.TYPE##_value == VALUE))
#define COMPARE_ARG_I_END(TYPE, IDX, VALUE) (arg##IDX == VALUE)
#define COMPARE_ARG_I(TYPE, IDX, VALUE) COMPARE_ARG_I_END(TYPE, IDX, VALUE)&&
#define ReturnType v8::AnyCType
MachineType machine_type = MachineType::Int64();
#define CHECK_RESULT(CALL, EXPECT) \
v8::AnyCType ret = CALL; \
CHECK_EQ(ret.int64_value, EXPECT);
#define IF_SIMULATOR_ADD_SIGNATURE \
EncodedCSignature sig = m.call_descriptor()->ToEncodedCSignature(); \
Simulator::current(m.main_isolate()) \
->AddSignatureForTargetForTesting(func_address, sig);
#else // def USE_SIMULATOR_WITH_GENERIC_C_CALLS
#define IF_SIMULATOR_ADD_SIGNATURE
#ifdef V8_TARGET_ARCH_64_BIT
#define ReturnType int64_t
MachineType machine_type = MachineType::Int64();
#else // V8_TARGET_ARCH_64_BIT
#define ReturnType int32_t
MachineType machine_type = MachineType::Int32();
#endif // V8_TARGET_ARCH_64_BIT
#define CHECK_ARG_I(TYPE, IDX, VALUE) (result = result && (arg##IDX == VALUE))
#define CHECK_RESULT(CALL, EXPECT) \
int64_t ret = CALL; \
CHECK_EQ(ret, EXPECT);
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
#define SIGNATURE_TEST(NAME, SIGNATURE, FUNC) \
TEST(NAME) { \
RawMachineAssemblerTester<ReturnType> m(SIGNATURE(SIGNATURE_TYPES)); \
\
Address func_address = FUNCTION_ADDR(&FUNC); \
ExternalReference::Type func_type = ExternalReference::FAST_C_CALL; \
ApiFunction func(func_address); \
ExternalReference ref = ExternalReference::Create(&func, func_type); \
\
IF_SIMULATOR_ADD_SIGNATURE \
\
Node* function = m.ExternalConstant(ref); \
m.Return(m.CallCFunction(function, machine_type, SIGNATURE(PARAM_PAIRS))); \
\
CHECK_RESULT(m.Call(SIGNATURE(CALL_ARGS)), 42); \
#define SIGNATURE_TEST(NAME, SIGNATURE, FUNC) \
TEST(NAME) { \
RawMachineAssemblerTester<int32_t> m(SIGNATURE(SIGNATURE_TYPES)); \
\
Address func_address = FUNCTION_ADDR(&FUNC); \
ExternalReference::Type dummy_type = ExternalReference::BUILTIN_CALL; \
ApiFunction func(func_address); \
ExternalReference ref = ExternalReference::Create(&func, dummy_type); \
\
Node* function = m.ExternalConstant(ref); \
m.Return(m.CallCFunction(function, MachineType::Int32(), \
SIGNATURE(PARAM_PAIRS))); \
\
int32_t c = m.Call(SIGNATURE(CALL_ARGS)); \
CHECK_EQ(c, 42); \
}
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
#define SIGNATURE_ONLY_INT(V) \
V(int64_t, 0, 0), V(int64_t, 1, 1), V(int64_t, 2, 2), V(int64_t, 3, 3), \
V(int64_t, 4, 4), V(int64_t, 5, 5), V(int64_t, 6, 6), V(int64_t, 7, 7), \
V(int64_t, 8, 8), V(int64_t, 9, 9)
#define SIGNATURE_ONLY_INT(V) \
V(int32_t, 0, 0) \
V(int32_t, 1, 1) \
V(int32_t, 2, 2) \
V(int32_t, 3, 3) \
V(int32_t, 4, 4) \
V(int32_t, 5, 5) \
V(int32_t, 6, 6) \
V(int32_t, 7, 7) \
V(int32_t, 8, 8) \
V##_END(int32_t, 9, 9)
Int64OrDoubleUnion func_only_int(
Int64OrDoubleUnion arg0, Int64OrDoubleUnion arg1, Int64OrDoubleUnion arg2,
Int64OrDoubleUnion arg3, Int64OrDoubleUnion arg4, Int64OrDoubleUnion arg5,
Int64OrDoubleUnion arg6, Int64OrDoubleUnion arg7, Int64OrDoubleUnion arg8,
Int64OrDoubleUnion arg9) {
#elif defined(V8_TARGET_ARCH_64_BIT)
#define SIGNATURE_ONLY_INT(V) \
V(int64_t, 0, 0), V(int64_t, 1, 1), V(int64_t, 2, 2), V(int64_t, 3, 3), \
V(int64_t, 4, 4), V(int64_t, 5, 5), V(int64_t, 6, 6), V(int64_t, 7, 7), \
V(int64_t, 8, 8), V(int64_t, 9, 9)
ReturnType func_only_int(int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3,
int64_t arg4, int64_t arg5, int64_t arg6, int64_t arg7,
int64_t arg8, int64_t arg9) {
#else // defined(V8_TARGET_ARCH_64_BIT)
#define SIGNATURE_ONLY_INT(V) \
V(int32_t, 0, 0), V(int32_t, 1, 1), V(int32_t, 2, 2), V(int32_t, 3, 3), \
V(int32_t, 4, 4), V(int32_t, 5, 5), V(int32_t, 6, 6), V(int32_t, 7, 7), \
V(int32_t, 8, 8), V(int32_t, 9, 9)
ReturnType func_only_int(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3,
int32_t arg4, int32_t arg5, int32_t arg6, int32_t arg7,
int32_t arg8, int32_t arg9) {
#endif
bool result = true;
SIGNATURE_ONLY_INT(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t func_only_int(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3,
int32_t arg4, int32_t arg5, int32_t arg6, int32_t arg7,
int32_t arg8, int32_t arg9) {
CHECK(SIGNATURE_ONLY_INT(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithSignatureOnlyInt, SIGNATURE_ONLY_INT, func_only_int)
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
#define SIGNATURE_ONLY_INT_20(V) \
V(int64_t, 0, 0), V(int64_t, 1, 1), V(int64_t, 2, 2), V(int64_t, 3, 3), \
V(int64_t, 4, 4), V(int64_t, 5, 5), V(int64_t, 6, 6), V(int64_t, 7, 7), \
V(int64_t, 8, 8), V(int64_t, 9, 9), V(int64_t, 10, 10), \
V(int64_t, 11, 11), V(int64_t, 12, 12), V(int64_t, 13, 13), \
V(int64_t, 14, 14), V(int64_t, 15, 15), V(int64_t, 16, 16), \
V(int64_t, 17, 17), V(int64_t, 18, 18), V(int64_t, 19, 19)
#define SIGNATURE_ONLY_INT_20(V) \
V(int32_t, 0, 0) \
V(int32_t, 1, 1) \
V(int32_t, 2, 2) \
V(int32_t, 3, 3) \
V(int32_t, 4, 4) \
V(int32_t, 5, 5) \
V(int32_t, 6, 6) \
V(int32_t, 7, 7) \
V(int32_t, 8, 8) \
V(int32_t, 9, 9) \
V(int32_t, 10, 10) \
V(int32_t, 11, 11) \
V(int32_t, 12, 12) \
V(int32_t, 13, 13) \
V(int32_t, 14, 14) \
V(int32_t, 15, 15) \
V(int32_t, 16, 16) \
V(int32_t, 17, 17) \
V(int32_t, 18, 18) \
V##_END(int32_t, 19, 19)
Int64OrDoubleUnion func_only_int_20(
Int64OrDoubleUnion arg0, Int64OrDoubleUnion arg1, Int64OrDoubleUnion arg2,
Int64OrDoubleUnion arg3, Int64OrDoubleUnion arg4, Int64OrDoubleUnion arg5,
Int64OrDoubleUnion arg6, Int64OrDoubleUnion arg7, Int64OrDoubleUnion arg8,
Int64OrDoubleUnion arg9, Int64OrDoubleUnion arg10, Int64OrDoubleUnion arg11,
Int64OrDoubleUnion arg12, Int64OrDoubleUnion arg13,
Int64OrDoubleUnion arg14, Int64OrDoubleUnion arg15,
Int64OrDoubleUnion arg16, Int64OrDoubleUnion arg17,
Int64OrDoubleUnion arg18, Int64OrDoubleUnion arg19) {
#elif defined(V8_TARGET_ARCH_64_BIT)
#define SIGNATURE_ONLY_INT_20(V) \
V(int64_t, 0, 0), V(int64_t, 1, 1), V(int64_t, 2, 2), V(int64_t, 3, 3), \
V(int64_t, 4, 4), V(int64_t, 5, 5), V(int64_t, 6, 6), V(int64_t, 7, 7), \
V(int64_t, 8, 8), V(int64_t, 9, 9), V(int64_t, 10, 10), \
V(int64_t, 11, 11), V(int64_t, 12, 12), V(int64_t, 13, 13), \
V(int64_t, 14, 14), V(int64_t, 15, 15), V(int64_t, 16, 16), \
V(int64_t, 17, 17), V(int64_t, 18, 18), V(int64_t, 19, 19)
ReturnType func_only_int_20(int64_t arg0, int64_t arg1, int64_t arg2,
int64_t arg3, int64_t arg4, int64_t arg5,
int64_t arg6, int64_t arg7, int64_t arg8,
int64_t arg9, int64_t arg10, int64_t arg11,
int64_t arg12, int64_t arg13, int64_t arg14,
int64_t arg15, int64_t arg16, int64_t arg17,
int64_t arg18, int64_t arg19) {
#else // defined(V8_TARGET_ARCH_64_BIT)
#define SIGNATURE_ONLY_INT_20(V) \
V(int32_t, 0, 0), V(int32_t, 1, 1), V(int32_t, 2, 2), V(int32_t, 3, 3), \
V(int32_t, 4, 4), V(int32_t, 5, 5), V(int32_t, 6, 6), V(int32_t, 7, 7), \
V(int32_t, 8, 8), V(int32_t, 9, 9), V(int32_t, 10, 10), \
V(int32_t, 11, 11), V(int32_t, 12, 12), V(int32_t, 13, 13), \
V(int32_t, 14, 14), V(int32_t, 15, 15), V(int32_t, 16, 16), \
V(int32_t, 17, 17), V(int32_t, 18, 18), V(int32_t, 19, 19)
ReturnType func_only_int_20(int32_t arg0, int32_t arg1, int32_t arg2,
int32_t arg3, int32_t arg4, int32_t arg5,
int32_t arg6, int32_t arg7, int32_t arg8,
int32_t arg9, int32_t arg10, int32_t arg11,
int32_t arg12, int32_t arg13, int32_t arg14,
int32_t arg15, int32_t arg16, int32_t arg17,
int32_t arg18, int32_t arg19) {
#endif
bool result = true;
SIGNATURE_ONLY_INT_20(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t func_only_int_20(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3,
int32_t arg4, int32_t arg5, int32_t arg6, int32_t arg7,
int32_t arg8, int32_t arg9, int32_t arg10,
int32_t arg11, int32_t arg12, int32_t arg13,
int32_t arg14, int32_t arg15, int32_t arg16,
int32_t arg17, int32_t arg18, int32_t arg19) {
CHECK(SIGNATURE_ONLY_INT_20(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithSignatureOnlyInt20, SIGNATURE_ONLY_INT_20,
@ -577,270 +489,453 @@ SIGNATURE_TEST(RunCallWithSignatureOnlyInt20, SIGNATURE_ONLY_INT_20,
#ifdef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
#define MIXED_SIGNATURE_SIMPLE(V) \
V(int64_t, 0, 0), V(double, 1, 1.5), V(int64_t, 2, 2)
V(int32_t, 0, 0) \
V(double, 1, 1.5) \
V##_END(int32_t, 2, 2)
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion test_api_func_simple(Int64OrDoubleUnion arg0,
Int64OrDoubleUnion arg1,
Int64OrDoubleUnion arg2) {
#else
ReturnType test_api_func_simple(int64_t arg0, double arg1, int64_t arg2) {
#endif
bool result = true;
MIXED_SIGNATURE_SIMPLE(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t test_api_func_simple(int32_t arg0, double arg1, int32_t arg2) {
CHECK(MIXED_SIGNATURE_SIMPLE(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithMixedSignatureSimple, MIXED_SIGNATURE_SIMPLE,
test_api_func_simple)
#define MIXED_SIGNATURE(V) \
V(int64_t, 0, 0), V(double, 1, 1.5), V(int64_t, 2, 2), V(double, 3, 3.5), \
V(int64_t, 4, 4), V(double, 5, 5.5), V(int64_t, 6, 6), \
V(double, 7, 7.5), V(int64_t, 8, 8), V(double, 9, 9.5), \
V(int64_t, 10, 10)
#define MIXED_SIGNATURE(V) \
V(int32_t, 0, 0) \
V(double, 1, 1.5) \
V(int32_t, 2, 2) \
V(double, 3, 3.5) \
V(int32_t, 4, 4) \
V(double, 5, 5.5) \
V(int32_t, 6, 6) \
V(double, 7, 7.5) \
V(int32_t, 8, 8) \
V(double, 9, 9.5) \
V##_END(int32_t, 10, 10)
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion test_api_func(
Int64OrDoubleUnion arg0, Int64OrDoubleUnion arg1, Int64OrDoubleUnion arg2,
Int64OrDoubleUnion arg3, Int64OrDoubleUnion arg4, Int64OrDoubleUnion arg5,
Int64OrDoubleUnion arg6, Int64OrDoubleUnion arg7, Int64OrDoubleUnion arg8,
Int64OrDoubleUnion arg9, Int64OrDoubleUnion arg10) {
#else
ReturnType test_api_func(int64_t arg0, double arg1, int64_t arg2, double arg3,
int64_t arg4, double arg5, int64_t arg6, double arg7,
int64_t arg8, double arg9, int64_t arg10) {
#endif
bool result = true;
MIXED_SIGNATURE(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t test_api_func(int32_t arg0, double arg1, int32_t arg2, double arg3,
int32_t arg4, double arg5, int32_t arg6, double arg7,
int32_t arg8, double arg9, int32_t arg10) {
CHECK(MIXED_SIGNATURE(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithMixedSignature, MIXED_SIGNATURE, test_api_func)
#define MIXED_SIGNATURE_DOUBLE_INT(V) \
V(double, 0, 0.5), V(double, 1, 1.5), V(double, 2, 2.5), V(double, 3, 3.5), \
V(double, 4, 4.5), V(double, 5, 5.5), V(double, 6, 6.5), \
V(double, 7, 7.5), V(double, 8, 8.5), V(double, 9, 9.5), \
V(int64_t, 10, 10), V(int64_t, 11, 11), V(int64_t, 12, 12), \
V(int64_t, 13, 13), V(int64_t, 14, 14), V(int64_t, 15, 15), \
V(int64_t, 16, 16), V(int64_t, 17, 17), V(int64_t, 18, 18), \
V(int64_t, 19, 19)
#define MIXED_SIGNATURE_DOUBLE_INT(V) \
V(double, 0, 0.5) \
V(double, 1, 1.5) \
V(double, 2, 2.5) \
V(double, 3, 3.5) \
V(double, 4, 4.5) \
V(double, 5, 5.5) \
V(double, 6, 6.5) \
V(double, 7, 7.5) \
V(double, 8, 8.5) \
V(double, 9, 9.5) \
V(int32_t, 10, 10) \
V(int32_t, 11, 11) \
V(int32_t, 12, 12) \
V(int32_t, 13, 13) \
V(int32_t, 14, 14) \
V(int32_t, 15, 15) \
V(int32_t, 16, 16) \
V(int32_t, 17, 17) \
V(int32_t, 18, 18) \
V##_END(int32_t, 19, 19)
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion func_mixed_double_int(
Int64OrDoubleUnion arg0, Int64OrDoubleUnion arg1, Int64OrDoubleUnion arg2,
Int64OrDoubleUnion arg3, Int64OrDoubleUnion arg4, Int64OrDoubleUnion arg5,
Int64OrDoubleUnion arg6, Int64OrDoubleUnion arg7, Int64OrDoubleUnion arg8,
Int64OrDoubleUnion arg9, Int64OrDoubleUnion arg10, Int64OrDoubleUnion arg11,
Int64OrDoubleUnion arg12, Int64OrDoubleUnion arg13,
Int64OrDoubleUnion arg14, Int64OrDoubleUnion arg15,
Int64OrDoubleUnion arg16, Int64OrDoubleUnion arg17,
Int64OrDoubleUnion arg18, Int64OrDoubleUnion arg19) {
#else
ReturnType func_mixed_double_int(double arg0, double arg1, double arg2,
double arg3, double arg4, double arg5,
double arg6, double arg7, double arg8,
double arg9, int64_t arg10, int64_t arg11,
int64_t arg12, int64_t arg13, int64_t arg14,
int64_t arg15, int64_t arg16, int64_t arg17,
int64_t arg18, int64_t arg19) {
#endif
bool result = true;
MIXED_SIGNATURE_DOUBLE_INT(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t func_mixed_double_int(double arg0, double arg1, double arg2,
double arg3, double arg4, double arg5,
double arg6, double arg7, double arg8,
double arg9, int32_t arg10, int32_t arg11,
int32_t arg12, int32_t arg13, int32_t arg14,
int32_t arg15, int32_t arg16, int32_t arg17,
int32_t arg18, int32_t arg19) {
CHECK(MIXED_SIGNATURE_DOUBLE_INT(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithMixedSignatureDoubleInt, MIXED_SIGNATURE_DOUBLE_INT,
func_mixed_double_int)
#define MIXED_SIGNATURE_INT_DOUBLE(V) \
V(int64_t, 0, 0), V(int64_t, 1, 1), V(int64_t, 2, 2), V(int64_t, 3, 3), \
V(int64_t, 4, 4), V(int64_t, 5, 5), V(int64_t, 6, 6), V(int64_t, 7, 7), \
V(int64_t, 8, 8), V(int64_t, 9, 9), V(double, 10, 10.5), \
V(double, 11, 11.5), V(double, 12, 12.5), V(double, 13, 13.5), \
V(double, 14, 14.5), V(double, 15, 15.5), V(double, 16, 16.5), \
V(double, 17, 17.5), V(double, 18, 18.5), V(double, 19, 19.5)
#define MIXED_SIGNATURE_INT_DOUBLE(V) \
V(int32_t, 0, 0) \
V(int32_t, 1, 1) \
V(int32_t, 2, 2) \
V(int32_t, 3, 3) \
V(int32_t, 4, 4) \
V(int32_t, 5, 5) \
V(int32_t, 6, 6) \
V(int32_t, 7, 7) \
V(int32_t, 8, 8) \
V(int32_t, 9, 9) \
V(double, 10, 10.5) \
V(double, 11, 11.5) \
V(double, 12, 12.5) \
V(double, 13, 13.5) \
V(double, 14, 14.5) \
V(double, 15, 15.5) \
V(double, 16, 16.5) \
V(double, 17, 17.5) \
V(double, 18, 18.5) \
V##_END(double, 19, 19.5)
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion func_mixed_int_double(
Int64OrDoubleUnion arg0, Int64OrDoubleUnion arg1, Int64OrDoubleUnion arg2,
Int64OrDoubleUnion arg3, Int64OrDoubleUnion arg4, Int64OrDoubleUnion arg5,
Int64OrDoubleUnion arg6, Int64OrDoubleUnion arg7, Int64OrDoubleUnion arg8,
Int64OrDoubleUnion arg9, Int64OrDoubleUnion arg10, Int64OrDoubleUnion arg11,
Int64OrDoubleUnion arg12, Int64OrDoubleUnion arg13,
Int64OrDoubleUnion arg14, Int64OrDoubleUnion arg15,
Int64OrDoubleUnion arg16, Int64OrDoubleUnion arg17,
Int64OrDoubleUnion arg18, Int64OrDoubleUnion arg19) {
#else
ReturnType func_mixed_int_double(int64_t arg0, int64_t arg1, int64_t arg2,
int64_t arg3, int64_t arg4, int64_t arg5,
int64_t arg6, int64_t arg7, int64_t arg8,
int64_t arg9, double arg10, double arg11,
double arg12, double arg13, double arg14,
double arg15, double arg16, double arg17,
double arg18, double arg19) {
#endif
bool result = true;
MIXED_SIGNATURE_INT_DOUBLE(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t func_mixed_int_double(int32_t arg0, int32_t arg1, int32_t arg2,
int32_t arg3, int32_t arg4, int32_t arg5,
int32_t arg6, int32_t arg7, int32_t arg8,
int32_t arg9, double arg10, double arg11,
double arg12, double arg13, double arg14,
double arg15, double arg16, double arg17,
double arg18, double arg19) {
CHECK(MIXED_SIGNATURE_INT_DOUBLE(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithMixedSignatureIntDouble, MIXED_SIGNATURE_INT_DOUBLE,
func_mixed_int_double)
#define MIXED_SIGNATURE_INT_DOUBLE_ALT(V) \
V(int64_t, 0, 0), V(double, 1, 1.5), V(int64_t, 2, 2), V(double, 3, 3.5), \
V(int64_t, 4, 4), V(double, 5, 5.5), V(int64_t, 6, 6), \
V(double, 7, 7.5), V(int64_t, 8, 8), V(double, 9, 9.5), \
V(int64_t, 10, 10), V(double, 11, 11.5), V(int64_t, 12, 12), \
V(double, 13, 13.5), V(int64_t, 14, 14), V(double, 15, 15.5), \
V(int64_t, 16, 16), V(double, 17, 17.5), V(int64_t, 18, 18), \
V(double, 19, 19.5)
#define MIXED_SIGNATURE_INT_DOUBLE_ALT(V) \
V(int32_t, 0, 0) \
V(double, 1, 1.5) \
V(int32_t, 2, 2) \
V(double, 3, 3.5) \
V(int32_t, 4, 4) \
V(double, 5, 5.5) \
V(int32_t, 6, 6) \
V(double, 7, 7.5) \
V(int32_t, 8, 8) \
V(double, 9, 9.5) \
V(int32_t, 10, 10) \
V(double, 11, 11.5) \
V(int32_t, 12, 12) \
V(double, 13, 13.5) \
V(int32_t, 14, 14) \
V(double, 15, 15.5) \
V(int32_t, 16, 16) \
V(double, 17, 17.5) \
V(int32_t, 18, 18) \
V##_END(double, 19, 19.5)
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion func_mixed_int_double_alt(
Int64OrDoubleUnion arg0, Int64OrDoubleUnion arg1, Int64OrDoubleUnion arg2,
Int64OrDoubleUnion arg3, Int64OrDoubleUnion arg4, Int64OrDoubleUnion arg5,
Int64OrDoubleUnion arg6, Int64OrDoubleUnion arg7, Int64OrDoubleUnion arg8,
Int64OrDoubleUnion arg9, Int64OrDoubleUnion arg10, Int64OrDoubleUnion arg11,
Int64OrDoubleUnion arg12, Int64OrDoubleUnion arg13,
Int64OrDoubleUnion arg14, Int64OrDoubleUnion arg15,
Int64OrDoubleUnion arg16, Int64OrDoubleUnion arg17,
Int64OrDoubleUnion arg18, Int64OrDoubleUnion arg19) {
#else
ReturnType func_mixed_int_double_alt(int64_t arg0, double arg1, int64_t arg2,
double arg3, int64_t arg4, double arg5,
int64_t arg6, double arg7, int64_t arg8,
double arg9, int64_t arg10, double arg11,
int64_t arg12, double arg13, int64_t arg14,
double arg15, int64_t arg16, double arg17,
int64_t arg18, double arg19) {
#endif
bool result = true;
MIXED_SIGNATURE_INT_DOUBLE_ALT(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t func_mixed_int_double_alt(int32_t arg0, double arg1, int32_t arg2,
double arg3, int32_t arg4, double arg5,
int32_t arg6, double arg7, int32_t arg8,
double arg9, int32_t arg10, double arg11,
int32_t arg12, double arg13, int32_t arg14,
double arg15, int32_t arg16, double arg17,
int32_t arg18, double arg19) {
CHECK(MIXED_SIGNATURE_INT_DOUBLE_ALT(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithMixedSignatureIntDoubleAlt,
MIXED_SIGNATURE_INT_DOUBLE_ALT, func_mixed_int_double_alt)
#define SIGNATURE_ONLY_DOUBLE(V) \
V(double, 0, 0.5), V(double, 1, 1.5), V(double, 2, 2.5), V(double, 3, 3.5), \
V(double, 4, 4.5), V(double, 5, 5.5), V(double, 6, 6.5), \
V(double, 7, 7.5), V(double, 8, 8.5), V(double, 9, 9.5)
#define SIGNATURE_ONLY_DOUBLE(V) \
V(double, 0, 0.5) \
V(double, 1, 1.5) \
V(double, 2, 2.5) \
V(double, 3, 3.5) \
V(double, 4, 4.5) \
V(double, 5, 5.5) \
V(double, 6, 6.5) \
V(double, 7, 7.5) \
V(double, 8, 8.5) \
V##_END(double, 9, 9.5)
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion func_only_double(
Int64OrDoubleUnion arg0, Int64OrDoubleUnion arg1, Int64OrDoubleUnion arg2,
Int64OrDoubleUnion arg3, Int64OrDoubleUnion arg4, Int64OrDoubleUnion arg5,
Int64OrDoubleUnion arg6, Int64OrDoubleUnion arg7, Int64OrDoubleUnion arg8,
Int64OrDoubleUnion arg9) {
#else
ReturnType func_only_double(double arg0, double arg1, double arg2, double arg3,
double arg4, double arg5, double arg6, double arg7,
double arg8, double arg9) {
#endif
bool result = true;
SIGNATURE_ONLY_DOUBLE(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t func_only_double(double arg0, double arg1, double arg2, double arg3,
double arg4, double arg5, double arg6, double arg7,
double arg8, double arg9) {
CHECK(SIGNATURE_ONLY_DOUBLE(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithSignatureOnlyDouble, SIGNATURE_ONLY_DOUBLE,
func_only_double)
#define SIGNATURE_ONLY_DOUBLE_20(V) \
V(double, 0, 0.5), V(double, 1, 1.5), V(double, 2, 2.5), V(double, 3, 3.5), \
V(double, 4, 4.5), V(double, 5, 5.5), V(double, 6, 6.5), \
V(double, 7, 7.5), V(double, 8, 8.5), V(double, 9, 9.5), \
V(double, 10, 10.5), V(double, 11, 11.5), V(double, 12, 12.5), \
V(double, 13, 13.5), V(double, 14, 14.5), V(double, 15, 15.5), \
V(double, 16, 16.5), V(double, 17, 17.5), V(double, 18, 18.5), \
V(double, 19, 19.5)
#define SIGNATURE_ONLY_DOUBLE_20(V) \
V(double, 0, 0.5) \
V(double, 1, 1.5) \
V(double, 2, 2.5) \
V(double, 3, 3.5) \
V(double, 4, 4.5) \
V(double, 5, 5.5) \
V(double, 6, 6.5) \
V(double, 7, 7.5) \
V(double, 8, 8.5) \
V(double, 9, 9.5) \
V(double, 10, 10.5) \
V(double, 11, 11.5) \
V(double, 12, 12.5) \
V(double, 13, 13.5) \
V(double, 14, 14.5) \
V(double, 15, 15.5) \
V(double, 16, 16.5) \
V(double, 17, 17.5) \
V(double, 18, 18.5) \
V##_END(double, 19, 19.5)
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion func_only_double_20(
Int64OrDoubleUnion arg0, Int64OrDoubleUnion arg1, Int64OrDoubleUnion arg2,
Int64OrDoubleUnion arg3, Int64OrDoubleUnion arg4, Int64OrDoubleUnion arg5,
Int64OrDoubleUnion arg6, Int64OrDoubleUnion arg7, Int64OrDoubleUnion arg8,
Int64OrDoubleUnion arg9, Int64OrDoubleUnion arg10, Int64OrDoubleUnion arg11,
Int64OrDoubleUnion arg12, Int64OrDoubleUnion arg13,
Int64OrDoubleUnion arg14, Int64OrDoubleUnion arg15,
Int64OrDoubleUnion arg16, Int64OrDoubleUnion arg17,
Int64OrDoubleUnion arg18, Int64OrDoubleUnion arg19) {
#else
ReturnType func_only_double_20(double arg0, double arg1, double arg2,
double arg3, double arg4, double arg5,
double arg6, double arg7, double arg8,
double arg9, double arg10, double arg11,
double arg12, double arg13, double arg14,
double arg15, double arg16, double arg17,
double arg18, double arg19) {
#endif
bool result = true;
SIGNATURE_ONLY_DOUBLE_20(CHECK_ARG_I);
CHECK(result);
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
Int64OrDoubleUnion ret;
ret.int64_t_value = 42;
return ret;
#else
int32_t func_only_double_20(double arg0, double arg1, double arg2, double arg3,
double arg4, double arg5, double arg6, double arg7,
double arg8, double arg9, double arg10,
double arg11, double arg12, double arg13,
double arg14, double arg15, double arg16,
double arg17, double arg18, double arg19) {
CHECK(SIGNATURE_ONLY_DOUBLE_20(COMPARE_ARG_I));
return 42;
#endif
}
SIGNATURE_TEST(RunCallWithSignatureOnlyDouble20, SIGNATURE_ONLY_DOUBLE_20,
func_only_double_20)
#define MIXED_SIGNATURE_SIMPLE_FLOAT(V) \
V(int32_t, 0, 0) \
V(float, 1, 1.5) \
V##_END(int32_t, 2, 2)
int32_t test_api_func_simple_float(int32_t arg0, float arg1, int32_t arg2) {
CHECK(MIXED_SIGNATURE_SIMPLE_FLOAT(COMPARE_ARG_I));
return 42;
}
SIGNATURE_TEST(RunCallWithMixedSignatureSimpleFloat,
MIXED_SIGNATURE_SIMPLE_FLOAT, test_api_func_simple_float)
#define MIXED_SIGNATURE_FLOAT(V) \
V(int32_t, 0, 0) \
V(float, 1, 1.5) \
V(int32_t, 2, 2) \
V(float, 3, 3.5) \
V(int32_t, 4, 4) \
V(float, 5, 5.5) \
V(int32_t, 6, 6) \
V(float, 7, 7.5) \
V(int32_t, 8, 8) \
V(float, 9, 9.5) \
V##_END(int32_t, 10, 10)
int32_t test_api_func_float(int32_t arg0, float arg1, int32_t arg2, float arg3,
int32_t arg4, float arg5, int32_t arg6, float arg7,
int32_t arg8, float arg9, int32_t arg10) {
CHECK(MIXED_SIGNATURE_FLOAT(COMPARE_ARG_I));
return 42;
}
SIGNATURE_TEST(RunCallWithMixedSignatureFloat, MIXED_SIGNATURE_FLOAT,
test_api_func_float)
#define MIXED_SIGNATURE_INT_FLOAT_ALT(V) \
V(int32_t, 0, 0) \
V(float, 1, 1.5) \
V(int32_t, 2, 2) \
V(float, 3, 3.5) \
V(int32_t, 4, 4) \
V(float, 5, 5.5) \
V(int32_t, 6, 6) \
V(float, 7, 7.5) \
V(int32_t, 8, 8) \
V(float, 9, 9.5) \
V(int32_t, 10, 10) \
V(float, 11, 11.5) \
V(int32_t, 12, 12) \
V(float, 13, 13.5) \
V(int32_t, 14, 14) \
V(float, 15, 15.5) \
V(int32_t, 16, 16) \
V(float, 17, 17.5) \
V(int32_t, 18, 18) \
V##_END(float, 19, 19.5)
int32_t func_mixed_int_float_alt(int32_t arg0, float arg1, int32_t arg2,
float arg3, int32_t arg4, float arg5,
int32_t arg6, float arg7, int32_t arg8,
float arg9, int32_t arg10, float arg11,
int32_t arg12, float arg13, int32_t arg14,
float arg15, int32_t arg16, float arg17,
int32_t arg18, float arg19) {
CHECK(MIXED_SIGNATURE_INT_FLOAT_ALT(COMPARE_ARG_I));
return 42;
}
SIGNATURE_TEST(RunCallWithMixedSignatureIntFloatAlt,
MIXED_SIGNATURE_INT_FLOAT_ALT, func_mixed_int_float_alt)
#define SIGNATURE_ONLY_FLOAT_20(V) \
V(float, 0, 0.5) \
V(float, 1, 1.5) \
V(float, 2, 2.5) \
V(float, 3, 3.5) \
V(float, 4, 4.5) \
V(float, 5, 5.5) \
V(float, 6, 6.5) \
V(float, 7, 7.5) \
V(float, 8, 8.5) \
V(float, 9, 9.5) \
V(float, 10, 10.5) \
V(float, 11, 11.5) \
V(float, 12, 12.5) \
V(float, 13, 13.5) \
V(float, 14, 14.5) \
V(float, 15, 15.5) \
V(float, 16, 16.5) \
V(float, 17, 17.5) \
V(float, 18, 18.5) \
V##_END(float, 19, 19.5)
int32_t func_only_float_20(float arg0, float arg1, float arg2, float arg3,
float arg4, float arg5, float arg6, float arg7,
float arg8, float arg9, float arg10, float arg11,
float arg12, float arg13, float arg14, float arg15,
float arg16, float arg17, float arg18, float arg19) {
CHECK(SIGNATURE_ONLY_FLOAT_20(COMPARE_ARG_I));
return 42;
}
SIGNATURE_TEST(RunCallWithSignatureOnlyFloat20, SIGNATURE_ONLY_FLOAT_20,
func_only_float_20)
#define MIXED_SIGNATURE_FLOAT_INT(V) \
V(float, 0, 0.5) \
V(float, 1, 1.5) \
V(float, 2, 2.5) \
V(float, 3, 3.5) \
V(float, 4, 4.5) \
V(float, 5, 5.5) \
V(float, 6, 6.5) \
V(float, 7, 7.5) \
V(float, 8, 8.5) \
V(float, 9, 9.5) \
V(int32_t, 10, 10) \
V(int32_t, 11, 11) \
V(int32_t, 12, 12) \
V(int32_t, 13, 13) \
V(int32_t, 14, 14) \
V(int32_t, 15, 15) \
V(int32_t, 16, 16) \
V(int32_t, 17, 17) \
V(int32_t, 18, 18) \
V##_END(int32_t, 19, 19)
int32_t func_mixed_float_int(float arg0, float arg1, float arg2, float arg3,
float arg4, float arg5, float arg6, float arg7,
float arg8, float arg9, int32_t arg10,
int32_t arg11, int32_t arg12, int32_t arg13,
int32_t arg14, int32_t arg15, int32_t arg16,
int32_t arg17, int32_t arg18, int32_t arg19) {
CHECK(MIXED_SIGNATURE_FLOAT_INT(COMPARE_ARG_I));
return 42;
}
SIGNATURE_TEST(RunCallWithMixedSignatureFloatInt, MIXED_SIGNATURE_FLOAT_INT,
func_mixed_float_int)
#define MIXED_SIGNATURE_INT_FLOAT(V) \
V(int32_t, 0, 0) \
V(int32_t, 1, 1) \
V(int32_t, 2, 2) \
V(int32_t, 3, 3) \
V(int32_t, 4, 4) \
V(int32_t, 5, 5) \
V(int32_t, 6, 6) \
V(int32_t, 7, 7) \
V(int32_t, 8, 8) \
V(int32_t, 9, 9) \
V(float, 10, 10.5) \
V(float, 11, 11.5) \
V(float, 12, 12.5) \
V(float, 13, 13.5) \
V(float, 14, 14.5) \
V(float, 15, 15.5) \
V(float, 16, 16.5) \
V(float, 17, 17.5) \
V(float, 18, 18.5) \
V##_END(float, 19, 19.5)
int32_t func_mixed_int_float(int32_t arg0, int32_t arg1, int32_t arg2,
int32_t arg3, int32_t arg4, int32_t arg5,
int32_t arg6, int32_t arg7, int32_t arg8,
int32_t arg9, float arg10, float arg11,
float arg12, float arg13, float arg14, float arg15,
float arg16, float arg17, float arg18,
float arg19) {
CHECK(MIXED_SIGNATURE_INT_FLOAT(COMPARE_ARG_I));
return 42;
}
SIGNATURE_TEST(RunCallWithMixedSignatureIntFloat, MIXED_SIGNATURE_INT_FLOAT,
func_mixed_int_float)
#define MIXED_SIGNATURE_FLOAT_DOUBLE(V) \
V(float, 0, 0.5) \
V(float, 1, 1.5) \
V(float, 2, 2.5) \
V(float, 3, 3.5) \
V(float, 4, 4.5) \
V(float, 5, 5.5) \
V(float, 6, 6.5) \
V(float, 7, 7.5) \
V(float, 8, 8.5) \
V(float, 9, 9.5) \
V(double, 10, 10.7) \
V(double, 11, 11.7) \
V(double, 12, 12.7) \
V(double, 13, 13.7) \
V(double, 14, 14.7) \
V(double, 15, 15.7) \
V(double, 16, 16.7) \
V(double, 17, 17.7) \
V(double, 18, 18.7) \
V##_END(double, 19, 19.7)
int32_t func_mixed_float_double(float arg0, float arg1, float arg2, float arg3,
float arg4, float arg5, float arg6, float arg7,
float arg8, float arg9, double arg10,
double arg11, double arg12, double arg13,
double arg14, double arg15, double arg16,
double arg17, double arg18, double arg19) {
CHECK(MIXED_SIGNATURE_FLOAT_DOUBLE(COMPARE_ARG_I));
return 42;
}
SIGNATURE_TEST(RunCallWithMixedSignatureFloatDouble,
MIXED_SIGNATURE_FLOAT_DOUBLE, func_mixed_float_double)
#define MIXED_SIGNATURE_DOUBLE_FLOAT(V) \
V(double, 0, 0.7) \
V(double, 1, 1.7) \
V(double, 2, 2.7) \
V(double, 3, 3.7) \
V(double, 4, 4.7) \
V(double, 5, 5.7) \
V(double, 6, 6.7) \
V(double, 7, 7.7) \
V(double, 8, 8.7) \
V(double, 9, 9.7) \
V(float, 10, 10.5) \
V(float, 11, 11.5) \
V(float, 12, 12.5) \
V(float, 13, 13.5) \
V(float, 14, 14.5) \
V(float, 15, 15.5) \
V(float, 16, 16.5) \
V(float, 17, 17.5) \
V(float, 18, 18.5) \
V##_END(float, 19, 19.5)
int32_t func_mixed_double_float(double arg0, double arg1, double arg2,
double arg3, double arg4, double arg5,
double arg6, double arg7, double arg8,
double arg9, float arg10, float arg11,
float arg12, float arg13, float arg14,
float arg15, float arg16, float arg17,
float arg18, float arg19) {
CHECK(MIXED_SIGNATURE_DOUBLE_FLOAT(COMPARE_ARG_I));
return 42;
}
SIGNATURE_TEST(RunCallWithMixedSignatureDoubleFloat,
MIXED_SIGNATURE_DOUBLE_FLOAT, func_mixed_double_float)
#endif // V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
} // namespace compiler

View File

@ -6699,310 +6699,7 @@ TEST(RunCallCFunction9) {
m.Call(x));
}
}
#endif // !USE_SIMULATOR
#ifdef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
#define IF_SIMULATOR_ADD_SIGNATURE \
EncodedCSignature sig = m.call_descriptor()->ToEncodedCSignature(); \
Simulator::current(m.main_isolate()) \
->AddSignatureForTargetForTesting(func_address, sig);
#else
#define IF_SIMULATOR_ADD_SIGNATURE
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
#define EXTERNAL_REF_FROM_FUNC(FUNC) \
Address func_address = FUNCTION_ADDR(&FUNC); \
ExternalReference::Type func_type = ExternalReference::FAST_C_CALL; \
ApiFunction func(func_address); \
ExternalReference ref = ExternalReference::Create(&func, func_type);
namespace {
void CheckEqual(double expected, double actual) {
if (std::isnan(expected)) {
CHECK(std::isnan(actual));
} else {
CHECK_EQ(actual, expected);
}
}
void CheckLessOrEqual(double actual, double expected) {
if (std::isnan(expected)) {
CHECK(std::isnan(actual));
} else if (std::isnan(actual)) {
return;
} else {
CHECK_LE(actual, expected);
}
}
const double foo_result = 3.14;
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
union Int64OrDoubleUnion {
int64_t int64_value;
double double_value;
};
Int64OrDoubleUnion double_foo0() {
Int64OrDoubleUnion ret;
ret.double_value = foo_result;
return ret;
}
Int64OrDoubleUnion double_foo1(Int64OrDoubleUnion x) {
Int64OrDoubleUnion ret;
ret.double_value = x.double_value;
return ret;
}
Int64OrDoubleUnion double_foo2(Int64OrDoubleUnion x, Int64OrDoubleUnion y) {
Int64OrDoubleUnion ret;
ret.double_value = x.double_value * 10 + y.double_value;
return ret;
}
Int64OrDoubleUnion double_foo8(Int64OrDoubleUnion a, Int64OrDoubleUnion b,
Int64OrDoubleUnion c, Int64OrDoubleUnion d,
Int64OrDoubleUnion e, Int64OrDoubleUnion f,
Int64OrDoubleUnion g, Int64OrDoubleUnion h) {
Int64OrDoubleUnion ret;
ret.double_value = a.double_value + b.double_value + c.double_value +
d.double_value + e.double_value + f.double_value +
g.double_value + h.double_value;
return ret;
}
Int64OrDoubleUnion double_foo9(Int64OrDoubleUnion a, Int64OrDoubleUnion b,
Int64OrDoubleUnion c, Int64OrDoubleUnion d,
Int64OrDoubleUnion e, Int64OrDoubleUnion f,
Int64OrDoubleUnion g, Int64OrDoubleUnion h,
Int64OrDoubleUnion i) {
Int64OrDoubleUnion ret;
ret.double_value = a.double_value + b.double_value + c.double_value +
d.double_value + e.double_value + f.double_value +
g.double_value + h.double_value + i.double_value;
return ret;
}
Int64OrDoubleUnion double_foo10(Int64OrDoubleUnion a, Int64OrDoubleUnion b,
Int64OrDoubleUnion c, Int64OrDoubleUnion d,
Int64OrDoubleUnion e, Int64OrDoubleUnion f,
Int64OrDoubleUnion g, Int64OrDoubleUnion h,
Int64OrDoubleUnion i, Int64OrDoubleUnion j) {
Int64OrDoubleUnion ret;
ret.double_value = a.double_value + b.double_value + c.double_value +
d.double_value + e.double_value + f.double_value +
g.double_value + h.double_value + i.double_value +
j.int64_value;
return ret;
}
Int64OrDoubleUnion int_foo10(Int64OrDoubleUnion a, Int64OrDoubleUnion b,
Int64OrDoubleUnion c, Int64OrDoubleUnion d,
Int64OrDoubleUnion e, Int64OrDoubleUnion f,
Int64OrDoubleUnion g, Int64OrDoubleUnion h,
Int64OrDoubleUnion i, Int64OrDoubleUnion j) {
Int64OrDoubleUnion ret;
ret.double_value = a.int64_value + b.int64_value + c.int64_value +
d.int64_value + e.int64_value + f.int64_value +
g.int64_value + h.int64_value + i.int64_value +
j.double_value;
return ret;
}
#else // def USE_SIMULATOR_WITH_GENERIC_C_CALLS
double double_foo0() { return foo_result; }
double double_foo1(double x) { return x; }
double double_foo2(double x, double y) { return x * 10 + y; }
double double_foo8(double a, double b, double c, double d, double e, double f,
double g, double h) {
return a + b + c + d + e + f + g + h;
}
double double_foo9(double a, double b, double c, double d, double e, double f,
double g, double h, double i) {
return a + b + c + d + e + f + g + h + i;
}
double double_foo10(double a, double b, double c, double d, double e, double f,
double g, double h, double i, int64_t j) {
return a + b + c + d + e + f + g + h + i + j;
}
double int_foo10(int64_t a, int64_t b, int64_t c, int64_t d, int64_t e,
int64_t f, int64_t g, int64_t h, int64_t i, double j) {
return a + b + c + d + e + f + g + h + i + j;
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
} // namespace
TEST(RunCallDoubleCFunction0) {
RawMachineAssemblerTester<double> m;
EXTERNAL_REF_FROM_FUNC(double_foo0)
IF_SIMULATOR_ADD_SIGNATURE
Node* function = m.ExternalConstant(ref);
m.Return(m.CallCFunction(function, MachineType::Float64()));
CheckEqual(foo_result, m.Call());
}
TEST(RunCallDoubleCFunction1) {
RawMachineAssemblerTester<double> m(MachineType::Float64());
EXTERNAL_REF_FROM_FUNC(double_foo1)
IF_SIMULATOR_ADD_SIGNATURE
Node* function = m.ExternalConstant(ref);
m.Return(
m.CallCFunction(function, MachineType::Float64(),
std::make_pair(MachineType::Float64(), m.Parameter(0))));
FOR_FLOAT64_INPUTS(x) { CheckEqual(x, m.Call(x)); }
}
TEST(RunCallDoubleCFunction2) {
RawMachineAssemblerTester<double> m(MachineType::Float64(),
MachineType::Float64());
EXTERNAL_REF_FROM_FUNC(double_foo2)
IF_SIMULATOR_ADD_SIGNATURE
Node* function = m.ExternalConstant(ref);
m.Return(
m.CallCFunction(function, MachineType::Float64(),
std::make_pair(MachineType::Float64(), m.Parameter(0)),
std::make_pair(MachineType::Float64(), m.Parameter(1))));
FOR_FLOAT64_INPUTS(x) {
if (std::isnan(x)) continue;
FOR_FLOAT64_INPUTS(y) { CheckEqual(x * 10 + y, m.Call(x, y)); }
}
}
TEST(RunCallDoubleCFunction8) {
RawMachineAssemblerTester<double> m(
MachineType::Float64(), MachineType::Float64(), MachineType::Float64(),
MachineType::Float64(), MachineType::Float64(), MachineType::Float64(),
MachineType::Float64(), MachineType::Float64());
EXTERNAL_REF_FROM_FUNC(double_foo8)
IF_SIMULATOR_ADD_SIGNATURE
Node* function = m.ExternalConstant(ref);
Node* param = m.Parameter(0);
m.Return(m.CallCFunction(function, MachineType::Float64(),
std::make_pair(MachineType::Float64(), param),
std::make_pair(MachineType::Float64(), param),
std::make_pair(MachineType::Float64(), param),
std::make_pair(MachineType::Float64(), param),
std::make_pair(MachineType::Float64(), param),
std::make_pair(MachineType::Float64(), param),
std::make_pair(MachineType::Float64(), param),
std::make_pair(MachineType::Float64(), param)));
FOR_FLOAT64_INPUTS(x) {
double diff = std::fabs(x * 8.0 - m.Call(x));
CheckLessOrEqual(diff, std::numeric_limits<double>::epsilon());
}
}
TEST(RunCallDoubleCFunction9) {
RawMachineAssemblerTester<double> m(
MachineType::Float64(), MachineType::Float64(), MachineType::Float64(),
MachineType::Float64(), MachineType::Float64(), MachineType::Float64(),
MachineType::Float64(), MachineType::Float64(), MachineType::Float64());
EXTERNAL_REF_FROM_FUNC(double_foo9)
IF_SIMULATOR_ADD_SIGNATURE
Node* function = m.ExternalConstant(ref);
Node* param = m.Parameter(0);
m.Return(m.CallCFunction(
function, MachineType::Float64(),
std::make_pair(MachineType::Float64(), param),
std::make_pair(MachineType::Float64(),
m.Float64Add(param, m.Float64Constant(1))),
std::make_pair(MachineType::Float64(),
m.Float64Add(param, m.Float64Constant(2))),
std::make_pair(MachineType::Float64(),
m.Float64Add(param, m.Float64Constant(3))),
std::make_pair(MachineType::Float64(),
m.Float64Add(param, m.Float64Constant(4))),
std::make_pair(MachineType::Float64(),
m.Float64Add(param, m.Float64Constant(5))),
std::make_pair(MachineType::Float64(),
m.Float64Add(param, m.Float64Constant(6))),
std::make_pair(MachineType::Float64(),
m.Float64Add(param, m.Float64Constant(7))),
std::make_pair(MachineType::Float64(),
m.Float64Add(param, m.Float64Constant(8)))));
FOR_FLOAT64_INPUTS(x) {
double diff = x * 9.0 + 36.0 - m.Call(x);
CheckLessOrEqual(diff, std::numeric_limits<double>::epsilon());
}
}
TEST(RunCallDoubleCFunction10) {
RawMachineAssemblerTester<double> m(
MachineType::Float64(), MachineType::Float64(), MachineType::Float64(),
MachineType::Float64(), MachineType::Float64(), MachineType::Float64(),
MachineType::Float64(), MachineType::Float64(), MachineType::Float64(),
MachineType::Int64());
EXTERNAL_REF_FROM_FUNC(double_foo10)
IF_SIMULATOR_ADD_SIGNATURE
Node* function = m.ExternalConstant(ref);
m.Return(
m.CallCFunction(function, MachineType::Float64(),
std::make_pair(MachineType::Float64(), m.Parameter(0)),
std::make_pair(MachineType::Float64(), m.Parameter(1)),
std::make_pair(MachineType::Float64(), m.Parameter(2)),
std::make_pair(MachineType::Float64(), m.Parameter(3)),
std::make_pair(MachineType::Float64(), m.Parameter(4)),
std::make_pair(MachineType::Float64(), m.Parameter(5)),
std::make_pair(MachineType::Float64(), m.Parameter(6)),
std::make_pair(MachineType::Float64(), m.Parameter(7)),
std::make_pair(MachineType::Float64(), m.Parameter(8)),
std::make_pair(MachineType::Int64(), m.Parameter(9))));
FOR_INT64_INPUTS(x) {
double c = m.Call(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, x);
double diff = 45.0 + x - c;
CheckLessOrEqual(fabs(diff), std::numeric_limits<double>::epsilon());
}
}
TEST(RunCallIntCFunction10) {
RawMachineAssemblerTester<double> m(
MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
MachineType::Float64());
EXTERNAL_REF_FROM_FUNC(int_foo10)
IF_SIMULATOR_ADD_SIGNATURE
Node* function = m.ExternalConstant(ref);
m.Return(
m.CallCFunction(function, MachineType::Float64(),
std::make_pair(MachineType::Int64(), m.Parameter(0)),
std::make_pair(MachineType::Int64(), m.Parameter(1)),
std::make_pair(MachineType::Int64(), m.Parameter(2)),
std::make_pair(MachineType::Int64(), m.Parameter(3)),
std::make_pair(MachineType::Int64(), m.Parameter(4)),
std::make_pair(MachineType::Int64(), m.Parameter(5)),
std::make_pair(MachineType::Int64(), m.Parameter(6)),
std::make_pair(MachineType::Int64(), m.Parameter(7)),
std::make_pair(MachineType::Int64(), m.Parameter(8)),
std::make_pair(MachineType::Float64(), m.Parameter(9))));
FOR_FLOAT64_INPUTS(x) {
double c = m.Call(static_cast<int64_t>(1), static_cast<int64_t>(2),
static_cast<int64_t>(3), static_cast<int64_t>(4),
static_cast<int64_t>(5), static_cast<int64_t>(6),
static_cast<int64_t>(7), static_cast<int64_t>(8),
static_cast<int64_t>(9), x);
double diff = 45.0 + x - c;
CheckLessOrEqual(fabs(diff), std::numeric_limits<double>::epsilon());
}
}
#endif // V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
#endif // USE_SIMULATOR
#if V8_TARGET_ARCH_64_BIT
// TODO(titzer): run int64 tests on all platforms when supported.

View File

@ -27867,81 +27867,6 @@ UNINITIALIZED_TEST(NestedIsolates) {
#ifndef V8_LITE_MODE
namespace {
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
template <typename Value>
Value PrimitiveFromMixedType(v8::AnyCType argument);
template <>
bool PrimitiveFromMixedType(v8::AnyCType argument) {
return argument.bool_value;
}
template <>
int32_t PrimitiveFromMixedType(v8::AnyCType argument) {
return argument.int32_value;
}
template <>
uint32_t PrimitiveFromMixedType(v8::AnyCType argument) {
return argument.uint32_value;
}
template <>
int64_t PrimitiveFromMixedType(v8::AnyCType argument) {
return argument.int64_value;
}
template <>
uint64_t PrimitiveFromMixedType(v8::AnyCType argument) {
return argument.uint64_value;
}
template <>
float PrimitiveFromMixedType(v8::AnyCType argument) {
return argument.float_value;
}
template <>
double PrimitiveFromMixedType(v8::AnyCType argument) {
return argument.double_value;
}
template <>
v8::Local<v8::Value> PrimitiveFromMixedType(v8::AnyCType argument) {
return argument.object_value;
}
template <typename T>
v8::AnyCType PrimitiveToMixedType(T value) {
return v8::AnyCType();
}
template <>
v8::AnyCType PrimitiveToMixedType(bool value) {
v8::AnyCType ret;
ret.bool_value = value;
return ret;
}
template <>
v8::AnyCType PrimitiveToMixedType(int32_t value) {
v8::AnyCType ret;
ret.int32_value = value;
return ret;
}
template <>
v8::AnyCType PrimitiveToMixedType(uint32_t value) {
v8::AnyCType ret;
ret.uint32_value = value;
return ret;
}
template <>
v8::AnyCType PrimitiveToMixedType(float value) {
v8::AnyCType ret;
ret.float_value = value;
return ret;
}
template <>
v8::AnyCType PrimitiveToMixedType(double value) {
v8::AnyCType ret;
ret.double_value = value;
return ret;
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
template <typename Value, typename Impl, typename Ret>
struct BasicApiChecker {
static Ret FastCallback(v8::Local<v8::Object> receiver, Value argument,
@ -27957,7 +27882,6 @@ struct BasicApiChecker {
v8::FastApiCallbackOptions options = {false, {0}};
return Impl::FastCallback(receiver, argument, options);
}
static void SlowCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
Impl::SlowCallback(info);
}
@ -27974,44 +27898,6 @@ struct BasicApiChecker {
ApiCheckerResultFlags result_ = ApiCheckerResult::kNotCalled;
};
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
template <typename Value, typename Impl, typename Ret,
typename = std::enable_if_t<!std::is_void<Ret>::value>>
static v8::AnyCType FastCallbackPatch(v8::AnyCType receiver,
v8::AnyCType argument,
v8::AnyCType options) {
v8::AnyCType ret = PrimitiveToMixedType<Ret>(Impl::FastCallback(
receiver.object_value, PrimitiveFromMixedType<Value>(argument),
*(options.options_value)));
return ret;
}
template <typename Value, typename Impl, typename Ret,
typename = std::enable_if_t<!std::is_void<Ret>::value>>
static v8::AnyCType FastCallbackNoFallbackWrapper(v8::AnyCType receiver,
v8::AnyCType argument) {
v8::FastApiCallbackOptions options = {false, {0}};
v8::AnyCType ret = PrimitiveToMixedType<Ret>(Impl::FastCallback(
receiver.object_value, PrimitiveFromMixedType<Value>(argument), options));
return ret;
}
template <typename Value, typename Impl, typename Ret,
typename = std::enable_if_t<std::is_void<Ret>::value>>
static void FastCallbackPatch(v8::AnyCType receiver, v8::AnyCType argument,
v8::AnyCType options) {
return Impl::FastCallback(receiver.object_value,
PrimitiveFromMixedType<Value>(argument),
*(options.options_value));
}
template <typename Value, typename Impl, typename Ret,
typename = std::enable_if_t<std::is_void<Ret>::value>>
static void FastCallbackNoFallbackWrapper(v8::AnyCType receiver,
v8::AnyCType argument) {
v8::FastApiCallbackOptions options = {false, {0}};
return Impl::FastCallback(receiver.object_value,
PrimitiveFromMixedType<Value>(argument), options);
}
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
enum class Behavior {
kNoException,
kException, // An exception should be thrown by the callback function.
@ -28156,23 +28042,11 @@ bool SetupTest(v8::Local<v8::Value> initial_value, LocalContext* env,
v8::CFunction c_func;
if (supports_fallback) {
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
c_func =
v8::CFunction::Make(BasicApiChecker<Value, Impl, Ret>::FastCallback,
FastCallbackPatch<Value, Impl, Ret>);
#else // USE_SIMULATOR_WITH_GENERIC_C_CALLS
c_func =
v8::CFunction::Make(BasicApiChecker<Value, Impl, Ret>::FastCallback);
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
} else {
#ifdef USE_SIMULATOR_WITH_GENERIC_C_CALLS
c_func = v8::CFunction::Make(
BasicApiChecker<Value, Impl, Ret>::FastCallbackNoFallback,
FastCallbackNoFallbackWrapper<Value, Impl, Ret>);
#else // USE_SIMULATOR_WITH_GENERIC_C_CALLS
c_func = v8::CFunction::Make(
BasicApiChecker<Value, Impl, Ret>::FastCallbackNoFallback);
#endif // USE_SIMULATOR_WITH_GENERIC_C_CALLS
}
CHECK_EQ(c_func.ArgumentInfo(0).GetType(), v8::CTypeInfo::Type::kV8Value);