797e4afefe
WasmModuleBuilder is a class that is used to build Wasm modules in the asm.js parser, in the fuzzer, as well as some tests. When it comes to Wasm tables, WasmModuleBuilder currently supports only basic tables (before the reftypes proposal) using an ad-hoc indirect-function index vector. This CL adds proper support for element sections and tables that use them in the full potential of the reftypes extension. The new functionality will only be used in the fuzzer and potentially some tests in the future. Along this, we drop some functionality from WasmModuleBuilder that was only used in tests and is redundant with the new architecture. Additionally, we remove tables other than externref and funcref from the fuzzer (which were not supported properly or used anyway). We will reintroduce them at a later time. Bug: v8:11954 Change-Id: I0a4f6e7b63b6e3d9f7da03b5202fbf14d8678332 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3122162 Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/main@{#76597}
110 lines
3.7 KiB
C++
110 lines
3.7 KiB
C++
// 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.
|
|
|
|
#include "test/wasm-api-tests/wasm-api-test.h"
|
|
|
|
#include "src/execution/isolate.h"
|
|
#include "src/heap/heap.h"
|
|
#include "src/wasm/c-api.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace wasm {
|
|
|
|
using ::wasm::ExportType;
|
|
using ::wasm::GlobalType;
|
|
using ::wasm::MemoryType;
|
|
using ::wasm::TableType;
|
|
|
|
namespace {
|
|
|
|
const char* kFuncName = "func1";
|
|
const char* kGlobalName = "global2";
|
|
const char* kTableName = "table3";
|
|
const char* kMemoryName = "memory4";
|
|
|
|
void ExpectName(const char* expected, const ::wasm::Name& name) {
|
|
size_t len = strlen(expected);
|
|
EXPECT_EQ(len, name.size());
|
|
EXPECT_EQ(0, strncmp(expected, name.get(), len));
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST_F(WasmCapiTest, Reflect) {
|
|
// Create a module exporting a function, a global, a table, and a memory.
|
|
byte code[] = {WASM_UNREACHABLE};
|
|
ValueType types[] = {kWasmI32, kWasmExternRef, kWasmI32,
|
|
kWasmI64, kWasmF32, kWasmF64};
|
|
FunctionSig sig(2, 4, types);
|
|
AddExportedFunction(base::CStrVector(kFuncName), code, sizeof(code), &sig);
|
|
|
|
builder()->AddExportedGlobal(kWasmF64, false, WasmInitExpr(0.0),
|
|
base::CStrVector(kGlobalName));
|
|
|
|
builder()->AddTable(kWasmFuncRef, 12, 12);
|
|
builder()->AddExport(base::CStrVector(kTableName), kExternalTable, 0);
|
|
|
|
builder()->SetMinMemorySize(1);
|
|
builder()->AddExport(base::CStrVector(kMemoryName), kExternalMemory, 0);
|
|
|
|
Instantiate(nullptr);
|
|
|
|
ownvec<ExportType> export_types = module()->exports();
|
|
const ownvec<Extern>& exports = this->exports();
|
|
EXPECT_EQ(exports.size(), export_types.size());
|
|
EXPECT_EQ(4u, exports.size());
|
|
for (size_t i = 0; i < exports.size(); i++) {
|
|
::wasm::ExternKind kind = exports[i]->kind();
|
|
const ::wasm::ExternType* extern_type = export_types[i]->type();
|
|
EXPECT_EQ(kind, extern_type->kind());
|
|
if (kind == ::wasm::EXTERN_FUNC) {
|
|
ExpectName(kFuncName, export_types[i]->name());
|
|
const FuncType* type = extern_type->func();
|
|
const ownvec<ValType>& params = type->params();
|
|
EXPECT_EQ(4u, params.size());
|
|
EXPECT_EQ(::wasm::I32, params[0]->kind());
|
|
EXPECT_EQ(::wasm::I64, params[1]->kind());
|
|
EXPECT_EQ(::wasm::F32, params[2]->kind());
|
|
EXPECT_EQ(::wasm::F64, params[3]->kind());
|
|
const ownvec<ValType>& results = type->results();
|
|
EXPECT_EQ(2u, results.size());
|
|
EXPECT_EQ(::wasm::I32, results[0]->kind());
|
|
EXPECT_EQ(::wasm::ANYREF, results[1]->kind());
|
|
|
|
const Func* func = exports[i]->func();
|
|
EXPECT_EQ(4u, func->param_arity());
|
|
EXPECT_EQ(2u, func->result_arity());
|
|
|
|
} else if (kind == ::wasm::EXTERN_GLOBAL) {
|
|
ExpectName(kGlobalName, export_types[i]->name());
|
|
const GlobalType* type = extern_type->global();
|
|
EXPECT_EQ(::wasm::F64, type->content()->kind());
|
|
EXPECT_EQ(::wasm::CONST, type->mutability());
|
|
|
|
} else if (kind == ::wasm::EXTERN_TABLE) {
|
|
ExpectName(kTableName, export_types[i]->name());
|
|
const TableType* type = extern_type->table();
|
|
EXPECT_EQ(::wasm::FUNCREF, type->element()->kind());
|
|
::wasm::Limits limits = type->limits();
|
|
EXPECT_EQ(12u, limits.min);
|
|
EXPECT_EQ(12u, limits.max);
|
|
|
|
} else if (kind == ::wasm::EXTERN_MEMORY) {
|
|
ExpectName(kMemoryName, export_types[i]->name());
|
|
const MemoryType* type = extern_type->memory();
|
|
::wasm::Limits limits = type->limits();
|
|
EXPECT_EQ(1u, limits.min);
|
|
EXPECT_EQ(std::numeric_limits<uint32_t>::max(), limits.max);
|
|
|
|
} else {
|
|
UNREACHABLE();
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace wasm
|
|
} // namespace internal
|
|
} // namespace v8
|