@@ -52,11 +52,11 @@ let empty_types () = {tmap = VarMap.empty; tlist = []}
52
52
53
53
type context =
54
54
{types : types ; funcs : space ; imports : space ;
55
- locals : space ; labels : int VarMap .t }
55
+ locals : space ; globals : space ; labels : int VarMap .t }
56
56
57
57
let empty_context () =
58
58
{types = empty_types () ; funcs = empty () ; imports = empty () ;
59
- locals = empty () ; labels = VarMap. empty}
59
+ locals = empty () ; globals = empty () ; labels = VarMap. empty}
60
60
61
61
let enter_func c =
62
62
assert (VarMap. is_empty c.labels);
@@ -73,6 +73,7 @@ let lookup category space x =
73
73
let func c x = lookup " function" c.funcs x
74
74
let import c x = lookup " import" c.imports x
75
75
let local c x = lookup " local" c.locals x
76
+ let global c x = lookup " global" c.globals x
76
77
let label c x =
77
78
try VarMap. find x.it c.labels
78
79
with Not_found -> error x.at (" unknown label " ^ x.it)
@@ -92,6 +93,7 @@ let bind category space x =
92
93
let bind_func c x = bind " function" c.funcs x
93
94
let bind_import c x = bind " import" c.imports x
94
95
let bind_local c x = bind " local" c.locals x
96
+ let bind_global c x = bind " global" c.globals x
95
97
let bind_label c x =
96
98
{c with labels = VarMap. add x.it 0 (VarMap. map ((+ ) 1 ) c.labels)}
97
99
@@ -103,6 +105,7 @@ let anon space n = space.count <- space.count + n
103
105
let anon_func c = anon c.funcs 1
104
106
let anon_import c = anon c.imports 1
105
107
let anon_locals c ts = anon c.locals (List. length ts)
108
+ let anon_global c = anon c.globals 1
106
109
let anon_label c = {c with labels = VarMap. map ((+ ) 1 ) c.labels}
107
110
108
111
let empty_type = {ins = [] ; out = None }
@@ -127,10 +130,11 @@ let implicit_decl c t at =
127
130
% token NAT INT FLOAT TEXT VAR VALUE_TYPE LPAR RPAR
128
131
% token NOP DROP BLOCK IF THEN ELSE SELECT LOOP BR BR_IF BR_TABLE
129
132
% token CALL CALL_IMPORT CALL_INDIRECT RETURN
130
- % token GET_LOCAL SET_LOCAL TEE_LOCAL LOAD STORE OFFSET ALIGN
133
+ % token GET_LOCAL SET_LOCAL TEE_LOCAL GET_GLOBAL SET_GLOBAL
134
+ % token LOAD STORE OFFSET ALIGN
131
135
% token CONST UNARY BINARY COMPARE CONVERT
132
136
% token UNREACHABLE CURRENT_MEMORY GROW_MEMORY
133
- % token FUNC START TYPE PARAM RESULT LOCAL
137
+ % token FUNC START TYPE PARAM RESULT LOCAL GLOBAL
134
138
% token MODULE MEMORY SEGMENT IMPORT EXPORT TABLE
135
139
% token ASSERT_INVALID ASSERT_RETURN ASSERT_RETURN_NAN ASSERT_TRAP INVOKE
136
140
% token INPUT OUTPUT
@@ -262,6 +266,8 @@ expr1 :
262
266
| GET_LOCAL var { fun c -> Get_local ($2 c local) }
263
267
| SET_LOCAL var expr { fun c -> Set_local ($2 c local, $3 c) }
264
268
| TEE_LOCAL var expr { fun c -> Tee_local ($2 c local, $3 c) }
269
+ | GET_GLOBAL var { fun c -> Get_global ($2 c global) }
270
+ | SET_GLOBAL var expr { fun c -> Set_global ($2 c global, $3 c) }
265
271
| LOAD offset align expr { fun c -> $1 ($2, $3, $4 c) }
266
272
| STORE offset align expr expr { fun c -> $1 ($2, $3, $4 c, $5 c) }
267
273
| CONST literal { fun c -> fst (literal $1 $2) }
@@ -350,6 +356,16 @@ export_opt :
350
356
start :
351
357
| LPAR START var RPAR
352
358
{ fun c -> $ 3 c func }
359
+ ;
360
+
361
+ global :
362
+ | LPAR GLOBAL VALUE_TYPE expr RPAR
363
+ { let at = at () in
364
+ fun c -> anon_global c; fun () -> {gtype = $ 3 ; init = $ 4 c} @@ at }
365
+ | LPAR GLOBAL bind_var VALUE_TYPE expr RPAR /* Sugar */
366
+ { let at = at () in
367
+ fun c -> bind_global c $ 3 ; fun () -> {gtype = $ 4 ; init = $ 5 c} @@ at }
368
+ ;
353
369
354
370
segment :
355
371
| LPAR SEGMENT NAT text_list RPAR
@@ -410,11 +426,14 @@ export :
410
426
module_fields :
411
427
| /* empty */
412
428
{ fun c ->
413
- {memory = None ; types = c.types.tlist; funcs = [] ; start = None ; imports = [] ;
414
- exports = [] ; table = [] } }
429
+ {memory = None ; types = c.types.tlist; globals = [] ; funcs = [] ;
430
+ start = None ; imports = [] ; exports = [] ; table = [] } }
415
431
| func module_fields
416
432
{ fun c -> let f = $ 1 c in let m = $ 2 c in let func, exs = f () in
417
433
{m with funcs = func :: m .funcs; exports = exs @ m.exports} }
434
+ | global module_fields
435
+ { fun c -> let g = $ 1 c in let m = $ 2 c in
436
+ {m with globals = g () :: m.globals} }
418
437
| import module_fields
419
438
{ fun c -> let i = $ 1 c in let m = $ 2 c in
420
439
{m with imports = i :: m .imports} }
@@ -423,7 +442,7 @@ module_fields :
423
442
{m with exports = $ 1 c :: m .exports} }
424
443
| table module_fields
425
444
{ fun c -> let m = $ 2 c in
426
- {m with table = ( $ 1 c) @ m.table} }
445
+ {m with table = $ 1 c @ m.table} }
427
446
| type_def module_fields
428
447
{ fun c -> $ 1 c; $ 2 c }
429
448
| memory module_fields
0 commit comments