diff --git a/src/passes/TranslateEH.cpp b/src/passes/TranslateEH.cpp index 1b15f6db533..fff528660d7 100644 --- a/src/passes/TranslateEH.cpp +++ b/src/passes/TranslateEH.cpp @@ -313,11 +313,9 @@ struct TranslateEHOldToNew curr->body, delegateBrTarget, brToOuter, Type(HeapType::exn, Nullable)); } curr->body = builder.makeThrowRef(innerBody); - assert(outerBlock->list.empty()); - outerBlock->list.push_back(curr->body); } - void processDelegate(Try* curr) { + void processDelegate(Try* curr, Block* outerBlock) { Builder builder(*getModule()); // Convert // (try @@ -337,11 +335,20 @@ struct TranslateEHOldToNew // processDelegateTarget(), when we process the 'try' that is the target of // this try~delegate. See processDelegateTarget() for how the rest of the // conversion is completed. - replaceCurrent( + auto* tryTable = builder.makeTryTable(curr->body, {Name()}, {delegateTargetToBrTarget[curr->delegateTarget]}, - {true})); + {true}); + // If we need an outer block for other reasons (if this is a target of a + // delegate), we insert the new try_table into it. If not we just replace + // the current try with the new try_table. + if (outerBlock) { + outerBlock->list.push_back(tryTable); + replaceCurrent(outerBlock); + } else { + replaceCurrent(tryTable); + } } void processCatches(Try* curr, Block* outerBlock) { @@ -667,12 +674,10 @@ struct TranslateEHOldToNew items.swap(nextItems); } - // In case this was already popuated in processDelegateTarget(), we empty - // the block to repopulate with the newly created structures here - outerBlock->list.clear(); for (auto* item : items) { outerBlock->list.push_back(item); } + replaceCurrent(outerBlock); } void visitTry(Try* curr) { @@ -689,14 +694,10 @@ struct TranslateEHOldToNew processDelegateTarget(curr, outerBlock); } if (curr->isDelegate()) { - processDelegate(curr); + processDelegate(curr, outerBlock); } else { // try-catch or catch-less try processCatches(curr, outerBlock); } - - if (outerBlock) { - replaceCurrent(outerBlock); - } } void visitPop(Pop* curr) { diff --git a/test/lit/passes/translate-eh-old-to-new.wast b/test/lit/passes/translate-eh-old-to-new.wast index 0b81a1272b8..20271714663 100644 --- a/test/lit/passes/translate-eh-old-to-new.wast +++ b/test/lit/passes/translate-eh-old-to-new.wast @@ -1201,7 +1201,7 @@ ) ;; CHECK: (func $deletate-target-outer-try-unreachable (type $1) - ;; CHECK-NEXT: (block $outer1 + ;; CHECK-NEXT: (try_table ;; CHECK-NEXT: (throw_ref ;; CHECK-NEXT: (block $l00 (result exnref) ;; CHECK-NEXT: (try_table (catch_all_ref $l00) @@ -1357,12 +1357,14 @@ ;; CHECK-NEXT: (throw_ref ;; CHECK-NEXT: (block $__binaryen_delegate_caller_target0 (result exnref) ;; CHECK-NEXT: (block $outer2 - ;; CHECK-NEXT: (throw_ref - ;; CHECK-NEXT: (block $l01 (result exnref) - ;; CHECK-NEXT: (try_table (catch_all_ref $l01) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (try_table (catch_all_ref $__binaryen_delegate_caller_target0) + ;; CHECK-NEXT: (throw_ref + ;; CHECK-NEXT: (block $l01 (result exnref) + ;; CHECK-NEXT: (try_table (catch_all_ref $l01) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $outer2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $outer2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1389,11 +1391,13 @@ ;; CHECK-NEXT: (block $__binaryen_delegate_caller_target0 (result exnref) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (block $outer2 (result i32) - ;; CHECK-NEXT: (throw_ref - ;; CHECK-NEXT: (block $l01 (result exnref) - ;; CHECK-NEXT: (br $outer2 - ;; CHECK-NEXT: (try_table (result i32) (catch_all_ref $l01) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (try_table (catch_all_ref $__binaryen_delegate_caller_target0) + ;; CHECK-NEXT: (throw_ref + ;; CHECK-NEXT: (block $l01 (result exnref) + ;; CHECK-NEXT: (br $outer2 + ;; CHECK-NEXT: (try_table (result i32) (catch_all_ref $l01) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: )