Skip to content

Commit cd67924

Browse files
committed
Allow storing values into a global variable with an explicit type
1 parent 97f8f23 commit cd67924

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

compiler/lib-wasm/code_generation.ml

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,27 @@ let placeholder_value typ f =
585585

586586
let array_placeholder typ = placeholder_value typ (fun typ -> ArrayNewFixed (typ, []))
587587

588+
let default_value val_typ st =
589+
match val_typ with
590+
| W.Ref { typ = I31 | Eq | Any; _ } -> (W.RefI31 (Const (I32 0l)), val_typ, None), st
591+
| W.Ref { typ = Type typ; nullable = false } -> (
592+
match (Var.Hashtbl.find st.context.types typ).typ with
593+
| Array _ ->
594+
(let* placeholder = array_placeholder typ in
595+
return (placeholder, val_typ, None))
596+
st
597+
| Struct _ | Func _ ->
598+
( ( W.RefNull (Type typ)
599+
, W.Ref { typ = Type typ; nullable = true }
600+
, Some { W.typ = Type typ; nullable = false } )
601+
, st ))
602+
| I32 -> (Const (I32 0l), val_typ, None), st
603+
| F32 -> (Const (F32 0.), val_typ, None), st
604+
| I64 -> (Const (I64 0L), val_typ, None), st
605+
| F64 -> (Const (F64 0.), val_typ, None), st
606+
| W.Ref { nullable = true; _ }
607+
| W.Ref { typ = Func | Extern | Struct | Array | None_; _ } -> assert false
608+
588609
let rec store ?(always = false) ?typ x e =
589610
let* e = e in
590611
match e with
@@ -599,23 +620,26 @@ let rec store ?(always = false) ?typ x e =
599620
let* b = should_make_global x in
600621
if b
601622
then
602-
let* typ =
603-
match typ with
604-
| Some typ -> return typ
605-
| None -> value_type
606-
in
607623
let* () =
608624
let* b = global_is_registered x in
609625
if b
610626
then return ()
611627
else
612-
register_global
613-
~constant:true
614-
x
615-
{ mut = true; typ }
616-
(W.RefI31 (Const (I32 0l)))
628+
let* typ =
629+
match typ with
630+
| Some typ -> return typ
631+
| None -> value_type
632+
in
633+
let* default, typ', cast = default_value typ in
634+
let* () =
635+
register_constant
636+
x
637+
(match cast with
638+
| Some typ -> W.RefCast (typ, W.GlobalGet x)
639+
| None -> W.GlobalGet x)
640+
in
641+
register_global ~constant:true x { mut = true; typ = typ' } default
617642
in
618-
let* () = register_constant x (W.GlobalGet x) in
619643
instr (GlobalSet (x, e))
620644
else
621645
let* i = add_var ?typ x in

0 commit comments

Comments
 (0)