@@ -271,6 +271,9 @@ type st =
271271 ; mutable pos : pos
272272 ; variables : value StringMap .t
273273 ; buf : Buffer .t
274+ ; mutable head : int
275+ ; head_buf : Buffer .t
276+ ; mutable id : int (* to generate distinct string id names *)
274277 }
275278
276279let value_type v : typ =
@@ -395,6 +398,11 @@ let insert st s =
395398let pred_position { loc; byte_loc } =
396399 { loc = { loc with pos_cnum = loc.pos_cnum - 1 }; byte_loc = byte_loc - 1 }
397400
401+ let generate_id st _ =
402+ let id = Printf. sprintf " $js$string$%d$" st.id in
403+ st.id < - st.id + 1 ;
404+ id
405+
398406let rec rewrite_list st l = List. iter ~f: (rewrite st) l
399407
400408and rewrite st elt =
@@ -491,35 +499,116 @@ and rewrite st elt =
491499 then raise (Error (position_of_loc loc_value, " Expecting a string" ));
492500 let s = parse_string loc_value value in
493501 write st pos;
502+ if variable_is_set st " use-js-string"
503+ then (
504+ Printf. bprintf
505+ st.head_buf
506+ " (import \"\" %s (global %s$string externref)) "
507+ value
508+ name;
509+ insert
510+ st
511+ (Printf. sprintf
512+ " (global %s (ref eq) (struct.new $string (any.convert_extern (global.get \
513+ %s$string))))"
514+ name
515+ name))
516+ else
517+ insert
518+ st
519+ (Format. asprintf
520+ " (global %s (ref eq) (array.new_fixed $bytes %d%a))"
521+ name
522+ (String. length s)
523+ (fun f s ->
524+ String. iter
525+ ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c))
526+ s)
527+ s);
528+ skip st pos'
529+ | { desc = List [ { desc = Atom " @string" ; _ }; { desc = Atom value; loc = loc_value } ]
530+ ; loc = pos, pos'
531+ } ->
532+ if not (is_string value)
533+ then raise (Error (position_of_loc loc_value, " Expecting a string" ));
534+ let s = parse_string loc_value value in
535+ let name = generate_id st s in
536+ write st pos;
537+ if variable_is_set st " use-js-string"
538+ then (
539+ Printf. bprintf
540+ st.head_buf
541+ " (import \"\" %s (global %s$string externref)) "
542+ value
543+ name;
544+ insert
545+ st
546+ (Printf. sprintf
547+ " (struct.new $string (any.convert_extern (global.get %s$string)))"
548+ name))
549+ else
550+ insert
551+ st
552+ (Format. asprintf
553+ " (array.new_fixed $bytes %d%a)"
554+ (String. length s)
555+ (fun f s ->
556+ String. iter
557+ ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c))
558+ s)
559+ s);
560+ skip st pos'
561+ | { desc =
562+ List
563+ [ { desc = Atom " @jsstring" ; _ }
564+ ; { desc = Atom name; _ }
565+ ; { desc = Atom value; _ }
566+ ]
567+ ; loc = pos, pos'
568+ } ->
569+ write st pos;
570+ Printf. bprintf
571+ st.head_buf
572+ " (import \"\" %s (global %s$string externref)) "
573+ value
574+ name;
494575 insert
495576 st
496- (Format. asprintf
497- " (global %s (ref eq) (array.new_fixed $bytes %d%a))"
577+ (Printf. sprintf
578+ " (global %s (ref eq) (struct.new $js (any.convert_extern (global.get \
579+ %s$string))))"
498580 name
499- (String. length s)
500- (fun f s ->
501- String. iter ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c)) s)
502- s);
581+ name);
503582 skip st pos'
504- | { desc = List [ { desc = Atom " @string" ; _ }; { desc = Atom value; loc = loc_value } ]
583+ | { desc =
584+ List [ { desc = Atom " @jsstring" ; _ }; { desc = Atom value; loc = loc_value } ]
505585 ; loc = pos, pos'
506586 } ->
507587 if not (is_string value)
508588 then raise (Error (position_of_loc loc_value, " Expecting a string" ));
509589 let s = parse_string loc_value value in
590+ let name = generate_id st s in
510591 write st pos;
592+ Printf. bprintf
593+ st.head_buf
594+ " (import \"\" %s (global %s$string externref)) "
595+ value
596+ name;
511597 insert
512598 st
513- (Format. asprintf
514- " (array.new_fixed $bytes %d%a)"
515- (String. length s)
516- (fun f s ->
517- String. iter ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c)) s)
518- s);
599+ (Printf. sprintf
600+ " (struct.new $%s (any.convert_extern (global.get %s$string))))"
601+ (if variable_is_set st " use-js-string" then " string" else " js" )
602+ name);
519603 skip st pos'
520- | { desc = List [ { desc = Atom " @string" ; loc = _, pos } ]; loc = _ , pos' } ->
604+ | { desc = List [ { desc = Atom (" @string" | " @jsstring" ); loc = _, pos } ]
605+ ; loc = _, pos'
606+ } ->
521607 raise (Error ((pos.loc, pos'.loc), Printf. sprintf " Expecting an id or a string.\n " ))
522- | { desc = List ({ desc = Atom "@string" ; _ } :: _ :: _ :: { loc; _ } :: _ ); _ } ->
608+ | { desc =
609+ List ({ desc = Atom (" @string" | " @jsstring" ); _ } :: _ :: _ :: { loc; _ } :: _)
610+ ; _
611+ } ->
523612 raise
524613 (Error (position_of_loc loc, Printf. sprintf " Expecting a closing parenthesis.\n " ))
525614 | { desc =
@@ -544,6 +633,9 @@ and rewrite st elt =
544633 insert st (Printf. sprintf " $%s " (parse_string export_loc export_name));
545634 skip st pos';
546635 rewrite_list st l
636+ | { desc = List ({ desc = Atom "module" ; loc = _ , pos } :: _ as l ); _ } ->
637+ st.head < - pos.byte_loc;
638+ rewrite_list st l
547639 | { desc = List l ; _ } -> rewrite_list st l
548640 | _ -> ()
549641
@@ -553,7 +645,7 @@ let ocaml_version =
553645 Scanf. sscanf Sys. ocaml_version " %d.%d.%d" (fun major minor patchlevel ->
554646 Version (major, minor, patchlevel))
555647
556- let default_settings = [ " name-wasm-functions" , Bool true ]
648+ let default_settings = [ " name-wasm-functions" , Bool true ; " use-js-string " , Bool false ]
557649
558650let f ~variables ~filename ~contents :text =
559651 let variables =
@@ -567,10 +659,23 @@ let f ~variables ~filename ~contents:text =
567659 Sedlexing. set_filename lexbuf filename;
568660 try
569661 let t, (pos, end_pos) = parse lexbuf in
570- let st = { text; pos; variables; buf = Buffer. create (String. length text) } in
662+ let st =
663+ { text
664+ ; pos
665+ ; variables
666+ ; buf = Buffer. create (String. length text)
667+ ; head_buf = Buffer. create 128
668+ ; head = 0
669+ ; id = 0
670+ }
671+ in
571672 rewrite_list st t;
572673 write st end_pos;
573- Buffer. contents st.buf
674+ let head = Buffer. contents st.head_buf in
675+ let contents = Buffer. contents st.buf in
676+ String. sub contents ~pos: 0 ~len: st.head
677+ ^ head
678+ ^ String. sub contents ~pos: st.head ~len: (String. length contents - st.head)
574679 with Error (loc , msg ) -> report_error loc msg
575680
576681type source =
0 commit comments