Skip to content

Commit 0d30888

Browse files
authored
feat(compiler): Add ability to match on low level wasm types (#1588)
1 parent 8d465b7 commit 0d30888

File tree

6 files changed

+877
-18
lines changed

6 files changed

+877
-18
lines changed

compiler/src/middle_end/matchcomp.re

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ and switch_type =
8888
| ArraySwitch
8989

9090
and equality_type =
91-
| PhysicalEquality
91+
| PhysicalEquality(wasm_repr)
9292
| StructuralEquality;
9393

9494
type conversion_result = {
@@ -544,13 +544,10 @@ let equality_type =
544544
| Const_void
545545
| Const_bool(_)
546546
| Const_char(_)
547-
| Const_wasmi32(_) => PhysicalEquality
548-
| Const_wasmi64(_)
549-
| Const_wasmf32(_)
550-
| Const_wasmf64(_) =>
551-
failwith(
552-
"Pattern matching not supported on low-level i64/f32/f64 types.",
553-
);
547+
| Const_wasmi32(_) => PhysicalEquality(WasmI32)
548+
| Const_wasmi64(_) => PhysicalEquality(WasmI64)
549+
| Const_wasmf32(_) => PhysicalEquality(WasmF32)
550+
| Const_wasmf64(_) => PhysicalEquality(WasmF64);
554551

555552
let rec compile_matrix = mtx =>
556553
switch (mtx) {
@@ -878,7 +875,25 @@ module MatchTreeCompiler = {
878875
let equality_op =
879876
switch (equality_type) {
880877
| StructuralEquality => Eq
881-
| PhysicalEquality => Is
878+
| PhysicalEquality(WasmI32) => Is
879+
| PhysicalEquality(WasmI64) =>
880+
WasmBinaryI64({
881+
wasm_op: Op_eq_int64,
882+
arg_types: (Wasm_int64, Wasm_int64),
883+
ret_type: Grain_bool,
884+
})
885+
| PhysicalEquality(WasmF32) =>
886+
WasmBinaryF32({
887+
wasm_op: Op_eq_float32,
888+
arg_types: (Wasm_float32, Wasm_float32),
889+
ret_type: Grain_bool,
890+
})
891+
| PhysicalEquality(WasmF64) =>
892+
WasmBinaryF64({
893+
wasm_op: Op_eq_float64,
894+
arg_types: (Wasm_float64, Wasm_float64),
895+
ret_type: Grain_bool,
896+
})
882897
};
883898
let (const, const_setup) =
884899
switch (helpConst(const)) {
@@ -1158,23 +1173,24 @@ module MatchTreeCompiler = {
11581173
let collect_bindings = (~mut_boxing=false, ~global=Nonglobal, branches) => {
11591174
let rec collect_bindings = pat => {
11601175
let bind = id => {
1176+
let allocation_type = get_allocation_type(pat.pat_env, pat.pat_type);
11611177
// Dummy value to be filled in during matching
1162-
let dummy_value = Imm.const(Const_wasmi32(0l));
1178+
let dummy_value =
1179+
switch (allocation_type) {
1180+
| Managed
1181+
| Unmanaged(WasmI32) => Imm.const(Const_wasmi32(0l))
1182+
| Unmanaged(WasmI64) => Imm.const(Const_wasmi64(0L))
1183+
| Unmanaged(WasmF32) => Imm.const(Const_wasmf32(0.))
1184+
| Unmanaged(WasmF64) => Imm.const(Const_wasmf64(0.))
1185+
};
11631186
if (mut_boxing) {
11641187
BLetMut(
11651188
id,
11661189
Comp.prim1(~allocation_type=Managed, BoxBind, dummy_value),
11671190
Nonglobal,
11681191
);
11691192
} else {
1170-
BLetMut(
1171-
id,
1172-
Comp.imm(
1173-
~allocation_type=get_allocation_type(pat.pat_env, pat.pat_type),
1174-
dummy_value,
1175-
),
1176-
global,
1177-
);
1193+
BLetMut(id, Comp.imm(~allocation_type, dummy_value), global);
11781194
};
11791195
};
11801196
switch (pat.pat_desc) {
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
pattern matching › low_level_constant_match_2
2+
(module
3+
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
4+
(type $none_=>_i32 (func (result i32)))
5+
(type $none_=>_none (func))
6+
(import \"_grainEnv\" \"mem\" (memory $0 0))
7+
(import \"_grainEnv\" \"tbl\" (table $tbl 0 funcref))
8+
(import \"_grainEnv\" \"relocBase\" (global $relocBase_0 i32))
9+
(import \"_grainEnv\" \"moduleRuntimeId\" (global $moduleRuntimeId_0 i32))
10+
(import \"GRAIN$MODULE$runtime/gc\" \"GRAIN$EXPORT$incRef\" (global $GRAIN$EXPORT$incRef_0 (mut i32)))
11+
(import \"GRAIN$MODULE$pervasives\" \"GRAIN$EXPORT$print\" (global $print_1134 (mut i32)))
12+
(import \"GRAIN$MODULE$runtime/gc\" \"incRef\" (func $incRef_0 (param i32 i32) (result i32)))
13+
(import \"GRAIN$MODULE$pervasives\" \"print\" (func $print_1134 (param i32 i32) (result i32)))
14+
(global $GRAIN$TABLE_SIZE i32 (i32.const 0))
15+
(elem $elem (global.get $relocBase_0))
16+
(export \"memory\" (memory $0))
17+
(export \"_gmain\" (func $_gmain))
18+
(export \"_start\" (func $_start))
19+
(export \"GRAIN$TABLE_SIZE\" (global $GRAIN$TABLE_SIZE))
20+
(func $_gmain (result i32)
21+
(local $0 i32)
22+
(local $1 i32)
23+
(local $2 i32)
24+
(local $3 i64)
25+
(local $4 f32)
26+
(local $5 f64)
27+
(local $6 i32)
28+
(local $7 i32)
29+
(local $8 i32)
30+
(local $9 i32)
31+
(return
32+
(block $cleanup_locals.26 (result i32)
33+
(local.set $0
34+
(block $compile_block.25 (result i32)
35+
(block $compile_store.2
36+
(local.set $6
37+
(select
38+
(i32.const -2)
39+
(i32.const 2147483646)
40+
(i64.eq
41+
(i64.const 1)
42+
(i64.const 0)
43+
)
44+
)
45+
)
46+
(block $do_backpatches.1
47+
)
48+
)
49+
(block $compile_store.14
50+
(local.set $7
51+
(if (result i32)
52+
(i32.shr_u
53+
(local.get $6)
54+
(i32.const 31)
55+
)
56+
(block $compile_block.3 (result i32)
57+
(i32.const 1)
58+
)
59+
(block $compile_block.12 (result i32)
60+
(block $compile_store.5
61+
(local.set $7
62+
(select
63+
(i32.const -2)
64+
(i32.const 2147483646)
65+
(i64.eq
66+
(i64.const 1)
67+
(i64.const 1)
68+
)
69+
)
70+
)
71+
(block $do_backpatches.4
72+
)
73+
)
74+
(if (result i32)
75+
(i32.shr_u
76+
(local.get $7)
77+
(i32.const 31)
78+
)
79+
(block $compile_block.6 (result i32)
80+
(i32.const 3)
81+
)
82+
(block $compile_block.11 (result i32)
83+
(block $compile_store.8
84+
(local.set $8
85+
(select
86+
(i32.const -2)
87+
(i32.const 2147483646)
88+
(i64.eq
89+
(i64.const 1)
90+
(i64.const 2)
91+
)
92+
)
93+
)
94+
(block $do_backpatches.7
95+
)
96+
)
97+
(if (result i32)
98+
(i32.shr_u
99+
(local.get $8)
100+
(i32.const 31)
101+
)
102+
(block $compile_block.9 (result i32)
103+
(i32.const 5)
104+
)
105+
(block $compile_block.10 (result i32)
106+
(i32.const 7)
107+
)
108+
)
109+
)
110+
)
111+
)
112+
)
113+
)
114+
(block $do_backpatches.13
115+
)
116+
)
117+
(block $compile_store.22
118+
(local.set $8
119+
(block $switch.15_outer (result i32)
120+
(block $switch.15_branch_0 (result i32)
121+
(drop
122+
(block $switch.15_branch_1 (result i32)
123+
(drop
124+
(block $switch.15_branch_2 (result i32)
125+
(drop
126+
(block $switch.15_branch_3 (result i32)
127+
(drop
128+
(block $switch.15_branch_4 (result i32)
129+
(drop
130+
(block $switch.15_default (result i32)
131+
(br_table $switch.15_branch_1 $switch.15_branch_2 $switch.15_branch_3 $switch.15_branch_4 $switch.15_default $switch.15_default
132+
(i32.const 0)
133+
(i32.shr_s
134+
(local.get $7)
135+
(i32.const 1)
136+
)
137+
)
138+
)
139+
)
140+
(br $switch.15_outer
141+
(block $compile_block.20 (result i32)
142+
(unreachable)
143+
)
144+
)
145+
)
146+
)
147+
(br $switch.15_outer
148+
(block $compile_block.19 (result i32)
149+
(i32.const 2147483646)
150+
)
151+
)
152+
)
153+
)
154+
(br $switch.15_outer
155+
(block $compile_block.18 (result i32)
156+
(i32.const 2147483646)
157+
)
158+
)
159+
)
160+
)
161+
(br $switch.15_outer
162+
(block $compile_block.17 (result i32)
163+
(i32.const -2)
164+
)
165+
)
166+
)
167+
)
168+
(br $switch.15_outer
169+
(block $compile_block.16 (result i32)
170+
(i32.const 2147483646)
171+
)
172+
)
173+
)
174+
)
175+
)
176+
(block $do_backpatches.21
177+
)
178+
)
179+
(block $compile_store.24
180+
(local.set $9
181+
(call $print_1134
182+
(call $incRef_0
183+
(global.get $GRAIN$EXPORT$incRef_0)
184+
(global.get $print_1134)
185+
)
186+
(local.get $8)
187+
)
188+
)
189+
(block $do_backpatches.23
190+
)
191+
)
192+
(i32.const 1)
193+
)
194+
)
195+
(local.get $0)
196+
)
197+
)
198+
)
199+
(func $_start
200+
(drop
201+
(call $_gmain)
202+
)
203+
)
204+
;; custom section \"cmi\", size 258
205+
)

0 commit comments

Comments
 (0)