From 5bf548b32e30fbae16dde5df703541ca7ac72f15 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 5 Jan 2023 09:48:51 -0600 Subject: [Parser] Parse blocks (#5393) Parse both the folded and unfolded forms of blocks and structure the code to make supporting additional block instructions like if-else and try-catch relatively simple. Parsing block types is extra fun because they may implicitly define new signature heap types via a typeuse, but only if their types are not given by a single result type. To figuring out whether a new type may be introduced in all the relevant parsing stages, always track at least the arity of parsed results. The parser parses block labels, but more work will be required to support branch instructions that use them. --- test/lit/wat-kitchen-sink.wast | 110 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index f2110dc42..889b82fc4 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -9,12 +9,12 @@ ;; CHECK: (type $pair (struct (field (mut i32)) (field (mut i64)))) - ;; CHECK: (type $none_=>_i32 (func (result i32))) - ;; CHECK: (type $ret2 (func (result i32 i32))) (type $ret2 (func (result i32 i32))) (rec + ;; CHECK: (type $none_=>_i32 (func (result i32))) + ;; CHECK: (type $i32_i64_=>_none (func (param i32 i64))) ;; CHECK: (type $a1 (array i64)) @@ -701,6 +701,112 @@ drop ) + ;; CHECK: (func $block (type $void) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (block $l + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $block + nop + block $l (type $void) + nop + nop + nop + end $l + ) + + ;; CHECK: (func $block-folded (type $void) + ;; CHECK-NEXT: (local $scratch (i32 i32)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $scratch + ;; CHECK-NEXT: (block $l (result i32 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (tuple.extract 0 + ;; CHECK-NEXT: (local.get $scratch) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (tuple.extract 1 + ;; CHECK-NEXT: (local.get $scratch) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $block-folded + nop + (block $l (result i32) (result) (result i32) + nop + nop + unreachable + ) + unreachable + ) + + ;; CHECK: (func $block-mix (type $void) + ;; CHECK-NEXT: (local $scratch i32) + ;; CHECK-NEXT: (local $scratch_0 (i32 i32)) + ;; CHECK-NEXT: (local $scratch_1 i32) + ;; CHECK-NEXT: (block $0 + ;; CHECK-NEXT: (local.set $scratch_0 + ;; CHECK-NEXT: (block $1 (result i32 i32) + ;; CHECK-NEXT: (tuple.make + ;; CHECK-NEXT: (block $2 (result i32) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $scratch + ;; CHECK-NEXT: (block $3 (result i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.get $scratch) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $scratch_1 + ;; CHECK-NEXT: (tuple.extract 0 + ;; CHECK-NEXT: (local.get $scratch_0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (tuple.extract 1 + ;; CHECK-NEXT: (local.get $scratch_0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $scratch_1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $block-mix + (block $0 + block $1 (type $ret2) + (block $2 (result i32) + block $3 (result i32) + i32.const 0 + end + nop + ) + i32.const 1 + end $1 + drop + drop + ) + nop + ) ;; CHECK: (func $binary (type $i32_i32_f64_f64_=>_none) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) ;; CHECK-NEXT: (drop -- cgit v1.2.3