From 2739185b790e040c3b044c577327f5d44bffad4a Mon Sep 17 00:00:00 2001 From: Michaƫl Zasso Date: Fri, 23 Dec 2016 16:30:57 +0100 Subject: deps: update V8 to 5.5.372.40 PR-URL: https://github.com/nodejs/node/pull/9618 Reviewed-By: Ali Ijaz Sheikh Reviewed-By: Ben Noordhuis --- deps/v8/test/common/DEPS | 3 + deps/v8/test/common/wasm/test-signatures.h | 132 ++++++++++++++ deps/v8/test/common/wasm/wasm-module-runner.cc | 231 +++++++++++++++++++++++++ deps/v8/test/common/wasm/wasm-module-runner.h | 66 +++++++ 4 files changed, 432 insertions(+) create mode 100644 deps/v8/test/common/DEPS create mode 100644 deps/v8/test/common/wasm/test-signatures.h create mode 100644 deps/v8/test/common/wasm/wasm-module-runner.cc create mode 100644 deps/v8/test/common/wasm/wasm-module-runner.h (limited to 'deps/v8/test/common') diff --git a/deps/v8/test/common/DEPS b/deps/v8/test/common/DEPS new file mode 100644 index 0000000000..3e73aa244f --- /dev/null +++ b/deps/v8/test/common/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+src", +] diff --git a/deps/v8/test/common/wasm/test-signatures.h b/deps/v8/test/common/wasm/test-signatures.h new file mode 100644 index 0000000000..3bf53f6867 --- /dev/null +++ b/deps/v8/test/common/wasm/test-signatures.h @@ -0,0 +1,132 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TEST_SIGNATURES_H +#define TEST_SIGNATURES_H + +#include "src/signature.h" +#include "src/wasm/wasm-opcodes.h" + +namespace v8 { +namespace internal { +namespace wasm { + +typedef Signature FunctionSig; + +// A helper class with many useful signatures in order to simplify tests. +class TestSignatures { + public: + TestSignatures() + : sig_i_v(1, 0, kIntTypes4), + sig_i_i(1, 1, kIntTypes4), + sig_i_ii(1, 2, kIntTypes4), + sig_i_iii(1, 3, kIntTypes4), + sig_i_f(1, 1, kIntFloatTypes4), + sig_i_ff(1, 2, kIntFloatTypes4), + sig_i_d(1, 1, kIntDoubleTypes4), + sig_i_dd(1, 2, kIntDoubleTypes4), + sig_l_v(1, 0, kLongTypes4), + sig_l_l(1, 1, kLongTypes4), + sig_l_ll(1, 2, kLongTypes4), + sig_i_ll(1, 2, kIntLongTypes4), + sig_f_f(1, 1, kFloatTypes4), + sig_f_ff(1, 2, kFloatTypes4), + sig_d_d(1, 1, kDoubleTypes4), + sig_d_dd(1, 2, kDoubleTypes4), + sig_v_v(0, 0, kIntTypes4), + sig_v_i(0, 1, kIntTypes4), + sig_v_ii(0, 2, kIntTypes4), + sig_v_iii(0, 3, kIntTypes4), + sig_s_i(1, 1, kSimd128IntTypes4) { + // I used C++ and you won't believe what happened next.... + for (int i = 0; i < 4; i++) kIntTypes4[i] = kAstI32; + for (int i = 0; i < 4; i++) kLongTypes4[i] = kAstI64; + for (int i = 0; i < 4; i++) kFloatTypes4[i] = kAstF32; + for (int i = 0; i < 4; i++) kDoubleTypes4[i] = kAstF64; + for (int i = 0; i < 4; i++) kIntLongTypes4[i] = kAstI64; + for (int i = 0; i < 4; i++) kIntFloatTypes4[i] = kAstF32; + for (int i = 0; i < 4; i++) kIntDoubleTypes4[i] = kAstF64; + for (int i = 0; i < 4; i++) kSimd128IntTypes4[i] = kAstS128; + kIntLongTypes4[0] = kAstI32; + kIntFloatTypes4[0] = kAstI32; + kIntDoubleTypes4[0] = kAstI32; + kSimd128IntTypes4[1] = kAstI32; + } + + FunctionSig* i_v() { return &sig_i_v; } + FunctionSig* i_i() { return &sig_i_i; } + FunctionSig* i_ii() { return &sig_i_ii; } + FunctionSig* i_iii() { return &sig_i_iii; } + + FunctionSig* i_f() { return &sig_i_f; } + FunctionSig* i_ff() { return &sig_i_ff; } + FunctionSig* i_d() { return &sig_i_d; } + FunctionSig* i_dd() { return &sig_i_dd; } + + FunctionSig* l_v() { return &sig_l_v; } + FunctionSig* l_l() { return &sig_l_l; } + FunctionSig* l_ll() { return &sig_l_ll; } + FunctionSig* i_ll() { return &sig_i_ll; } + + FunctionSig* f_f() { return &sig_f_f; } + FunctionSig* f_ff() { return &sig_f_ff; } + FunctionSig* d_d() { return &sig_d_d; } + FunctionSig* d_dd() { return &sig_d_dd; } + + FunctionSig* v_v() { return &sig_v_v; } + FunctionSig* v_i() { return &sig_v_i; } + FunctionSig* v_ii() { return &sig_v_ii; } + FunctionSig* v_iii() { return &sig_v_iii; } + FunctionSig* s_i() { return &sig_s_i; } + + FunctionSig* many(Zone* zone, LocalType ret, LocalType param, int count) { + FunctionSig::Builder builder(zone, ret == kAstStmt ? 0 : 1, count); + if (ret != kAstStmt) builder.AddReturn(ret); + for (int i = 0; i < count; i++) { + builder.AddParam(param); + } + return builder.Build(); + } + + private: + LocalType kIntTypes4[4]; + LocalType kLongTypes4[4]; + LocalType kFloatTypes4[4]; + LocalType kDoubleTypes4[4]; + LocalType kIntLongTypes4[4]; + LocalType kIntFloatTypes4[4]; + LocalType kIntDoubleTypes4[4]; + LocalType kSimd128IntTypes4[4]; + + FunctionSig sig_i_v; + FunctionSig sig_i_i; + FunctionSig sig_i_ii; + FunctionSig sig_i_iii; + + FunctionSig sig_i_f; + FunctionSig sig_i_ff; + FunctionSig sig_i_d; + FunctionSig sig_i_dd; + + FunctionSig sig_l_v; + FunctionSig sig_l_l; + FunctionSig sig_l_ll; + FunctionSig sig_i_ll; + + FunctionSig sig_f_f; + FunctionSig sig_f_ff; + FunctionSig sig_d_d; + FunctionSig sig_d_dd; + + FunctionSig sig_v_v; + FunctionSig sig_v_i; + FunctionSig sig_v_ii; + FunctionSig sig_v_iii; + FunctionSig sig_s_i; +}; +} // namespace wasm +} // namespace internal +} // namespace v8 + +#endif // TEST_SIGNATURES_H diff --git a/deps/v8/test/common/wasm/wasm-module-runner.cc b/deps/v8/test/common/wasm/wasm-module-runner.cc new file mode 100644 index 0000000000..15c3ef433f --- /dev/null +++ b/deps/v8/test/common/wasm/wasm-module-runner.cc @@ -0,0 +1,231 @@ +// Copyright 2016 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 "test/common/wasm/wasm-module-runner.h" + +#include "src/handles.h" +#include "src/isolate.h" +#include "src/objects.h" +#include "src/property-descriptor.h" +#include "src/wasm/module-decoder.h" +#include "src/wasm/wasm-interpreter.h" +#include "src/wasm/wasm-js.h" +#include "src/wasm/wasm-module.h" +#include "src/wasm/wasm-result.h" + +namespace v8 { +namespace internal { +namespace wasm { +namespace testing { + +uint32_t GetMinModuleMemSize(const WasmModule* module) { + return WasmModule::kPageSize * module->min_mem_pages; +} + +const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate, Zone* zone, + ErrorThrower* thrower, + const byte* module_start, + const byte* module_end, + ModuleOrigin origin) { + // Decode the module, but don't verify function bodies, since we'll + // be compiling them anyway. + ModuleResult decoding_result = + DecodeWasmModule(isolate, zone, module_start, module_end, false, origin); + + std::unique_ptr module(decoding_result.val); + if (decoding_result.failed()) { + // Module verification failed. throw. + thrower->Error("WASM.compileRun() failed: %s", + decoding_result.error_msg.get()); + return nullptr; + } + + if (thrower->error()) return nullptr; + return module.release(); +} + +const Handle InstantiateModuleForTesting(Isolate* isolate, + ErrorThrower* thrower, + const WasmModule* module) { + CHECK(module != nullptr); + + if (module->import_table.size() > 0) { + thrower->Error("Not supported: module has imports."); + } + if (module->export_table.size() == 0) { + thrower->Error("Not supported: module has no exports."); + } + if (thrower->error()) return Handle::null(); + + // Although we decoded the module for some pre-validation, run the bytes + // again through the normal pipeline. + MaybeHandle module_object = CreateModuleObjectFromBytes( + isolate, module->module_start, module->module_end, thrower, + ModuleOrigin::kWasmOrigin); + if (module_object.is_null()) { + thrower->Error("Module pre-validation failed."); + return Handle::null(); + } + MaybeHandle maybe_instance = WasmModule::Instantiate( + isolate, thrower, module_object.ToHandleChecked(), + Handle::null(), Handle::null()); + Handle instance; + if (!maybe_instance.ToHandle(&instance)) { + return Handle::null(); + } + return instance; +} + +const Handle CompileInstantiateWasmModuleForTesting( + Isolate* isolate, Zone* zone, const byte* module_start, + const byte* module_end, ModuleOrigin origin) { + ErrorThrower thrower(isolate, "CompileInstantiateWasmModule"); + std::unique_ptr module(DecodeWasmModuleForTesting( + isolate, zone, &thrower, module_start, module_end, origin)); + + if (module == nullptr) { + thrower.Error("Wasm module decode failed"); + return Handle::null(); + } + return InstantiateModuleForTesting(isolate, &thrower, module.get()); +} + +int32_t RunWasmModuleForTesting(Isolate* isolate, Handle instance, + int argc, Handle argv[], + ModuleOrigin origin) { + ErrorThrower thrower(isolate, "RunWasmModule"); + const char* f_name = origin == ModuleOrigin::kAsmJsOrigin ? "caller" : "main"; + return CallWasmFunctionForTesting(isolate, instance, &thrower, f_name, argc, + argv, origin); +} + +int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, + const byte* module_end, ModuleOrigin origin) { + HandleScope scope(isolate); + Zone zone(isolate->allocator()); + + Handle instance = CompileInstantiateWasmModuleForTesting( + isolate, &zone, module_start, module_end, origin); + if (instance.is_null()) { + return -1; + } + return RunWasmModuleForTesting(isolate, instance, 0, nullptr, origin); +} + +int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, + const WasmModule* module, int function_index, + WasmVal* args) { + CHECK(module != nullptr); + + Zone zone(isolate->allocator()); + v8::internal::HandleScope scope(isolate); + + if (module->import_table.size() > 0) { + thrower->Error("Not supported: module has imports."); + } + if (module->export_table.size() == 0) { + thrower->Error("Not supported: module has no exports."); + } + + if (thrower->error()) return -1; + + ModuleEnv module_env; + module_env.module = module; + module_env.origin = module->origin; + + for (size_t i = 0; i < module->functions.size(); i++) { + FunctionBody body = { + &module_env, module->functions[i].sig, module->module_start, + module->module_start + module->functions[i].code_start_offset, + module->module_start + module->functions[i].code_end_offset}; + DecodeResult result = VerifyWasmCode(isolate->allocator(), body); + if (result.failed()) { + thrower->Error("Function did not verify"); + return -1; + } + } + + // The code verifies, we create an instance to run it in the interpreter. + WasmModuleInstance instance(module); + instance.context = isolate->native_context(); + instance.mem_size = GetMinModuleMemSize(module); + // TODO(ahaas): Move memory allocation to wasm-module.cc for better + // encapsulation. + instance.mem_start = + static_cast(calloc(GetMinModuleMemSize(module), 1)); + instance.globals_start = nullptr; + module_env.instance = &instance; + + WasmInterpreter interpreter(&instance, isolate->allocator()); + + WasmInterpreter::Thread* thread = interpreter.GetThread(0); + thread->Reset(); + thread->PushFrame(&(module->functions[function_index]), args); + WasmInterpreter::State interpreter_result = thread->Run(); + if (instance.mem_start) { + free(instance.mem_start); + } + if (interpreter_result == WasmInterpreter::FINISHED) { + WasmVal val = thread->GetReturnValue(); + return val.to(); + } else if (thread->state() == WasmInterpreter::TRAPPED) { + return 0xdeadbeef; + } else { + thrower->Error( + "Interpreter did not finish execution within its step bound"); + return -1; + } +} + +int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle instance, + ErrorThrower* thrower, const char* name, + int argc, Handle argv[], + ModuleOrigin origin) { + Handle exports_object; + if (origin == ModuleOrigin::kAsmJsOrigin) { + exports_object = instance; + } else { + Handle exports = isolate->factory()->InternalizeUtf8String("exports"); + exports_object = Handle::cast( + JSObject::GetProperty(instance, exports).ToHandleChecked()); + } + Handle main_name = isolate->factory()->NewStringFromAsciiChecked(name); + PropertyDescriptor desc; + Maybe property_found = JSReceiver::GetOwnPropertyDescriptor( + isolate, exports_object, main_name, &desc); + if (!property_found.FromMaybe(false)) return -1; + + Handle main_export = Handle::cast(desc.value()); + + // Call the JS function. + Handle undefined = isolate->factory()->undefined_value(); + MaybeHandle retval = + Execution::Call(isolate, main_export, undefined, argc, argv); + + // The result should be a number. + if (retval.is_null()) { + thrower->Error("WASM.compileRun() failed: Invocation was null"); + return -1; + } + Handle result = retval.ToHandleChecked(); + if (result->IsSmi()) { + return Smi::cast(*result)->value(); + } + if (result->IsHeapNumber()) { + return static_cast(HeapNumber::cast(*result)->value()); + } + thrower->Error("WASM.compileRun() failed: Return value should be number"); + return -1; +} + +void SetupIsolateForWasmModule(Isolate* isolate) { + WasmJs::InstallWasmMapsIfNeeded(isolate, isolate->native_context()); + WasmJs::InstallWasmModuleSymbolIfNeeded(isolate, isolate->global_object(), + isolate->native_context()); +} + +} // namespace testing +} // namespace wasm +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/common/wasm/wasm-module-runner.h b/deps/v8/test/common/wasm/wasm-module-runner.h new file mode 100644 index 0000000000..780d23e06f --- /dev/null +++ b/deps/v8/test/common/wasm/wasm-module-runner.h @@ -0,0 +1,66 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_WASM_MODULE_RUNNER_H_ +#define V8_WASM_MODULE_RUNNER_H_ + +#include "src/handles.h" +#include "src/isolate.h" +#include "src/objects.h" +#include "src/wasm/wasm-interpreter.h" +#include "src/wasm/wasm-module.h" +#include "src/wasm/wasm-result.h" +#include "src/zone/zone.h" + +namespace v8 { +namespace internal { +namespace wasm { +namespace testing { + +// Decodes the given encoded module. +const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate, Zone* zone, + ErrorThrower* thrower, + const byte* module_start, + const byte* module_end, + ModuleOrigin origin); + +// Instantiates a module without any imports and exports. +const Handle InstantiateModuleForTesting(Isolate* isolate, + ErrorThrower* thrower, + const WasmModule* module); + +int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle instance, + ErrorThrower* thrower, const char* name, + int argc, Handle argv[], + ModuleOrigin origin); + +// Decode, verify, and run the function labeled "main" in the +// given encoded module. The module should have no imports. +int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, + const byte* module_end, ModuleOrigin origin); + +// Interprets the given module, starting at the function specified by +// {function_index}. The return type of the function has to be int32. The module +// should not have any imports or exports +int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, + const WasmModule* module, int function_index, + WasmVal* args); + +// Compiles WasmModule bytes and return an instance of the compiled module. +const Handle CompileInstantiateWasmModuleForTesting( + Isolate* isolate, Zone* zone, const byte* module_start, + const byte* module_end, ModuleOrigin origin); + +// Runs the module instance with arguments. +int32_t RunWasmModuleForTesting(Isolate* isolate, Handle instance, + int argc, Handle argv[], + ModuleOrigin origin); +// Install function map, module symbol for testing +void SetupIsolateForWasmModule(Isolate* isolate); +} // namespace testing +} // namespace wasm +} // namespace internal +} // namespace v8 + +#endif // V8_WASM_MODULE_RUNNER_H_ -- cgit v1.2.3