1 // Copyright 2014 the V8 project authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file.
4 
5 #include "src/codegen/external-reference.h"
6 #include "src/objects/objects-inl.h"
7 #include "test/cctest/cctest.h"
8 #include "test/cctest/compiler/codegen-tester.h"
9 #include "test/cctest/compiler/value-helper.h"
10 
11 #if V8_ENABLE_WEBASSEMBLY
12 #include "src/wasm/wasm-external-refs.h"
13 #endif  // V8_ENABLE_WEBASSEMBLY
14 
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18 
19 template <typename InType, typename OutType, typename Iterable>
TestExternalReference_ConvertOp(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,void (* wrapper)(Address),Iterable inputs)20 void TestExternalReference_ConvertOp(
21     BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
22     void (*wrapper)(Address), Iterable inputs) {
23   constexpr size_t kBufferSize = std::max(sizeof(InType), sizeof(OutType));
24   uint8_t buffer[kBufferSize] = {0};
25   Address buffer_addr = reinterpret_cast<Address>(buffer);
26 
27   Node* function = m->ExternalConstant(ref);
28   m->CallCFunction(
29       function, MachineType::Pointer(),
30       std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer)));
31   m->Return(m->Int32Constant(4356));
32 
33   for (InType input : inputs) {
34     WriteUnalignedValue<InType>(buffer_addr, input);
35 
36     CHECK_EQ(4356, m->Call());
37     OutType output = ReadUnalignedValue<OutType>(buffer_addr);
38 
39     WriteUnalignedValue<InType>(buffer_addr, input);
40     wrapper(buffer_addr);
41     OutType expected_output = ReadUnalignedValue<OutType>(buffer_addr);
42 
43     CHECK_EQ(expected_output, output);
44   }
45 }
46 
47 template <typename InType, typename OutType, typename Iterable>
TestExternalReference_ConvertOpWithOutputAndReturn(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,int32_t (* wrapper)(Address),Iterable inputs)48 void TestExternalReference_ConvertOpWithOutputAndReturn(
49     BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
50     int32_t (*wrapper)(Address), Iterable inputs) {
51   constexpr size_t kBufferSize = std::max(sizeof(InType), sizeof(OutType));
52   uint8_t buffer[kBufferSize] = {0};
53   Address buffer_addr = reinterpret_cast<Address>(buffer);
54 
55   Node* function = m->ExternalConstant(ref);
56   m->Return(m->CallCFunction(
57       function, MachineType::Int32(),
58       std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer))));
59 
60   for (InType input : inputs) {
61     WriteUnalignedValue<InType>(buffer_addr, input);
62 
63     int32_t ret = m->Call();
64     OutType output = ReadUnalignedValue<OutType>(buffer_addr);
65 
66     WriteUnalignedValue<InType>(buffer_addr, input);
67     int32_t expected_ret = wrapper(buffer_addr);
68     OutType expected_output = ReadUnalignedValue<OutType>(buffer_addr);
69 
70     CHECK_EQ(expected_ret, ret);
71     CHECK_EQ(expected_output, output);
72   }
73 }
74 
75 template <typename InType, typename OutType, typename Iterable>
TestExternalReference_ConvertOpWithReturn(BufferedRawMachineAssemblerTester<OutType> * m,ExternalReference ref,OutType (* wrapper)(Address),Iterable inputs)76 void TestExternalReference_ConvertOpWithReturn(
77     BufferedRawMachineAssemblerTester<OutType>* m, ExternalReference ref,
78     OutType (*wrapper)(Address), Iterable inputs) {
79   constexpr size_t kBufferSize = sizeof(InType);
80   uint8_t buffer[kBufferSize] = {0};
81   Address buffer_addr = reinterpret_cast<Address>(buffer);
82 
83   Node* function = m->ExternalConstant(ref);
84   m->Return(m->CallCFunction(
85       function, MachineType::Int32(),
86       std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer))));
87 
88   for (InType input : inputs) {
89     WriteUnalignedValue<InType>(buffer_addr, input);
90 
91     OutType ret = m->Call();
92 
93     WriteUnalignedValue<InType>(buffer_addr, input);
94     OutType expected_ret = wrapper(buffer_addr);
95 
96     CHECK_EQ(expected_ret, ret);
97   }
98 }
99 
100 template <typename Type>
isnan(Type value)101 bool isnan(Type value) {
102   return false;
103 }
104 template <>
isnan(float value)105 bool isnan<float>(float value) {
106   return std::isnan(value);
107 }
108 template <>
isnan(double value)109 bool isnan<double>(double value) {
110   return std::isnan(value);
111 }
112 
113 template <typename Type, typename Iterable>
TestExternalReference_UnOp(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,void (* wrapper)(Address),Iterable inputs)114 void TestExternalReference_UnOp(BufferedRawMachineAssemblerTester<int32_t>* m,
115                                 ExternalReference ref, void (*wrapper)(Address),
116                                 Iterable inputs) {
117   constexpr size_t kBufferSize = sizeof(Type);
118   uint8_t buffer[kBufferSize] = {0};
119   Address buffer_addr = reinterpret_cast<Address>(buffer);
120 
121   Node* function = m->ExternalConstant(ref);
122   m->CallCFunction(
123       function, MachineType::Int32(),
124       std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer)));
125   m->Return(m->Int32Constant(4356));
126 
127   for (Type input : inputs) {
128     WriteUnalignedValue<Type>(buffer_addr, input);
129     CHECK_EQ(4356, m->Call());
130     Type output = ReadUnalignedValue<Type>(buffer_addr);
131 
132     WriteUnalignedValue<Type>(buffer_addr, input);
133     wrapper(buffer_addr);
134     Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
135 
136     if (isnan(expected_output) && isnan(output)) continue;
137     CHECK_EQ(expected_output, output);
138   }
139 }
140 
141 template <typename Type, typename Iterable>
TestExternalReference_BinOp(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,void (* wrapper)(Address),Iterable inputs)142 void TestExternalReference_BinOp(BufferedRawMachineAssemblerTester<int32_t>* m,
143                                  ExternalReference ref,
144                                  void (*wrapper)(Address), Iterable inputs) {
145   constexpr size_t kBufferSize = 2 * sizeof(Type);
146   uint8_t buffer[kBufferSize] = {0};
147   Address buffer_addr = reinterpret_cast<Address>(buffer);
148 
149   Node* function = m->ExternalConstant(ref);
150   m->CallCFunction(
151       function, MachineType::Int32(),
152       std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer)));
153   m->Return(m->Int32Constant(4356));
154 
155   for (Type input1 : inputs) {
156     for (Type input2 : inputs) {
157       WriteUnalignedValue<Type>(buffer_addr, input1);
158       WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
159       CHECK_EQ(4356, m->Call());
160       Type output = ReadUnalignedValue<Type>(buffer_addr);
161 
162       WriteUnalignedValue<Type>(buffer_addr, input1);
163       WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
164       wrapper(buffer_addr);
165       Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
166 
167       if (isnan(expected_output) && isnan(output)) continue;
168       CHECK_EQ(expected_output, output);
169     }
170   }
171 }
172 
173 template <typename Type, typename Iterable>
TestExternalReference_BinOpWithReturn(BufferedRawMachineAssemblerTester<int32_t> * m,ExternalReference ref,int32_t (* wrapper)(Address),Iterable inputs)174 void TestExternalReference_BinOpWithReturn(
175     BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
176     int32_t (*wrapper)(Address), Iterable inputs) {
177   constexpr size_t kBufferSize = 2 * sizeof(Type);
178   uint8_t buffer[kBufferSize] = {0};
179   Address buffer_addr = reinterpret_cast<Address>(buffer);
180 
181   Node* function = m->ExternalConstant(ref);
182   m->Return(m->CallCFunction(
183       function, MachineType::Int32(),
184       std::make_pair(MachineType::Pointer(), m->PointerConstant(buffer))));
185 
186   for (Type input1 : inputs) {
187     for (Type input2 : inputs) {
188       WriteUnalignedValue<Type>(buffer_addr, input1);
189       WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
190       int32_t ret = m->Call();
191       Type output = ReadUnalignedValue<Type>(buffer_addr);
192 
193       WriteUnalignedValue<Type>(buffer_addr, input1);
194       WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
195       int32_t expected_ret = wrapper(buffer_addr);
196       Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
197 
198       CHECK_EQ(expected_ret, ret);
199       if (isnan(expected_output) && isnan(output)) continue;
200       CHECK_EQ(expected_output, output);
201     }
202   }
203 }
204 
205 #if V8_ENABLE_WEBASSEMBLY
TEST(RunCallF32Trunc)206 TEST(RunCallF32Trunc) {
207   BufferedRawMachineAssemblerTester<int32_t> m;
208   ExternalReference ref = ExternalReference::wasm_f32_trunc();
209   TestExternalReference_UnOp<float>(&m, ref, wasm::f32_trunc_wrapper,
210                                     ValueHelper::float32_vector());
211 }
212 
TEST(RunCallF32Floor)213 TEST(RunCallF32Floor) {
214   BufferedRawMachineAssemblerTester<int32_t> m;
215   ExternalReference ref = ExternalReference::wasm_f32_floor();
216   TestExternalReference_UnOp<float>(&m, ref, wasm::f32_floor_wrapper,
217                                     ValueHelper::float32_vector());
218 }
219 
TEST(RunCallF32Ceil)220 TEST(RunCallF32Ceil) {
221   BufferedRawMachineAssemblerTester<int32_t> m;
222   ExternalReference ref = ExternalReference::wasm_f32_ceil();
223   TestExternalReference_UnOp<float>(&m, ref, wasm::f32_ceil_wrapper,
224                                     ValueHelper::float32_vector());
225 }
226 
TEST(RunCallF32RoundTiesEven)227 TEST(RunCallF32RoundTiesEven) {
228   BufferedRawMachineAssemblerTester<int32_t> m;
229   ExternalReference ref = ExternalReference::wasm_f32_nearest_int();
230   TestExternalReference_UnOp<float>(&m, ref, wasm::f32_nearest_int_wrapper,
231                                     ValueHelper::float32_vector());
232 }
233 
TEST(RunCallF64Trunc)234 TEST(RunCallF64Trunc) {
235   BufferedRawMachineAssemblerTester<int32_t> m;
236   ExternalReference ref = ExternalReference::wasm_f64_trunc();
237   TestExternalReference_UnOp<double>(&m, ref, wasm::f64_trunc_wrapper,
238                                      ValueHelper::float64_vector());
239 }
240 
TEST(RunCallF64Floor)241 TEST(RunCallF64Floor) {
242   BufferedRawMachineAssemblerTester<int32_t> m;
243   ExternalReference ref = ExternalReference::wasm_f64_floor();
244   TestExternalReference_UnOp<double>(&m, ref, wasm::f64_floor_wrapper,
245                                      ValueHelper::float64_vector());
246 }
247 
TEST(RunCallF64Ceil)248 TEST(RunCallF64Ceil) {
249   BufferedRawMachineAssemblerTester<int32_t> m;
250   ExternalReference ref = ExternalReference::wasm_f64_ceil();
251   TestExternalReference_UnOp<double>(&m, ref, wasm::f64_ceil_wrapper,
252                                      ValueHelper::float64_vector());
253 }
254 
TEST(RunCallF64RoundTiesEven)255 TEST(RunCallF64RoundTiesEven) {
256   BufferedRawMachineAssemblerTester<int32_t> m;
257   ExternalReference ref = ExternalReference::wasm_f64_nearest_int();
258   TestExternalReference_UnOp<double>(&m, ref, wasm::f64_nearest_int_wrapper,
259                                      ValueHelper::float64_vector());
260 }
261 
TEST(RunCallInt64ToFloat32)262 TEST(RunCallInt64ToFloat32) {
263   BufferedRawMachineAssemblerTester<int32_t> m;
264   ExternalReference ref = ExternalReference::wasm_int64_to_float32();
265   TestExternalReference_ConvertOp<int64_t, float>(
266       &m, ref, wasm::int64_to_float32_wrapper, ValueHelper::int64_vector());
267 }
268 
TEST(RunCallUint64ToFloat32)269 TEST(RunCallUint64ToFloat32) {
270   BufferedRawMachineAssemblerTester<int32_t> m;
271   ExternalReference ref = ExternalReference::wasm_uint64_to_float32();
272   TestExternalReference_ConvertOp<uint64_t, float>(
273       &m, ref, wasm::uint64_to_float32_wrapper, ValueHelper::uint64_vector());
274 }
275 
TEST(RunCallInt64ToFloat64)276 TEST(RunCallInt64ToFloat64) {
277   BufferedRawMachineAssemblerTester<int32_t> m;
278   ExternalReference ref = ExternalReference::wasm_int64_to_float64();
279   TestExternalReference_ConvertOp<int64_t, double>(
280       &m, ref, wasm::int64_to_float64_wrapper, ValueHelper::int64_vector());
281 }
282 
TEST(RunCallUint64ToFloat64)283 TEST(RunCallUint64ToFloat64) {
284   BufferedRawMachineAssemblerTester<int32_t> m;
285   ExternalReference ref = ExternalReference::wasm_uint64_to_float64();
286   TestExternalReference_ConvertOp<uint64_t, double>(
287       &m, ref, wasm::uint64_to_float64_wrapper, ValueHelper::uint64_vector());
288 }
289 
TEST(RunCallFloat32ToInt64)290 TEST(RunCallFloat32ToInt64) {
291   BufferedRawMachineAssemblerTester<int32_t> m;
292   ExternalReference ref = ExternalReference::wasm_float32_to_int64();
293   TestExternalReference_ConvertOpWithOutputAndReturn<float, int64_t>(
294       &m, ref, wasm::float32_to_int64_wrapper, ValueHelper::float32_vector());
295 }
296 
TEST(RunCallFloat32ToUint64)297 TEST(RunCallFloat32ToUint64) {
298   BufferedRawMachineAssemblerTester<int32_t> m;
299   ExternalReference ref = ExternalReference::wasm_float32_to_uint64();
300   TestExternalReference_ConvertOpWithOutputAndReturn<float, uint64_t>(
301       &m, ref, wasm::float32_to_uint64_wrapper, ValueHelper::float32_vector());
302 }
303 
TEST(RunCallFloat64ToInt64)304 TEST(RunCallFloat64ToInt64) {
305   BufferedRawMachineAssemblerTester<int32_t> m;
306   ExternalReference ref = ExternalReference::wasm_float64_to_int64();
307   TestExternalReference_ConvertOpWithOutputAndReturn<double, int64_t>(
308       &m, ref, wasm::float64_to_int64_wrapper, ValueHelper::float64_vector());
309 }
310 
TEST(RunCallFloat64ToUint64)311 TEST(RunCallFloat64ToUint64) {
312   BufferedRawMachineAssemblerTester<int32_t> m;
313   ExternalReference ref = ExternalReference::wasm_float64_to_uint64();
314   TestExternalReference_ConvertOpWithOutputAndReturn<double, uint64_t>(
315       &m, ref, wasm::float64_to_uint64_wrapper, ValueHelper::float64_vector());
316 }
317 
TEST(RunCallInt64Div)318 TEST(RunCallInt64Div) {
319   BufferedRawMachineAssemblerTester<int32_t> m;
320   ExternalReference ref = ExternalReference::wasm_int64_div();
321   TestExternalReference_BinOpWithReturn<int64_t>(
322       &m, ref, wasm::int64_div_wrapper, ValueHelper::int64_vector());
323 }
324 
TEST(RunCallInt64Mod)325 TEST(RunCallInt64Mod) {
326   BufferedRawMachineAssemblerTester<int32_t> m;
327   ExternalReference ref = ExternalReference::wasm_int64_mod();
328   TestExternalReference_BinOpWithReturn<int64_t>(
329       &m, ref, wasm::int64_mod_wrapper, ValueHelper::int64_vector());
330 }
331 
TEST(RunCallUint64Div)332 TEST(RunCallUint64Div) {
333   BufferedRawMachineAssemblerTester<int32_t> m;
334   ExternalReference ref = ExternalReference::wasm_uint64_div();
335   TestExternalReference_BinOpWithReturn<uint64_t>(
336       &m, ref, wasm::uint64_div_wrapper, ValueHelper::uint64_vector());
337 }
338 
TEST(RunCallUint64Mod)339 TEST(RunCallUint64Mod) {
340   BufferedRawMachineAssemblerTester<int32_t> m;
341   ExternalReference ref = ExternalReference::wasm_uint64_mod();
342   TestExternalReference_BinOpWithReturn<uint64_t>(
343       &m, ref, wasm::uint64_mod_wrapper, ValueHelper::uint64_vector());
344 }
345 
TEST(RunCallWord32Ctz)346 TEST(RunCallWord32Ctz) {
347   BufferedRawMachineAssemblerTester<uint32_t> m;
348   ExternalReference ref = ExternalReference::wasm_word32_ctz();
349   TestExternalReference_ConvertOpWithReturn<int32_t, uint32_t>(
350       &m, ref, wasm::word32_ctz_wrapper, ValueHelper::int32_vector());
351 }
352 
TEST(RunCallWord64Ctz)353 TEST(RunCallWord64Ctz) {
354   BufferedRawMachineAssemblerTester<uint32_t> m;
355   ExternalReference ref = ExternalReference::wasm_word64_ctz();
356   TestExternalReference_ConvertOpWithReturn<int64_t, uint32_t>(
357       &m, ref, wasm::word64_ctz_wrapper, ValueHelper::int64_vector());
358 }
359 
TEST(RunCallWord32Popcnt)360 TEST(RunCallWord32Popcnt) {
361   BufferedRawMachineAssemblerTester<uint32_t> m;
362   ExternalReference ref = ExternalReference::wasm_word32_popcnt();
363   TestExternalReference_ConvertOpWithReturn<uint32_t, uint32_t>(
364       &m, ref, wasm::word32_popcnt_wrapper, ValueHelper::int32_vector());
365 }
366 
TEST(RunCallWord64Popcnt)367 TEST(RunCallWord64Popcnt) {
368   BufferedRawMachineAssemblerTester<uint32_t> m;
369   ExternalReference ref = ExternalReference::wasm_word64_popcnt();
370   TestExternalReference_ConvertOpWithReturn<int64_t, uint32_t>(
371       &m, ref, wasm::word64_popcnt_wrapper, ValueHelper::int64_vector());
372 }
373 
TEST(RunCallFloat64Pow)374 TEST(RunCallFloat64Pow) {
375   BufferedRawMachineAssemblerTester<int32_t> m;
376   ExternalReference ref = ExternalReference::wasm_float64_pow();
377   TestExternalReference_BinOp<double>(&m, ref, wasm::float64_pow_wrapper,
378                                       ValueHelper::float64_vector());
379 }
380 #endif  // V8_ENABLE_WEBASSEMBLY
381 
382 #ifdef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
383 
384 template <typename T>
MachineTypeForCType()385 MachineType MachineTypeForCType() {
386   UNREACHABLE();
387 }
388 
389 template <>
MachineTypeForCType()390 MachineType MachineTypeForCType<int32_t>() {
391   return MachineType::Int32();
392 }
393 
394 template <>
MachineTypeForCType()395 MachineType MachineTypeForCType<double>() {
396   return MachineType::Float64();
397 }
398 
399 template <>
MachineTypeForCType()400 MachineType MachineTypeForCType<float>() {
401   return MachineType::Float32();
402 }
403 
404 #define SIGNATURE_TYPES_END(TYPE, IDX, VALUE) MachineTypeForCType<TYPE>()
405 #define SIGNATURE_TYPES(TYPE, IDX, VALUE) SIGNATURE_TYPES_END(TYPE, IDX, VALUE),
406 
407 #define PARAM_PAIRS_END(TYPE, IDX, VALUE) \
408   std::make_pair(MachineTypeForCType<TYPE>(), m.Parameter(IDX))
409 
410 #define PARAM_PAIRS(TYPE, IDX, VALUE) PARAM_PAIRS_END(TYPE, IDX, VALUE),
411 
412 #define CALL_ARGS_END(TYPE, IDX, VALUE) static_cast<TYPE>(VALUE)
413 #define CALL_ARGS(TYPE, IDX, VALUE) CALL_ARGS_END(TYPE, IDX, VALUE),
414 
415 #define COMPARE_ARG_I_END(TYPE, IDX, VALUE) (arg##IDX == VALUE)
416 #define COMPARE_ARG_I(TYPE, IDX, VALUE) COMPARE_ARG_I_END(TYPE, IDX, VALUE)&&
417 
418 #define SIGNATURE_TEST(NAME, SIGNATURE, FUNC)                             \
419   TEST(NAME) {                                                            \
420     RawMachineAssemblerTester<int64_t> m(SIGNATURE(SIGNATURE_TYPES));     \
421                                                                           \
422     Address func_address = FUNCTION_ADDR(&FUNC);                          \
423     ExternalReference::Type dummy_type = ExternalReference::BUILTIN_CALL; \
424     ApiFunction func(func_address);                                       \
425     ExternalReference ref = ExternalReference::Create(&func, dummy_type); \
426                                                                           \
427     Node* function = m.ExternalConstant(ref);                             \
428     m.Return(m.CallCFunction(function, MachineType::Int64(),              \
429                              SIGNATURE(PARAM_PAIRS)));                    \
430                                                                           \
431     int64_t c = m.Call(SIGNATURE(CALL_ARGS));                             \
432     CHECK_EQ(c, 42);                                                      \
433   }
434 
435 #define MIXED_SIGNATURE_SIMPLE(V) \
436   V(int32_t, 0, 0)                \
437   V(double, 1, 1.5)               \
438   V##_END(int32_t, 2, 2)
439 
test_api_func_simple(int32_t arg0,double arg1,int32_t arg2)440 int64_t test_api_func_simple(int32_t arg0, double arg1, int32_t arg2) {
441   CHECK(MIXED_SIGNATURE_SIMPLE(COMPARE_ARG_I));
442   return 42;
443 }
444 
SIGNATURE_TEST(RunCallWithMixedSignatureSimple,MIXED_SIGNATURE_SIMPLE,test_api_func_simple)445 SIGNATURE_TEST(RunCallWithMixedSignatureSimple, MIXED_SIGNATURE_SIMPLE,
446                test_api_func_simple)
447 
448 #define MIXED_SIGNATURE(V) \
449   V(int32_t, 0, 0)         \
450   V(double, 1, 1.5)        \
451   V(int32_t, 2, 2)         \
452   V(double, 3, 3.5)        \
453   V(int32_t, 4, 4)         \
454   V(double, 5, 5.5)        \
455   V(int32_t, 6, 6)         \
456   V(double, 7, 7.5)        \
457   V(int32_t, 8, 8)         \
458   V(double, 9, 9.5)        \
459   V##_END(int32_t, 10, 10)
460 
461 int64_t test_api_func(int32_t arg0, double arg1, int32_t arg2, double arg3,
462                       int32_t arg4, double arg5, int32_t arg6, double arg7,
463                       int32_t arg8, double arg9, int32_t arg10) {
464   CHECK(MIXED_SIGNATURE(COMPARE_ARG_I));
465   return 42;
466 }
467 
SIGNATURE_TEST(RunCallWithMixedSignature,MIXED_SIGNATURE,test_api_func)468 SIGNATURE_TEST(RunCallWithMixedSignature, MIXED_SIGNATURE, test_api_func)
469 
470 #define MIXED_SIGNATURE_DOUBLE_INT(V) \
471   V(double, 0, 0.5)                   \
472   V(double, 1, 1.5)                   \
473   V(double, 2, 2.5)                   \
474   V(double, 3, 3.5)                   \
475   V(double, 4, 4.5)                   \
476   V(double, 5, 5.5)                   \
477   V(double, 6, 6.5)                   \
478   V(double, 7, 7.5)                   \
479   V(double, 8, 8.5)                   \
480   V(double, 9, 9.5)                   \
481   V(int32_t, 10, 10)                  \
482   V(int32_t, 11, 11)                  \
483   V(int32_t, 12, 12)                  \
484   V(int32_t, 13, 13)                  \
485   V(int32_t, 14, 14)                  \
486   V(int32_t, 15, 15)                  \
487   V(int32_t, 16, 16)                  \
488   V(int32_t, 17, 17)                  \
489   V(int32_t, 18, 18)                  \
490   V##_END(int32_t, 19, 19)
491 
492 int64_t func_mixed_double_int(double arg0, double arg1, double arg2,
493                               double arg3, double arg4, double arg5,
494                               double arg6, double arg7, double arg8,
495                               double arg9, int32_t arg10, int32_t arg11,
496                               int32_t arg12, int32_t arg13, int32_t arg14,
497                               int32_t arg15, int32_t arg16, int32_t arg17,
498                               int32_t arg18, int32_t arg19) {
499   CHECK(MIXED_SIGNATURE_DOUBLE_INT(COMPARE_ARG_I));
500   return 42;
501 }
502 
SIGNATURE_TEST(RunCallWithMixedSignatureDoubleInt,MIXED_SIGNATURE_DOUBLE_INT,func_mixed_double_int)503 SIGNATURE_TEST(RunCallWithMixedSignatureDoubleInt, MIXED_SIGNATURE_DOUBLE_INT,
504                func_mixed_double_int)
505 
506 #define MIXED_SIGNATURE_INT_DOUBLE(V) \
507   V(int32_t, 0, 0)                    \
508   V(int32_t, 1, 1)                    \
509   V(int32_t, 2, 2)                    \
510   V(int32_t, 3, 3)                    \
511   V(int32_t, 4, 4)                    \
512   V(int32_t, 5, 5)                    \
513   V(int32_t, 6, 6)                    \
514   V(int32_t, 7, 7)                    \
515   V(int32_t, 8, 8)                    \
516   V(int32_t, 9, 9)                    \
517   V(double, 10, 10.5)                 \
518   V(double, 11, 11.5)                 \
519   V(double, 12, 12.5)                 \
520   V(double, 13, 13.5)                 \
521   V(double, 14, 14.5)                 \
522   V(double, 15, 15.5)                 \
523   V(double, 16, 16.5)                 \
524   V(double, 17, 17.5)                 \
525   V(double, 18, 18.5)                 \
526   V##_END(double, 19, 19.5)
527 
528 int64_t func_mixed_int_double(int32_t arg0, int32_t arg1, int32_t arg2,
529                               int32_t arg3, int32_t arg4, int32_t arg5,
530                               int32_t arg6, int32_t arg7, int32_t arg8,
531                               int32_t arg9, double arg10, double arg11,
532                               double arg12, double arg13, double arg14,
533                               double arg15, double arg16, double arg17,
534                               double arg18, double arg19) {
535   CHECK(MIXED_SIGNATURE_INT_DOUBLE(COMPARE_ARG_I));
536   return 42;
537 }
538 
SIGNATURE_TEST(RunCallWithMixedSignatureIntDouble,MIXED_SIGNATURE_INT_DOUBLE,func_mixed_int_double)539 SIGNATURE_TEST(RunCallWithMixedSignatureIntDouble, MIXED_SIGNATURE_INT_DOUBLE,
540                func_mixed_int_double)
541 
542 #define MIXED_SIGNATURE_INT_DOUBLE_ALT(V) \
543   V(int32_t, 0, 0)                        \
544   V(double, 1, 1.5)                       \
545   V(int32_t, 2, 2)                        \
546   V(double, 3, 3.5)                       \
547   V(int32_t, 4, 4)                        \
548   V(double, 5, 5.5)                       \
549   V(int32_t, 6, 6)                        \
550   V(double, 7, 7.5)                       \
551   V(int32_t, 8, 8)                        \
552   V(double, 9, 9.5)                       \
553   V(int32_t, 10, 10)                      \
554   V(double, 11, 11.5)                     \
555   V(int32_t, 12, 12)                      \
556   V(double, 13, 13.5)                     \
557   V(int32_t, 14, 14)                      \
558   V(double, 15, 15.5)                     \
559   V(int32_t, 16, 16)                      \
560   V(double, 17, 17.5)                     \
561   V(int32_t, 18, 18)                      \
562   V##_END(double, 19, 19.5)
563 
564 int64_t func_mixed_int_double_alt(int32_t arg0, double arg1, int32_t arg2,
565                                   double arg3, int32_t arg4, double arg5,
566                                   int32_t arg6, double arg7, int32_t arg8,
567                                   double arg9, int32_t arg10, double arg11,
568                                   int32_t arg12, double arg13, int32_t arg14,
569                                   double arg15, int32_t arg16, double arg17,
570                                   int32_t arg18, double arg19) {
571   CHECK(MIXED_SIGNATURE_INT_DOUBLE_ALT(COMPARE_ARG_I));
572   return 42;
573 }
574 
SIGNATURE_TEST(RunCallWithMixedSignatureIntDoubleAlt,MIXED_SIGNATURE_INT_DOUBLE_ALT,func_mixed_int_double_alt)575 SIGNATURE_TEST(RunCallWithMixedSignatureIntDoubleAlt,
576                MIXED_SIGNATURE_INT_DOUBLE_ALT, func_mixed_int_double_alt)
577 
578 #define SIGNATURE_ONLY_DOUBLE(V) \
579   V(double, 0, 0.5)              \
580   V(double, 1, 1.5)              \
581   V(double, 2, 2.5)              \
582   V(double, 3, 3.5)              \
583   V(double, 4, 4.5)              \
584   V(double, 5, 5.5)              \
585   V(double, 6, 6.5)              \
586   V(double, 7, 7.5)              \
587   V(double, 8, 8.5)              \
588   V##_END(double, 9, 9.5)
589 
590 int64_t func_only_double(double arg0, double arg1, double arg2, double arg3,
591                          double arg4, double arg5, double arg6, double arg7,
592                          double arg8, double arg9) {
593   CHECK(SIGNATURE_ONLY_DOUBLE(COMPARE_ARG_I));
594   return 42;
595 }
596 
SIGNATURE_TEST(RunCallWithSignatureOnlyDouble,SIGNATURE_ONLY_DOUBLE,func_only_double)597 SIGNATURE_TEST(RunCallWithSignatureOnlyDouble, SIGNATURE_ONLY_DOUBLE,
598                func_only_double)
599 
600 #define SIGNATURE_ONLY_DOUBLE_20(V) \
601   V(double, 0, 0.5)                 \
602   V(double, 1, 1.5)                 \
603   V(double, 2, 2.5)                 \
604   V(double, 3, 3.5)                 \
605   V(double, 4, 4.5)                 \
606   V(double, 5, 5.5)                 \
607   V(double, 6, 6.5)                 \
608   V(double, 7, 7.5)                 \
609   V(double, 8, 8.5)                 \
610   V(double, 9, 9.5)                 \
611   V(double, 10, 10.5)               \
612   V(double, 11, 11.5)               \
613   V(double, 12, 12.5)               \
614   V(double, 13, 13.5)               \
615   V(double, 14, 14.5)               \
616   V(double, 15, 15.5)               \
617   V(double, 16, 16.5)               \
618   V(double, 17, 17.5)               \
619   V(double, 18, 18.5)               \
620   V##_END(double, 19, 19.5)
621 
622 int64_t func_only_double_20(double arg0, double arg1, double arg2, double arg3,
623                             double arg4, double arg5, double arg6, double arg7,
624                             double arg8, double arg9, double arg10,
625                             double arg11, double arg12, double arg13,
626                             double arg14, double arg15, double arg16,
627                             double arg17, double arg18, double arg19) {
628   CHECK(SIGNATURE_ONLY_DOUBLE_20(COMPARE_ARG_I));
629   return 42;
630 }
631 
SIGNATURE_TEST(RunCallWithSignatureOnlyDouble20,SIGNATURE_ONLY_DOUBLE_20,func_only_double_20)632 SIGNATURE_TEST(RunCallWithSignatureOnlyDouble20, SIGNATURE_ONLY_DOUBLE_20,
633                func_only_double_20)
634 
635 #define SIGNATURE_ONLY_INT(V) \
636   V(int32_t, 0, 0)            \
637   V(int32_t, 1, 1)            \
638   V(int32_t, 2, 2)            \
639   V(int32_t, 3, 3)            \
640   V(int32_t, 4, 4)            \
641   V(int32_t, 5, 5)            \
642   V(int32_t, 6, 6)            \
643   V(int32_t, 7, 7)            \
644   V(int32_t, 8, 8)            \
645   V##_END(int32_t, 9, 9)
646 
647 int64_t func_only_int(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3,
648                       int32_t arg4, int32_t arg5, int32_t arg6, int32_t arg7,
649                       int32_t arg8, int32_t arg9) {
650   CHECK(SIGNATURE_ONLY_INT(COMPARE_ARG_I));
651   return 42;
652 }
653 
SIGNATURE_TEST(RunCallWithSignatureOnlyInt,SIGNATURE_ONLY_INT,func_only_int)654 SIGNATURE_TEST(RunCallWithSignatureOnlyInt, SIGNATURE_ONLY_INT, func_only_int)
655 
656 #define SIGNATURE_ONLY_INT_20(V) \
657   V(int32_t, 0, 0)               \
658   V(int32_t, 1, 1)               \
659   V(int32_t, 2, 2)               \
660   V(int32_t, 3, 3)               \
661   V(int32_t, 4, 4)               \
662   V(int32_t, 5, 5)               \
663   V(int32_t, 6, 6)               \
664   V(int32_t, 7, 7)               \
665   V(int32_t, 8, 8)               \
666   V(int32_t, 9, 9)               \
667   V(int32_t, 10, 10)             \
668   V(int32_t, 11, 11)             \
669   V(int32_t, 12, 12)             \
670   V(int32_t, 13, 13)             \
671   V(int32_t, 14, 14)             \
672   V(int32_t, 15, 15)             \
673   V(int32_t, 16, 16)             \
674   V(int32_t, 17, 17)             \
675   V(int32_t, 18, 18)             \
676   V##_END(int32_t, 19, 19)
677 
678 int64_t func_only_int_20(int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3,
679                          int32_t arg4, int32_t arg5, int32_t arg6, int32_t arg7,
680                          int32_t arg8, int32_t arg9, int32_t arg10,
681                          int32_t arg11, int32_t arg12, int32_t arg13,
682                          int32_t arg14, int32_t arg15, int32_t arg16,
683                          int32_t arg17, int32_t arg18, int32_t arg19) {
684   CHECK(SIGNATURE_ONLY_INT_20(COMPARE_ARG_I));
685   return 42;
686 }
687 
SIGNATURE_TEST(RunCallWithSignatureOnlyInt20,SIGNATURE_ONLY_INT_20,func_only_int_20)688 SIGNATURE_TEST(RunCallWithSignatureOnlyInt20, SIGNATURE_ONLY_INT_20,
689                func_only_int_20)
690 
691 #define MIXED_SIGNATURE_SIMPLE_FLOAT(V) \
692   V(int32_t, 0, 0)                      \
693   V(float, 1, 1.5)                      \
694   V##_END(int32_t, 2, 2)
695 
696 int64_t test_api_func_simple_float(int32_t arg0, float arg1, int32_t arg2) {
697   CHECK(MIXED_SIGNATURE_SIMPLE_FLOAT(COMPARE_ARG_I));
698   return 42;
699 }
700 
SIGNATURE_TEST(RunCallWithMixedSignatureSimpleFloat,MIXED_SIGNATURE_SIMPLE_FLOAT,test_api_func_simple_float)701 SIGNATURE_TEST(RunCallWithMixedSignatureSimpleFloat,
702                MIXED_SIGNATURE_SIMPLE_FLOAT, test_api_func_simple_float)
703 
704 #define MIXED_SIGNATURE_FLOAT(V) \
705   V(int32_t, 0, 0)               \
706   V(float, 1, 1.5)               \
707   V(int32_t, 2, 2)               \
708   V(float, 3, 3.5)               \
709   V(int32_t, 4, 4)               \
710   V(float, 5, 5.5)               \
711   V(int32_t, 6, 6)               \
712   V(float, 7, 7.5)               \
713   V(int32_t, 8, 8)               \
714   V(float, 9, 9.5)               \
715   V##_END(int32_t, 10, 10)
716 
717 int64_t test_api_func_float(int32_t arg0, float arg1, int32_t arg2, float arg3,
718                             int32_t arg4, float arg5, int32_t arg6, float arg7,
719                             int32_t arg8, float arg9, int32_t arg10) {
720   CHECK(MIXED_SIGNATURE_FLOAT(COMPARE_ARG_I));
721   return 42;
722 }
723 
SIGNATURE_TEST(RunCallWithMixedSignatureFloat,MIXED_SIGNATURE_FLOAT,test_api_func_float)724 SIGNATURE_TEST(RunCallWithMixedSignatureFloat, MIXED_SIGNATURE_FLOAT,
725                test_api_func_float)
726 
727 #define MIXED_SIGNATURE_INT_FLOAT_ALT(V) \
728   V(int32_t, 0, 0)                       \
729   V(float, 1, 1.5)                       \
730   V(int32_t, 2, 2)                       \
731   V(float, 3, 3.5)                       \
732   V(int32_t, 4, 4)                       \
733   V(float, 5, 5.5)                       \
734   V(int32_t, 6, 6)                       \
735   V(float, 7, 7.5)                       \
736   V(int32_t, 8, 8)                       \
737   V(float, 9, 9.5)                       \
738   V(int32_t, 10, 10)                     \
739   V(float, 11, 11.5)                     \
740   V(int32_t, 12, 12)                     \
741   V(float, 13, 13.5)                     \
742   V(int32_t, 14, 14)                     \
743   V(float, 15, 15.5)                     \
744   V(int32_t, 16, 16)                     \
745   V(float, 17, 17.5)                     \
746   V(int32_t, 18, 18)                     \
747   V##_END(float, 19, 19.5)
748 
749 int64_t func_mixed_int_float_alt(int32_t arg0, float arg1, int32_t arg2,
750                                  float arg3, int32_t arg4, float arg5,
751                                  int32_t arg6, float arg7, int32_t arg8,
752                                  float arg9, int32_t arg10, float arg11,
753                                  int32_t arg12, float arg13, int32_t arg14,
754                                  float arg15, int32_t arg16, float arg17,
755                                  int32_t arg18, float arg19) {
756   CHECK(MIXED_SIGNATURE_INT_FLOAT_ALT(COMPARE_ARG_I));
757   return 42;
758 }
759 
SIGNATURE_TEST(RunCallWithMixedSignatureIntFloatAlt,MIXED_SIGNATURE_INT_FLOAT_ALT,func_mixed_int_float_alt)760 SIGNATURE_TEST(RunCallWithMixedSignatureIntFloatAlt,
761                MIXED_SIGNATURE_INT_FLOAT_ALT, func_mixed_int_float_alt)
762 
763 #define SIGNATURE_ONLY_FLOAT_20(V) \
764   V(float, 0, 0.5)                 \
765   V(float, 1, 1.5)                 \
766   V(float, 2, 2.5)                 \
767   V(float, 3, 3.5)                 \
768   V(float, 4, 4.5)                 \
769   V(float, 5, 5.5)                 \
770   V(float, 6, 6.5)                 \
771   V(float, 7, 7.5)                 \
772   V(float, 8, 8.5)                 \
773   V(float, 9, 9.5)                 \
774   V(float, 10, 10.5)               \
775   V(float, 11, 11.5)               \
776   V(float, 12, 12.5)               \
777   V(float, 13, 13.5)               \
778   V(float, 14, 14.5)               \
779   V(float, 15, 15.5)               \
780   V(float, 16, 16.5)               \
781   V(float, 17, 17.5)               \
782   V(float, 18, 18.5)               \
783   V##_END(float, 19, 19.5)
784 
785 int64_t func_only_float_20(float arg0, float arg1, float arg2, float arg3,
786                            float arg4, float arg5, float arg6, float arg7,
787                            float arg8, float arg9, float arg10, float arg11,
788                            float arg12, float arg13, float arg14, float arg15,
789                            float arg16, float arg17, float arg18, float arg19) {
790   CHECK(SIGNATURE_ONLY_FLOAT_20(COMPARE_ARG_I));
791   return 42;
792 }
793 
SIGNATURE_TEST(RunCallWithSignatureOnlyFloat20,SIGNATURE_ONLY_FLOAT_20,func_only_float_20)794 SIGNATURE_TEST(RunCallWithSignatureOnlyFloat20, SIGNATURE_ONLY_FLOAT_20,
795                func_only_float_20)
796 
797 #define MIXED_SIGNATURE_FLOAT_INT(V) \
798   V(float, 0, 0.5)                   \
799   V(float, 1, 1.5)                   \
800   V(float, 2, 2.5)                   \
801   V(float, 3, 3.5)                   \
802   V(float, 4, 4.5)                   \
803   V(float, 5, 5.5)                   \
804   V(float, 6, 6.5)                   \
805   V(float, 7, 7.5)                   \
806   V(float, 8, 8.5)                   \
807   V(float, 9, 9.5)                   \
808   V(int32_t, 10, 10)                 \
809   V(int32_t, 11, 11)                 \
810   V(int32_t, 12, 12)                 \
811   V(int32_t, 13, 13)                 \
812   V(int32_t, 14, 14)                 \
813   V(int32_t, 15, 15)                 \
814   V(int32_t, 16, 16)                 \
815   V(int32_t, 17, 17)                 \
816   V(int32_t, 18, 18)                 \
817   V##_END(int32_t, 19, 19)
818 
819 int64_t func_mixed_float_int(float arg0, float arg1, float arg2, float arg3,
820                              float arg4, float arg5, float arg6, float arg7,
821                              float arg8, float arg9, int32_t arg10,
822                              int32_t arg11, int32_t arg12, int32_t arg13,
823                              int32_t arg14, int32_t arg15, int32_t arg16,
824                              int32_t arg17, int32_t arg18, int32_t arg19) {
825   CHECK(MIXED_SIGNATURE_FLOAT_INT(COMPARE_ARG_I));
826   return 42;
827 }
828 
SIGNATURE_TEST(RunCallWithMixedSignatureFloatInt,MIXED_SIGNATURE_FLOAT_INT,func_mixed_float_int)829 SIGNATURE_TEST(RunCallWithMixedSignatureFloatInt, MIXED_SIGNATURE_FLOAT_INT,
830                func_mixed_float_int)
831 
832 #define MIXED_SIGNATURE_INT_FLOAT(V) \
833   V(int32_t, 0, 0)                   \
834   V(int32_t, 1, 1)                   \
835   V(int32_t, 2, 2)                   \
836   V(int32_t, 3, 3)                   \
837   V(int32_t, 4, 4)                   \
838   V(int32_t, 5, 5)                   \
839   V(int32_t, 6, 6)                   \
840   V(int32_t, 7, 7)                   \
841   V(int32_t, 8, 8)                   \
842   V(int32_t, 9, 9)                   \
843   V(float, 10, 10.5)                 \
844   V(float, 11, 11.5)                 \
845   V(float, 12, 12.5)                 \
846   V(float, 13, 13.5)                 \
847   V(float, 14, 14.5)                 \
848   V(float, 15, 15.5)                 \
849   V(float, 16, 16.5)                 \
850   V(float, 17, 17.5)                 \
851   V(float, 18, 18.5)                 \
852   V##_END(float, 19, 19.5)
853 
854 int64_t func_mixed_int_float(int32_t arg0, int32_t arg1, int32_t arg2,
855                              int32_t arg3, int32_t arg4, int32_t arg5,
856                              int32_t arg6, int32_t arg7, int32_t arg8,
857                              int32_t arg9, float arg10, float arg11,
858                              float arg12, float arg13, float arg14, float arg15,
859                              float arg16, float arg17, float arg18,
860                              float arg19) {
861   CHECK(MIXED_SIGNATURE_INT_FLOAT(COMPARE_ARG_I));
862   return 42;
863 }
864 
SIGNATURE_TEST(RunCallWithMixedSignatureIntFloat,MIXED_SIGNATURE_INT_FLOAT,func_mixed_int_float)865 SIGNATURE_TEST(RunCallWithMixedSignatureIntFloat, MIXED_SIGNATURE_INT_FLOAT,
866                func_mixed_int_float)
867 
868 #define MIXED_SIGNATURE_FLOAT_DOUBLE(V) \
869   V(float, 0, 0.5)                      \
870   V(float, 1, 1.5)                      \
871   V(float, 2, 2.5)                      \
872   V(float, 3, 3.5)                      \
873   V(float, 4, 4.5)                      \
874   V(float, 5, 5.5)                      \
875   V(float, 6, 6.5)                      \
876   V(float, 7, 7.5)                      \
877   V(float, 8, 8.5)                      \
878   V(float, 9, 9.5)                      \
879   V(double, 10, 10.7)                   \
880   V(double, 11, 11.7)                   \
881   V(double, 12, 12.7)                   \
882   V(double, 13, 13.7)                   \
883   V(double, 14, 14.7)                   \
884   V(double, 15, 15.7)                   \
885   V(double, 16, 16.7)                   \
886   V(double, 17, 17.7)                   \
887   V(double, 18, 18.7)                   \
888   V##_END(double, 19, 19.7)
889 
890 int64_t func_mixed_float_double(float arg0, float arg1, float arg2, float arg3,
891                                 float arg4, float arg5, float arg6, float arg7,
892                                 float arg8, float arg9, double arg10,
893                                 double arg11, double arg12, double arg13,
894                                 double arg14, double arg15, double arg16,
895                                 double arg17, double arg18, double arg19) {
896   CHECK(MIXED_SIGNATURE_FLOAT_DOUBLE(COMPARE_ARG_I));
897   return 42;
898 }
899 
SIGNATURE_TEST(RunCallWithMixedSignatureFloatDouble,MIXED_SIGNATURE_FLOAT_DOUBLE,func_mixed_float_double)900 SIGNATURE_TEST(RunCallWithMixedSignatureFloatDouble,
901                MIXED_SIGNATURE_FLOAT_DOUBLE, func_mixed_float_double)
902 
903 #define MIXED_SIGNATURE_DOUBLE_FLOAT(V) \
904   V(double, 0, 0.7)                     \
905   V(double, 1, 1.7)                     \
906   V(double, 2, 2.7)                     \
907   V(double, 3, 3.7)                     \
908   V(double, 4, 4.7)                     \
909   V(double, 5, 5.7)                     \
910   V(double, 6, 6.7)                     \
911   V(double, 7, 7.7)                     \
912   V(double, 8, 8.7)                     \
913   V(double, 9, 9.7)                     \
914   V(float, 10, 10.5)                    \
915   V(float, 11, 11.5)                    \
916   V(float, 12, 12.5)                    \
917   V(float, 13, 13.5)                    \
918   V(float, 14, 14.5)                    \
919   V(float, 15, 15.5)                    \
920   V(float, 16, 16.5)                    \
921   V(float, 17, 17.5)                    \
922   V(float, 18, 18.5)                    \
923   V##_END(float, 19, 19.5)
924 
925 int64_t func_mixed_double_float(double arg0, double arg1, double arg2,
926                                 double arg3, double arg4, double arg5,
927                                 double arg6, double arg7, double arg8,
928                                 double arg9, float arg10, float arg11,
929                                 float arg12, float arg13, float arg14,
930                                 float arg15, float arg16, float arg17,
931                                 float arg18, float arg19) {
932   CHECK(MIXED_SIGNATURE_DOUBLE_FLOAT(COMPARE_ARG_I));
933   return 42;
934 }
935 
936 SIGNATURE_TEST(RunCallWithMixedSignatureDoubleFloat,
937                MIXED_SIGNATURE_DOUBLE_FLOAT, func_mixed_double_float)
938 
939 #endif  // V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
940 
941 }  // namespace compiler
942 }  // namespace internal
943 }  // namespace v8
944