From 7aec2c301d0f8bc777bb2bec1ef26b982fcd9b73 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 5 Mar 2026 11:29:30 -0800 Subject: [PATCH 1/2] fix --- src/ir/possible-contents.cpp | 3 ++ test/lit/passes/gufa-cont.wast | 92 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 09ae0169674..84affdbf25b 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -1366,6 +1366,9 @@ struct InfoCollector void visitSuspend(Suspend* curr) { // TODO: optimize when possible addRoot(curr); + + // The given values are written to the tag, just the same as a throw. + handleThrow(curr); } template void handleResume(T* curr) { diff --git a/test/lit/passes/gufa-cont.wast b/test/lit/passes/gufa-cont.wast index cb6ea98a173..52047017f8e 100644 --- a/test/lit/passes/gufa-cont.wast +++ b/test/lit/passes/gufa-cont.wast @@ -281,3 +281,95 @@ ) ) ) + +(module + ;; CHECK: (type $func-i32 (func (result i32))) + ;; OPEN_WORLD: (type $func-i32 (func (result i32))) + (type $func (func)) + + (type $func-i32 (func (param i32))) + + ;; CHECK: (type $cont-i32 (cont $func-i32)) + ;; OPEN_WORLD: (type $cont-i32 (cont $func-i32)) + (type $cont (cont $func)) + + ;; CHECK: (type $4 (func (result i32 (ref $cont)))) + + ;; CHECK: (elem declare func $cont $cont-i32) + + (tag $tag (type $func)) + + ;; OPEN_WORLD: (type $4 (func (result i32 (ref $cont)))) + + ;; OPEN_WORLD: (elem declare func $cont $cont-i32) + + ;; OPEN_WORLD: (tag $tag (type $func)) + (tag $tag-i32 (type $func-i32)) + + ;; CHECK: (export "resume" (func $resume)) + + ;; CHECK: (export "resume_throw" (func $resume_throw)) + + ;; CHECK: (export "resume-i32" (func $resume-i32)) + + ;; CHECK: (func $cont (type $func) + ;; CHECK-NEXT: (suspend $tag) + ;; CHECK-NEXT: ) + ;; OPEN_WORLD: (export "resume" (func $resume)) + + ;; OPEN_WORLD: (export "resume_throw" (func $resume_throw)) + + ;; OPEN_WORLD: (export "resume-i32" (func $resume-i32)) + + ;; OPEN_WORLD: (func $cont (type $func) + ;; OPEN_WORLD-NEXT: (suspend $tag) + ;; OPEN_WORLD-NEXT: ) + (func $cont + ;; Helper for below. + (suspend $tag-i32 + (i32.const 1337) + ) + ) + + ;; CHECK: (func $resume (type $func) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $block (result (ref $cont)) + ;; CHECK-NEXT: (resume $cont (on $tag $block) + ;; CHECK-NEXT: (cont.new $cont + ;; CHECK-NEXT: (ref.func $cont) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; OPEN_WORLD: (func $resume (type $func) + ;; OPEN_WORLD-NEXT: (drop + ;; OPEN_WORLD-NEXT: (block $block (result (ref $cont)) + ;; OPEN_WORLD-NEXT: (resume $cont (on $tag $block) + ;; OPEN_WORLD-NEXT: (cont.new $cont + ;; OPEN_WORLD-NEXT: (ref.func $cont) + ;; OPEN_WORLD-NEXT: ) + ;; OPEN_WORLD-NEXT: ) + ;; OPEN_WORLD-NEXT: (return) + ;; OPEN_WORLD-NEXT: ) + ;; OPEN_WORLD-NEXT: ) + ;; OPEN_WORLD-NEXT: ) + (func $resume (export "resume") (result i32) + ;; A continuation is created, it suspends, and we handle that. We can even + ;; infer the suspended value, 1337. + (tuple.extract 2 0 + (block $block (result i32 (ref $cont)) + (resume $cont (on $tag-i32 $block) + (cont.new $cont + (ref.func $cont) + ) + ) + (return + (i32.const 42) + ) + ) + ) + ) +) + From a44e3c5fdf423fff6bf5dffa680d06622c7729da Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 5 Mar 2026 11:31:04 -0800 Subject: [PATCH 2/2] finish --- test/lit/passes/gufa-cont.wast | 70 ++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/test/lit/passes/gufa-cont.wast b/test/lit/passes/gufa-cont.wast index 52047017f8e..4be884daee1 100644 --- a/test/lit/passes/gufa-cont.wast +++ b/test/lit/passes/gufa-cont.wast @@ -283,46 +283,54 @@ ) (module - ;; CHECK: (type $func-i32 (func (result i32))) - ;; OPEN_WORLD: (type $func-i32 (func (result i32))) + ;; CHECK: (type $func (func)) + ;; OPEN_WORLD: (type $func (func)) (type $func (func)) + ;; CHECK: (type $cont (cont $func)) + (type $cont (cont $func)) + + ;; CHECK: (type $func-i32 (func (param i32))) + ;; OPEN_WORLD: (type $cont (cont $func)) + + ;; OPEN_WORLD: (type $func-i32 (func (param i32))) (type $func-i32 (func (param i32))) - ;; CHECK: (type $cont-i32 (cont $func-i32)) - ;; OPEN_WORLD: (type $cont-i32 (cont $func-i32)) - (type $cont (cont $func)) + + + ;; CHECK: (type $3 (func (result i32))) ;; CHECK: (type $4 (func (result i32 (ref $cont)))) - ;; CHECK: (elem declare func $cont $cont-i32) + ;; CHECK: (elem declare func $cont) - (tag $tag (type $func)) + ;; CHECK: (tag $tag (type $func)) + ;; OPEN_WORLD: (type $3 (func (result i32))) ;; OPEN_WORLD: (type $4 (func (result i32 (ref $cont)))) - ;; OPEN_WORLD: (elem declare func $cont $cont-i32) + ;; OPEN_WORLD: (elem declare func $cont) ;; OPEN_WORLD: (tag $tag (type $func)) + (tag $tag (type $func)) + + ;; CHECK: (tag $tag-i32 (type $func-i32) (param i32)) + ;; OPEN_WORLD: (tag $tag-i32 (type $func-i32) (param i32)) (tag $tag-i32 (type $func-i32)) ;; CHECK: (export "resume" (func $resume)) - ;; CHECK: (export "resume_throw" (func $resume_throw)) - - ;; CHECK: (export "resume-i32" (func $resume-i32)) - ;; CHECK: (func $cont (type $func) - ;; CHECK-NEXT: (suspend $tag) + ;; CHECK-NEXT: (suspend $tag-i32 + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; OPEN_WORLD: (export "resume" (func $resume)) - ;; OPEN_WORLD: (export "resume_throw" (func $resume_throw)) - - ;; OPEN_WORLD: (export "resume-i32" (func $resume-i32)) - ;; OPEN_WORLD: (func $cont (type $func) - ;; OPEN_WORLD-NEXT: (suspend $tag) + ;; OPEN_WORLD-NEXT: (suspend $tag-i32 + ;; OPEN_WORLD-NEXT: (i32.const 1337) + ;; OPEN_WORLD-NEXT: ) ;; OPEN_WORLD-NEXT: ) (func $cont ;; Helper for below. @@ -331,29 +339,35 @@ ) ) - ;; CHECK: (func $resume (type $func) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $block (result (ref $cont)) - ;; CHECK-NEXT: (resume $cont (on $tag $block) + ;; CHECK: (func $resume (type $3) (result i32) + ;; CHECK-NEXT: (tuple.drop 2 + ;; CHECK-NEXT: (block $block (type $4) (result i32 (ref $cont)) + ;; CHECK-NEXT: (resume $cont (on $tag-i32 $block) ;; CHECK-NEXT: (cont.new $cont ;; CHECK-NEXT: (ref.func $cont) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: ) - ;; OPEN_WORLD: (func $resume (type $func) - ;; OPEN_WORLD-NEXT: (drop - ;; OPEN_WORLD-NEXT: (block $block (result (ref $cont)) - ;; OPEN_WORLD-NEXT: (resume $cont (on $tag $block) + ;; OPEN_WORLD: (func $resume (type $3) (result i32) + ;; OPEN_WORLD-NEXT: (tuple.drop 2 + ;; OPEN_WORLD-NEXT: (block $block (type $4) (result i32 (ref $cont)) + ;; OPEN_WORLD-NEXT: (resume $cont (on $tag-i32 $block) ;; OPEN_WORLD-NEXT: (cont.new $cont ;; OPEN_WORLD-NEXT: (ref.func $cont) ;; OPEN_WORLD-NEXT: ) ;; OPEN_WORLD-NEXT: ) - ;; OPEN_WORLD-NEXT: (return) + ;; OPEN_WORLD-NEXT: (return + ;; OPEN_WORLD-NEXT: (i32.const 42) + ;; OPEN_WORLD-NEXT: ) ;; OPEN_WORLD-NEXT: ) ;; OPEN_WORLD-NEXT: ) + ;; OPEN_WORLD-NEXT: (i32.const 1337) ;; OPEN_WORLD-NEXT: ) (func $resume (export "resume") (result i32) ;; A continuation is created, it suspends, and we handle that. We can even