@@ -282,6 +282,9 @@ type st =
282
282
; mutable pos : pos
283
283
; variables : value StringMap .t
284
284
; buf : Buffer .t
285
+ ; mutable head : int
286
+ ; head_buf : Buffer .t
287
+ ; mutable id : int (* to generate distinct string id names *)
285
288
}
286
289
287
290
let value_type v : typ =
@@ -406,6 +409,11 @@ let insert st s =
406
409
let pred_position { loc; byte_loc } =
407
410
{ loc = { loc with pos_cnum = loc.pos_cnum - 1 }; byte_loc = byte_loc - 1 }
408
411
412
+ let generate_id st _ =
413
+ let id = Printf. sprintf " $js$string$%d$" st.id in
414
+ st.id < - st.id + 1 ;
415
+ id
416
+
409
417
let rec rewrite_list st l = List. iter ~f: (rewrite st) l
410
418
411
419
and rewrite st elt =
@@ -502,35 +510,116 @@ and rewrite st elt =
502
510
then raise (Error (position_of_loc loc_value, " Expecting a string" ));
503
511
let s = parse_string loc_value value in
504
512
write st pos;
513
+ if variable_is_set st " use-js-string"
514
+ then (
515
+ Printf. bprintf
516
+ st.head_buf
517
+ " (import \"\" %s (global %s$string externref)) "
518
+ value
519
+ name;
520
+ insert
521
+ st
522
+ (Printf. sprintf
523
+ " (global %s (ref eq) (struct.new $string (any.convert_extern (global.get \
524
+ %s$string))))"
525
+ name
526
+ name))
527
+ else
528
+ insert
529
+ st
530
+ (Format. asprintf
531
+ " (global %s (ref eq) (array.new_fixed $bytes %d%a))"
532
+ name
533
+ (String. length s)
534
+ (fun f s ->
535
+ String. iter
536
+ ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c))
537
+ s)
538
+ s);
539
+ skip st pos'
540
+ | { desc = List [ { desc = Atom " @string" ; _ }; { desc = Atom value; loc = loc_value } ]
541
+ ; loc = pos, pos'
542
+ } ->
543
+ if not (is_string value)
544
+ then raise (Error (position_of_loc loc_value, " Expecting a string" ));
545
+ let s = parse_string loc_value value in
546
+ let name = generate_id st s in
547
+ write st pos;
548
+ if variable_is_set st " use-js-string"
549
+ then (
550
+ Printf. bprintf
551
+ st.head_buf
552
+ " (import \"\" %s (global %s$string externref)) "
553
+ value
554
+ name;
555
+ insert
556
+ st
557
+ (Printf. sprintf
558
+ " (struct.new $string (any.convert_extern (global.get %s$string)))"
559
+ name))
560
+ else
561
+ insert
562
+ st
563
+ (Format. asprintf
564
+ " (array.new_fixed $bytes %d%a)"
565
+ (String. length s)
566
+ (fun f s ->
567
+ String. iter
568
+ ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c))
569
+ s)
570
+ s);
571
+ skip st pos'
572
+ | { desc =
573
+ List
574
+ [ { desc = Atom " @jsstring" ; _ }
575
+ ; { desc = Atom name; _ }
576
+ ; { desc = Atom value; _ }
577
+ ]
578
+ ; loc = pos, pos'
579
+ } ->
580
+ write st pos;
581
+ Printf. bprintf
582
+ st.head_buf
583
+ " (import \"\" %s (global %s$string externref)) "
584
+ value
585
+ name;
505
586
insert
506
587
st
507
- (Format. asprintf
508
- " (global %s (ref eq) (array.new_fixed $bytes %d%a))"
588
+ (Printf. sprintf
589
+ " (global %s (ref eq) (struct.new $js (any.convert_extern (global.get \
590
+ %s$string))))"
509
591
name
510
- (String. length s)
511
- (fun f s ->
512
- String. iter ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c)) s)
513
- s);
592
+ name);
514
593
skip st pos'
515
- | { desc = List [ { desc = Atom " @string" ; _ }; { desc = Atom value; loc = loc_value } ]
594
+ | { desc =
595
+ List [ { desc = Atom " @jsstring" ; _ }; { desc = Atom value; loc = loc_value } ]
516
596
; loc = pos, pos'
517
597
} ->
518
598
if not (is_string value)
519
599
then raise (Error (position_of_loc loc_value, " Expecting a string" ));
520
600
let s = parse_string loc_value value in
601
+ let name = generate_id st s in
521
602
write st pos;
603
+ Printf. bprintf
604
+ st.head_buf
605
+ " (import \"\" %s (global %s$string externref)) "
606
+ value
607
+ name;
522
608
insert
523
609
st
524
- (Format. asprintf
525
- " (array.new_fixed $bytes %d%a)"
526
- (String. length s)
527
- (fun f s ->
528
- String. iter ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c)) s)
529
- s);
610
+ (Printf. sprintf
611
+ " (struct.new $%s (any.convert_extern (global.get %s$string))))"
612
+ (if variable_is_set st " use-js-string" then " string" else " js" )
613
+ name);
530
614
skip st pos'
531
- | { desc = List [ { desc = Atom " @string" ; loc = _, pos } ]; loc = _ , pos' } ->
615
+ | { desc = List [ { desc = Atom (" @string" | " @jsstring" ); loc = _, pos } ]
616
+ ; loc = _, pos'
617
+ } ->
532
618
raise (Error ((pos.loc, pos'.loc), Printf. sprintf " Expecting an id or a string.\n " ))
533
- | { desc = List ({ desc = Atom "@string" ; _ } :: _ :: _ :: { loc; _ } :: _ ); _ } ->
619
+ | { desc =
620
+ List ({ desc = Atom (" @string" | " @jsstring" ); _ } :: _ :: _ :: { loc; _ } :: _)
621
+ ; _
622
+ } ->
534
623
raise
535
624
(Error (position_of_loc loc, Printf. sprintf " Expecting a closing parenthesis.\n " ))
536
625
| { desc = List [ { desc = Atom " @char" ; _ }; { desc = Atom value; loc = loc_value } ]
@@ -570,6 +659,9 @@ and rewrite st elt =
570
659
insert st (Printf. sprintf " $%s " (parse_string export_loc export_name));
571
660
skip st pos';
572
661
rewrite_list st l
662
+ | { desc = List ({ desc = Atom "module" ; loc = _ , pos } :: _ as l ); _ } ->
663
+ st.head < - pos.byte_loc;
664
+ rewrite_list st l
573
665
| { desc = List l ; _ } -> rewrite_list st l
574
666
| _ -> ()
575
667
@@ -579,7 +671,7 @@ let ocaml_version =
579
671
Scanf. sscanf Sys. ocaml_version " %d.%d.%d" (fun major minor patchlevel ->
580
672
Version (major, minor, patchlevel))
581
673
582
- let default_settings = [ " name-wasm-functions" , Bool true ]
674
+ let default_settings = [ " name-wasm-functions" , Bool true ; " use-js-string " , Bool false ]
583
675
584
676
let f ~variables ~filename ~contents :text =
585
677
let variables =
@@ -593,10 +685,23 @@ let f ~variables ~filename ~contents:text =
593
685
Sedlexing. set_filename lexbuf filename;
594
686
try
595
687
let t, (pos, end_pos) = parse lexbuf in
596
- let st = { text; pos; variables; buf = Buffer. create (String. length text) } in
688
+ let st =
689
+ { text
690
+ ; pos
691
+ ; variables
692
+ ; buf = Buffer. create (String. length text)
693
+ ; head_buf = Buffer. create 128
694
+ ; head = 0
695
+ ; id = 0
696
+ }
697
+ in
597
698
rewrite_list st t;
598
699
write st end_pos;
599
- Buffer. contents st.buf
700
+ let head = Buffer. contents st.head_buf in
701
+ let contents = Buffer. contents st.buf in
702
+ String. sub contents ~pos: 0 ~len: st.head
703
+ ^ head
704
+ ^ String. sub contents ~pos: st.head ~len: (String. length contents - st.head)
600
705
with Error (loc , msg ) -> report_error loc msg
601
706
602
707
type source =
0 commit comments