@@ -271,6 +271,9 @@ type st =
271
271
; mutable pos : pos
272
272
; variables : value StringMap .t
273
273
; buf : Buffer .t
274
+ ; mutable head : int
275
+ ; head_buf : Buffer .t
276
+ ; mutable id : int (* to generate distinct string id names *)
274
277
}
275
278
276
279
let value_type v : typ =
@@ -395,6 +398,11 @@ let insert st s =
395
398
let pred_position { loc; byte_loc } =
396
399
{ loc = { loc with pos_cnum = loc.pos_cnum - 1 }; byte_loc = byte_loc - 1 }
397
400
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
+
398
406
let rec rewrite_list st l = List. iter ~f: (rewrite st) l
399
407
400
408
and rewrite st elt =
@@ -491,35 +499,116 @@ and rewrite st elt =
491
499
then raise (Error (position_of_loc loc_value, " Expecting a string" ));
492
500
let s = parse_string loc_value value in
493
501
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;
494
575
insert
495
576
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))))"
498
580
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);
503
582
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 } ]
505
585
; loc = pos, pos'
506
586
} ->
507
587
if not (is_string value)
508
588
then raise (Error (position_of_loc loc_value, " Expecting a string" ));
509
589
let s = parse_string loc_value value in
590
+ let name = generate_id st s in
510
591
write st pos;
592
+ Printf. bprintf
593
+ st.head_buf
594
+ " (import \"\" %s (global %s$string externref)) "
595
+ value
596
+ name;
511
597
insert
512
598
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);
519
603
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
+ } ->
521
607
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
+ } ->
523
612
raise
524
613
(Error (position_of_loc loc, Printf. sprintf " Expecting a closing parenthesis.\n " ))
525
614
| { desc =
@@ -544,6 +633,9 @@ and rewrite st elt =
544
633
insert st (Printf. sprintf " $%s " (parse_string export_loc export_name));
545
634
skip st pos';
546
635
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
547
639
| { desc = List l ; _ } -> rewrite_list st l
548
640
| _ -> ()
549
641
@@ -553,7 +645,7 @@ let ocaml_version =
553
645
Scanf. sscanf Sys. ocaml_version " %d.%d.%d" (fun major minor patchlevel ->
554
646
Version (major, minor, patchlevel))
555
647
556
- let default_settings = [ " name-wasm-functions" , Bool true ]
648
+ let default_settings = [ " name-wasm-functions" , Bool true ; " use-js-string " , Bool false ]
557
649
558
650
let f ~variables ~filename ~contents :text =
559
651
let variables =
@@ -567,10 +659,23 @@ let f ~variables ~filename ~contents:text =
567
659
Sedlexing. set_filename lexbuf filename;
568
660
try
569
661
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
571
672
rewrite_list st t;
572
673
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)
574
679
with Error (loc , msg ) -> report_error loc msg
575
680
576
681
type source =
0 commit comments