Skip to content

Commit dedde1b

Browse files
committed
Add support for ref.test instruction
Work in progress
1 parent ea193b4 commit dedde1b

29 files changed

+1295
-1165
lines changed

include/wabt/binary-reader-logging.h

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
221221
Result OnRefFuncExpr(Index index) override;
222222
Result OnRefNullExpr(Type type) override;
223223
Result OnRefIsNullExpr() override;
224+
Result OnRefTestExpr(Type type) override;
224225
Result OnNopExpr() override;
225226
Result OnRethrowExpr(Index depth) override;
226227
Result OnReturnCallExpr(Index func_index) override;

include/wabt/binary-reader-nop.h

+1
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ class BinaryReaderNop : public BinaryReaderDelegate {
302302
Result OnRefFuncExpr(Index func_index) override { return Result::Ok; }
303303
Result OnRefNullExpr(Type type) override { return Result::Ok; }
304304
Result OnRefIsNullExpr() override { return Result::Ok; }
305+
Result OnRefTestExpr(Type type) override { return Result::Ok; }
305306
Result OnNopExpr() override { return Result::Ok; }
306307
Result OnRethrowExpr(Index depth) override { return Result::Ok; }
307308
Result OnReturnCallExpr(Index sig_index) override { return Result::Ok; }

include/wabt/binary-reader.h

+1
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ class BinaryReaderDelegate {
297297
virtual Result OnRefFuncExpr(Index func_index) = 0;
298298
virtual Result OnRefNullExpr(Type type) = 0;
299299
virtual Result OnRefIsNullExpr() = 0;
300+
virtual Result OnRefTestExpr(Type check_type) = 0;
300301
virtual Result OnNopExpr() = 0;
301302
virtual Result OnRethrowExpr(Index depth) = 0;
302303
virtual Result OnReturnExpr() = 0;

include/wabt/expr-visitor.h

+2
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class ExprVisitor::Delegate {
112112
virtual Result OnRefFuncExpr(RefFuncExpr*) = 0;
113113
virtual Result OnRefNullExpr(RefNullExpr*) = 0;
114114
virtual Result OnRefIsNullExpr(RefIsNullExpr*) = 0;
115+
virtual Result OnRefTestExpr(RefTestExpr*) = 0;
115116
virtual Result OnNopExpr(NopExpr*) = 0;
116117
virtual Result OnReturnExpr(ReturnExpr*) = 0;
117118
virtual Result OnReturnCallExpr(ReturnCallExpr*) = 0;
@@ -189,6 +190,7 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate {
189190
Result OnRefFuncExpr(RefFuncExpr*) override { return Result::Ok; }
190191
Result OnRefNullExpr(RefNullExpr*) override { return Result::Ok; }
191192
Result OnRefIsNullExpr(RefIsNullExpr*) override { return Result::Ok; }
193+
Result OnRefTestExpr(RefTestExpr*) override { return Result::Ok; }
192194
Result OnNopExpr(NopExpr*) override { return Result::Ok; }
193195
Result OnReturnExpr(ReturnExpr*) override { return Result::Ok; }
194196
Result OnReturnCallExpr(ReturnCallExpr*) override { return Result::Ok; }

include/wabt/ir.h

+9
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ enum class ExprType {
400400
RefIsNull,
401401
RefFunc,
402402
RefNull,
403+
RefTest,
403404
Rethrow,
404405
Return,
405406
ReturnCall,
@@ -553,6 +554,14 @@ class RefTypeExpr : public ExprMixin<TypeEnum> {
553554
using RefNullExpr = RefTypeExpr<ExprType::RefNull>;
554555
using RefIsNullExpr = ExprMixin<ExprType::RefIsNull>;
555556

557+
class RefTestExpr : public ExprMixin<ExprType::RefTest> {
558+
public:
559+
RefTestExpr(Var type, const Location& loc = Location())
560+
: ExprMixin<ExprType::RefTest>(loc), type(type) {}
561+
562+
Var type;
563+
};
564+
556565
template <ExprType TypeEnum>
557566
class OpcodeExpr : public ExprMixin<TypeEnum> {
558567
public:

include/wabt/opcode.def

+1
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ WABT_OPCODE(___, I32, ___, I32, 0, 0xfc, 0x11, TableFill, "table.fill", "")
264264
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd0, RefNull, "ref.null", "")
265265
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd1, RefIsNull, "ref.is_null", "")
266266
WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd2, RefFunc, "ref.func", "")
267+
WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x14, RefTest, "ref.test", "")
267268

268269
/* Simd opcodes */
269270
WABT_OPCODE(V128, I32, ___, ___, 16, 0xfd, 0x00, V128Load, "v128.load", "")

include/wabt/opcode.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,17 @@ struct Opcode {
8484
Address GetAlignment(Address alignment) const;
8585

8686
static bool IsPrefixByte(uint8_t byte) {
87-
return byte == kMathPrefix || byte == kThreadsPrefix || byte == kSimdPrefix;
87+
return byte == kMathPrefix || byte == kThreadsPrefix || byte == kSimdPrefix || byte == kReferencePrefix;
8888
}
8989

9090
bool IsEnabled(const Features& features) const;
9191
bool IsInvalid() const { return enum_ >= Invalid; }
9292

9393
private:
94+
static constexpr uint32_t kReferencePrefix = 0xfb;
9495
static constexpr uint32_t kMathPrefix = 0xfc;
95-
static constexpr uint32_t kThreadsPrefix = 0xfe;
9696
static constexpr uint32_t kSimdPrefix = 0xfd;
97+
static constexpr uint32_t kThreadsPrefix = 0xfe;
9798

9899
struct Info {
99100
const char* name;

include/wabt/shared-validator.h

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ class SharedValidator {
178178
Result OnRefFunc(const Location&, Var func_var);
179179
Result OnRefIsNull(const Location&);
180180
Result OnRefNull(const Location&, Type type);
181+
Result OnRefTest(const Location&, Var type);
181182
Result OnRethrow(const Location&, Var depth);
182183
Result OnReturnCall(const Location&, Var func_var);
183184
Result OnReturnCallIndirect(const Location&, Var sig_var, Var table_var);

include/wabt/token.def

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ WABT_TOKEN(RefExtern, "ref.extern")
133133
WABT_TOKEN(RefFunc, "ref.func")
134134
WABT_TOKEN(RefIsNull, "ref.is_null")
135135
WABT_TOKEN(RefNull, "ref.null")
136+
WABT_TOKEN(RefTest, "ref.test")
136137
WABT_TOKEN(Rethrow, "rethrow")
137138
WABT_TOKEN(ReturnCallIndirect, "return_call_indirect")
138139
WABT_TOKEN(ReturnCall, "return_call")

include/wabt/type-checker.h

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ class TypeChecker {
118118
Result OnRefFuncExpr(Index func_type, bool force_generic_funcref);
119119
Result OnRefNullExpr(Type type);
120120
Result OnRefIsNullExpr();
121+
Result OnRefTestExpr();
121122
Result OnRethrow(Index depth);
122123
Result OnReturn();
123124
Result OnSelect(const TypeVector& result_types);

src/apply-names.cc

+6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class NameApplier : public ExprVisitor::DelegateNop {
4343
Result OnBrTableExpr(BrTableExpr*) override;
4444
Result OnCallExpr(CallExpr*) override;
4545
Result OnRefFuncExpr(RefFuncExpr*) override;
46+
Result OnRefTestExpr(RefTestExpr*) override;
4647
Result OnCallIndirectExpr(CallIndirectExpr*) override;
4748
Result OnReturnCallExpr(ReturnCallExpr*) override;
4849
Result OnReturnCallIndirectExpr(ReturnCallIndirectExpr*) override;
@@ -423,6 +424,11 @@ Result NameApplier::OnRefFuncExpr(RefFuncExpr* expr) {
423424
return Result::Ok;
424425
}
425426

427+
Result NameApplier::OnRefTestExpr(RefTestExpr* expr) {
428+
CHECK_RESULT(UseNameForFuncTypeVar(&expr->type));
429+
return Result::Ok;
430+
}
431+
426432
Result NameApplier::OnCallIndirectExpr(CallIndirectExpr* expr) {
427433
if (expr->decl.has_func_type) {
428434
CHECK_RESULT(UseNameForFuncTypeVar(&expr->decl.type_var));

src/binary-reader-ir.cc

+8
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ class BinaryReaderIR : public BinaryReaderNop {
249249
Result OnRefFuncExpr(Index func_index) override;
250250
Result OnRefNullExpr(Type type) override;
251251
Result OnRefIsNullExpr() override;
252+
Result OnRefTestExpr(Type type) override;
252253
Result OnNopExpr() override;
253254
Result OnRethrowExpr(Index depth) override;
254255
Result OnReturnExpr() override;
@@ -1160,6 +1161,13 @@ Result BinaryReaderIR::OnRefIsNullExpr() {
11601161
return AppendExpr(std::make_unique<RefIsNullExpr>());
11611162
}
11621163

1164+
Result BinaryReaderIR::OnRefTestExpr(Type type) {
1165+
assert(type.IsIndex());
1166+
Index type_index = type.GetIndex();
1167+
return AppendExpr(
1168+
std::make_unique<RefTestExpr>(Var(type_index, GetLocation())));
1169+
}
1170+
11631171
Result BinaryReaderIR::OnNopExpr() {
11641172
return AppendExpr(std::make_unique<NopExpr>());
11651173
}

src/binary-reader-logging.cc

+1
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,7 @@ DEFINE_INDEX(OnTableSizeExpr)
873873
DEFINE_INDEX_DESC(OnTableFillExpr, "table index")
874874
DEFINE_INDEX(OnRefFuncExpr)
875875
DEFINE_TYPE(OnRefNullExpr)
876+
DEFINE_TYPE(OnRefTestExpr)
876877
DEFINE0(OnRefIsNullExpr)
877878
DEFINE0(OnNopExpr)
878879
DEFINE_INDEX_DESC(OnRethrowExpr, "depth");

src/binary-reader.cc

+7
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,13 @@ Result BinaryReader::ReadInstructions(Offset end_offset, const char* context) {
19251925
CALLBACK(OnOpcodeBare);
19261926
break;
19271927

1928+
case Opcode::RefTest:
1929+
Type type;
1930+
CHECK_RESULT(ReadType(&type, "ref.test type"));
1931+
CALLBACK(OnRefTestExpr, type);
1932+
CALLBACK(OnOpcodeBare);
1933+
break;
1934+
19281935
case Opcode::CallRef:
19291936
CALLBACK(OnCallRefExpr);
19301937
CALLBACK(OnOpcodeBare);

src/binary-writer.cc

+7
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,13 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
10091009
WriteU32Leb128WithReloc(index, "function index", RelocType::FuncIndexLEB);
10101010
break;
10111011
}
1012+
case ExprType::RefTest: {
1013+
WriteOpcode(stream_, Opcode::RefTest);
1014+
WriteType(stream_,
1015+
module_->GetFuncTypeIndex(cast<RefTestExpr>(expr)->type),
1016+
"ref.test type");
1017+
break;
1018+
}
10121019
case ExprType::RefNull: {
10131020
WriteOpcode(stream_, Opcode::RefNull);
10141021
WriteType(stream_, cast<RefNullExpr>(expr)->type, "ref.null type");

src/c-writer.cc

+1
Original file line numberDiff line numberDiff line change
@@ -4148,6 +4148,7 @@ void CWriter::Write(const ExprList& exprs) {
41484148
case ExprType::CallRef:
41494149
case ExprType::ThrowRef:
41504150
case ExprType::TryTable:
4151+
case ExprType::RefTest:
41514152
UNIMPLEMENTED("...");
41524153
break;
41534154
}

src/expr-visitor.cc

+4
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,10 @@ Result ExprVisitor::HandleDefaultState(Expr* expr) {
365365
CHECK_RESULT(delegate_->OnRefIsNullExpr(cast<RefIsNullExpr>(expr)));
366366
break;
367367

368+
case ExprType::RefTest:
369+
CHECK_RESULT(delegate_->OnRefTestExpr(cast<RefTestExpr>(expr)));
370+
break;
371+
368372
case ExprType::Nop:
369373
CHECK_RESULT(delegate_->OnNopExpr(cast<NopExpr>(expr)));
370374
break;

src/interp/binary-reader-interp.cc

+12
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ class BinaryReaderInterp : public BinaryReaderNop {
222222
Result OnRefFuncExpr(Index func_index) override;
223223
Result OnRefNullExpr(Type type) override;
224224
Result OnRefIsNullExpr() override;
225+
Result OnRefTestExpr(Type type) override;
225226
Result OnNopExpr() override;
226227
Result OnRethrowExpr(Index depth) override;
227228
Result OnReturnExpr() override;
@@ -1393,6 +1394,17 @@ Result BinaryReaderInterp::OnRefIsNullExpr() {
13931394
return Result::Ok;
13941395
}
13951396

1397+
Result BinaryReaderInterp::OnRefTestExpr(Type type) {
1398+
int type_index = 0;
1399+
if (type.IsIndex()) {
1400+
type_index = type.GetIndex();
1401+
}
1402+
CHECK_RESULT(
1403+
validator_.OnRefTest(GetLocation(), Var(type_index, GetLocation())));
1404+
istream_.Emit(Opcode::RefTest);
1405+
return Result::Ok;
1406+
}
1407+
13961408
Result BinaryReaderInterp::OnNopExpr() {
13971409
CHECK_RESULT(validator_.OnNop(GetLocation()));
13981410
return Result::Ok;

src/interp/interp.cc

+1
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,7 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) {
18771877
case O::MemoryAtomicNotify:
18781878
case O::MemoryAtomicWait32:
18791879
case O::MemoryAtomicWait64:
1880+
case O::RefTest:
18801881
return TRAP("not implemented");
18811882

18821883
case O::I32AtomicLoad: return DoAtomicLoad<u32>(instr, out_trap);

src/interp/istream.cc

+1
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ Instr Istream::Read(Offset* offset) const {
532532
case Opcode::LocalTee:
533533
case Opcode::MemoryGrow:
534534
case Opcode::TableGet:
535+
case Opcode::RefTest:
535536
// Index immediate, 1 operand.
536537
instr.kind = InstrKind::Imm_Index_Op_1;
537538
instr.imm_u32 = ReadAt<u32>(offset);

src/ir-util.cc

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ ModuleContext::Arities ModuleContext::GetExprArity(const Expr& expr) const {
186186
case ExprType::RefIsNull:
187187
case ExprType::LoadSplat:
188188
case ExprType::LoadZero:
189+
case ExprType::RefTest:
189190
return {1, 1};
190191

191192
case ExprType::Drop:

src/ir.cc

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const char* ExprTypeName[] = {
6363
"RefIsNull",
6464
"RefFunc",
6565
"RefNull",
66+
"RefTest",
6667
"Rethrow",
6768
"Return",
6869
"ReturnCall",

src/lexer-keywords.txt

+1
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ ref.extern, TokenType::RefExtern
566566
ref.func, TokenType::RefFunc, Opcode::RefFunc
567567
ref.is_null, TokenType::RefIsNull, Opcode::RefIsNull
568568
ref.null, TokenType::RefNull, Opcode::RefNull
569+
ref.test, TokenType::RefTest, Opcode::RefTest
569570
register, TokenType::Register
570571
result, TokenType::Result
571572
rethrow, TokenType::Rethrow, Opcode::Rethrow

0 commit comments

Comments
 (0)