v8/test/cctest/compiler/test-run-calls-to-external-references.cc
Andreas Haas 2a3c2c73d5 Reland: [refactoring] Remove the isolate from signatures of ExternalReferences
I missed one required change which was hidden behind an #if. The fix is in
the diff between Patch 1 and Patch 3.

Original message:
In this CL I remove the isolate from signatures of ExternalReference
accessor functions where the isolate is not used. The uses of the
isolate were already removed in previous CLs.

Changes:
* I split the ExternalReference list in external-reference.h into
those which need the isolate for initialization and those which do not.

* I removed the public constructors and replaced them by
  ExternalReference::Create(). The reason is to separate external
  creation more clearly from internal creation, because externally
  created ExternalReferences sometimes need redirection, whereas
  internally created ExternalReferences are just stored as they are.
  In addition, by removing the isolate from the signature of the
  public constructors, they suddenly exactly matched the interal
  constructor.

* Replace all uses of the public constructors with
  ExternalReference::Create().

* Remove the isolate from all call sites where necessary.


This is a step towards making WebAssembly compilation independent of
the isolate.

R=mstarzinger@chromium.org

Bug: v8:7570
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I750c162f5d58ed32e866722b0db920f8b9bd8057
Reviewed-on: https://chromium-review.googlesource.com/1026673
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52777}
2018-04-25 09:47:30 +00:00

373 lines
14 KiB
C++

// Copyright 2014 the V8 project authors. All rights reserved. Use of this
// source code is governed by a BSD-style license that can be found in the
// LICENSE file.
#include "src/objects-inl.h"
#include "src/wasm/wasm-external-refs.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/codegen-tester.h"
#include "test/cctest/compiler/value-helper.h"
namespace v8 {
namespace internal {
namespace compiler {
template <typename InType, typename OutType, typename Iterable>
void TestExternalReference_ConvertOp(
BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
void (*wrapper)(Address), Iterable inputs) {
constexpr size_t kBufferSize = Max(sizeof(InType), sizeof(OutType));
uint8_t buffer[kBufferSize] = {0};
Address buffer_addr = reinterpret_cast<Address>(buffer);
Node* function = m->ExternalConstant(ref);
m->CallCFunction1(MachineType::Pointer(), MachineType::Pointer(), function,
m->PointerConstant(buffer));
m->Return(m->Int32Constant(4356));
for (InType input : inputs) {
WriteUnalignedValue<InType>(buffer_addr, input);
CHECK_EQ(4356, m->Call());
OutType output = ReadUnalignedValue<OutType>(buffer_addr);
WriteUnalignedValue<InType>(buffer_addr, input);
wrapper(buffer_addr);
OutType expected_output = ReadUnalignedValue<OutType>(buffer_addr);
CHECK_EQ(expected_output, output);
}
}
template <typename InType, typename OutType, typename Iterable>
void TestExternalReference_ConvertOpWithOutputAndReturn(
BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
int32_t (*wrapper)(Address), Iterable inputs) {
constexpr size_t kBufferSize = Max(sizeof(InType), sizeof(OutType));
uint8_t buffer[kBufferSize] = {0};
Address buffer_addr = reinterpret_cast<Address>(buffer);
Node* function = m->ExternalConstant(ref);
m->Return(m->CallCFunction1(MachineType::Int32(), MachineType::Pointer(),
function, m->PointerConstant(buffer)));
for (InType input : inputs) {
WriteUnalignedValue<InType>(buffer_addr, input);
int32_t ret = m->Call();
OutType output = ReadUnalignedValue<OutType>(buffer_addr);
WriteUnalignedValue<InType>(buffer_addr, input);
int32_t expected_ret = wrapper(buffer_addr);
OutType expected_output = ReadUnalignedValue<OutType>(buffer_addr);
CHECK_EQ(expected_ret, ret);
CHECK_EQ(expected_output, output);
}
}
template <typename InType, typename OutType, typename Iterable>
void TestExternalReference_ConvertOpWithReturn(
BufferedRawMachineAssemblerTester<OutType>* m, ExternalReference ref,
OutType (*wrapper)(Address), Iterable inputs) {
constexpr size_t kBufferSize = sizeof(InType);
uint8_t buffer[kBufferSize] = {0};
Address buffer_addr = reinterpret_cast<Address>(buffer);
Node* function = m->ExternalConstant(ref);
m->Return(m->CallCFunction1(MachineType::Int32(), MachineType::Pointer(),
function, m->PointerConstant(buffer)));
for (InType input : inputs) {
WriteUnalignedValue<InType>(buffer_addr, input);
OutType ret = m->Call();
WriteUnalignedValue<InType>(buffer_addr, input);
OutType expected_ret = wrapper(buffer_addr);
CHECK_EQ(expected_ret, ret);
}
}
template <typename Type>
bool isnan(Type value) {
return false;
}
template <>
bool isnan<float>(float value) {
return std::isnan(value);
}
template <>
bool isnan<double>(double value) {
return std::isnan(value);
}
template <typename Type, typename Iterable>
void TestExternalReference_UnOp(BufferedRawMachineAssemblerTester<int32_t>* m,
ExternalReference ref, void (*wrapper)(Address),
Iterable inputs) {
constexpr size_t kBufferSize = sizeof(Type);
uint8_t buffer[kBufferSize] = {0};
Address buffer_addr = reinterpret_cast<Address>(buffer);
Node* function = m->ExternalConstant(ref);
m->CallCFunction1(MachineType::Int32(), MachineType::Pointer(), function,
m->PointerConstant(buffer));
m->Return(m->Int32Constant(4356));
for (Type input : inputs) {
WriteUnalignedValue<Type>(buffer_addr, input);
CHECK_EQ(4356, m->Call());
Type output = ReadUnalignedValue<Type>(buffer_addr);
WriteUnalignedValue<Type>(buffer_addr, input);
wrapper(buffer_addr);
Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
if (isnan(expected_output) && isnan(output)) continue;
CHECK_EQ(expected_output, output);
}
}
template <typename Type, typename Iterable>
void TestExternalReference_BinOp(BufferedRawMachineAssemblerTester<int32_t>* m,
ExternalReference ref,
void (*wrapper)(Address), Iterable inputs) {
constexpr size_t kBufferSize = 2 * sizeof(Type);
uint8_t buffer[kBufferSize] = {0};
Address buffer_addr = reinterpret_cast<Address>(buffer);
Node* function = m->ExternalConstant(ref);
m->CallCFunction1(MachineType::Int32(), MachineType::Pointer(), function,
m->PointerConstant(buffer));
m->Return(m->Int32Constant(4356));
for (Type input1 : inputs) {
for (Type input2 : inputs) {
WriteUnalignedValue<Type>(buffer_addr, input1);
WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
CHECK_EQ(4356, m->Call());
Type output = ReadUnalignedValue<Type>(buffer_addr);
WriteUnalignedValue<Type>(buffer_addr, input1);
WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
wrapper(buffer_addr);
Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
if (isnan(expected_output) && isnan(output)) continue;
CHECK_EQ(expected_output, output);
}
}
}
template <typename Type, typename Iterable>
void TestExternalReference_BinOpWithReturn(
BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
int32_t (*wrapper)(Address), Iterable inputs) {
constexpr size_t kBufferSize = 2 * sizeof(Type);
uint8_t buffer[kBufferSize] = {0};
Address buffer_addr = reinterpret_cast<Address>(buffer);
Node* function = m->ExternalConstant(ref);
m->Return(m->CallCFunction1(MachineType::Int32(), MachineType::Pointer(),
function, m->PointerConstant(buffer)));
for (Type input1 : inputs) {
for (Type input2 : inputs) {
WriteUnalignedValue<Type>(buffer_addr, input1);
WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
int32_t ret = m->Call();
Type output = ReadUnalignedValue<Type>(buffer_addr);
WriteUnalignedValue<Type>(buffer_addr, input1);
WriteUnalignedValue<Type>(buffer_addr + sizeof(Type), input2);
int32_t expected_ret = wrapper(buffer_addr);
Type expected_output = ReadUnalignedValue<Type>(buffer_addr);
CHECK_EQ(expected_ret, ret);
if (isnan(expected_output) && isnan(output)) continue;
CHECK_EQ(expected_output, output);
}
}
}
TEST(RunCallF32Trunc) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_f32_trunc();
TestExternalReference_UnOp<float>(&m, ref, wasm::f32_trunc_wrapper,
ValueHelper::float32_vector());
}
TEST(RunCallF32Floor) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_f32_floor();
TestExternalReference_UnOp<float>(&m, ref, wasm::f32_floor_wrapper,
ValueHelper::float32_vector());
}
TEST(RunCallF32Ceil) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_f32_ceil();
TestExternalReference_UnOp<float>(&m, ref, wasm::f32_ceil_wrapper,
ValueHelper::float32_vector());
}
TEST(RunCallF32RoundTiesEven) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_f32_nearest_int();
TestExternalReference_UnOp<float>(&m, ref, wasm::f32_nearest_int_wrapper,
ValueHelper::float32_vector());
}
TEST(RunCallF64Trunc) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_f64_trunc();
TestExternalReference_UnOp<double>(&m, ref, wasm::f64_trunc_wrapper,
ValueHelper::float64_vector());
}
TEST(RunCallF64Floor) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_f64_floor();
TestExternalReference_UnOp<double>(&m, ref, wasm::f64_floor_wrapper,
ValueHelper::float64_vector());
}
TEST(RunCallF64Ceil) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_f64_ceil();
TestExternalReference_UnOp<double>(&m, ref, wasm::f64_ceil_wrapper,
ValueHelper::float64_vector());
}
TEST(RunCallF64RoundTiesEven) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_f64_nearest_int();
TestExternalReference_UnOp<double>(&m, ref, wasm::f64_nearest_int_wrapper,
ValueHelper::float64_vector());
}
TEST(RunCallInt64ToFloat32) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_int64_to_float32();
TestExternalReference_ConvertOp<int64_t, float>(
&m, ref, wasm::int64_to_float32_wrapper, ValueHelper::int64_vector());
}
TEST(RunCallUint64ToFloat32) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_uint64_to_float32();
TestExternalReference_ConvertOp<uint64_t, float>(
&m, ref, wasm::uint64_to_float32_wrapper, ValueHelper::uint64_vector());
}
TEST(RunCallInt64ToFloat64) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_int64_to_float64();
TestExternalReference_ConvertOp<int64_t, double>(
&m, ref, wasm::int64_to_float64_wrapper, ValueHelper::int64_vector());
}
TEST(RunCallUint64ToFloat64) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_uint64_to_float64();
TestExternalReference_ConvertOp<uint64_t, double>(
&m, ref, wasm::uint64_to_float64_wrapper, ValueHelper::uint64_vector());
}
TEST(RunCallFloat32ToInt64) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_float32_to_int64();
TestExternalReference_ConvertOpWithOutputAndReturn<float, int64_t>(
&m, ref, wasm::float32_to_int64_wrapper, ValueHelper::float32_vector());
}
TEST(RunCallFloat32ToUint64) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_float32_to_uint64();
TestExternalReference_ConvertOpWithOutputAndReturn<float, uint64_t>(
&m, ref, wasm::float32_to_uint64_wrapper, ValueHelper::float32_vector());
}
TEST(RunCallFloat64ToInt64) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_float64_to_int64();
TestExternalReference_ConvertOpWithOutputAndReturn<double, int64_t>(
&m, ref, wasm::float64_to_int64_wrapper, ValueHelper::float64_vector());
}
TEST(RunCallFloat64ToUint64) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_float64_to_uint64();
TestExternalReference_ConvertOpWithOutputAndReturn<double, uint64_t>(
&m, ref, wasm::float64_to_uint64_wrapper, ValueHelper::float64_vector());
}
TEST(RunCallInt64Div) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_int64_div();
TestExternalReference_BinOpWithReturn<int64_t>(
&m, ref, wasm::int64_div_wrapper, ValueHelper::int64_vector());
}
TEST(RunCallInt64Mod) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_int64_mod();
TestExternalReference_BinOpWithReturn<int64_t>(
&m, ref, wasm::int64_mod_wrapper, ValueHelper::int64_vector());
}
TEST(RunCallUint64Div) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_uint64_div();
TestExternalReference_BinOpWithReturn<uint64_t>(
&m, ref, wasm::uint64_div_wrapper, ValueHelper::uint64_vector());
}
TEST(RunCallUint64Mod) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_uint64_mod();
TestExternalReference_BinOpWithReturn<uint64_t>(
&m, ref, wasm::uint64_mod_wrapper, ValueHelper::uint64_vector());
}
TEST(RunCallWord32Ctz) {
BufferedRawMachineAssemblerTester<uint32_t> m;
ExternalReference ref = ExternalReference::wasm_word32_ctz();
TestExternalReference_ConvertOpWithReturn<int32_t, uint32_t>(
&m, ref, wasm::word32_ctz_wrapper, ValueHelper::int32_vector());
}
TEST(RunCallWord64Ctz) {
BufferedRawMachineAssemblerTester<uint32_t> m;
ExternalReference ref = ExternalReference::wasm_word64_ctz();
TestExternalReference_ConvertOpWithReturn<int64_t, uint32_t>(
&m, ref, wasm::word64_ctz_wrapper, ValueHelper::int64_vector());
}
TEST(RunCallWord32Popcnt) {
BufferedRawMachineAssemblerTester<uint32_t> m;
ExternalReference ref = ExternalReference::wasm_word32_popcnt();
TestExternalReference_ConvertOpWithReturn<uint32_t, uint32_t>(
&m, ref, wasm::word32_popcnt_wrapper, ValueHelper::int32_vector());
}
TEST(RunCallWord64Popcnt) {
BufferedRawMachineAssemblerTester<uint32_t> m;
ExternalReference ref = ExternalReference::wasm_word64_popcnt();
TestExternalReference_ConvertOpWithReturn<int64_t, uint32_t>(
&m, ref, wasm::word64_popcnt_wrapper, ValueHelper::int64_vector());
}
TEST(RunCallFloat64Pow) {
BufferedRawMachineAssemblerTester<int32_t> m;
ExternalReference ref = ExternalReference::wasm_float64_pow();
TestExternalReference_BinOp<double>(&m, ref, wasm::float64_pow_wrapper,
ValueHelper::float64_vector());
}
} // namespace compiler
} // namespace internal
} // namespace v8