@@ -35,14 +35,31 @@ module Type = struct
3535 ; typ = W. Array { mut = true ; typ = Value value }
3636 })
3737
38- let string_type =
39- register_type " string " (fun () ->
38+ let bytes_type =
39+ register_type " bytes " (fun () ->
4040 return
4141 { supertype = None
4242 ; final = true
4343 ; typ = W. Array { mut = true ; typ = Packed I8 }
4444 })
4545
46+ let string_type =
47+ register_type " string" (fun () ->
48+ return
49+ (if Config.Flag. use_js_string ()
50+ then
51+ { supertype = None
52+ ; final = true
53+ ; typ =
54+ W. Struct
55+ [ { mut = false ; typ = Value (Ref { nullable = true ; typ = Any }) } ]
56+ }
57+ else
58+ { supertype = None
59+ ; final = true
60+ ; typ = W. Array { mut = true ; typ = Packed I8 }
61+ }))
62+
4663 let float_type =
4764 register_type " float" (fun () ->
4865 return
@@ -794,15 +811,50 @@ module Memory = struct
794811 wasm_array_set ~ty: Type. float_array_type (load a) (load i) (unbox_float (load v)))
795812
796813 let bytes_length e =
797- let * ty = Type. string_type in
814+ let * ty = Type. bytes_type in
798815 let * e = wasm_cast ty e in
799816 return (W. ArrayLen e)
800817
801818 let bytes_get e e' =
802- Value. val_int (wasm_array_get ~ty: Type. string_type e (Value. int_val e'))
819+ Value. val_int (wasm_array_get ~ty: Type. bytes_type e (Value. int_val e'))
803820
804821 let bytes_set e e' e'' =
805- wasm_array_set ~ty: Type. string_type e (Value. int_val e') (Value. int_val e'')
822+ wasm_array_set ~ty: Type. bytes_type e (Value. int_val e') (Value. int_val e'')
823+
824+ let string_value e =
825+ let * string = Type. string_type in
826+ let * e = wasm_struct_get string (wasm_cast string e) 0 in
827+ return (W. ExternConvertAny e)
828+
829+ let string_length e =
830+ if Config.Flag. use_js_string ()
831+ then
832+ let * f =
833+ register_import
834+ ~import_module: " wasm:js-string"
835+ ~name: " length"
836+ (Fun { W. params = [ Ref { nullable = true ; typ = Extern } ]; result = [ I32 ] })
837+ in
838+ let * e = string_value e in
839+ return (W. Call (f, [ e ]))
840+ else bytes_length e
841+
842+ let string_get e e' =
843+ if Config.Flag. use_js_string ()
844+ then
845+ let * f =
846+ register_import
847+ ~import_module: " wasm:js-string"
848+ ~name: " charCodeAt"
849+ (Fun
850+ { W. params = [ Ref { nullable = true ; typ = Extern }; I32 ]
851+ ; result = [ I32 ]
852+ })
853+ in
854+ let * e = string_value e in
855+ let * e' = Value. int_val e' in
856+ Value. val_int (return (W. Call (f, [ e; e' ])))
857+ else bytes_get e e'
806858
807859 let field e idx = wasm_array_get e (Arith. const (Int32. of_int (idx + 1 )))
808860
@@ -929,6 +981,21 @@ module Constant = struct
929981 | Const_named of string
930982 | Mutated
931983
984+ let translate_js_string s =
985+ let * i = register_string s in
986+ let * x =
987+ let * name = unit_name in
988+ register_import
989+ ~import_module:
990+ (match name with
991+ | None -> " strings"
992+ | Some name -> name ^ " .strings" )
993+ ~name: (string_of_int i)
994+ (Global { mut = false ; typ = Ref { nullable = false ; typ = Any } })
995+ in
996+ let * ty = Type. js_type in
997+ return (Const_named (" str_" ^ s), W. StructNew (ty, [ GlobalGet x ]))
998+
932999 let rec translate_rec c =
9331000 match c with
9341001 | Code. Int i -> return (Const , W. RefI31 (Const (I32 (Targetint. to_int32 i))))
@@ -987,38 +1054,29 @@ module Constant = struct
9871054 | Utf (Utf8 s ) -> str_js_utf8 s
9881055 | Byte s -> str_js_byte s
9891056 in
990- let * i = register_string s in
991- let * x =
992- let * name = unit_name in
993- register_import
994- ~import_module:
995- (match name with
996- | None -> " strings"
997- | Some name -> name ^ " .strings" )
998- ~name: (string_of_int i)
999- (Global { mut = false ; typ = Ref { nullable = false ; typ = Any } })
1000- in
1001- let * ty = Type. js_type in
1002- return (Const_named (" str_" ^ s), W. StructNew (ty, [ GlobalGet x ]))
1057+ translate_js_string s
10031058 | String s ->
1004- let * ty = Type. string_type in
1005- if String. length s > = string_length_threshold
1006- then
1007- let name = Code.Var. fresh_n " string" in
1008- let * () = register_data_segment name s in
1009- return
1010- ( Mutated
1011- , W. ArrayNewData
1012- (ty, name, Const (I32 0l ), Const (I32 (Int32. of_int (String. length s))))
1013- )
1059+ if Config.Flag. use_js_string ()
1060+ then translate_js_string (str_js_byte s)
10141061 else
1015- let l =
1016- String. fold_right
1017- ~f: (fun c r -> W. Const (I32 (Int32. of_int (Char. code c))) :: r)
1018- s
1019- ~init: []
1020- in
1021- return (Const_named (" str_" ^ s), W. ArrayNewFixed (ty, l))
1062+ let * ty = Type. string_type in
1063+ if String. length s > = string_length_threshold
1064+ then
1065+ let name = Code.Var. fresh_n " string" in
1066+ let * () = register_data_segment name s in
1067+ return
1068+ ( Mutated
1069+ , W. ArrayNewData
1070+ (ty, name, Const (I32 0l ), Const (I32 (Int32. of_int (String. length s))))
1071+ )
1072+ else
1073+ let l =
1074+ String. fold_right
1075+ ~f: (fun c r -> W. Const (I32 (Int32. of_int (Char. code c))) :: r)
1076+ s
1077+ ~init: []
1078+ in
1079+ return (Const_named (" str_" ^ s), W. ArrayNewFixed (ty, l))
10221080 | Float f ->
10231081 let * ty = Type. float_type in
10241082 return (Const , W. StructNew (ty, [ Const (F64 f) ]))
0 commit comments