Skip to content

Commit 598b03e

Browse files
authored
[EH] Handle pops in Directize (#8666)
1 parent e29edae commit 598b03e

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

src/passes/Directize.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "call-utils.h"
3333
#include "ir/drop.h"
34+
#include "ir/eh-utils.h"
3435
#include "ir/find_all.h"
3536
#include "ir/table-utils.h"
3637
#include "ir/utils.h"
@@ -52,6 +53,8 @@ struct FunctionDirectizer : public WalkerPass<PostWalker<FunctionDirectizer>> {
5253

5354
FunctionDirectizer(const TableUtils::TableInfoMap& tables) : tables(tables) {}
5455

56+
bool optimized = false;
57+
5558
void visitCallIndirect(CallIndirect* curr) {
5659
auto& table = tables.at(curr->table);
5760
if (!table.canOptimizeByEntry()) {
@@ -62,6 +65,7 @@ struct FunctionDirectizer : public WalkerPass<PostWalker<FunctionDirectizer>> {
6265
std::vector<Expression*> operands(curr->operands.begin(),
6366
curr->operands.end());
6467
makeDirectCall(operands, curr->target, table, curr);
68+
optimized = true;
6569
return;
6670
}
6771

@@ -74,15 +78,25 @@ struct FunctionDirectizer : public WalkerPass<PostWalker<FunctionDirectizer>> {
7478
*getFunction(),
7579
*getModule())) {
7680
replaceCurrent(calls);
81+
optimized = true;
7782
// Note that types may have changed, as the utility here can add locals
7883
// which require fixups if they are non-nullable, for example.
7984
changedTypes = true;
8085
return;
8186
}
8287
}
8388

89+
bool hasTry = false;
90+
91+
void visitTry(Try* curr) { hasTry = true; }
92+
8493
void doWalkFunction(Function* func) {
8594
WalkerPass<PostWalker<FunctionDirectizer>>::doWalkFunction(func);
95+
96+
if (optimized && hasTry) {
97+
EHUtils::handleBlockNestedPops(func, *getModule());
98+
}
99+
86100
if (changedTypes) {
87101
ReFinalize().walkFunctionInModule(func, getModule());
88102
}

test/lit/passes/directize_all-features.wast

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,3 +1867,89 @@
18671867
)
18681868
)
18691869
)
1870+
1871+
(module
1872+
;; CHECK: (type $0 (func (param i32)))
1873+
1874+
;; CHECK: (type $ii (func (param i32) (result i32)))
1875+
;; IMMUT: (type $0 (func (param i32)))
1876+
1877+
;; IMMUT: (type $ii (func (param i32) (result i32)))
1878+
(type $ii (func (param i32) (result i32)))
1879+
1880+
;; CHECK: (table $0 10 10 funcref)
1881+
1882+
;; CHECK: (elem $0 (i32.const 0) $0)
1883+
1884+
;; CHECK: (tag $e (type $0) (param i32))
1885+
;; IMMUT: (table $0 10 10 funcref)
1886+
1887+
;; IMMUT: (elem $0 (i32.const 0) $0)
1888+
1889+
;; IMMUT: (tag $e (type $0) (param i32))
1890+
(tag $e (param i32))
1891+
1892+
(table 10 10 funcref)
1893+
1894+
(elem (i32.const 0) $0)
1895+
1896+
;; CHECK: (func $0 (type $ii) (param $0 i32) (result i32)
1897+
;; CHECK-NEXT: (local $1 i32)
1898+
;; CHECK-NEXT: (try
1899+
;; CHECK-NEXT: (do
1900+
;; CHECK-NEXT: )
1901+
;; CHECK-NEXT: (catch $e
1902+
;; CHECK-NEXT: (local.set $1
1903+
;; CHECK-NEXT: (pop i32)
1904+
;; CHECK-NEXT: )
1905+
;; CHECK-NEXT: (drop
1906+
;; CHECK-NEXT: (block
1907+
;; CHECK-NEXT: (drop
1908+
;; CHECK-NEXT: (local.get $1)
1909+
;; CHECK-NEXT: )
1910+
;; CHECK-NEXT: (unreachable)
1911+
;; CHECK-NEXT: )
1912+
;; CHECK-NEXT: )
1913+
;; CHECK-NEXT: )
1914+
;; CHECK-NEXT: )
1915+
;; CHECK-NEXT: (i32.const 42)
1916+
;; CHECK-NEXT: )
1917+
;; IMMUT: (func $0 (type $ii) (param $0 i32) (result i32)
1918+
;; IMMUT-NEXT: (local $1 i32)
1919+
;; IMMUT-NEXT: (try
1920+
;; IMMUT-NEXT: (do
1921+
;; IMMUT-NEXT: )
1922+
;; IMMUT-NEXT: (catch $e
1923+
;; IMMUT-NEXT: (local.set $1
1924+
;; IMMUT-NEXT: (pop i32)
1925+
;; IMMUT-NEXT: )
1926+
;; IMMUT-NEXT: (drop
1927+
;; IMMUT-NEXT: (block
1928+
;; IMMUT-NEXT: (drop
1929+
;; IMMUT-NEXT: (local.get $1)
1930+
;; IMMUT-NEXT: )
1931+
;; IMMUT-NEXT: (unreachable)
1932+
;; IMMUT-NEXT: )
1933+
;; IMMUT-NEXT: )
1934+
;; IMMUT-NEXT: )
1935+
;; IMMUT-NEXT: )
1936+
;; IMMUT-NEXT: (i32.const 42)
1937+
;; IMMUT-NEXT: )
1938+
(func $0 (param i32) (result i32)
1939+
(try
1940+
(do)
1941+
(catch $e
1942+
;; This is out of bounds (100 is far too large), so this will trap. We emit
1943+
;; a block with the pop, and must handle that properly.
1944+
(drop
1945+
(call_indirect (type $ii)
1946+
(pop i32)
1947+
(i32.const 100)
1948+
)
1949+
)
1950+
)
1951+
)
1952+
(i32.const 42)
1953+
)
1954+
)
1955+

0 commit comments

Comments
 (0)