From ebacbf1a10e6583c22604768f6557d027b7f42b2 Mon Sep 17 00:00:00 2001 From: Amir Bawab Date: Thu, 11 Apr 2019 23:13:24 -0400 Subject: [PATCH 1/3] Started refactoring --- deps/v8/gypfiles/v8.gyp | 9 +- deps/v8/src/third_party/native_wasm/math.cc | 1 + deps/v8/src/third_party/native_wasm/math.h | 0 deps/v8/src/third_party/native_wasm/native.cc | 26 ++ deps/v8/src/third_party/native_wasm/system.cc | 60 ++++ deps/v8/src/third_party/native_wasm/system.h | 27 ++ deps/v8/src/wasm/module-decoder.cc | 4 +- deps/v8/src/wasm/wasm-external-refs.cc | 2 +- deps/v8/src/wasm/wasm-sable-external-refs.cc | 269 +++++++----------- deps/v8/src/wasm/wasm-sable-external-refs.h | 52 +++- 10 files changed, 285 insertions(+), 165 deletions(-) create mode 100644 deps/v8/src/third_party/native_wasm/math.cc create mode 100644 deps/v8/src/third_party/native_wasm/math.h create mode 100644 deps/v8/src/third_party/native_wasm/native.cc create mode 100644 deps/v8/src/third_party/native_wasm/system.cc create mode 100644 deps/v8/src/third_party/native_wasm/system.h diff --git a/deps/v8/gypfiles/v8.gyp b/deps/v8/gypfiles/v8.gyp index 566f19a96b3696..157dba4f77bd43 100644 --- a/deps/v8/gypfiles/v8.gyp +++ b/deps/v8/gypfiles/v8.gyp @@ -1603,6 +1603,11 @@ '../src/strtod.h', '../src/task-utils.cc', '../src/task-utils.h', + '../src/third_party/native_wasm/math.cc', + '../src/third_party/native_wasm/math.h', + '../src/third_party/native_wasm/native.cc', + '../src/third_party/native_wasm/system.cc', + '../src/third_party/native_wasm/system.h', '../src/third_party/siphash/halfsiphash.cc', '../src/third_party/siphash/halfsiphash.h', '../src/third_party/utf8-decoder/utf8-decoder.h', @@ -1699,8 +1704,6 @@ '../src/wasm/wasm-engine.h', '../src/wasm/wasm-external-refs.cc', '../src/wasm/wasm-external-refs.h', - '../src/wasm/wasm-sable-external-refs.cc', - '../src/wasm/wasm-sable-external-refs.h', '../src/wasm/wasm-feature-flags.h', '../src/wasm/wasm-features.cc', '../src/wasm/wasm-features.h', @@ -1724,6 +1727,8 @@ '../src/wasm/wasm-opcodes.h', '../src/wasm/wasm-result.cc', '../src/wasm/wasm-result.h', + '../src/wasm/wasm-sable-external-refs.cc', + '../src/wasm/wasm-sable-external-refs.h', '../src/wasm/wasm-serialization.cc', '../src/wasm/wasm-serialization.h', '../src/wasm/wasm-text.cc', diff --git a/deps/v8/src/third_party/native_wasm/math.cc b/deps/v8/src/third_party/native_wasm/math.cc new file mode 100644 index 00000000000000..5c0ae26f26e38e --- /dev/null +++ b/deps/v8/src/third_party/native_wasm/math.cc @@ -0,0 +1 @@ +#include "src/base/ieee754.h" diff --git a/deps/v8/src/third_party/native_wasm/math.h b/deps/v8/src/third_party/native_wasm/math.h new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/deps/v8/src/third_party/native_wasm/native.cc b/deps/v8/src/third_party/native_wasm/native.cc new file mode 100644 index 00000000000000..17d46b2c2bfb0b --- /dev/null +++ b/deps/v8/src/third_party/native_wasm/native.cc @@ -0,0 +1,26 @@ +#include "src/wasm/wasm-sable-external-refs.h" +#include "src/third_party/native_wasm/system.h" + +namespace v8 { +namespace internal { +namespace wasm { +namespace native { + +void init_native() { + register_native_function("i32.print_s", nf_print_stack, {kWasmI32}, {}); + register_native_function("i64.print_s", nf_print_stack, {kWasmI64}, {}); + register_native_function("f32.print_s", nf_print_stack, {kWasmF32}, {}); + register_native_function("f64.print_s", nf_print_stack, {kWasmF64}, {}); + + register_native_function("i64.time_ms", nf_time_ms, {}, {kWasmI64}); + + register_native_function("i32.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); + register_native_function("i64.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); + register_native_function("f32.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); + register_native_function("f64.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); +} + +} +} +} +} diff --git a/deps/v8/src/third_party/native_wasm/system.cc b/deps/v8/src/third_party/native_wasm/system.cc new file mode 100644 index 00000000000000..075ec6ab833724 --- /dev/null +++ b/deps/v8/src/third_party/native_wasm/system.cc @@ -0,0 +1,60 @@ +#include "src/third_party/native_wasm/system.h" +#include +#include + +namespace v8 { +namespace internal { +namespace wasm { +namespace native { + +template +void nf_print_mem(std::vector args, std::vector rets, native::Memory memory) { + DCHECK_EQ(2, args.size()); + DCHECK_EQ(0, rets.size()); + + int32_t offset = args[0].Get(); + int32_t size = args[1].Get(); + for(int i=0; i < size; ++i) { + std::cout << memory.Read(offset) << " "; + } + std::cout << std::endl; +} + +// explicit instantiation of nf_print_mem template +template void nf_print_mem(std::vector args, std::vector rets, + native::Memory memory); +template void nf_print_mem(std::vector args, std::vector rets, + native::Memory memory); +template void nf_print_mem(std::vector args, std::vector rets, + native::Memory memory); +template void nf_print_mem(std::vector args, std::vector rets, + native::Memory memory); + +void nf_time_ms(std::vector args, std::vector rets, native::Memory memory) { + DCHECK_EQ(0, args.size()); + DCHECK_EQ(1, rets.size()); + rets[0].Set(std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count()); +} + +template +void nf_print_stack(std::vector args, std::vector rets, native::Memory memory) { + DCHECK_EQ(1, args.size()); + DCHECK_EQ(0, rets.size()); + std::cout << args[0].Get() << std::endl; +} + +// explicit instantiation of nf_print_stack template +template void nf_print_stack(std::vector args, std::vector rets, + native::Memory memory); +template void nf_print_stack(std::vector args, std::vector rets, + native::Memory memory); +template void nf_print_stack(std::vector args, std::vector rets, + native::Memory memory); +template void nf_print_stack(std::vector args, std::vector rets, + native::Memory memory); + +} +} +} +} diff --git a/deps/v8/src/third_party/native_wasm/system.h b/deps/v8/src/third_party/native_wasm/system.h new file mode 100644 index 00000000000000..2d7d4b0514d19e --- /dev/null +++ b/deps/v8/src/third_party/native_wasm/system.h @@ -0,0 +1,27 @@ +#ifndef WASM_NATIVE_WASM_SYSTEM_H +#define WASM_NATIVE_WASM_SYSTEM_H + +#include "src/wasm/wasm-sable-external-refs.h" + +namespace v8 { +namespace internal { +namespace wasm { +namespace native { + +// print stack content +template +void nf_print_stack(std::vector args, std::vector rets, native::Memory memory); + +// get time in ms +void nf_time_ms(std::vector args, std::vector rets, native::Memory memory); + +// print linear memory +template +void nf_print_mem(std::vector args, std::vector rets, native::Memory memory); + +} // namespace native +} // namespace wasm +} // namespace internal +} // namespace v8 + +#endif diff --git a/deps/v8/src/wasm/module-decoder.cc b/deps/v8/src/wasm/module-decoder.cc index 266b16b1f7df75..10b056a613ba90 100644 --- a/deps/v8/src/wasm/module-decoder.cc +++ b/deps/v8/src/wasm/module-decoder.cc @@ -491,6 +491,8 @@ class ModuleDecoderImpl : public Decoder { } void DecodeNativeSection() { + // initialize native environment + native::init_native(); uint32_t natives_count = consume_count("natives count", kV8MaxWasmNatives); module_->natives.reserve(natives_count); for (uint32_t i = 0; ok() && i < natives_count; ++i) { @@ -501,7 +503,7 @@ class ModuleDecoderImpl : public Decoder { const char* func_name = std::string( reinterpret_cast(start() + GetBufferRelativeOffset(native.func_name.offset())), native.func_name.length()).c_str(); - if(!find_native_function(func_name, native.sig, &native.native_index)) { + if(!native::find_native_function(func_name, native.sig, &native.native_index)) { errorf(pc_, "native function %s not found", func_name); } module_->natives.push_back(std::move(native)); diff --git a/deps/v8/src/wasm/wasm-external-refs.cc b/deps/v8/src/wasm/wasm-external-refs.cc index b4fac55e3f6ec1..55e9650d34cc7b 100644 --- a/deps/v8/src/wasm/wasm-external-refs.cc +++ b/deps/v8/src/wasm/wasm-external-refs.cc @@ -258,7 +258,7 @@ void memory_fill_wrapper(Address dst, uint32_t value, uint32_t size) { } int32_t native_call_wrapper(uint32_t functionId, Address mem, Address data) { - return native_function_gateway(functionId, mem, data); + return native::native_function_gateway(functionId, mem, data); } static WasmTrapCallbackForTesting wasm_trap_callback_for_testing = nullptr; diff --git a/deps/v8/src/wasm/wasm-sable-external-refs.cc b/deps/v8/src/wasm/wasm-sable-external-refs.cc index c39354cde60ab7..f5e24f486aae1d 100644 --- a/deps/v8/src/wasm/wasm-sable-external-refs.cc +++ b/deps/v8/src/wasm/wasm-sable-external-refs.cc @@ -1,102 +1,16 @@ #include "src/wasm/wasm-sable-external-refs.h" #include "src/signature.h" -#include "src/base/ieee754.h" -#include -#include #include +#include namespace v8 { namespace internal { namespace wasm { +namespace native { -/******************** - * Helper functions - ********************/ -template -inline T ReadValue(byte* address) { - return ReadUnalignedValue(reinterpret_cast
(address)); -} - -template -inline T ReadValueAndAdvance(byte** address) { - T val = ReadValue(*address); - *address += sizeof(T); - return val; -} - -template -inline void WriteValue(T* address, T val) { - WriteUnalignedValue(reinterpret_cast
(address), val); -} - -template -inline void WriteValueAndAdvance(T** address, T val) { - WriteValue(*address, val); - *address += sizeof(T); -} - -/********************* - * Defines - *********************/ -#define ___ void -#define I32 int32_t -#define I64 int64_t -#define F32 float -#define F64 double - -// all native functions should be declared -// in FOREACH_NATIVE_FUNCTION_[NON_]TEMPLATE -#define FOREACH_NATIVE_FUNCTION_NON_TEMPLATE(V, P, R) \ - V(exp, "f64.exp", ___, P(kWasmF64), R(kWasmF64)) \ - V(time_ms, "i64.time_ms", ___, P(), R(kWasmI64)) - -#define FOREACH_NATIVE_FUNCTION_TEMPLATE(V, P, R) \ - V(matrix_multiplication, "i32.mat_mul", I32, P(kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32), R()) \ - V(matrix_multiplication, "i64.mat_mul", I64, P(kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32), R()) \ - V(matrix_multiplication, "f32.mat_mul", F32, P(kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32), R()) \ - V(matrix_multiplication, "f64.mat_mul", F64, P(kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32), R()) \ - V(print_mem, "i32.print_m", I32, P(kWasmI32, kWasmI32), R()) \ - V(print_mem, "i64.print_m", I64, P(kWasmI32, kWasmI32), R()) \ - V(print_mem, "f32.print_m", F32, P(kWasmI32, kWasmI32), R()) \ - V(print_mem, "f64.print_m", F64, P(kWasmI32, kWasmI32), R()) \ - V(print_stack, "i32.print_s", I32, P(kWasmI32), R()) \ - V(print_stack, "i64.print_s", I64, P(kWasmI64), R()) \ - V(print_stack, "f32.print_s", F32, P(kWasmF32), R()) \ - V(print_stack, "f64.print_s", F64, P(kWasmF64), R()) - -#define FOREACH_NATIVE_FUNCTION(V, P, R) \ - FOREACH_NATIVE_FUNCTION_NON_TEMPLATE(V, P, R) \ - FOREACH_NATIVE_FUNCTION_TEMPLATE(V, P, R) - -// declare functions prototype -#define NATIVE_FUNCTION_PROTOTYPE(function, name, type, param, ret) \ - void f_##function(byte*,byte*); - FOREACH_NATIVE_FUNCTION_NON_TEMPLATE(NATIVE_FUNCTION_PROTOTYPE, ___, ___) -#undef NATIVE_FUNCTION_PROTOTYPE - -#define NATIVE_FUNCTION_PROTOTYPE(function, name, type, param, ret) \ - template \ - void f_##function(byte*,byte*); - FOREACH_NATIVE_FUNCTION_TEMPLATE(NATIVE_FUNCTION_PROTOTYPE, ___, ___) -#undef NATIVE_FUNCTION_PROTOTYPE - -// use an enum to give each function -// a unique index -enum NativeFunction { - FIRST, -#define NATIVE_FUNCTION_ENUM(function, name, type, param, ret) \ - k##function##_##type, -FOREACH_NATIVE_FUNCTION(NATIVE_FUNCTION_ENUM, ___, ___) -#undef NATIVE_FUNCTION_ENUM - LAST -}; - -// structure to hold the definition -// of a native function -typedef void (*native)(byte*, byte*); -struct NativeFunctionDefinition { - native func; - NativeFunction id; +struct Function { + std::string name; + native_t func; std::vector params; std::vector rets; bool sig_match(FunctionSig *sig) { @@ -117,97 +31,132 @@ struct NativeFunctionDefinition { } }; -// store all native functions into -// a global array -NativeFunctionDefinition g_functions[] = { - {}, // NativeFunction::FIRST -#define ARGS_TO_VECTOR(...) {__VA_ARGS__} -#define NATIVE_FUNCTION_ARRAY(function, name, type, param, ret) \ - {f_##function, k##function##_##type, param, ret}, - FOREACH_NATIVE_FUNCTION_NON_TEMPLATE(NATIVE_FUNCTION_ARRAY, ARGS_TO_VECTOR, ARGS_TO_VECTOR) -#undef NATIVE_FUNCTION_ARRAY - -#define NATIVE_FUNCTION_ARRAY(function, name, type, param, ret) \ - {f_##function, k##function##_##type, param, ret}, - FOREACH_NATIVE_FUNCTION_TEMPLATE(NATIVE_FUNCTION_ARRAY, ARGS_TO_VECTOR, ARGS_TO_VECTOR) -#undef NATIVE_FUNCTION_ARRAY -#undef ARGS_TO_VECTOR -}; +template <> int32_t Argument::Get() const { + CHECK_EQ(type_, kWasmI32); + return ReadUnalignedValue(val_add_); +} -/******************* - * Native functions - ******************/ +template <> int64_t Argument::Get() const { + CHECK_EQ(type_, kWasmI64); + return ReadUnalignedValue(val_add_); +} -template -void f_matrix_multiplication(byte* memByte, byte* dataByte) { - I32 mat1Offset = ReadValueAndAdvance(&dataByte); - I32 mat2Offset = ReadValueAndAdvance(&dataByte); - I32 resOffset = ReadValueAndAdvance(&dataByte); - I32 m = ReadValueAndAdvance(&dataByte); - I32 n = ReadValueAndAdvance(&dataByte); - I32 p = ReadValueAndAdvance(&dataByte); - - T* mat1 = reinterpret_cast(memByte + mat1Offset); - T* mat2 = reinterpret_cast(memByte + mat2Offset); - T* res = reinterpret_cast(memByte + resOffset); - - for(int r=0; r < m; ++r) { - for(int c=0; c < p; ++c) { - T resCell = 0; - for(int cr=0; cr < n; ++cr) { - resCell += *(mat1 + r * n + cr) * *(mat2 + cr * p + c); - } - WriteValue(res + r * p + c, resCell); - } - } +template <> float Argument::Get() const { + CHECK_EQ(type_, kWasmF32); + return ReadUnalignedValue(val_add_); } -template -void f_print_mem(byte* memByte, byte* dataByte) { - I32 offset = ReadValueAndAdvance(&dataByte); - I32 size = ReadValueAndAdvance(&dataByte); - for(int i=0; i < size; ++i) { - std::cout << *(reinterpret_cast(memByte + offset + i * sizeof(T))) << " "; - } - std::cout << std::endl; +template <> double Argument::Get() const { + CHECK_EQ(type_, kWasmF64); + return ReadUnalignedValue(val_add_); } -void f_exp(byte* memByte, byte* dataByte) { - F64 x = ReadValueAndAdvance(&dataByte); - WriteValue(reinterpret_cast(dataByte), base::ieee754::exp(x)); +template <> void Return::Set(int32_t val) { + CHECK_EQ(type_, kWasmI32); + WriteUnalignedValue(ret_add_, val); } -void f_time_ms(byte* memByte, byte* dataByte) { - WriteValue(reinterpret_cast(dataByte), std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count()); +template <> void Return::Set(int64_t val) { + CHECK_EQ(type_, kWasmI64); + WriteUnalignedValue(ret_add_, val); } -template -void f_print_stack(byte* memByte, byte* dataByte) { - std::cout << *(reinterpret_cast(dataByte)) << std::endl; +template <> void Return::Set(float val) { + CHECK_EQ(type_, kWasmF32); + WriteUnalignedValue(ret_add_, val); } +template <> void Return::Set(double val) { + CHECK_EQ(type_, kWasmF64); + WriteUnalignedValue(ret_add_, val); +} + +/******************* + * Native functions + ******************/ + +//template +//void f_matrix_multiplication(byte* memByte, byte* dataByte) { +// I32 mat1Offset = ReadValueAndAdvance(&dataByte); +// I32 mat2Offset = ReadValueAndAdvance(&dataByte); +// I32 resOffset = ReadValueAndAdvance(&dataByte); +// I32 m = ReadValueAndAdvance(&dataByte); +// I32 n = ReadValueAndAdvance(&dataByte); +// I32 p = ReadValueAndAdvance(&dataByte); +// +// T* mat1 = reinterpret_cast(memByte + mat1Offset); +// T* mat2 = reinterpret_cast(memByte + mat2Offset); +// T* res = reinterpret_cast(memByte + resOffset); +// +// for(int r=0; r < m; ++r) { +// for(int c=0; c < p; ++c) { +// T resCell = 0; +// for(int cr=0; cr < n; ++cr) { +// resCell += *(mat1 + r * n + cr) * *(mat2 + cr * p + c); +// } +// WriteValue(res + r * p + c, resCell); +// } +// } +//} +// +// +//void f_exp(byte* memByte, byte* dataByte) { +// F64 x = ReadValueAndAdvance(&dataByte); +// WriteValue(reinterpret_cast(dataByte), base::ieee754::exp(x)); +//} +// + /******************************* * External reference functions *******************************/ +std::vector g_func_vec; +std::map g_func_map; + +bool register_native_function(std::string name, native_t func, + std::vector args, std::vector rets) { + if(g_func_map.find(name) != g_func_map.end()) { + return false; + } + g_func_map[name] = g_func_vec.size(); + g_func_vec.emplace_back(Function{ + std::move(name), std::move(func), std::move(args), std::move(rets) + }); + return true; +} -bool find_native_function(const char* find_name, FunctionSig* sig, int *index) { -#define FIND_NATIVE_FUNCTION(function, name, type, param, ret) \ - if(strcmp(name, find_name) == 0) { \ - *index = k##function##_##type; \ - return g_functions[*index].sig_match(sig);\ +bool find_native_function(const char* find_name, FunctionSig* sig, int *out_index) { + int funcId; + if(g_func_map.find(find_name) == g_func_map.end() || !g_func_vec[funcId = g_func_map[find_name]].sig_match(sig)) { + return false; } - FOREACH_NATIVE_FUNCTION(FIND_NATIVE_FUNCTION, ___, ___) -#undef FIND_NATIVE_FUNCTION - return false; + *out_index = funcId; + return true; } int native_function_gateway(int funcId, Address mem, Address data) { - DCHECK_GT(funcId, NativeFunction::FIRST); - DCHECK_LT(funcId, NativeFunction::LAST); - (*g_functions[funcId].func)(reinterpret_cast(mem), reinterpret_cast(data)); + CHECK_GE(funcId, 0); + CHECK_LT(funcId, g_func_vec.size()); + const Function &func = g_func_vec[funcId]; + arg_vec_t args; + ret_vec_t rets; + byte* byteData = reinterpret_cast(data); + for(size_t i=0; i < func.params.size(); ++i) { + args.emplace_back(Argument{ + reinterpret_cast
(byteData), func.params[i] + }); + byteData += ValueTypes::ElementSizeInBytes(func.params[i]); + } + for(size_t i=0; i < func.rets.size(); ++i) { + rets.emplace_back(Return{ + reinterpret_cast
(byteData), func.rets[i] + }); + byteData += ValueTypes::ElementSizeInBytes(func.rets[i]); + } + (*func.func)(args, rets, Memory{mem, mem /*TODO*/}); + return 0; } +} // namespace native } // namespace wasm } // namespace internal } // namespace v8 diff --git a/deps/v8/src/wasm/wasm-sable-external-refs.h b/deps/v8/src/wasm/wasm-sable-external-refs.h index 434855eed7bd56..0adcfaf354c599 100644 --- a/deps/v8/src/wasm/wasm-sable-external-refs.h +++ b/deps/v8/src/wasm/wasm-sable-external-refs.h @@ -7,19 +7,69 @@ #include "src/wasm/value-type.h" #include "src/v8memory.h" +#include namespace v8 { namespace internal { namespace wasm { +namespace native { + +class Memory { +public: + Memory(Address s, Address e) : start_(reinterpret_cast(s)), end_(reinterpret_cast(e)) {} + template + void Write(int offset, T val) { + CHECK_LT(start_ + offset + sizeof(T), end_); + WriteUnalignedValue(reinterpret_cast
(start_ + offset), val); + } + template + T Read(int offset) { + CHECK_LT(start_ + offset + sizeof(T), end_); + return ReadUnalignedValue(reinterpret_cast
(start_ + offset)); + } +private: + byte* start_ = nullptr; + byte* end_ = nullptr; +}; + +class Argument { +public: + Argument(Address add, ValueType type) : val_add_(add), type_(type) {} + template T Get() const; +private: + Address val_add_; + ValueType type_; +}; + +class Return { +public: + Return(Address add, ValueType type) : ret_add_(add), type_(type) {} + template void Set(T val); + ValueType type() const { return type_; } +private: + ValueType type_; + Address ret_add_; +}; + +typedef std::vector arg_vec_t; +typedef std::vector ret_vec_t; +typedef void (*native_t)(arg_vec_t , ret_vec_t, Memory); + +// initialize environment +void init_native(); + +// register a native function +bool register_native_function(std::string name, native_t func, std::vector args, std::vector rets); // find native function and set its index -bool find_native_function(const char* find_name, FunctionSig* sig, int *index); +bool find_native_function(const char* find_name, FunctionSig* sig, int *out_index); // entry point to calling a native function // this gateway function will call the appropriate // function based on the given function id int native_function_gateway(int funcId, Address mem, Address data); +} // namespace native } // namespace wasm } // namespace internal } // namespace v8 From 19e83e94352e113459aad2a4c2b59d6beae322a8 Mon Sep 17 00:00:00 2001 From: Amir Bawab Date: Sat, 13 Apr 2019 15:01:46 -0400 Subject: [PATCH 2/3] Updated api --- deps/v8/src/compiler/wasm-compiler.cc | 13 ++--- deps/v8/src/third_party/native_wasm/math.cc | 58 +++++++++++++++++++ deps/v8/src/third_party/native_wasm/math.h | 24 ++++++++ deps/v8/src/third_party/native_wasm/native.cc | 14 ++++- deps/v8/src/wasm/wasm-external-refs.cc | 4 +- deps/v8/src/wasm/wasm-external-refs.h | 2 +- deps/v8/src/wasm/wasm-sable-external-refs.cc | 39 +------------ deps/v8/src/wasm/wasm-sable-external-refs.h | 31 ++++++++-- 8 files changed, 131 insertions(+), 54 deletions(-) diff --git a/deps/v8/src/compiler/wasm-compiler.cc b/deps/v8/src/compiler/wasm-compiler.cc index ffc3bba4377d1c..e4e0d92638b59d 100644 --- a/deps/v8/src/compiler/wasm-compiler.cc +++ b/deps/v8/src/compiler/wasm-compiler.cc @@ -2782,20 +2782,19 @@ Node* WasmGraphBuilder::CallNative(uint32_t index, Node** args, Node** rets, paramStackSlotIndex += wasm::ValueTypes::ElementSizeInBytes(type); } - // TODO benchmark bound checking (check generated assembly) - Node* linearMemory = BoundsCheckMemRange(mcgraph()->Int32Constant(0), - // TODO input another size value (maybe page size?) - mcgraph()->Int32Constant(0), position); - + Node* linearMemory = instance_cache_->mem_start; + Node* linearMemorySize = instance_cache_->mem_size; Node* function = graph()->NewNode(mcgraph()->common()->ExternalConstant(ExternalReference::wasm_native_call())); MachineType sig_types[] = { MachineType::Int32(), // wasm_native_call return type MachineType::Int32(), // Native function id value MachineType::Pointer(), // Linear memory address + MachineType::Uint32(), // Linear memory size MachineType::Pointer() // Stack slot address (parameter slots followed by return slots) }; - MachineSignature sig(1, 3, sig_types); - Node* call = BuildCCall(&sig, function, mcgraph()->Int32Constant(native.native_index), linearMemory, stack_slot); + MachineSignature sig(1, 4, sig_types); + Node* call = BuildCCall(&sig, function, mcgraph()->Int32Constant(native.native_index), linearMemory, + linearMemorySize, stack_slot); // Check if return value is zero (currently not used) // ZeroCheck32(wasm::kTrapFuncInvalid, call, position); diff --git a/deps/v8/src/third_party/native_wasm/math.cc b/deps/v8/src/third_party/native_wasm/math.cc index 5c0ae26f26e38e..e6ac5b7424a03a 100644 --- a/deps/v8/src/third_party/native_wasm/math.cc +++ b/deps/v8/src/third_party/native_wasm/math.cc @@ -1 +1,59 @@ +#include "src/third_party/native_wasm/math.h" #include "src/base/ieee754.h" + +namespace v8 { +namespace internal { +namespace wasm { +namespace native { + +template +void nf_matrix_multiplication(std::vector args, std::vector rets, + native::Memory memory) { + DCHECK_EQ(6, args.size()); + DCHECK_EQ(0, rets.size()); + + int32_t mat1Offset = args[0].Get(); + int32_t mat2Offset = args[1].Get(); + int32_t resOffset = args[2].Get(); + int32_t m = args[3].Get(); + int32_t n = args[4].Get(); + int32_t p = args[5].Get(); + + if(!memory.SafeAccess(mat1Offset) || !memory.SafeAccess(resOffset + m * p)) { + // TODO trap + return; + } + + for(int r=0; r < m; ++r) { + for(int c=0; c < p; ++c) { + T resCell = 0; + for(int cr=0; cr < n; ++cr) { + resCell += memory.ReadUnsafe(mat1Offset + (r * n + cr) * sizeof(T)) * + memory.ReadUnsafe(mat2Offset + (cr * p + c) * sizeof(T)); + } + memory.WriteUnsafe(resOffset + (r * p + c) * sizeof(T), resCell); + } + } +} + +// explicit instantiation of nf_matrix_multiplication template +template void nf_matrix_multiplication(std::vector args, std::vector rets, + native::Memory memory); +template void nf_matrix_multiplication(std::vector args, std::vector rets, + native::Memory memory); +template void nf_matrix_multiplication(std::vector args, std::vector rets, + native::Memory memory); +template void nf_matrix_multiplication(std::vector args, std::vector rets, + native::Memory memory); + +void nf_exp(std::vector args, std::vector rets, native::Memory memory) { + DCHECK_EQ(1, args.size()); + DCHECK_EQ(1, rets.size()); + + rets[0].Set(base::ieee754::exp(args[0].Get())); +} + +} +} +} +} diff --git a/deps/v8/src/third_party/native_wasm/math.h b/deps/v8/src/third_party/native_wasm/math.h index e69de29bb2d1d6..650995543c5d00 100644 --- a/deps/v8/src/third_party/native_wasm/math.h +++ b/deps/v8/src/third_party/native_wasm/math.h @@ -0,0 +1,24 @@ +#ifndef WASM_NATIVE_WASM_MATH_H +#define WASM_NATIVE_WASM_MATH_H + +#include "src/wasm/wasm-sable-external-refs.h" + +namespace v8 { +namespace internal { +namespace wasm { +namespace native { + +// matrix multiplication +template +void nf_matrix_multiplication(std::vector args, std::vector rets, + native::Memory memory); + +// exp(x) +void nf_exp(std::vector args, std::vector rets, native::Memory memory); + +} // namespace native +} // namespace wasm +} // namespace internal +} // namespace v8 + +#endif diff --git a/deps/v8/src/third_party/native_wasm/native.cc b/deps/v8/src/third_party/native_wasm/native.cc index 17d46b2c2bfb0b..fee7890462fc64 100644 --- a/deps/v8/src/third_party/native_wasm/native.cc +++ b/deps/v8/src/third_party/native_wasm/native.cc @@ -1,5 +1,5 @@ -#include "src/wasm/wasm-sable-external-refs.h" #include "src/third_party/native_wasm/system.h" +#include "src/third_party/native_wasm/math.h" namespace v8 { namespace internal { @@ -7,6 +7,7 @@ namespace wasm { namespace native { void init_native() { + // system register_native_function("i32.print_s", nf_print_stack, {kWasmI32}, {}); register_native_function("i64.print_s", nf_print_stack, {kWasmI64}, {}); register_native_function("f32.print_s", nf_print_stack, {kWasmF32}, {}); @@ -18,6 +19,17 @@ void init_native() { register_native_function("i64.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); register_native_function("f32.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); register_native_function("f64.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); + + // math + register_native_function("f64.exp", nf_exp, {kWasmF64}, {kWasmF64}); + register_native_function("i32.mat_mul", nf_matrix_multiplication, + {kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32}, {}); + register_native_function("i64.mat_mul", nf_matrix_multiplication, + {kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32}, {}); + register_native_function("f32.mat_mul", nf_matrix_multiplication, + {kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32}, {}); + register_native_function("f64.mat_mul", nf_matrix_multiplication, + {kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32}, {}); } } diff --git a/deps/v8/src/wasm/wasm-external-refs.cc b/deps/v8/src/wasm/wasm-external-refs.cc index 55e9650d34cc7b..828c617b811db7 100644 --- a/deps/v8/src/wasm/wasm-external-refs.cc +++ b/deps/v8/src/wasm/wasm-external-refs.cc @@ -257,8 +257,8 @@ void memory_fill_wrapper(Address dst, uint32_t value, uint32_t size) { memset(reinterpret_cast(dst), value, size); } -int32_t native_call_wrapper(uint32_t functionId, Address mem, Address data) { - return native::native_function_gateway(functionId, mem, data); +int32_t native_call_wrapper(int32_t funcId, Address mem, uint32_t memSize, Address data) { + return native::native_function_gateway(funcId, mem, memSize, data); } static WasmTrapCallbackForTesting wasm_trap_callback_for_testing = nullptr; diff --git a/deps/v8/src/wasm/wasm-external-refs.h b/deps/v8/src/wasm/wasm-external-refs.h index bf600d0dbbfe15..6d57d2afacfcf6 100644 --- a/deps/v8/src/wasm/wasm-external-refs.h +++ b/deps/v8/src/wasm/wasm-external-refs.h @@ -71,7 +71,7 @@ void memory_copy_wrapper(Address dst, Address src, uint32_t size); void memory_fill_wrapper(Address dst, uint32_t value, uint32_t size); -int32_t native_call_wrapper(uint32_t functionIndex, Address mem, Address data); +int32_t native_call_wrapper(int32_t funcId, Address mem, uint32_t memSize, Address data); typedef void (*WasmTrapCallbackForTesting)(); diff --git a/deps/v8/src/wasm/wasm-sable-external-refs.cc b/deps/v8/src/wasm/wasm-sable-external-refs.cc index f5e24f486aae1d..737d8b46a62537 100644 --- a/deps/v8/src/wasm/wasm-sable-external-refs.cc +++ b/deps/v8/src/wasm/wasm-sable-external-refs.cc @@ -71,41 +71,6 @@ template <> void Return::Set(double val) { WriteUnalignedValue(ret_add_, val); } -/******************* - * Native functions - ******************/ - -//template -//void f_matrix_multiplication(byte* memByte, byte* dataByte) { -// I32 mat1Offset = ReadValueAndAdvance(&dataByte); -// I32 mat2Offset = ReadValueAndAdvance(&dataByte); -// I32 resOffset = ReadValueAndAdvance(&dataByte); -// I32 m = ReadValueAndAdvance(&dataByte); -// I32 n = ReadValueAndAdvance(&dataByte); -// I32 p = ReadValueAndAdvance(&dataByte); -// -// T* mat1 = reinterpret_cast(memByte + mat1Offset); -// T* mat2 = reinterpret_cast(memByte + mat2Offset); -// T* res = reinterpret_cast(memByte + resOffset); -// -// for(int r=0; r < m; ++r) { -// for(int c=0; c < p; ++c) { -// T resCell = 0; -// for(int cr=0; cr < n; ++cr) { -// resCell += *(mat1 + r * n + cr) * *(mat2 + cr * p + c); -// } -// WriteValue(res + r * p + c, resCell); -// } -// } -//} -// -// -//void f_exp(byte* memByte, byte* dataByte) { -// F64 x = ReadValueAndAdvance(&dataByte); -// WriteValue(reinterpret_cast(dataByte), base::ieee754::exp(x)); -//} -// - /******************************* * External reference functions *******************************/ @@ -133,7 +98,7 @@ bool find_native_function(const char* find_name, FunctionSig* sig, int *out_inde return true; } -int native_function_gateway(int funcId, Address mem, Address data) { +int native_function_gateway(int32_t funcId, Address mem, uint32_t memSize, Address data) { CHECK_GE(funcId, 0); CHECK_LT(funcId, g_func_vec.size()); const Function &func = g_func_vec[funcId]; @@ -152,7 +117,7 @@ int native_function_gateway(int funcId, Address mem, Address data) { }); byteData += ValueTypes::ElementSizeInBytes(func.rets[i]); } - (*func.func)(args, rets, Memory{mem, mem /*TODO*/}); + (*func.func)(args, rets, Memory{reinterpret_cast(mem), reinterpret_cast(mem) + memSize}); return 0; } diff --git a/deps/v8/src/wasm/wasm-sable-external-refs.h b/deps/v8/src/wasm/wasm-sable-external-refs.h index 0adcfaf354c599..6dca41e3f2d975 100644 --- a/deps/v8/src/wasm/wasm-sable-external-refs.h +++ b/deps/v8/src/wasm/wasm-sable-external-refs.h @@ -16,17 +16,36 @@ namespace native { class Memory { public: - Memory(Address s, Address e) : start_(reinterpret_cast(s)), end_(reinterpret_cast(e)) {} + Memory(byte* s, byte* e) : start_(s), end_(e) {} template - void Write(int offset, T val) { - CHECK_LT(start_ + offset + sizeof(T), end_); + inline void Write(int offset, T val) { + if(!SafeAccess(std::move(offset))) { + // TODO trap + return; + } WriteUnalignedValue(reinterpret_cast
(start_ + offset), val); } template - T Read(int offset) { - CHECK_LT(start_ + offset + sizeof(T), end_); + inline T Read(int offset) { + if(!SafeAccess(std::move(offset))) { + // TODO trap + return 0; + } return ReadUnalignedValue(reinterpret_cast
(start_ + offset)); } + template + inline void WriteUnsafe(int offset, T val) { + WriteUnalignedValue(reinterpret_cast
(start_ + offset), val); + } + template + inline T ReadUnsafe(int offset) { + return ReadUnalignedValue(reinterpret_cast
(start_ + offset)); + } + template + inline bool SafeAccess(int offset) { + byte* so = start_ + offset; + return so >= start_ && so + sizeof(T) < end_; + } private: byte* start_ = nullptr; byte* end_ = nullptr; @@ -67,7 +86,7 @@ bool find_native_function(const char* find_name, FunctionSig* sig, int *out_inde // entry point to calling a native function // this gateway function will call the appropriate // function based on the given function id -int native_function_gateway(int funcId, Address mem, Address data); +int native_function_gateway(int32_t funcId, Address mem, uint32_t memSize, Address data); } // namespace native } // namespace wasm From 292c695d6ccbe75fe8d1596e7c279421e945f344 Mon Sep 17 00:00:00 2001 From: Amir Bawab Date: Tue, 16 Apr 2019 20:10:56 -0400 Subject: [PATCH 3/3] Reverted api --- deps/v8/gypfiles/v8.gyp | 5 - deps/v8/src/compiler/wasm-compiler.cc | 14 +- deps/v8/src/external-reference.cc | 17 +- deps/v8/src/external-reference.h | 21 +- deps/v8/src/third_party/native_wasm/math.cc | 59 ----- deps/v8/src/third_party/native_wasm/math.h | 24 -- deps/v8/src/third_party/native_wasm/native.cc | 38 --- deps/v8/src/third_party/native_wasm/system.cc | 60 ----- deps/v8/src/third_party/native_wasm/system.h | 27 -- deps/v8/src/wasm/module-decoder.cc | 4 +- deps/v8/src/wasm/wasm-external-refs.cc | 4 - deps/v8/src/wasm/wasm-external-refs.h | 10 +- deps/v8/src/wasm/wasm-module.h | 1 + deps/v8/src/wasm/wasm-sable-external-refs.cc | 230 +++++++++++------- deps/v8/src/wasm/wasm-sable-external-refs.h | 114 ++++----- 15 files changed, 234 insertions(+), 394 deletions(-) delete mode 100644 deps/v8/src/third_party/native_wasm/math.cc delete mode 100644 deps/v8/src/third_party/native_wasm/math.h delete mode 100644 deps/v8/src/third_party/native_wasm/native.cc delete mode 100644 deps/v8/src/third_party/native_wasm/system.cc delete mode 100644 deps/v8/src/third_party/native_wasm/system.h diff --git a/deps/v8/gypfiles/v8.gyp b/deps/v8/gypfiles/v8.gyp index 157dba4f77bd43..8ca0f2d585056f 100644 --- a/deps/v8/gypfiles/v8.gyp +++ b/deps/v8/gypfiles/v8.gyp @@ -1603,11 +1603,6 @@ '../src/strtod.h', '../src/task-utils.cc', '../src/task-utils.h', - '../src/third_party/native_wasm/math.cc', - '../src/third_party/native_wasm/math.h', - '../src/third_party/native_wasm/native.cc', - '../src/third_party/native_wasm/system.cc', - '../src/third_party/native_wasm/system.h', '../src/third_party/siphash/halfsiphash.cc', '../src/third_party/siphash/halfsiphash.h', '../src/third_party/utf8-decoder/utf8-decoder.h', diff --git a/deps/v8/src/compiler/wasm-compiler.cc b/deps/v8/src/compiler/wasm-compiler.cc index e4e0d92638b59d..d674f98c5fa105 100644 --- a/deps/v8/src/compiler/wasm-compiler.cc +++ b/deps/v8/src/compiler/wasm-compiler.cc @@ -2784,17 +2784,17 @@ Node* WasmGraphBuilder::CallNative(uint32_t index, Node** args, Node** rets, Node* linearMemory = instance_cache_->mem_start; Node* linearMemorySize = instance_cache_->mem_size; - Node* function = graph()->NewNode(mcgraph()->common()->ExternalConstant(ExternalReference::wasm_native_call())); + Node* function = graph()->NewNode(mcgraph()->common()->ExternalConstant((*native.func)())); MachineType sig_types[] = { - MachineType::Int32(), // wasm_native_call return type - MachineType::Int32(), // Native function id value +// MachineType::Int32(), // wasm_native_call return type +// MachineType::Int32(), // Native function id value MachineType::Pointer(), // Linear memory address - MachineType::Uint32(), // Linear memory size +// MachineType::Uint32(), // Linear memory size MachineType::Pointer() // Stack slot address (parameter slots followed by return slots) }; - MachineSignature sig(1, 4, sig_types); - Node* call = BuildCCall(&sig, function, mcgraph()->Int32Constant(native.native_index), linearMemory, - linearMemorySize, stack_slot); + MachineSignature sig(0, 2, sig_types); + Node* call = BuildCCall(&sig, function, /*mcgraph()->Int32Constant(native.native_index),*/ linearMemory, + /*linearMemorySize,*/ stack_slot); // Check if return value is zero (currently not used) // ZeroCheck32(wasm::kTrapFuncInvalid, call, position); diff --git a/deps/v8/src/external-reference.cc b/deps/v8/src/external-reference.cc index 1b3e9d23a76445..f411cf197066c5 100644 --- a/deps/v8/src/external-reference.cc +++ b/deps/v8/src/external-reference.cc @@ -305,7 +305,22 @@ FUNCTION_REFERENCE(wasm_word32_rol, wasm::word32_rol_wrapper) FUNCTION_REFERENCE(wasm_word32_ror, wasm::word32_ror_wrapper) FUNCTION_REFERENCE(wasm_memory_copy, wasm::memory_copy_wrapper) FUNCTION_REFERENCE(wasm_memory_fill, wasm::memory_fill_wrapper) -FUNCTION_REFERENCE(wasm_native_call, wasm::native_call_wrapper) + +FUNCTION_REFERENCE(wasm_time_ms, wasm::time_ms_wrapper) +FUNCTION_REFERENCE(wasm_exp, wasm::exp_wrapper) +FUNCTION_REFERENCE(wasm_add_I32, wasm::add_wrapper) +FUNCTION_REFERENCE(wasm_matrix_multiplication_I32, wasm::matrix_multiplication_wrapper) +FUNCTION_REFERENCE(wasm_matrix_multiplication_I64, wasm::matrix_multiplication_wrapper) +FUNCTION_REFERENCE(wasm_matrix_multiplication_F32, wasm::matrix_multiplication_wrapper) +FUNCTION_REFERENCE(wasm_matrix_multiplication_F64, wasm::matrix_multiplication_wrapper) +FUNCTION_REFERENCE(wasm_print_memory_I32, wasm::print_memory_wrapper) +FUNCTION_REFERENCE(wasm_print_memory_I64, wasm::print_memory_wrapper) +FUNCTION_REFERENCE(wasm_print_memory_F32, wasm::print_memory_wrapper) +FUNCTION_REFERENCE(wasm_print_memory_F64, wasm::print_memory_wrapper) +FUNCTION_REFERENCE(wasm_print_stack_I32, wasm::print_stack_wrapper) +FUNCTION_REFERENCE(wasm_print_stack_I64, wasm::print_stack_wrapper) +FUNCTION_REFERENCE(wasm_print_stack_F32, wasm::print_stack_wrapper) +FUNCTION_REFERENCE(wasm_print_stack_F64, wasm::print_stack_wrapper) static void f64_acos_wrapper(Address data) { double input = ReadUnalignedValue(data); diff --git a/deps/v8/src/external-reference.h b/deps/v8/src/external-reference.h index 70c65d184dbde1..5c8e2a2a238ed0 100644 --- a/deps/v8/src/external-reference.h +++ b/deps/v8/src/external-reference.h @@ -74,6 +74,23 @@ class StatsCounter; "IsolateData::fast_c_call_caller_pc_address") \ EXTERNAL_REFERENCE_LIST_NON_INTERPRETED_REGEXP(V) +#define EXTERNAL_REFERENCE_LIST_WASM(V) \ +V(wasm_time_ms, "wasm::time_ms") \ +V(wasm_exp, "wasm::exp") \ +V(wasm_add_I32, "wasm::add_I32") \ +V(wasm_matrix_multiplication_I32, "wasm::matrix_multiplication_I32") \ +V(wasm_matrix_multiplication_I64, "wasm::matrix_multiplication_I64") \ +V(wasm_matrix_multiplication_F32, "wasm::matrix_multiplication_F32") \ +V(wasm_matrix_multiplication_F64, "wasm::matrix_multiplication_F64") \ +V(wasm_print_memory_I32, "wasm::print_memory_I32") \ +V(wasm_print_memory_I64, "wasm::print_memory_I64") \ +V(wasm_print_memory_F32, "wasm::print_memory_F32") \ +V(wasm_print_memory_F64, "wasm::print_memory_F64") \ +V(wasm_print_stack_I32, "wasm::print_stack_I32") \ +V(wasm_print_stack_I64, "wasm::print_stack_I64") \ +V(wasm_print_stack_F32, "wasm::print_stack_F32") \ +V(wasm_print_stack_F64, "wasm::print_stack_F64") \ + #define EXTERNAL_REFERENCE_LIST(V) \ V(abort_with_reason, "abort_with_reason") \ V(address_of_double_abs_constant, "double_absolute_constant") \ @@ -183,7 +200,6 @@ class StatsCounter; V(wasm_word64_popcnt, "wasm::word64_popcnt") \ V(wasm_memory_copy, "wasm::memory_copy") \ V(wasm_memory_fill, "wasm::memory_fill") \ - V(wasm_native_call, "wasm::native_call") \ V(call_enqueue_microtask_function, "MicrotaskQueue::CallEnqueueMicrotask") \ V(call_enter_context_function, "call_enter_context_function") \ V(atomic_pair_load_function, "atomic_pair_load_function") \ @@ -196,7 +212,8 @@ class StatsCounter; V(atomic_pair_exchange_function, "atomic_pair_exchange_function") \ V(atomic_pair_compare_exchange_function, \ "atomic_pair_compare_exchange_function") \ - EXTERNAL_REFERENCE_LIST_INTL(V) + EXTERNAL_REFERENCE_LIST_INTL(V) \ + EXTERNAL_REFERENCE_LIST_WASM(V) #ifndef V8_INTERPRETED_REGEXP #define EXTERNAL_REFERENCE_LIST_NON_INTERPRETED_REGEXP(V) \ diff --git a/deps/v8/src/third_party/native_wasm/math.cc b/deps/v8/src/third_party/native_wasm/math.cc deleted file mode 100644 index e6ac5b7424a03a..00000000000000 --- a/deps/v8/src/third_party/native_wasm/math.cc +++ /dev/null @@ -1,59 +0,0 @@ -#include "src/third_party/native_wasm/math.h" -#include "src/base/ieee754.h" - -namespace v8 { -namespace internal { -namespace wasm { -namespace native { - -template -void nf_matrix_multiplication(std::vector args, std::vector rets, - native::Memory memory) { - DCHECK_EQ(6, args.size()); - DCHECK_EQ(0, rets.size()); - - int32_t mat1Offset = args[0].Get(); - int32_t mat2Offset = args[1].Get(); - int32_t resOffset = args[2].Get(); - int32_t m = args[3].Get(); - int32_t n = args[4].Get(); - int32_t p = args[5].Get(); - - if(!memory.SafeAccess(mat1Offset) || !memory.SafeAccess(resOffset + m * p)) { - // TODO trap - return; - } - - for(int r=0; r < m; ++r) { - for(int c=0; c < p; ++c) { - T resCell = 0; - for(int cr=0; cr < n; ++cr) { - resCell += memory.ReadUnsafe(mat1Offset + (r * n + cr) * sizeof(T)) * - memory.ReadUnsafe(mat2Offset + (cr * p + c) * sizeof(T)); - } - memory.WriteUnsafe(resOffset + (r * p + c) * sizeof(T), resCell); - } - } -} - -// explicit instantiation of nf_matrix_multiplication template -template void nf_matrix_multiplication(std::vector args, std::vector rets, - native::Memory memory); -template void nf_matrix_multiplication(std::vector args, std::vector rets, - native::Memory memory); -template void nf_matrix_multiplication(std::vector args, std::vector rets, - native::Memory memory); -template void nf_matrix_multiplication(std::vector args, std::vector rets, - native::Memory memory); - -void nf_exp(std::vector args, std::vector rets, native::Memory memory) { - DCHECK_EQ(1, args.size()); - DCHECK_EQ(1, rets.size()); - - rets[0].Set(base::ieee754::exp(args[0].Get())); -} - -} -} -} -} diff --git a/deps/v8/src/third_party/native_wasm/math.h b/deps/v8/src/third_party/native_wasm/math.h deleted file mode 100644 index 650995543c5d00..00000000000000 --- a/deps/v8/src/third_party/native_wasm/math.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef WASM_NATIVE_WASM_MATH_H -#define WASM_NATIVE_WASM_MATH_H - -#include "src/wasm/wasm-sable-external-refs.h" - -namespace v8 { -namespace internal { -namespace wasm { -namespace native { - -// matrix multiplication -template -void nf_matrix_multiplication(std::vector args, std::vector rets, - native::Memory memory); - -// exp(x) -void nf_exp(std::vector args, std::vector rets, native::Memory memory); - -} // namespace native -} // namespace wasm -} // namespace internal -} // namespace v8 - -#endif diff --git a/deps/v8/src/third_party/native_wasm/native.cc b/deps/v8/src/third_party/native_wasm/native.cc deleted file mode 100644 index fee7890462fc64..00000000000000 --- a/deps/v8/src/third_party/native_wasm/native.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include "src/third_party/native_wasm/system.h" -#include "src/third_party/native_wasm/math.h" - -namespace v8 { -namespace internal { -namespace wasm { -namespace native { - -void init_native() { - // system - register_native_function("i32.print_s", nf_print_stack, {kWasmI32}, {}); - register_native_function("i64.print_s", nf_print_stack, {kWasmI64}, {}); - register_native_function("f32.print_s", nf_print_stack, {kWasmF32}, {}); - register_native_function("f64.print_s", nf_print_stack, {kWasmF64}, {}); - - register_native_function("i64.time_ms", nf_time_ms, {}, {kWasmI64}); - - register_native_function("i32.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); - register_native_function("i64.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); - register_native_function("f32.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); - register_native_function("f64.print_m", nf_print_mem, {kWasmI32, kWasmI32}, {}); - - // math - register_native_function("f64.exp", nf_exp, {kWasmF64}, {kWasmF64}); - register_native_function("i32.mat_mul", nf_matrix_multiplication, - {kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32}, {}); - register_native_function("i64.mat_mul", nf_matrix_multiplication, - {kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32}, {}); - register_native_function("f32.mat_mul", nf_matrix_multiplication, - {kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32}, {}); - register_native_function("f64.mat_mul", nf_matrix_multiplication, - {kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32}, {}); -} - -} -} -} -} diff --git a/deps/v8/src/third_party/native_wasm/system.cc b/deps/v8/src/third_party/native_wasm/system.cc deleted file mode 100644 index 075ec6ab833724..00000000000000 --- a/deps/v8/src/third_party/native_wasm/system.cc +++ /dev/null @@ -1,60 +0,0 @@ -#include "src/third_party/native_wasm/system.h" -#include -#include - -namespace v8 { -namespace internal { -namespace wasm { -namespace native { - -template -void nf_print_mem(std::vector args, std::vector rets, native::Memory memory) { - DCHECK_EQ(2, args.size()); - DCHECK_EQ(0, rets.size()); - - int32_t offset = args[0].Get(); - int32_t size = args[1].Get(); - for(int i=0; i < size; ++i) { - std::cout << memory.Read(offset) << " "; - } - std::cout << std::endl; -} - -// explicit instantiation of nf_print_mem template -template void nf_print_mem(std::vector args, std::vector rets, - native::Memory memory); -template void nf_print_mem(std::vector args, std::vector rets, - native::Memory memory); -template void nf_print_mem(std::vector args, std::vector rets, - native::Memory memory); -template void nf_print_mem(std::vector args, std::vector rets, - native::Memory memory); - -void nf_time_ms(std::vector args, std::vector rets, native::Memory memory) { - DCHECK_EQ(0, args.size()); - DCHECK_EQ(1, rets.size()); - rets[0].Set(std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count()); -} - -template -void nf_print_stack(std::vector args, std::vector rets, native::Memory memory) { - DCHECK_EQ(1, args.size()); - DCHECK_EQ(0, rets.size()); - std::cout << args[0].Get() << std::endl; -} - -// explicit instantiation of nf_print_stack template -template void nf_print_stack(std::vector args, std::vector rets, - native::Memory memory); -template void nf_print_stack(std::vector args, std::vector rets, - native::Memory memory); -template void nf_print_stack(std::vector args, std::vector rets, - native::Memory memory); -template void nf_print_stack(std::vector args, std::vector rets, - native::Memory memory); - -} -} -} -} diff --git a/deps/v8/src/third_party/native_wasm/system.h b/deps/v8/src/third_party/native_wasm/system.h deleted file mode 100644 index 2d7d4b0514d19e..00000000000000 --- a/deps/v8/src/third_party/native_wasm/system.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef WASM_NATIVE_WASM_SYSTEM_H -#define WASM_NATIVE_WASM_SYSTEM_H - -#include "src/wasm/wasm-sable-external-refs.h" - -namespace v8 { -namespace internal { -namespace wasm { -namespace native { - -// print stack content -template -void nf_print_stack(std::vector args, std::vector rets, native::Memory memory); - -// get time in ms -void nf_time_ms(std::vector args, std::vector rets, native::Memory memory); - -// print linear memory -template -void nf_print_mem(std::vector args, std::vector rets, native::Memory memory); - -} // namespace native -} // namespace wasm -} // namespace internal -} // namespace v8 - -#endif diff --git a/deps/v8/src/wasm/module-decoder.cc b/deps/v8/src/wasm/module-decoder.cc index 10b056a613ba90..c06a601d98d534 100644 --- a/deps/v8/src/wasm/module-decoder.cc +++ b/deps/v8/src/wasm/module-decoder.cc @@ -491,8 +491,6 @@ class ModuleDecoderImpl : public Decoder { } void DecodeNativeSection() { - // initialize native environment - native::init_native(); uint32_t natives_count = consume_count("natives count", kV8MaxWasmNatives); module_->natives.reserve(natives_count); for (uint32_t i = 0; ok() && i < natives_count; ++i) { @@ -503,7 +501,7 @@ class ModuleDecoderImpl : public Decoder { const char* func_name = std::string( reinterpret_cast(start() + GetBufferRelativeOffset(native.func_name.offset())), native.func_name.length()).c_str(); - if(!native::find_native_function(func_name, native.sig, &native.native_index)) { + if(!find_native_function(func_name, native.sig, &native.func)) { errorf(pc_, "native function %s not found", func_name); } module_->natives.push_back(std::move(native)); diff --git a/deps/v8/src/wasm/wasm-external-refs.cc b/deps/v8/src/wasm/wasm-external-refs.cc index 828c617b811db7..e382f3849e91c9 100644 --- a/deps/v8/src/wasm/wasm-external-refs.cc +++ b/deps/v8/src/wasm/wasm-external-refs.cc @@ -257,10 +257,6 @@ void memory_fill_wrapper(Address dst, uint32_t value, uint32_t size) { memset(reinterpret_cast(dst), value, size); } -int32_t native_call_wrapper(int32_t funcId, Address mem, uint32_t memSize, Address data) { - return native::native_function_gateway(funcId, mem, memSize, data); -} - static WasmTrapCallbackForTesting wasm_trap_callback_for_testing = nullptr; void set_trap_callback_for_testing(WasmTrapCallbackForTesting callback) { diff --git a/deps/v8/src/wasm/wasm-external-refs.h b/deps/v8/src/wasm/wasm-external-refs.h index 6d57d2afacfcf6..7bca3f7201de77 100644 --- a/deps/v8/src/wasm/wasm-external-refs.h +++ b/deps/v8/src/wasm/wasm-external-refs.h @@ -71,14 +71,20 @@ void memory_copy_wrapper(Address dst, Address src, uint32_t size); void memory_fill_wrapper(Address dst, uint32_t value, uint32_t size); -int32_t native_call_wrapper(int32_t funcId, Address mem, uint32_t memSize, Address data); - typedef void (*WasmTrapCallbackForTesting)(); void set_trap_callback_for_testing(WasmTrapCallbackForTesting callback); void call_trap_callback_for_testing(); +// wasm sable external reference +void time_ms_wrapper(Address, Address); +void exp_wrapper(Address, Address); +template void matrix_multiplication_wrapper(Address, Address); +template void print_stack_wrapper(Address, Address); +template void print_memory_wrapper(Address, Address); +template void add_wrapper(Address, Address); + } // namespace wasm } // namespace internal } // namespace v8 diff --git a/deps/v8/src/wasm/wasm-module.h b/deps/v8/src/wasm/wasm-module.h index b5a2ff648ad244..a27f39bf7dcc40 100644 --- a/deps/v8/src/wasm/wasm-module.h +++ b/deps/v8/src/wasm/wasm-module.h @@ -146,6 +146,7 @@ struct WasmNative { WireBytesRef func_name; // native function name. FunctionSig* sig; // native function signature. int native_index; // native function enum value. + ExternalReference (*func)(); // native function enum value. }; enum ModuleOrigin : uint8_t { kWasmOrigin, kAsmJsOrigin }; diff --git a/deps/v8/src/wasm/wasm-sable-external-refs.cc b/deps/v8/src/wasm/wasm-sable-external-refs.cc index 737d8b46a62537..732a7286898ec9 100644 --- a/deps/v8/src/wasm/wasm-sable-external-refs.cc +++ b/deps/v8/src/wasm/wasm-sable-external-refs.cc @@ -1,127 +1,175 @@ #include "src/wasm/wasm-sable-external-refs.h" #include "src/signature.h" +#include "src/base/ieee754.h" +#include #include -#include +#include namespace v8 { namespace internal { namespace wasm { -namespace native { - -struct Function { - std::string name; - native_t func; - std::vector params; - std::vector rets; - bool sig_match(FunctionSig *sig) { - if(params.size() != sig->parameter_count() || rets.size() != sig->return_count()) { - return false; - } - for(size_t i=0; i < params.size(); i++) { - if(params[i] != sig->GetParam(i)) { - return false; - } - } - for(size_t i=0; i < rets.size(); i++) { - if(rets[i] != sig->GetReturn(i)) { - return false; - } - } - return true; - } -}; -template <> int32_t Argument::Get() const { - CHECK_EQ(type_, kWasmI32); - return ReadUnalignedValue(val_add_); +/******************** + * Helper functions + ********************/ +template +inline T ReadValue(T* address) { + return ReadUnalignedValue(reinterpret_cast
(address)); } -template <> int64_t Argument::Get() const { - CHECK_EQ(type_, kWasmI64); - return ReadUnalignedValue(val_add_); +template +inline T ReadValueAndAdvance(T** address) { + T val = ReadValue(*address); + (*address)++; + return val; } -template <> float Argument::Get() const { - CHECK_EQ(type_, kWasmF32); - return ReadUnalignedValue(val_add_); +template +inline void WriteValue(T* address, T val) { + WriteUnalignedValue(reinterpret_cast
(address), val); +} + +template +inline void WriteValueAndAdvance(T** address, T val) { + WriteValue(*address, val); + (*address)++; +} + +/******************* + * Native functions + ******************/ + +template +void matrix_multiplication_wrapper(Address mem, Address data) { + I32* stack = reinterpret_cast(data); + byte* lmem = reinterpret_cast(mem); + + I32 mat1Offset = *(stack); + I32 mat2Offset = *(stack += 1); + I32 resOffset = *(stack += 1); + I32 m = *(stack += 1); + I32 n = *(stack += 1); + I32 p = *(stack += 1); + + T* mat1 = reinterpret_cast(lmem + mat1Offset); + T* mat2 = reinterpret_cast(lmem + mat2Offset); + T* res = reinterpret_cast(lmem + resOffset); + + for(int r=0; r < m; ++r) { + for(int c=0; c < p; ++c) { + T resCell = 0; + for(int cr=0; cr < n; ++cr) { + resCell += *(mat1 + r * n + cr) * *(mat2 + cr * p + c); + } + *(res + r * p + c) = resCell; + } + } } +template void matrix_multiplication_wrapper(Address, Address); +template void matrix_multiplication_wrapper(Address, Address); +template void matrix_multiplication_wrapper(Address, Address); +template void matrix_multiplication_wrapper(Address, Address); + +template +void print_memory_wrapper(Address mem, Address data) { + I32* stack = reinterpret_cast(data); -template <> double Argument::Get() const { - CHECK_EQ(type_, kWasmF64); - return ReadUnalignedValue(val_add_); + I32 offset = ReadValueAndAdvance(&stack); + I32 size = ReadValueAndAdvance(&stack); + T* lmem = reinterpret_cast(reinterpret_cast(mem) + offset); + for(int i=0; i < size; ++i) { + std::cout << ReadValue(lmem + i) << " "; + } + std::cout << std::endl; } +template void print_memory_wrapper(Address, Address); +template void print_memory_wrapper(Address, Address); +template void print_memory_wrapper(Address, Address); +template void print_memory_wrapper(Address, Address); -template <> void Return::Set(int32_t val) { - CHECK_EQ(type_, kWasmI32); - WriteUnalignedValue(ret_add_, val); +void exp_wrapper(Address mem, Address data) { + F64 x = ReadValueAndAdvance(reinterpret_cast(&data)); + WriteValue(reinterpret_cast(data), base::ieee754::exp(x)); } -template <> void Return::Set(int64_t val) { - CHECK_EQ(type_, kWasmI64); - WriteUnalignedValue(ret_add_, val); +template +void add_wrapper(Address mem, Address data) { + T* stack = reinterpret_cast(data); + T lhs = ReadValueAndAdvance(&stack); + T rhs = ReadValueAndAdvance(&stack); + WriteValue(stack, lhs + rhs); } +template void add_wrapper(Address, Address); -template <> void Return::Set(float val) { - CHECK_EQ(type_, kWasmF32); - WriteUnalignedValue(ret_add_, val); +void time_ms_wrapper(Address mem, Address data) { + WriteValue(reinterpret_cast(data), std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count()); } -template <> void Return::Set(double val) { - CHECK_EQ(type_, kWasmF64); - WriteUnalignedValue(ret_add_, val); +template +void print_stack_wrapper(Address mem, Address data) { + std::cout << ReadValue(reinterpret_cast(data)) << std::endl; } +template void print_stack_wrapper(Address, Address); +template void print_stack_wrapper(Address, Address); +template void print_stack_wrapper(Address, Address); +template void print_stack_wrapper(Address, Address); /******************************* * External reference functions *******************************/ -std::vector g_func_vec; -std::map g_func_map; - -bool register_native_function(std::string name, native_t func, - std::vector args, std::vector rets) { - if(g_func_map.find(name) != g_func_map.end()) { - return false; - } - g_func_map[name] = g_func_vec.size(); - g_func_vec.emplace_back(Function{ - std::move(name), std::move(func), std::move(args), std::move(rets) - }); - return true; -} -bool find_native_function(const char* find_name, FunctionSig* sig, int *out_index) { - int funcId; - if(g_func_map.find(find_name) == g_func_map.end() || !g_func_vec[funcId = g_func_map[find_name]].sig_match(sig)) { - return false; +bool find_native_function(const char* find_name, FunctionSig* sig, ExternalReference(**ref)()) { +#define ARGS_TO_VECTOR(...) {__VA_ARGS__} +#define FIND_NATIVE_FUNCTION(function, name, type, p, r) \ + if(strcmp(name, find_name) == 0) { \ + std::vector params = p; \ + std::vector rets = r; \ + *ref = ExternalReference::wasm_##function; \ + if(params.size() != sig->parameter_count() || rets.size() != sig->return_count()) { \ + return false; \ + } \ + for(size_t i=0; i < params.size(); i++) { \ + if(params[i] != sig->GetParam(i)) { \ + return false; \ + } \ + } \ + for(size_t i=0; i < rets.size(); i++) { \ + if(rets[i] != sig->GetReturn(i)) { \ + return false; \ + } \ + } \ + return true; \ } - *out_index = funcId; - return true; -} +FOREACH_NATIVE_FUNCTION_NON_TEMPLATE(FIND_NATIVE_FUNCTION, ARGS_TO_VECTOR, ARGS_TO_VECTOR) +#undef FIND_NATIVE_FUNCTION -int native_function_gateway(int32_t funcId, Address mem, uint32_t memSize, Address data) { - CHECK_GE(funcId, 0); - CHECK_LT(funcId, g_func_vec.size()); - const Function &func = g_func_vec[funcId]; - arg_vec_t args; - ret_vec_t rets; - byte* byteData = reinterpret_cast(data); - for(size_t i=0; i < func.params.size(); ++i) { - args.emplace_back(Argument{ - reinterpret_cast
(byteData), func.params[i] - }); - byteData += ValueTypes::ElementSizeInBytes(func.params[i]); - } - for(size_t i=0; i < func.rets.size(); ++i) { - rets.emplace_back(Return{ - reinterpret_cast
(byteData), func.rets[i] - }); - byteData += ValueTypes::ElementSizeInBytes(func.rets[i]); +#define FIND_NATIVE_FUNCTION(function, name, type, p, r) \ + if(strcmp(name, find_name) == 0) { \ + std::vector params = p; \ + std::vector rets = r; \ + *ref = ExternalReference::wasm_##function##_##type; \ + if(params.size() != sig->parameter_count() || rets.size() != sig->return_count()) { \ + return false; \ + } \ + for(size_t i=0; i < params.size(); i++) { \ + if(params[i] != sig->GetParam(i)) { \ + return false; \ + } \ + } \ + for(size_t i=0; i < rets.size(); i++) { \ + if(rets[i] != sig->GetReturn(i)) { \ + return false; \ + } \ + } \ + return true; \ } - (*func.func)(args, rets, Memory{reinterpret_cast(mem), reinterpret_cast(mem) + memSize}); - return 0; +FOREACH_NATIVE_FUNCTION_TEMPLATE(FIND_NATIVE_FUNCTION, ARGS_TO_VECTOR, ARGS_TO_VECTOR) +#undef FIND_NATIVE_FUNCTION +#undef ARGS_TO_VECTOR + return false; } -} // namespace native } // namespace wasm } // namespace internal } // namespace v8 diff --git a/deps/v8/src/wasm/wasm-sable-external-refs.h b/deps/v8/src/wasm/wasm-sable-external-refs.h index 6dca41e3f2d975..1a61fca0233a47 100644 --- a/deps/v8/src/wasm/wasm-sable-external-refs.h +++ b/deps/v8/src/wasm/wasm-sable-external-refs.h @@ -5,90 +5,62 @@ #ifndef V8_WASM_WASM_SABLE_EXTERNAL_REFS_H_ #define V8_WASM_WASM_SABLE_EXTERNAL_REFS_H_ +#include "src/external-reference.h" #include "src/wasm/value-type.h" #include "src/v8memory.h" -#include namespace v8 { namespace internal { namespace wasm { -namespace native { -class Memory { -public: - Memory(byte* s, byte* e) : start_(s), end_(e) {} - template - inline void Write(int offset, T val) { - if(!SafeAccess(std::move(offset))) { - // TODO trap - return; - } - WriteUnalignedValue(reinterpret_cast
(start_ + offset), val); - } - template - inline T Read(int offset) { - if(!SafeAccess(std::move(offset))) { - // TODO trap - return 0; - } - return ReadUnalignedValue(reinterpret_cast
(start_ + offset)); - } - template - inline void WriteUnsafe(int offset, T val) { - WriteUnalignedValue(reinterpret_cast
(start_ + offset), val); - } - template - inline T ReadUnsafe(int offset) { - return ReadUnalignedValue(reinterpret_cast
(start_ + offset)); - } - template - inline bool SafeAccess(int offset) { - byte* so = start_ + offset; - return so >= start_ && so + sizeof(T) < end_; - } -private: - byte* start_ = nullptr; - byte* end_ = nullptr; -}; +typedef void (*native_t)(Address, Address); -class Argument { -public: - Argument(Address add, ValueType type) : val_add_(add), type_(type) {} - template T Get() const; -private: - Address val_add_; - ValueType type_; -}; - -class Return { -public: - Return(Address add, ValueType type) : ret_add_(add), type_(type) {} - template void Set(T val); - ValueType type() const { return type_; } -private: - ValueType type_; - Address ret_add_; -}; - -typedef std::vector arg_vec_t; -typedef std::vector ret_vec_t; -typedef void (*native_t)(arg_vec_t , ret_vec_t, Memory); +// find native function and set its index +bool find_native_function(const char* find_name, FunctionSig* sig, ExternalReference (**ref)()); -// initialize environment -void init_native(); +#ifdef ___ +#error "___ already defined" +#endif +#ifdef I32 +#error "I32 already defined" +#endif +#ifdef I64 +#error "I64 already defined" +#endif +#ifdef F32 +#error "F32 already defined" +#endif +#ifdef F64 +#error "F64 already defined" +#endif -// register a native function -bool register_native_function(std::string name, native_t func, std::vector args, std::vector rets); +#define ___ void +#define I32 int32_t +#define I64 int64_t +#define F32 float +#define F64 double -// find native function and set its index -bool find_native_function(const char* find_name, FunctionSig* sig, int *out_index); +// all native functions should be declared +// in FOREACH_NATIVE_FUNCTION_[NON_]TEMPLATE +#define FOREACH_NATIVE_FUNCTION_NON_TEMPLATE(V, P, R) \ + V(time_ms, "i64.time_ms", ___, P(), R(kWasmI64)) \ + V(exp, "f64.exp", ___, P(kWasmF64), R(kWasmF64)) \ -// entry point to calling a native function -// this gateway function will call the appropriate -// function based on the given function id -int native_function_gateway(int32_t funcId, Address mem, uint32_t memSize, Address data); +#define FOREACH_NATIVE_FUNCTION_TEMPLATE(V, P, R) \ + V(add, "i32.add", I32, P(kWasmI32, kWasmI32), R(kWasmI32)) \ + V(matrix_multiplication, "i32.mat_mul", I32, P(kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32), R()) \ + V(matrix_multiplication, "i64.mat_mul", I64, P(kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32), R()) \ + V(matrix_multiplication, "f32.mat_mul", F32, P(kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32), R()) \ + V(matrix_multiplication, "f64.mat_mul", F64, P(kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32), R()) \ + V(print_stack, "i32.print_s", I32, P(kWasmI32), R()) \ + V(print_stack, "i64.print_s", I64, P(kWasmI64), R()) \ + V(print_stack, "f32.print_s", F32, P(kWasmF32), R()) \ + V(print_stack, "f64.print_s", F64, P(kWasmF64), R()) \ + V(print_memory, "i32.print_m", I32, P(kWasmI32, kWasmI32), R()) \ + V(print_memory, "i64.print_m", I64, P(kWasmI32, kWasmI32), R()) \ + V(print_memory, "f32.print_m", F32, P(kWasmI32, kWasmI32), R()) \ + V(print_memory, "f64.print_m", F64, P(kWasmI32, kWasmI32), R()) \ -} // namespace native } // namespace wasm } // namespace internal } // namespace v8