diff options
-rw-r--r-- | src/parser/contexts.h | 11 | ||||
-rw-r--r-- | src/parser/parsers.h | 10 | ||||
-rw-r--r-- | src/wasm-ir-builder.h | 3 | ||||
-rw-r--r-- | src/wasm.h | 1 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 18 | ||||
-rw-r--r-- | test/lit/wat-kitchen-sink.wast | 108 |
6 files changed, 129 insertions, 22 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h index bf6c291e7..4147f7bda 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -398,6 +398,12 @@ struct NullInstrParserCtx { template<typename TypeT> Result<> makeRefTest(Index, TypeT) { return Ok{}; } template<typename TypeT> Result<> makeRefCast(Index, TypeT) { return Ok{}; } + Result<> makeBrOn(Index, LabelIdxT, BrOnOp) { return Ok{}; } + + template<typename TypeT> Result<> makeBrOn(Index, LabelIdxT, BrOnOp, TypeT) { + return Ok{}; + } + template<typename HeapTypeT> Result<> makeStructNew(Index, HeapTypeT) { return Ok{}; } @@ -1290,6 +1296,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeRefCast(type)); } + Result<> + makeBrOn(Index pos, Index label, BrOnOp op, Type castType = Type::none) { + return withLoc(pos, irBuilder.makeBrOn(label, op, castType)); + } + Result<> makeStructNew(Index pos, HeapType type) { return withLoc(pos, irBuilder.makeStructNew(type)); } diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 6b6bb0aa5..e2fb3732a 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -1315,11 +1315,17 @@ template<typename Ctx> Result<> makeRefCast(Ctx& ctx, Index pos) { } template<typename Ctx> Result<> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) { - return ctx.in.err("unimplemented instruction"); + auto label = labelidx(ctx); + CHECK_ERR(label); + return ctx.makeBrOn(pos, *label, onFail ? BrOnNonNull : BrOnNull); } template<typename Ctx> Result<> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) { - return ctx.in.err("unimplemented instruction"); + auto label = labelidx(ctx); + CHECK_ERR(label); + auto type = reftype(ctx); + CHECK_ERR(type); + return ctx.makeBrOn(pos, *label, onFail ? BrOnCastFail : BrOnCast, *type); } template<typename Ctx> diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index c0cd7b4a1..64ee0d62e 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -151,7 +151,8 @@ public: // [[nodiscard]] Result<> makeCallRef(); [[nodiscard]] Result<> makeRefTest(Type type); [[nodiscard]] Result<> makeRefCast(Type type); - // [[nodiscard]] Result<> makeBrOn(); + [[nodiscard]] Result<> + makeBrOn(Index label, BrOnOp op, Type castType = Type::none); [[nodiscard]] Result<> makeStructNew(HeapType type); [[nodiscard]] Result<> makeStructNewDefault(HeapType type); [[nodiscard]] Result<> diff --git a/src/wasm.h b/src/wasm.h index 96c9271fe..dbedc05f4 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1566,6 +1566,7 @@ public: class BrOn : public SpecificExpression<Expression::BrOnId> { public: + BrOn() = default; BrOn(MixedArena& allocator) {} BrOnOp op; diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index c973238e9..cc2bfb433 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -220,18 +220,15 @@ Result<> IRBuilder::visitExpression(Expression* curr) { #define DELEGATE_FIELD_CHILD_VECTOR(id, field) \ WASM_UNREACHABLE("should have called visit" #id " because " #id \ " has child vector " #field); -#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) \ - WASM_UNREACHABLE("should have called visit" #id " because " #id \ - " has scope name use " #field); -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) \ - WASM_UNREACHABLE("should have called visit" #id " because " #id \ - " has scope name use vector " #field); #define DELEGATE_FIELD_INT(id, field) #define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) #define DELEGATE_FIELD_NAME_VECTOR(id, field) +#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) +#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) + #define DELEGATE_FIELD_TYPE(id, field) #define DELEGATE_FIELD_HEAPTYPE(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) @@ -933,7 +930,14 @@ Result<> IRBuilder::makeRefCast(Type type) { return Ok{}; } -// Result<> IRBuilder::makeBrOn() {} +Result<> IRBuilder::makeBrOn(Index label, BrOnOp op, Type castType) { + BrOn curr; + CHECK_ERR(visitBrOn(&curr)); + auto name = getLabelName(label); + CHECK_ERR(name); + push(builder.makeBrOn(op, *name, curr.ref, castType)); + return Ok{}; +} Result<> IRBuilder::makeStructNew(HeapType type) { StructNew curr(wasm.allocator); diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 77c31c7e1..a99cd4c24 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -23,13 +23,13 @@ ;; CHECK: (type $a2 (array (mut f32))) - ;; CHECK: (type $8 (func (param i32))) + ;; CHECK: (type $8 (func (param anyref))) - ;; CHECK: (type $9 (func (param i32 i32 i32))) + ;; CHECK: (type $9 (func (param i32))) - ;; CHECK: (type $10 (func (param v128 i32) (result v128))) + ;; CHECK: (type $10 (func (param i32 i32 i32))) - ;; CHECK: (type $11 (func (param anyref))) + ;; CHECK: (type $11 (func (param v128 i32) (result v128))) ;; CHECK: (rec ;; CHECK-NEXT: (type $s0 (struct )) @@ -234,11 +234,11 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK: (func $f1 (type $8) (param $0 i32) + ;; CHECK: (func $f1 (type $9) (param $0 i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f1 (param i32)) - ;; CHECK: (func $f2 (type $8) (param $x i32) + ;; CHECK: (func $f2 (type $9) (param $x i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f2 (param $x i32)) @@ -1756,7 +1756,7 @@ drop ) - ;; CHECK: (func $select (type $9) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $select (type $10) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $0) @@ -2048,7 +2048,7 @@ i32x4.extract_lane 3 ) - ;; CHECK: (func $simd-replace (type $10) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-replace (type $11) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i32x4.replace_lane 2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2086,7 +2086,7 @@ v128.bitselect ) - ;; CHECK: (func $simd-shift (type $10) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-shift (type $11) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i8x16.shl ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2141,7 +2141,7 @@ v128.store64_lane 3 align=4 0 ) - ;; CHECK: (func $memory-init (type $9) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $memory-init (type $10) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (memory.init $mem-i32 $passive ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2376,7 +2376,7 @@ drop ) - ;; CHECK: (func $ref-test (type $11) (param $0 anyref) + ;; CHECK: (func $ref-test (type $8) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.test i31ref ;; CHECK-NEXT: (local.get $0) @@ -2397,7 +2397,7 @@ drop ) - ;; CHECK: (func $ref-cast (type $11) (param $0 anyref) + ;; CHECK: (func $ref-cast (type $8) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast i31ref ;; CHECK-NEXT: (local.get $0) @@ -2418,6 +2418,90 @@ drop ) + ;; CHECK: (func $br-on-null (type $8) (param $0 anyref) + ;; CHECK-NEXT: (block $label + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (br_on_null $label + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br-on-null (param anyref) + local.get 0 + br_on_null 0 + drop + ) + + ;; CHECK: (func $br-on-non-null (type $8) (param $0 anyref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $label (result (ref any)) + ;; CHECK-NEXT: (br_on_non_null $label + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br-on-non-null (param anyref) + block (result (ref any)) + local.get 0 + br_on_non_null 0 + unreachable + end + drop + ) + + ;; CHECK: (func $br-on-cast (type $8) (param $0 anyref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $label (result i31ref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result (ref any)) + ;; CHECK-NEXT: (br_on_cast $label anyref i31ref + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br-on-cast (param anyref) + block (result i31ref) + block (result (ref any)) + local.get 0 + br_on_cast 1 i31ref + end + unreachable + end + drop + ) + + ;; CHECK: (func $br-on-cast-fail (type $8) (param $0 anyref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $label (result (ref any)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i31ref) + ;; CHECK-NEXT: (br_on_cast_fail $label anyref i31ref + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br-on-cast-fail (param anyref) + block (result (ref any)) + block (result i31ref) + local.get 0 + br_on_cast_fail 1 i31ref + end + unreachable + end + drop + ) + ;; CHECK: (func $struct-new (type $34) (param $0 i32) (param $1 i64) (result (ref $pair)) ;; CHECK-NEXT: (struct.new $pair ;; CHECK-NEXT: (local.get $0) |