Commit d87287bc authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm][anyref] Allow tables of different reference types

Allow the decoding of multiple tables, and allow these tables to have
any reference type. In addition, rename function-tables (in different
occurrences) to tables.

R=titzer@chromium.org

Bug: v8:7581
Change-Id: I191ea8e303b76563f9d91ae7447b373c4760d8b8
Reviewed-on: https://chromium-review.googlesource.com/1019581
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54355}
parent 7184ce39
...@@ -849,7 +849,7 @@ class WasmDecoder : public Decoder { ...@@ -849,7 +849,7 @@ class WasmDecoder : public Decoder {
} }
inline bool Validate(const byte* pc, CallIndirectImmediate<validate>& imm) { inline bool Validate(const byte* pc, CallIndirectImmediate<validate>& imm) {
if (!VALIDATE(module_ != nullptr && !module_->function_tables.empty())) { if (!VALIDATE(module_ != nullptr && !module_->tables.empty())) {
error("function table has to exist to execute call_indirect"); error("function table has to exist to execute call_indirect");
return false; return false;
} }
......
...@@ -1103,11 +1103,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { ...@@ -1103,11 +1103,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Reserve the metadata for indirect function tables. // Reserve the metadata for indirect function tables.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
int function_table_count = static_cast<int>(module_->function_tables.size()); int table_count = static_cast<int>(module_->tables.size());
table_instances_.reserve(module_->function_tables.size()); table_instances_.resize(table_count);
for (int index = 0; index < function_table_count; ++index) {
table_instances_.emplace_back();
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Process the imports for the module. // Process the imports for the module.
...@@ -1123,7 +1120,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { ...@@ -1123,7 +1120,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Initialize the indirect tables. // Initialize the indirect tables.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
if (function_table_count > 0) { if (table_count > 0) {
InitializeTables(instance); InitializeTables(instance);
} }
...@@ -1186,7 +1183,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { ...@@ -1186,7 +1183,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Initialize the indirect function tables. // Initialize the indirect function tables.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
if (function_table_count > 0) { if (table_count > 0) {
LoadTableSegments(instance); LoadTableSegments(instance);
} }
...@@ -1551,8 +1548,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) { ...@@ -1551,8 +1548,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
} }
uint32_t table_num = import.index; uint32_t table_num = import.index;
DCHECK_EQ(table_num, num_imported_tables); DCHECK_EQ(table_num, num_imported_tables);
const WasmIndirectFunctionTable& table = const WasmTable& table = module_->tables[table_num];
module_->function_tables[table_num];
TableInstance& table_instance = table_instances_[table_num]; TableInstance& table_instance = table_instances_[table_num];
table_instance.table_object = Handle<WasmTableObject>::cast(value); table_instance.table_object = Handle<WasmTableObject>::cast(value);
instance->set_table_object(*table_instance.table_object); instance->set_table_object(*table_instance.table_object);
...@@ -1840,7 +1836,7 @@ bool InstanceBuilder::NeedsWrappers() const { ...@@ -1840,7 +1836,7 @@ bool InstanceBuilder::NeedsWrappers() const {
for (auto& table_instance : table_instances_) { for (auto& table_instance : table_instances_) {
if (!table_instance.js_wrappers.is_null()) return true; if (!table_instance.js_wrappers.is_null()) return true;
} }
for (auto& table : module_->function_tables) { for (auto& table : module_->tables) {
if (table.exported) return true; if (table.exported) return true;
} }
return false; return false;
...@@ -1944,8 +1940,7 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) { ...@@ -1944,8 +1940,7 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
case kExternalTable: { case kExternalTable: {
// Export a table as a WebAssembly.Table object. // Export a table as a WebAssembly.Table object.
TableInstance& table_instance = table_instances_[exp.index]; TableInstance& table_instance = table_instances_[exp.index];
const WasmIndirectFunctionTable& table = const WasmTable& table = module_->tables[exp.index];
module_->function_tables[exp.index];
if (table_instance.table_object.is_null()) { if (table_instance.table_object.is_null()) {
uint32_t maximum = table.has_maximum_size ? table.maximum_size uint32_t maximum = table.has_maximum_size ? table.maximum_size
: FLAG_wasm_max_table_size; : FLAG_wasm_max_table_size;
...@@ -2048,9 +2043,9 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) { ...@@ -2048,9 +2043,9 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
} }
void InstanceBuilder::InitializeTables(Handle<WasmInstanceObject> instance) { void InstanceBuilder::InitializeTables(Handle<WasmInstanceObject> instance) {
size_t table_count = module_->function_tables.size(); size_t table_count = module_->tables.size();
for (size_t index = 0; index < table_count; ++index) { for (size_t index = 0; index < table_count; ++index) {
const WasmIndirectFunctionTable& table = module_->function_tables[index]; const WasmTable& table = module_->tables[index];
TableInstance& table_instance = table_instances_[index]; TableInstance& table_instance = table_instances_[index];
if (!instance->has_indirect_function_table()) { if (!instance->has_indirect_function_table()) {
...@@ -2063,8 +2058,8 @@ void InstanceBuilder::InitializeTables(Handle<WasmInstanceObject> instance) { ...@@ -2063,8 +2058,8 @@ void InstanceBuilder::InitializeTables(Handle<WasmInstanceObject> instance) {
void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) { void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) {
NativeModule* native_module = module_object_->native_module(); NativeModule* native_module = module_object_->native_module();
int function_table_count = static_cast<int>(module_->function_tables.size()); int table_count = static_cast<int>(module_->tables.size());
for (int index = 0; index < function_table_count; ++index) { for (int index = 0; index < table_count; ++index) {
TableInstance& table_instance = table_instances_[index]; TableInstance& table_instance = table_instances_[index];
// TODO(titzer): this does redundant work if there are multiple tables, // TODO(titzer): this does redundant work if there are multiple tables,
......
...@@ -473,12 +473,11 @@ class ModuleDecoderImpl : public Decoder { ...@@ -473,12 +473,11 @@ class ModuleDecoderImpl : public Decoder {
case kExternalTable: { case kExternalTable: {
// ===== Imported table ========================================== // ===== Imported table ==========================================
if (!AddTable(module_.get())) break; if (!AddTable(module_.get())) break;
import->index = import->index = static_cast<uint32_t>(module_->tables.size());
static_cast<uint32_t>(module_->function_tables.size()); module_->tables.emplace_back();
module_->function_tables.emplace_back(); WasmTable* table = &module_->tables.back();
WasmIndirectFunctionTable* table = &module_->function_tables.back();
table->imported = true; table->imported = true;
expect_u8("element type", kWasmAnyFunctionTypeCode); expect_u8("element type", kLocalAnyFunc);
uint8_t flags = validate_table_flags("element count"); uint8_t flags = validate_table_flags("element count");
consume_resizable_limits( consume_resizable_limits(
"element count", "elements", FLAG_wasm_max_table_size, "element count", "elements", FLAG_wasm_max_table_size,
...@@ -547,13 +546,16 @@ class ModuleDecoderImpl : public Decoder { ...@@ -547,13 +546,16 @@ class ModuleDecoderImpl : public Decoder {
} }
void DecodeTableSection() { void DecodeTableSection() {
uint32_t table_count = consume_count("table count", kV8MaxWasmTables); // TODO(ahaas): Set the correct limit to {kV8MaxWasmTables} once the
// implementation of AnyRef landed.
uint32_t max_count = FLAG_experimental_wasm_anyref ? 10 : kV8MaxWasmTables;
uint32_t table_count = consume_count("table count", max_count);
for (uint32_t i = 0; ok() && i < table_count; i++) { for (uint32_t i = 0; ok() && i < table_count; i++) {
if (!AddTable(module_.get())) break; if (!AddTable(module_.get())) break;
module_->function_tables.emplace_back(); module_->tables.emplace_back();
WasmIndirectFunctionTable* table = &module_->function_tables.back(); WasmTable* table = &module_->tables.back();
expect_u8("table type", kWasmAnyFunctionTypeCode); table->type = consume_reference_type();
uint8_t flags = validate_table_flags("table elements"); uint8_t flags = validate_table_flags("table elements");
consume_resizable_limits( consume_resizable_limits(
"table elements", "elements", FLAG_wasm_max_table_size, "table elements", "elements", FLAG_wasm_max_table_size,
...@@ -618,7 +620,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -618,7 +620,7 @@ class ModuleDecoderImpl : public Decoder {
break; break;
} }
case kExternalTable: { case kExternalTable: {
WasmIndirectFunctionTable* table = nullptr; WasmTable* table = nullptr;
exp->index = consume_table_index(module_.get(), &table); exp->index = consume_table_index(module_.get(), &table);
if (table) table->exported = true; if (table) table->exported = true;
break; break;
...@@ -694,7 +696,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -694,7 +696,7 @@ class ModuleDecoderImpl : public Decoder {
uint32_t element_count = uint32_t element_count =
consume_count("element count", FLAG_wasm_max_table_size); consume_count("element count", FLAG_wasm_max_table_size);
if (element_count > 0 && module_->function_tables.size() == 0) { if (element_count > 0 && module_->tables.size() == 0) {
error(pc_, "The element section requires a table"); error(pc_, "The element section requires a table");
} }
for (uint32_t i = 0; ok() && i < element_count; ++i) { for (uint32_t i = 0; ok() && i < element_count; ++i) {
...@@ -703,7 +705,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -703,7 +705,7 @@ class ModuleDecoderImpl : public Decoder {
if (table_index != 0) { if (table_index != 0) {
errorf(pos, "illegal table index %u != 0", table_index); errorf(pos, "illegal table index %u != 0", table_index);
} }
if (table_index >= module_->function_tables.size()) { if (table_index >= module_->tables.size()) {
errorf(pos, "out of bounds table index %u", table_index); errorf(pos, "out of bounds table index %u", table_index);
break; break;
} }
...@@ -932,7 +934,8 @@ class ModuleDecoderImpl : public Decoder { ...@@ -932,7 +934,8 @@ class ModuleDecoderImpl : public Decoder {
} }
bool AddTable(WasmModule* module) { bool AddTable(WasmModule* module) {
if (module->function_tables.size() > 0) { if (FLAG_experimental_wasm_anyref) return true;
if (module->tables.size() > 0) {
error("At most one table is supported"); error("At most one table is supported");
return false; return false;
} else { } else {
...@@ -1079,9 +1082,8 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1079,9 +1082,8 @@ class ModuleDecoderImpl : public Decoder {
return consume_index("global index", module->globals, global); return consume_index("global index", module->globals, global);
} }
uint32_t consume_table_index(WasmModule* module, uint32_t consume_table_index(WasmModule* module, WasmTable** table) {
WasmIndirectFunctionTable** table) { return consume_index("table index", module->tables, table);
return consume_index("table index", module->function_tables, table);
} }
template <typename T> template <typename T>
...@@ -1295,6 +1297,26 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1295,6 +1297,26 @@ class ModuleDecoderImpl : public Decoder {
} }
} }
// Reads a single 8-bit integer, interpreting it as a reference type.
ValueType consume_reference_type() {
byte val = consume_u8("reference type");
ValueTypeCode t = static_cast<ValueTypeCode>(val);
switch (t) {
case kLocalAnyFunc:
return kWasmAnyFunc;
case kLocalAnyRef:
if (!FLAG_experimental_wasm_anyref) {
error(pc_ - 1,
"Invalid type. Set --experimental-wasm-anyref to use 'AnyRef'");
}
return kWasmAnyRef;
default:
break;
}
error(pc_ - 1, "invalid reference type");
return kWasmStmt;
}
FunctionSig* consume_sig(Zone* zone) { FunctionSig* consume_sig(Zone* zone) {
constexpr bool has_return_values = true; constexpr bool has_return_values = true;
return consume_sig_internal(zone, has_return_values); return consume_sig_internal(zone, has_return_values);
......
...@@ -26,7 +26,6 @@ enum ValueTypeCode : uint8_t { ...@@ -26,7 +26,6 @@ enum ValueTypeCode : uint8_t {
}; };
// Binary encoding of other types. // Binary encoding of other types.
constexpr uint8_t kWasmFunctionTypeCode = 0x60; constexpr uint8_t kWasmFunctionTypeCode = 0x60;
constexpr uint8_t kWasmAnyFunctionTypeCode = 0x70;
// Binary encoding of import/export kinds. // Binary encoding of import/export kinds.
enum ImportExportKindCode : uint8_t { enum ImportExportKindCode : uint8_t {
......
...@@ -969,16 +969,14 @@ class CodeMap { ...@@ -969,16 +969,14 @@ class CodeMap {
InterpreterCode* GetIndirectCode(uint32_t table_index, uint32_t entry_index) { InterpreterCode* GetIndirectCode(uint32_t table_index, uint32_t entry_index) {
uint32_t saved_index; uint32_t saved_index;
USE(saved_index); USE(saved_index);
if (table_index >= module_->function_tables.size()) return nullptr; if (table_index >= module_->tables.size()) return nullptr;
// Mask table index for SSCA mitigation. // Mask table index for SSCA mitigation.
saved_index = table_index; saved_index = table_index;
table_index &= table_index &= static_cast<int32_t>((table_index - module_->tables.size()) &
static_cast<int32_t>((table_index - module_->function_tables.size()) & ~static_cast<int32_t>(table_index)) >>
~static_cast<int32_t>(table_index)) >> 31;
31;
DCHECK_EQ(table_index, saved_index); DCHECK_EQ(table_index, saved_index);
const WasmIndirectFunctionTable* table = const WasmTable* table = &module_->tables[table_index];
&module_->function_tables[table_index];
if (entry_index >= table->values.size()) return nullptr; if (entry_index >= table->values.size()) return nullptr;
// Mask entry_index for SSCA mitigation. // Mask entry_index for SSCA mitigation.
saved_index = entry_index; saved_index = entry_index;
...@@ -2249,7 +2247,7 @@ class ThreadImpl { ...@@ -2249,7 +2247,7 @@ class ThreadImpl {
code->at(pc)); code->at(pc));
uint32_t entry_index = Pop().to<uint32_t>(); uint32_t entry_index = Pop().to<uint32_t>();
// Assume only one table for now. // Assume only one table for now.
DCHECK_LE(module()->function_tables.size(), 1u); DCHECK_LE(module()->tables.size(), 1u);
ExternalCallResult result = ExternalCallResult result =
CallIndirectFunction(0, entry_index, imm.sig_index); CallIndirectFunction(0, entry_index, imm.sig_index);
switch (result.type) { switch (result.type) {
......
...@@ -392,7 +392,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { ...@@ -392,7 +392,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const {
if (indirect_functions_.size() > 0) { if (indirect_functions_.size() > 0) {
size_t start = EmitSection(kTableSectionCode, buffer); size_t start = EmitSection(kTableSectionCode, buffer);
buffer.write_u8(1); // table count buffer.write_u8(1); // table count
buffer.write_u8(kWasmAnyFunctionTypeCode); buffer.write_u8(kLocalAnyFunc);
buffer.write_u8(kHasMaximumFlag); buffer.write_u8(kHasMaximumFlag);
buffer.write_size(indirect_functions_.size()); buffer.write_size(indirect_functions_.size());
buffer.write_size(indirect_functions_.size()); buffer.write_size(indirect_functions_.size());
......
...@@ -330,7 +330,7 @@ size_t EstimateWasmModuleSize(const WasmModule* module) { ...@@ -330,7 +330,7 @@ size_t EstimateWasmModuleSize(const WasmModule* module) {
size_t estimate = size_t estimate =
sizeof(WasmModule) + VectorSize(module->signatures) + sizeof(WasmModule) + VectorSize(module->signatures) +
VectorSize(module->signature_ids) + VectorSize(module->functions) + VectorSize(module->signature_ids) + VectorSize(module->functions) +
VectorSize(module->data_segments) + VectorSize(module->function_tables) + VectorSize(module->data_segments) + VectorSize(module->tables) +
VectorSize(module->import_table) + VectorSize(module->export_table) + VectorSize(module->import_table) + VectorSize(module->export_table) +
VectorSize(module->exceptions) + VectorSize(module->table_inits); VectorSize(module->exceptions) + VectorSize(module->table_inits);
// TODO(wasm): include names table and wire bytes in size estimate // TODO(wasm): include names table and wire bytes in size estimate
......
...@@ -73,9 +73,9 @@ struct WasmDataSegment { ...@@ -73,9 +73,9 @@ struct WasmDataSegment {
}; };
// Static representation of a wasm indirect call table. // Static representation of a wasm indirect call table.
struct WasmIndirectFunctionTable { struct WasmTable {
MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmIndirectFunctionTable); MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmTable);
ValueType type = kWasmStmt; // table type.
uint32_t initial_size = 0; // initial table size. uint32_t initial_size = 0; // initial table size.
uint32_t maximum_size = 0; // maximum table size. uint32_t maximum_size = 0; // maximum table size.
bool has_maximum_size = false; // true if there is a maximum size. bool has_maximum_size = false; // true if there is a maximum size.
...@@ -146,7 +146,7 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -146,7 +146,7 @@ struct V8_EXPORT_PRIVATE WasmModule {
std::vector<uint32_t> signature_ids; // by signature index std::vector<uint32_t> signature_ids; // by signature index
std::vector<WasmFunction> functions; std::vector<WasmFunction> functions;
std::vector<WasmDataSegment> data_segments; std::vector<WasmDataSegment> data_segments;
std::vector<WasmIndirectFunctionTable> function_tables; std::vector<WasmTable> tables;
std::vector<WasmImport> import_table; std::vector<WasmImport> import_table;
std::vector<WasmExport> export_table; std::vector<WasmExport> export_table;
std::vector<WasmException> exceptions; std::vector<WasmException> exceptions;
......
...@@ -131,7 +131,7 @@ size_t EstimateNativeAllocationsSize(const WasmModule* module) { ...@@ -131,7 +131,7 @@ size_t EstimateNativeAllocationsSize(const WasmModule* module) {
size_t estimate = sizeof(WasmInstanceNativeAllocations) + size_t estimate = sizeof(WasmInstanceNativeAllocations) +
(1 * kPointerSize * module->num_imported_mutable_globals) + (1 * kPointerSize * module->num_imported_mutable_globals) +
(2 * kPointerSize * module->num_imported_functions); (2 * kPointerSize * module->num_imported_functions);
for (auto& table : module->function_tables) { for (auto& table : module->tables) {
estimate += 3 * kPointerSize * table.initial_size; estimate += 3 * kPointerSize * table.initial_size;
} }
return estimate; return estimate;
......
...@@ -147,8 +147,8 @@ Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) { ...@@ -147,8 +147,8 @@ Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
void TestingModuleBuilder::AddIndirectFunctionTable( void TestingModuleBuilder::AddIndirectFunctionTable(
const uint16_t* function_indexes, uint32_t table_size) { const uint16_t* function_indexes, uint32_t table_size) {
test_module_->function_tables.emplace_back(); test_module_->tables.emplace_back();
WasmIndirectFunctionTable& table = test_module_->function_tables.back(); WasmTable& table = test_module_->tables.back();
table.initial_size = table_size; table.initial_size = table_size;
table.maximum_size = table_size; table.maximum_size = table_size;
table.has_maximum_size = true; table.has_maximum_size = true;
...@@ -164,7 +164,7 @@ void TestingModuleBuilder::PopulateIndirectFunctionTable() { ...@@ -164,7 +164,7 @@ void TestingModuleBuilder::PopulateIndirectFunctionTable() {
auto instance = instance_object(); auto instance = instance_object();
uint32_t num_tables = 1; // TODO(titzer): multiple tables. uint32_t num_tables = 1; // TODO(titzer): multiple tables.
for (uint32_t i = 0; i < num_tables; i++) { for (uint32_t i = 0; i < num_tables; i++) {
WasmIndirectFunctionTable& table = test_module_->function_tables[i]; WasmTable& table = test_module_->tables[i];
int table_size = static_cast<int>(instance->indirect_function_table_size()); int table_size = static_cast<int>(instance->indirect_function_table_size());
for (int j = 0; j < table_size; j++) { for (int j = 0; j < table_size; j++) {
WasmFunction& function = test_module_->functions[table.values[j]]; WasmFunction& function = test_module_->functions[table.values[j]];
......
...@@ -245,7 +245,7 @@ class TestModuleBuilder { ...@@ -245,7 +245,7 @@ class TestModuleBuilder {
mod.maximum_pages = 100; mod.maximum_pages = 100;
} }
void InitializeFunctionTable() { mod.function_tables.emplace_back(); } void InitializeTable() { mod.tables.emplace_back(); }
WasmModule* module() { return &mod; } WasmModule* module() { return &mod; }
...@@ -1522,7 +1522,7 @@ TEST_F(FunctionBodyDecoderTest, MultiReturnType) { ...@@ -1522,7 +1522,7 @@ TEST_F(FunctionBodyDecoderTest, MultiReturnType) {
TEST_F(FunctionBodyDecoderTest, SimpleIndirectCalls) { TEST_F(FunctionBodyDecoderTest, SimpleIndirectCalls) {
FunctionSig* sig = sigs.i_i(); FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder; TestModuleBuilder builder;
builder.InitializeFunctionTable(); builder.InitializeTable();
module = builder.module(); module = builder.module();
byte f0 = builder.AddSignature(sigs.i_v()); byte f0 = builder.AddSignature(sigs.i_v());
...@@ -1538,7 +1538,7 @@ TEST_F(FunctionBodyDecoderTest, SimpleIndirectCalls) { ...@@ -1538,7 +1538,7 @@ TEST_F(FunctionBodyDecoderTest, SimpleIndirectCalls) {
TEST_F(FunctionBodyDecoderTest, IndirectCallsOutOfBounds) { TEST_F(FunctionBodyDecoderTest, IndirectCallsOutOfBounds) {
FunctionSig* sig = sigs.i_i(); FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder; TestModuleBuilder builder;
builder.InitializeFunctionTable(); builder.InitializeTable();
module = builder.module(); module = builder.module();
EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT0(0, WASM_ZERO)); EXPECT_FAILURE_S(sig, WASM_CALL_INDIRECT0(0, WASM_ZERO));
...@@ -1555,7 +1555,7 @@ TEST_F(FunctionBodyDecoderTest, IndirectCallsOutOfBounds) { ...@@ -1555,7 +1555,7 @@ TEST_F(FunctionBodyDecoderTest, IndirectCallsOutOfBounds) {
TEST_F(FunctionBodyDecoderTest, IndirectCallsWithMismatchedSigs3) { TEST_F(FunctionBodyDecoderTest, IndirectCallsWithMismatchedSigs3) {
FunctionSig* sig = sigs.i_i(); FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder; TestModuleBuilder builder;
builder.InitializeFunctionTable(); builder.InitializeTable();
module = builder.module(); module = builder.module();
byte f0 = builder.AddFunction(sigs.i_f()); byte f0 = builder.AddFunction(sigs.i_f());
...@@ -1593,7 +1593,7 @@ TEST_F(FunctionBodyDecoderTest, IndirectCallsWithoutTableCrash) { ...@@ -1593,7 +1593,7 @@ TEST_F(FunctionBodyDecoderTest, IndirectCallsWithoutTableCrash) {
TEST_F(FunctionBodyDecoderTest, IncompleteIndirectCall) { TEST_F(FunctionBodyDecoderTest, IncompleteIndirectCall) {
FunctionSig* sig = sigs.i_i(); FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder; TestModuleBuilder builder;
builder.InitializeFunctionTable(); builder.InitializeTable();
module = builder.module(); module = builder.module();
static byte code[] = {kExprCallIndirect}; static byte code[] = {kExprCallIndirect};
...@@ -1604,7 +1604,7 @@ TEST_F(FunctionBodyDecoderTest, IncompleteStore) { ...@@ -1604,7 +1604,7 @@ TEST_F(FunctionBodyDecoderTest, IncompleteStore) {
FunctionSig* sig = sigs.i_i(); FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder; TestModuleBuilder builder;
builder.InitializeMemory(); builder.InitializeMemory();
builder.InitializeFunctionTable(); builder.InitializeTable();
module = builder.module(); module = builder.module();
static byte code[] = {kExprI32StoreMem}; static byte code[] = {kExprI32StoreMem};
...@@ -1616,7 +1616,7 @@ TEST_F(FunctionBodyDecoderTest, IncompleteS8x16Shuffle) { ...@@ -1616,7 +1616,7 @@ TEST_F(FunctionBodyDecoderTest, IncompleteS8x16Shuffle) {
FunctionSig* sig = sigs.i_i(); FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder; TestModuleBuilder builder;
builder.InitializeMemory(); builder.InitializeMemory();
builder.InitializeFunctionTable(); builder.InitializeTable();
module = builder.module(); module = builder.module();
static byte code[] = {kSimdPrefix, static byte code[] = {kSimdPrefix,
......
...@@ -797,22 +797,22 @@ TEST_F(WasmModuleVerifyTest, OneIndirectFunction) { ...@@ -797,22 +797,22 @@ TEST_F(WasmModuleVerifyTest, OneIndirectFunction) {
// funcs --------------------------------------------------------------- // funcs ---------------------------------------------------------------
ONE_EMPTY_FUNCTION, ONE_EMPTY_FUNCTION,
// table declaration --------------------------------------------------- // table declaration ---------------------------------------------------
SECTION(Table, 4), ENTRY_COUNT(1), kWasmAnyFunctionTypeCode, 0, 1}; SECTION(Table, 4), ENTRY_COUNT(1), kLocalAnyFunc, 0, 1};
ModuleResult result = DecodeModule(data, data + sizeof(data)); ModuleResult result = DecodeModule(data, data + sizeof(data));
EXPECT_OK(result); EXPECT_OK(result);
if (result.ok()) { if (result.ok()) {
EXPECT_EQ(1u, result.val->signatures.size()); EXPECT_EQ(1u, result.val->signatures.size());
EXPECT_EQ(1u, result.val->functions.size()); EXPECT_EQ(1u, result.val->functions.size());
EXPECT_EQ(1u, result.val->function_tables.size()); EXPECT_EQ(1u, result.val->tables.size());
EXPECT_EQ(1u, result.val->function_tables[0].initial_size); EXPECT_EQ(1u, result.val->tables[0].initial_size);
} }
} }
TEST_F(WasmModuleVerifyTest, ElementSectionWithInternalTable) { TEST_F(WasmModuleVerifyTest, ElementSectionWithInternalTable) {
static const byte data[] = { static const byte data[] = {
// table --------------------------------------------------------------- // table ---------------------------------------------------------------
SECTION(Table, 4), ENTRY_COUNT(1), kWasmAnyFunctionTypeCode, 0, 1, SECTION(Table, 4), ENTRY_COUNT(1), kLocalAnyFunc, 0, 1,
// elements ------------------------------------------------------------ // elements ------------------------------------------------------------
SECTION(Element, 1), SECTION(Element, 1),
0 // entry count 0 // entry count
...@@ -825,14 +825,14 @@ TEST_F(WasmModuleVerifyTest, ElementSectionWithImportedTable) { ...@@ -825,14 +825,14 @@ TEST_F(WasmModuleVerifyTest, ElementSectionWithImportedTable) {
static const byte data[] = { static const byte data[] = {
// imports ------------------------------------------------------------- // imports -------------------------------------------------------------
SECTION(Import, 9), ENTRY_COUNT(1), SECTION(Import, 9), ENTRY_COUNT(1),
NAME_LENGTH(1), // -- NAME_LENGTH(1), // --
'm', // module name 'm', // module name
NAME_LENGTH(1), // -- NAME_LENGTH(1), // --
't', // table name 't', // table name
kExternalTable, // import kind kExternalTable, // import kind
kWasmAnyFunctionTypeCode, // elem_type kLocalAnyFunc, // elem_type
0, // no maximum field 0, // no maximum field
1, // initial size 1, // initial size
// elements ------------------------------------------------------------ // elements ------------------------------------------------------------
SECTION(Element, 1), SECTION(Element, 1),
0 // entry count 0 // entry count
...@@ -863,7 +863,7 @@ TEST_F(WasmModuleVerifyTest, Regression_735887) { ...@@ -863,7 +863,7 @@ TEST_F(WasmModuleVerifyTest, Regression_735887) {
// funcs --------------------------------------------------------------- // funcs ---------------------------------------------------------------
ONE_EMPTY_FUNCTION, ONE_EMPTY_FUNCTION,
// table declaration --------------------------------------------------- // table declaration ---------------------------------------------------
SECTION(Table, 4), ENTRY_COUNT(1), kWasmAnyFunctionTypeCode, 0, 1, SECTION(Table, 4), ENTRY_COUNT(1), kLocalAnyFunc, 0, 1,
// elements ------------------------------------------------------------ // elements ------------------------------------------------------------
SECTION(Element, 7), SECTION(Element, 7),
1, // entry count 1, // entry count
...@@ -882,7 +882,7 @@ TEST_F(WasmModuleVerifyTest, OneIndirectFunction_one_entry) { ...@@ -882,7 +882,7 @@ TEST_F(WasmModuleVerifyTest, OneIndirectFunction_one_entry) {
// funcs --------------------------------------------------------------- // funcs ---------------------------------------------------------------
ONE_EMPTY_FUNCTION, ONE_EMPTY_FUNCTION,
// table declaration --------------------------------------------------- // table declaration ---------------------------------------------------
SECTION(Table, 4), ENTRY_COUNT(1), kWasmAnyFunctionTypeCode, 0, 1, SECTION(Table, 4), ENTRY_COUNT(1), kLocalAnyFunc, 0, 1,
// elements ------------------------------------------------------------ // elements ------------------------------------------------------------
SECTION(Element, 7), SECTION(Element, 7),
1, // entry count 1, // entry count
...@@ -895,8 +895,8 @@ TEST_F(WasmModuleVerifyTest, OneIndirectFunction_one_entry) { ...@@ -895,8 +895,8 @@ TEST_F(WasmModuleVerifyTest, OneIndirectFunction_one_entry) {
if (result.ok()) { if (result.ok()) {
EXPECT_EQ(1u, result.val->signatures.size()); EXPECT_EQ(1u, result.val->signatures.size());
EXPECT_EQ(1u, result.val->functions.size()); EXPECT_EQ(1u, result.val->functions.size());
EXPECT_EQ(1u, result.val->function_tables.size()); EXPECT_EQ(1u, result.val->tables.size());
EXPECT_EQ(1u, result.val->function_tables[0].initial_size); EXPECT_EQ(1u, result.val->tables[0].initial_size);
} }
} }
...@@ -910,7 +910,7 @@ TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) { ...@@ -910,7 +910,7 @@ TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) {
// funcs ------------------------------------------------------ // funcs ------------------------------------------------------
FOUR_EMPTY_FUNCTIONS, FOUR_EMPTY_FUNCTIONS,
// table declaration ------------------------------------------- // table declaration -------------------------------------------
SECTION(Table, 4), ENTRY_COUNT(1), kWasmAnyFunctionTypeCode, 0, 8, SECTION(Table, 4), ENTRY_COUNT(1), kLocalAnyFunc, 0, 8,
// table elements ---------------------------------------------- // table elements ----------------------------------------------
SECTION(Element, 14), SECTION(Element, 14),
1, // entry count 1, // entry count
...@@ -931,8 +931,8 @@ TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) { ...@@ -931,8 +931,8 @@ TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) {
if (result.ok()) { if (result.ok()) {
EXPECT_EQ(2u, result.val->signatures.size()); EXPECT_EQ(2u, result.val->signatures.size());
EXPECT_EQ(4u, result.val->functions.size()); EXPECT_EQ(4u, result.val->functions.size());
EXPECT_EQ(1u, result.val->function_tables.size()); EXPECT_EQ(1u, result.val->tables.size());
EXPECT_EQ(8u, result.val->function_tables[0].initial_size); EXPECT_EQ(8u, result.val->tables[0].initial_size);
} }
} }
...@@ -960,6 +960,45 @@ TEST_F(WasmModuleVerifyTest, IndirectFunctionInvalidIndex) { ...@@ -960,6 +960,45 @@ TEST_F(WasmModuleVerifyTest, IndirectFunctionInvalidIndex) {
EXPECT_FAILURE(data); EXPECT_FAILURE(data);
} }
TEST_F(WasmModuleVerifyTest, MultipleTablesWithoutFlag) {
static const byte data[] = {
SECTION(Table, 7), // table section
ENTRY_COUNT(2), // 2 tables
kLocalAnyFunc, // table 1: type
0, // table 1: no maximum
10, // table 1: minimum size
kLocalAnyFunc, // table 2: type
0, // table 2: no maximum
10, // table 2: minimum size
};
EXPECT_FAILURE(data);
}
TEST_F(WasmModuleVerifyTest, MultipleTablesWithFlag) {
FlagScope<bool> flag_scope(&FLAG_experimental_wasm_anyref, true);
static const byte data[] = {
SECTION(Table, 7), // table section
ENTRY_COUNT(2), // 2 tables
kLocalAnyFunc, // table 1: type
0, // table 1: no maximum
10, // table 1: minimum size
kLocalAnyRef, // table 2: type
0, // table 2: no maximum
11, // table 2: minimum size
};
ModuleResult result = DecodeModule(data, data + sizeof(data));
EXPECT_OK(result);
EXPECT_EQ(2u, result.val->tables.size());
EXPECT_EQ(10u, result.val->tables[0].initial_size);
EXPECT_EQ(kWasmAnyFunc, result.val->tables[0].type);
EXPECT_EQ(11u, result.val->tables[1].initial_size);
EXPECT_EQ(kWasmAnyRef, result.val->tables[1].type);
}
class WasmSignatureDecodeTest : public TestWithZone { class WasmSignatureDecodeTest : public TestWithZone {
public: public:
WasmSignatureDecodeTest() WasmSignatureDecodeTest()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment