Skip to content

Commit f644a03

Browse files
authored
Several fixes for reference types (#1278)
- Allow `ref.func` for global initialization expressions - Allow `nullref` as a full-fledged type, after WebAssembly/reference-types#66 - Enable reference types when exnref is used (The reference types proposal is a prerequisite of the EH proposal)
1 parent 52953f3 commit f644a03

14 files changed

+1040
-1022
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Wabt has been compiled to JavaScript via emscripten. Some of the functionality i
5454
| [multi-value][] | `--enable-multi-value` |||||
5555
| [tail-call][] | `--enable-tail-call` |||||
5656
| [bulk memory][] | `--enable-bulk-memory` |||||
57-
| [reference types][] | `--enable-reference-types` |||| |
57+
| [reference types][] | `--enable-reference-types` |||| |
5858
| [annotations][] | `--enable-annotations` | || | |
5959

6060
[exception handling]: https://github.com/WebAssembly/exception-handling

src/binary-reader-ir.cc

+8
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ class BinaryReaderIR : public BinaryReaderNop {
245245
Result OnInitExprI32ConstExpr(Index index, uint32_t value) override;
246246
Result OnInitExprI64ConstExpr(Index index, uint64_t value) override;
247247
Result OnInitExprRefNull(Index index) override;
248+
Result OnInitExprRefFunc(Index index, Index func_index) override;
248249

249250
private:
250251
Location GetLocation() const;
@@ -1197,6 +1198,13 @@ Result BinaryReaderIR::OnInitExprRefNull(Index index) {
11971198
return Result::Ok;
11981199
}
11991200

1201+
Result BinaryReaderIR::OnInitExprRefFunc(Index index, Index func_index) {
1202+
Location loc = GetLocation();
1203+
current_init_expr_->push_back(
1204+
MakeUnique<RefFuncExpr>(Var(func_index, loc), loc));
1205+
return Result::Ok;
1206+
}
1207+
12001208
Result BinaryReaderIR::OnLocalName(Index func_index,
12011209
Index local_index,
12021210
string_view name) {

src/binary-reader.cc

+10-12
Original file line numberDiff line numberDiff line change
@@ -394,14 +394,14 @@ bool BinaryReader::IsConcreteType(Type type) {
394394
case Type::V128:
395395
return options_.features.simd_enabled();
396396

397-
case Type::Exnref:
398-
return options_.features.exceptions_enabled();
399-
397+
case Type::Funcref:
400398
case Type::Anyref:
399+
case Type::Nullref:
401400
return options_.features.reference_types_enabled();
402401

403-
case Type::Funcref:
404-
return options_.features.reference_types_enabled();
402+
case Type::Exnref:
403+
return options_.features.reference_types_enabled() &&
404+
options_.features.exceptions_enabled();
405405

406406
default:
407407
return false;
@@ -525,9 +525,8 @@ Result BinaryReader::ReadInitExpr(Index index, bool require_i32) {
525525

526526
Result BinaryReader::ReadTable(Type* out_elem_type, Limits* out_elem_limits) {
527527
CHECK_RESULT(ReadType(out_elem_type, "table elem type"));
528-
ERROR_UNLESS(
529-
*out_elem_type == Type::Funcref || *out_elem_type == Type::Anyref,
530-
"table elem type must by funcref or anyref");
528+
ERROR_UNLESS(IsRefType(*out_elem_type),
529+
"table elem type must be a reference type");
531530

532531
uint32_t flags;
533532
uint32_t initial;
@@ -2190,10 +2189,9 @@ Result BinaryReader::ReadElemSection(Offset section_size) {
21902189
if (!legacy) {
21912190
if (flags & SegUseElemExprs) {
21922191
CHECK_RESULT(ReadType(&elem_type, "table elem type"));
2193-
ERROR_UNLESS(
2194-
elem_type == Type::Funcref || elem_type == Type::Anyref,
2195-
"segment elem expr type must be funcref or anyref (got %s)",
2196-
GetTypeName(elem_type));
2192+
ERROR_UNLESS(IsRefType(elem_type),
2193+
"segment elem expr type must be a reference type (got %s)",
2194+
GetTypeName(elem_type));
21972195
} else {
21982196
ExternalKind kind;
21992197
CHECK_RESULT(ReadExternalKind(&kind, "export kind"));

src/common.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,12 @@ enum class Type : int32_t {
214214
V128 = -0x05, // 0x7b
215215
Funcref = -0x10, // 0x70
216216
Anyref = -0x11, // 0x6f
217+
Nullref = -0x12, // 0x6e
217218
Exnref = -0x18, // 0x68
218219
Func = -0x20, // 0x60
219220
Void = -0x40, // 0x40
220221
___ = Void, // Convenient for the opcode table in opcode.h
221222
Any = 0, // Not actually specified, but useful for type-checking
222-
Nullref = 1, // Not actually specified, but used in testing and type-checking
223223
Hostref = 2, // Not actually specified, but used in testing and type-checking
224224
I8 = 3, // Not actually specified, but used internally with load/store
225225
I8U = 4, // Not actually specified, but used internally with load/store
@@ -383,7 +383,7 @@ static WABT_INLINE const char* GetSymbolTypeName(SymbolType type) {
383383

384384
static WABT_INLINE bool IsRefType(Type t) {
385385
return t == Type::Anyref || t == Type::Funcref || t == Type::Nullref ||
386-
t == Type::Hostref;
386+
t == Type::Exnref || t == Type::Hostref;
387387
}
388388

389389
static WABT_INLINE bool IsNullableRefType(Type t) {
@@ -444,6 +444,7 @@ static WABT_INLINE TypeVector GetInlineTypeVector(Type type) {
444444
case Type::V128:
445445
case Type::Funcref:
446446
case Type::Anyref:
447+
case Type::Nullref:
447448
case Type::Exnref:
448449
return TypeVector(&type, &type + 1);
449450

src/decompiler-ls.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ inline const char *GetDecompTypeName(Type t) {
3636
case Type::F32: return "float";
3737
case Type::F64: return "double";
3838
case Type::V128: return "simd";
39-
case Type::Anyref: return "anyref";
4039
case Type::Func: return "func";
4140
case Type::Funcref: return "funcref";
42-
case Type::Exnref: return "exceptionref";
41+
case Type::Anyref: return "anyref";
42+
case Type::Nullref: return "nullref";
43+
case Type::Exnref: return "exnref";
4344
case Type::Void: return "void";
4445
default: return "ILLEGAL";
4546
}

src/lexer-keywords.txt

+1
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ memory, TokenType::Memory
442442
module, TokenType::Module
443443
mut, TokenType::Mut
444444
nop, TokenType::Nop, Opcode::Nop
445+
nullref, Type::Nullref
445446
offset, TokenType::Offset
446447
param, TokenType::Param
447448
quote, TokenType::Quote

0 commit comments

Comments
 (0)