// Copyright 2019 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_WASM_API_TESTS_WASM_API_TEST_H_ #define TEST_WASM_API_TESTS_WASM_API_TEST_H_ #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-opcodes.h" #include "src/zone/accounting-allocator.h" #include "src/zone/zone.h" #include "test/common/wasm/wasm-macro-gen.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/wasm-api/wasm.hh" namespace v8 { namespace internal { namespace wasm { using ::wasm::Engine; using ::wasm::Extern; using ::wasm::Foreign; using ::wasm::Func; using ::wasm::FuncType; using ::wasm::Global; using ::wasm::Instance; using ::wasm::Memory; using ::wasm::Module; using ::wasm::own; using ::wasm::ownvec; using ::wasm::Ref; using ::wasm::Store; using ::wasm::Table; using ::wasm::Trap; using ::wasm::Val; using ::wasm::ValType; using ::wasm::vec; class WasmCapiTest : public ::testing::Test { public: WasmCapiTest() : Test(), engine_(Engine::make()), allocator_(std::make_unique()), zone_(std::make_unique(allocator_.get(), ZONE_NAME)), wire_bytes_(zone_.get()), builder_(zone_->New(zone_.get())), exports_(ownvec::make()), binary_(vec::make()), wasm_i_i_sig_(1, 1, wasm_i_i_sig_types_) { store_ = Store::make(engine_.get()); cpp_i_i_sig_ = FuncType::make(ownvec::make(ValType::make(::wasm::I32)), ownvec::make(ValType::make(::wasm::I32))); } bool Validate() { if (binary_.size() == 0) { builder_->WriteTo(&wire_bytes_); size_t size = wire_bytes_.end() - wire_bytes_.begin(); binary_ = vec::make( size, reinterpret_cast(const_cast(wire_bytes_.begin()))); } return Module::validate(store_.get(), binary_); } void Compile() { if (binary_.size() == 0) { builder_->WriteTo(&wire_bytes_); size_t size = wire_bytes_.end() - wire_bytes_.begin(); binary_ = vec::make( size, reinterpret_cast(const_cast(wire_bytes_.begin()))); } module_ = Module::make(store_.get(), binary_); DCHECK_NE(module_.get(), nullptr); } void Instantiate(Extern* imports[]) { Compile(); instance_ = Instance::make(store_.get(), module_.get(), imports); DCHECK_NE(instance_.get(), nullptr); exports_ = instance_->exports(); } void AddExportedFunction(base::Vector name, uint8_t code[], size_t code_size, FunctionSig* sig) { WasmFunctionBuilder* fun = builder()->AddFunction(sig); fun->EmitCode(code, static_cast(code_size)); fun->Emit(kExprEnd); builder()->AddExport(name, fun); } void AddFunction(uint8_t code[], size_t code_size, FunctionSig* sig) { WasmFunctionBuilder* fun = builder()->AddFunction(sig); fun->EmitCode(code, static_cast(code_size)); fun->Emit(kExprEnd); } Func* GetExportedFunction(size_t index) { DCHECK_GT(exports_.size(), index); Extern* exported = exports_[index].get(); DCHECK_EQ(exported->kind(), ::wasm::EXTERN_FUNC); Func* func = exported->func(); DCHECK_NE(func, nullptr); return func; } Global* GetExportedGlobal(size_t index) { DCHECK_GT(exports_.size(), index); Extern* exported = exports_[index].get(); DCHECK_EQ(exported->kind(), ::wasm::EXTERN_GLOBAL); Global* global = exported->global(); DCHECK_NE(global, nullptr); return global; } Memory* GetExportedMemory(size_t index) { DCHECK_GT(exports_.size(), index); Extern* exported = exports_[index].get(); DCHECK_EQ(exported->kind(), ::wasm::EXTERN_MEMORY); Memory* memory = exported->memory(); DCHECK_NE(memory, nullptr); return memory; } Table* GetExportedTable(size_t index) { DCHECK_GT(exports_.size(), index); Extern* exported = exports_[index].get(); DCHECK_EQ(exported->kind(), ::wasm::EXTERN_TABLE); Table* table = exported->table(); DCHECK_NE(table, nullptr); return table; } void ResetModule() { module_.reset(); } void Shutdown() { exports_.reset(); instance_.reset(); module_.reset(); store_.reset(); builder_ = nullptr; zone_.reset(); allocator_.reset(); engine_.reset(); } WasmModuleBuilder* builder() { return builder_; } Engine* engine() { return engine_.get(); } Store* store() { return store_.get(); } Module* module() { return module_.get(); } Instance* instance() { return instance_.get(); } const ownvec& exports() { return exports_; } base::Vector wire_bytes() { return base::VectorOf(wire_bytes_); } FunctionSig* wasm_i_i_sig() { return &wasm_i_i_sig_; } FuncType* cpp_i_i_sig() { return cpp_i_i_sig_.get(); } private: own engine_; own allocator_; own zone_; ZoneBuffer wire_bytes_; WasmModuleBuilder* builder_; own store_; own module_; own instance_; ownvec exports_; vec binary_; own cpp_i_i_sig_; ValueType wasm_i_i_sig_types_[2] = {kWasmI32, kWasmI32}; FunctionSig wasm_i_i_sig_; }; } // namespace wasm } // namespace internal } // namespace v8 #endif // TEST_WASM_API_TESTS_WASM_API_TEST_H_