Skip to content

Commit 8be9a01

Browse files
authored
Support table initializer expressions; completes function references support (#2593)
Another large patch on the top of the other two. Now there are 3-4000 lines of new code is waiting for review, and it looks like the end is still far. The painful part so far: https://webassembly.github.io/function-references/core/binary/modules.html#element-section Since type 0-3 is reserved for `(ref func)`, all `(elem ... funcref ...)` must be encoded with 4-7, which increase binary size. This affect several tests, and probably real word programs :( There are spec tests to check this behavior.
1 parent ed94ed7 commit 8be9a01

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2103
-135
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ Wabt has been compiled to JavaScript via emscripten. Some of the functionality i
6363
| [extended-const][] | `--enable-extended-const` | ||||||
6464
| [relaxed-simd][] | `--enable-relaxed-simd` | ||||| |
6565
| [custom-page-sizes][] | `--enable-custom-page-sizes`| ||||||
66+
| [function-references][] | `--enable-function-references` | ||||| |
6667

6768
[exception handling]: https://github.com/WebAssembly/exception-handling
6869
[mutable globals]: https://github.com/WebAssembly/mutable-global
@@ -80,6 +81,7 @@ Wabt has been compiled to JavaScript via emscripten. Some of the functionality i
8081
[extended-const]: https://github.com/WebAssembly/extended-const
8182
[relaxed-simd]: https://github.com/WebAssembly/relaxed-simd
8283
[custom-page-sizes]: https://github.com/WebAssembly/custom-page-sizes
84+
[function-references]: https://github.com/WebAssembly/function-references
8385

8486
## Cloning
8587

include/wabt/binary-reader-logging.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,13 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
9696

9797
Result BeginTableSection(Offset size) override;
9898
Result OnTableCount(Index count) override;
99-
Result OnTable(Index index,
100-
Type elem_type,
101-
const Limits* elem_limits) override;
99+
Result BeginTable(Index index,
100+
Type elem_type,
101+
const Limits* elem_limits,
102+
TableInitExprStatus init_provided) override;
103+
Result BeginTableInitExpr(Index index) override;
104+
Result EndTableInitExpr(Index index) override;
105+
Result EndTable(Index index) override;
102106
Result EndTableSection() override;
103107

104108
Result BeginMemorySection(Offset size) override;

include/wabt/binary-reader-nop.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,15 @@ class BinaryReaderNop : public BinaryReaderDelegate {
121121
/* Table section */
122122
Result BeginTableSection(Offset size) override { return Result::Ok; }
123123
Result OnTableCount(Index count) override { return Result::Ok; }
124-
Result OnTable(Index index,
125-
Type elem_type,
126-
const Limits* elem_limits) override {
124+
Result BeginTable(Index index,
125+
Type elem_type,
126+
const Limits* elem_limits,
127+
TableInitExprStatus init_provided) override {
127128
return Result::Ok;
128129
}
130+
Result BeginTableInitExpr(Index index) override { return Result::Ok; }
131+
Result EndTableInitExpr(Index index) override { return Result::Ok; }
132+
Result EndTable(Index index) override { return Result::Ok; }
129133
Result EndTableSection() override { return Result::Ok; }
130134

131135
/* Memory section */

include/wabt/binary-reader.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ struct CatchClause {
6666
};
6767
using CatchClauseVector = std::vector<CatchClause>;
6868

69+
enum class TableInitExprStatus {
70+
TableWithInitExpression,
71+
TableWithoutInitExpression,
72+
};
73+
6974
class BinaryReaderDelegate {
7075
public:
7176
struct State {
@@ -156,9 +161,13 @@ class BinaryReaderDelegate {
156161
/* Table section */
157162
virtual Result BeginTableSection(Offset size) = 0;
158163
virtual Result OnTableCount(Index count) = 0;
159-
virtual Result OnTable(Index index,
160-
Type elem_type,
161-
const Limits* elem_limits) = 0;
164+
virtual Result BeginTable(Index index,
165+
Type elem_type,
166+
const Limits* elem_limits,
167+
TableInitExprStatus init_provided) = 0;
168+
virtual Result BeginTableInitExpr(Index index) = 0;
169+
virtual Result EndTableInitExpr(Index index) = 0;
170+
virtual Result EndTable(Index index) = 0;
162171
virtual Result EndTableSection() = 0;
163172

164173
/* Memory section */

include/wabt/interp/interp-inl.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -422,12 +422,6 @@ void RequireType(ValueType type) {
422422
assert(HasType<T>(type));
423423
}
424424

425-
inline bool TypesMatch(ValueType expected, ValueType actual) {
426-
// Currently there is no subtyping, so expected and actual must match
427-
// exactly. In the future this may be expanded.
428-
return expected == actual;
429-
}
430-
431425
//// Value ////
432426
inline Value WABT_VECTORCALL Value::Make(s32 val) { Value res; res.i32_ = val; res.SetType(ValueType::I32); return res; }
433427
inline Value WABT_VECTORCALL Value::Make(u32 val) { Value res; res.i32_ = val; res.SetType(ValueType::I32); return res; }
@@ -682,8 +676,8 @@ inline bool Table::classof(const Object* obj) {
682676
}
683677

684678
// static
685-
inline Table::Ptr Table::New(Store& store, TableType type) {
686-
return store.Alloc<Table>(store, type);
679+
inline Table::Ptr Table::New(Store& store, TableType type, Ref init_ref) {
680+
return store.Alloc<Table>(store, type, init_ref);
687681
}
688682

689683
inline const ExternType& Table::extern_type() {

include/wabt/interp/interp.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ using u32x2 = Simd<u32, 2>;
157157

158158
//// Types ////
159159

160+
bool TypesMatch(ValueType expected, ValueType actual);
161+
162+
//// Limits ////
163+
160164
bool CanGrow(const Limits&, u32 old_size, u32 delta, u32* new_size);
161165
Result Match(const Limits& expected,
162166
const Limits& actual,
@@ -334,6 +338,7 @@ struct FuncDesc {
334338

335339
struct TableDesc {
336340
TableType type;
341+
FuncDesc init_func;
337342
};
338343

339344
struct MemoryDesc {
@@ -818,7 +823,7 @@ class Table : public Extern {
818823
static const char* GetTypeName() { return "Table"; }
819824
using Ptr = RefPtr<Table>;
820825

821-
static Table::Ptr New(Store&, TableType);
826+
static Table::Ptr New(Store&, TableType, Ref);
822827

823828
Result Match(Store&, const ImportType&, Trap::Ptr* out_trap) override;
824829

@@ -850,7 +855,7 @@ class Table : public Extern {
850855

851856
private:
852857
friend Store;
853-
explicit Table(Store&, TableType);
858+
explicit Table(Store&, TableType, Ref);
854859
void Mark(Store&) override;
855860

856861
TableType type_;

include/wabt/ir.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,13 +987,14 @@ struct Table {
987987
std::string name;
988988
Limits elem_limits;
989989
Type elem_type;
990+
ExprList init_expr;
990991
};
991992

992993
using ExprListVector = std::vector<ExprList>;
993994

994995
struct ElemSegment {
995996
explicit ElemSegment(std::string_view name) : name(name) {}
996-
uint8_t GetFlags(const Module*) const;
997+
uint8_t GetFlags(const Module*, bool function_references_enabled) const;
997998

998999
SegmentKind kind = SegmentKind::Active;
9991000
std::string name;

include/wabt/shared-validator.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ struct ValidateOptions {
4040
Features features;
4141
};
4242

43+
enum class TableImportStatus {
44+
TableIsImported,
45+
TableIsNotImported,
46+
};
47+
4348
class SharedValidator {
4449
public:
4550
WABT_DISALLOW_COPY_AND_ASSIGN(SharedValidator);
@@ -75,7 +80,7 @@ class SharedValidator {
7580
Result OnArrayType(const Location&, TypeMut field);
7681

7782
Result OnFunction(const Location&, Var sig_var);
78-
Result OnTable(const Location&, Type elem_type, const Limits&);
83+
Result OnTable(const Location&, Type elem_type, const Limits&, TableImportStatus import_status, TableInitExprStatus init_provided);
7984
Result OnMemory(const Location&, const Limits&, uint32_t page_size);
8085
Result OnGlobalImport(const Location&, Type type, bool mutable_);
8186
Result OnGlobal(const Location&, Type type, bool mutable_);

src/apply-names.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class NameApplier : public ExprVisitor::DelegateNop {
102102
Result VisitGlobal(Global* global);
103103
Result VisitTag(Tag* tag);
104104
Result VisitExport(Index export_index, Export* export_);
105+
Result VisitTable(Table* table);
105106
Result VisitElemSegment(Index elem_segment_index, ElemSegment* segment);
106107
Result VisitDataSegment(Index data_segment_index, DataSegment* segment);
107108
Result VisitStart(Var* start_var);
@@ -559,6 +560,11 @@ Result NameApplier::VisitExport(Index export_index, Export* export_) {
559560
return Result::Ok;
560561
}
561562

563+
Result NameApplier::VisitTable(Table* table) {
564+
CHECK_RESULT(visitor_.VisitExprList(table->init_expr));
565+
return Result::Ok;
566+
}
567+
562568
Result NameApplier::VisitElemSegment(Index elem_segment_index,
563569
ElemSegment* segment) {
564570
CHECK_RESULT(UseNameForTableVar(&segment->table_var));
@@ -594,6 +600,8 @@ Result NameApplier::VisitModule(Module* module) {
594600
CHECK_RESULT(VisitTag(module->tags[i]));
595601
for (size_t i = 0; i < module->exports.size(); ++i)
596602
CHECK_RESULT(VisitExport(i, module->exports[i]));
603+
for (size_t i = 0; i < module->tables.size(); ++i)
604+
CHECK_RESULT(VisitTable(module->tables[i]));
597605
for (size_t i = 0; i < module->elem_segments.size(); ++i)
598606
CHECK_RESULT(VisitElemSegment(i, module->elem_segments[i]));
599607
for (size_t i = 0; i < module->data_segments.size(); ++i)

src/binary-reader-ir.cc

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,12 @@ class BinaryReaderIR : public BinaryReaderNop {
144144
Result OnFunction(Index index, Index sig_index) override;
145145

146146
Result OnTableCount(Index count) override;
147-
Result OnTable(Index index,
148-
Type elem_type,
149-
const Limits* elem_limits) override;
147+
Result BeginTable(Index index,
148+
Type elem_type,
149+
const Limits* elem_limits,
150+
TableInitExprStatus init_provided) override;
151+
Result BeginTableInitExpr(Index index) override;
152+
Result EndTableInitExpr(Index index) override;
150153

151154
Result OnMemoryCount(Index count) override;
152155
Result OnMemory(Index index,
@@ -700,9 +703,10 @@ Result BinaryReaderIR::OnTableCount(Index count) {
700703
return Result::Ok;
701704
}
702705

703-
Result BinaryReaderIR::OnTable(Index index,
704-
Type elem_type,
705-
const Limits* elem_limits) {
706+
Result BinaryReaderIR::BeginTable(Index index,
707+
Type elem_type,
708+
const Limits* elem_limits,
709+
TableInitExprStatus) {
706710
auto field = std::make_unique<TableModuleField>(GetLocation());
707711
Table& table = field->table;
708712
table.elem_limits = *elem_limits;
@@ -712,6 +716,16 @@ Result BinaryReaderIR::OnTable(Index index,
712716
return Result::Ok;
713717
}
714718

719+
Result BinaryReaderIR::BeginTableInitExpr(Index index) {
720+
assert(index == module_->tables.size() - 1);
721+
Table* table = module_->tables[index];
722+
return BeginInitExpr(&table->init_expr);
723+
}
724+
725+
Result BinaryReaderIR::EndTableInitExpr(Index index) {
726+
return EndInitExpr();
727+
}
728+
715729
Result BinaryReaderIR::OnMemoryCount(Index count) {
716730
WABT_TRY
717731
module_->memories.reserve(module_->num_memory_imports + count);

0 commit comments

Comments
 (0)