Skip to content

Commit f45046b

Browse files
committed
Compiler: move primitive generation in the runtime
1 parent 607a089 commit f45046b

File tree

18 files changed

+312
-140
lines changed

18 files changed

+312
-140
lines changed

compiler/bin-js_of_ocaml/check_runtime.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ let f (runtime_files, bytecode, target_env) =
4646
Config.set_target `JavaScript;
4747
Config.set_effects_backend `Disabled;
4848
Linker.reset ();
49+
Generate.reset ();
4950
let runtime_files, builtin =
5051
List.partition_map runtime_files ~f:(fun name ->
5152
match Builtins.find name with

compiler/bin-js_of_ocaml/compile.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ let run
169169
Jsoo_cmdline.Arg.eval common;
170170
Config.set_effects_backend effects;
171171
Linker.reset ();
172+
Generate.reset ();
172173
(match output_file with
173174
| `Stdout, _ -> ()
174175
| `Name name, _ when debug_mem () -> Debug.start_profiling name

compiler/bin-js_of_ocaml/link.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ let f
149149
Config.set_target `JavaScript;
150150
Jsoo_cmdline.Arg.eval common;
151151
Linker.reset ();
152+
Generate.reset ();
152153
let with_output f =
153154
match output_file with
154155
| None -> f stdout

compiler/lib-dynlink/js_of_ocaml_compiler_dynlink.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ let () =
4545
Config.set_effects_backend (Jsoo_runtime.Sys.Config.effects ());
4646
Linker.reset ();
4747
List.iter aliases ~f:(fun (a, b) -> Primitive.alias a b);
48+
Generate.reset ();
4849
(* this needs to stay synchronized with toplevel.js *)
4950
let toplevel_compile (s : string) (debug : Instruct.debug_event list array) :
5051
unit -> J.t =

compiler/lib-runtime-files/gen/gen.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ let () =
7373
| `Effects b -> Js_of_ocaml_compiler.Config.set_effects_backend b);
7474
List.iter Js_of_ocaml_compiler.Target_env.all ~f:(fun target_env ->
7575
Js_of_ocaml_compiler.Linker.reset ();
76+
Js_of_ocaml_compiler.Generate.reset ();
7677
List.iter fragments ~f:(fun (filename, frags) ->
7778
Js_of_ocaml_compiler.Linker.load_fragments ~target_env ~filename frags);
7879
let linkinfos = Js_of_ocaml_compiler.Linker.init () in

compiler/lib/annot_lexer.mll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ rule main = parse
2525
| "Requires" {TRequires}
2626
| "Version" {TVersion}
2727
| "Weakdef" {TWeakdef}
28+
| "Inline" {TInline}
2829
| "Always" {TAlways}
2930
| "If" {TIf}
3031
| "Alias" {TAlias}

compiler/lib/annot_parser.mly

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1818
*)
1919

20-
%token TProvides TRequires TVersion TWeakdef TIf TAlways TAlias
20+
%token TProvides TRequires TVersion TWeakdef TInline TIf TAlways TAlias
2121
%token TA_Pure TA_Const TA_Mutable TA_Mutator TA_Shallow TA_Object_literal
2222
%token<string> TIdent TIdent_percent TVNum
2323
%token TComma TColon EOF EOL LE LT GE GT EQ LPARENT RPARENT
@@ -40,6 +40,7 @@ annot:
4040
| TVersion TColon l=separated_nonempty_list(TComma,version) endline
4141
{ `Version (l) }
4242
| TWeakdef endline { `Weakdef }
43+
| TInline endline { `Inline }
4344
| TAlways endline { `Always }
4445
| TDeprecated endline { `Deprecated $1 }
4546
| TAlias TColon name=TIdent endline { `Alias (name) }

compiler/lib/generate.ml

Lines changed: 55 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -358,13 +358,6 @@ let one = J.ENum (J.Num.of_targetint Targetint.one)
358358

359359
let zero = J.ENum (J.Num.of_targetint Targetint.zero)
360360

361-
let plus_int x y =
362-
match x, y with
363-
| J.ENum y, x when J.Num.is_zero y -> x
364-
| x, J.ENum y when J.Num.is_zero y -> x
365-
| J.ENum x, J.ENum y -> J.ENum (J.Num.add x y)
366-
| x, y -> J.EBin (J.Plus, x, y)
367-
368361
let bool e = J.ECond (e, one, zero)
369362

370363
(****)
@@ -1075,16 +1068,6 @@ let register_un_prims names ?(need_loc = false) k f =
10751068

10761069
let register_un_prim name k f = register_un_prims [ name ] k f
10771070

1078-
let register_un_prim_ctx name k f =
1079-
register_prims [ name ] k (fun name l ctx loc ->
1080-
match l with
1081-
| [ x ] ->
1082-
let open Expr_builder in
1083-
let* cx = access' ~ctx x in
1084-
let* () = info (kind k) in
1085-
return (f ctx cx loc)
1086-
| _ -> invalid_arity name l ~loc ~expected:1)
1087-
10881071
let register_bin_prims names k f =
10891072
register_prims names k (fun name l ctx loc ->
10901073
match l with
@@ -1112,28 +1095,7 @@ let register_tern_prims names k f =
11121095

11131096
let register_tern_prim name k f = register_tern_prims [ name ] k f
11141097

1115-
let register_un_math_prim name prim =
1116-
let prim = Utf8_string.of_string_exn prim in
1117-
register_un_prim name `Pure (fun cx loc ->
1118-
J.call (J.dot (s_var "Math") prim) [ cx ] loc)
1119-
1120-
let register_bin_math_prim name prim =
1121-
let prim = Utf8_string.of_string_exn prim in
1122-
register_bin_prims [ name ] `Pure (fun cx cy loc ->
1123-
J.call (J.dot (s_var "Math") prim) [ cx; cy ] loc)
1124-
11251098
let _ =
1126-
register_un_prim_ctx "%caml_format_int_special" `Pure (fun ctx cx loc ->
1127-
let s = J.EBin (J.Plus, str_js_utf8 "", cx) in
1128-
ocaml_string ~ctx ~loc s);
1129-
register_un_prim "%direct_obj_tag" `Mutator (fun cx _loc -> Mlvalue.Block.tag cx);
1130-
register_bin_prims
1131-
[ "caml_array_unsafe_get"
1132-
; "caml_array_unsafe_get_float"
1133-
; "caml_floatarray_unsafe_get"
1134-
]
1135-
`Mutable
1136-
(fun cx cy _ -> Mlvalue.Array.field cx cy);
11371099
register_un_prims
11381100
[ "caml_int32_of_int"
11391101
; "caml_int32_to_int"
@@ -1147,83 +1109,6 @@ let _ =
11471109
]
11481110
`Pure
11491111
(fun cx _ -> cx);
1150-
register_bin_prims
1151-
[ "%int_add"; "caml_int32_add"; "caml_nativeint_add" ]
1152-
`Pure
1153-
(fun cx cy _ ->
1154-
match cx, cy with
1155-
| J.EBin (J.Minus, cz, J.ENum n), J.ENum m ->
1156-
to_int (J.EBin (J.Plus, cz, J.ENum (J.Num.add m (J.Num.neg n))))
1157-
| _ -> to_int (plus_int cx cy));
1158-
register_bin_prims
1159-
[ "%int_sub"; "caml_int32_sub"; "caml_nativeint_sub" ]
1160-
`Pure
1161-
(fun cx cy _ ->
1162-
match cx, cy with
1163-
| J.EBin (J.Minus, cz, J.ENum n), J.ENum m ->
1164-
to_int (J.EBin (J.Minus, cz, J.ENum (J.Num.add n m)))
1165-
| _ -> to_int (J.EBin (J.Minus, cx, cy)));
1166-
register_bin_prim "%direct_int_mul" `Pure (fun cx cy _ ->
1167-
to_int (J.EBin (J.Mul, cx, cy)));
1168-
register_bin_prim "%direct_int_div" `Pure (fun cx cy _ ->
1169-
to_int (J.EBin (J.Div, cx, cy)));
1170-
register_bin_prim "%direct_int_mod" `Pure (fun cx cy _ ->
1171-
to_int (J.EBin (J.Mod, cx, cy)));
1172-
register_bin_prims
1173-
[ "%int_and"; "caml_int32_and"; "caml_nativeint_and" ]
1174-
`Pure
1175-
(fun cx cy _ -> J.EBin (J.Band, cx, cy));
1176-
register_bin_prims
1177-
[ "%int_or"; "caml_int32_or"; "caml_nativeint_or" ]
1178-
`Pure
1179-
(fun cx cy _ -> J.EBin (J.Bor, cx, cy));
1180-
register_bin_prims
1181-
[ "%int_xor"; "caml_int32_xor"; "caml_nativeint_xor" ]
1182-
`Pure
1183-
(fun cx cy _ -> J.EBin (J.Bxor, cx, cy));
1184-
register_bin_prims
1185-
[ "%int_lsl"; "caml_int32_shift_left"; "caml_nativeint_shift_left" ]
1186-
`Pure
1187-
(fun cx cy _ -> J.EBin (J.Lsl, cx, cy));
1188-
register_bin_prims
1189-
[ "%int_lsr"
1190-
; "caml_int32_shift_right_unsigned"
1191-
; "caml_nativeint_shift_right_unsigned"
1192-
]
1193-
`Pure
1194-
(fun cx cy _ -> to_int (J.EBin (J.Lsr, cx, cy)));
1195-
register_bin_prims
1196-
[ "%int_asr"; "caml_int32_shift_right"; "caml_nativeint_shift_right" ]
1197-
`Pure
1198-
(fun cx cy _ -> J.EBin (J.Asr, cx, cy));
1199-
register_un_prims
1200-
[ "%int_neg"; "caml_int32_neg"; "caml_nativeint_neg" ]
1201-
`Pure
1202-
(fun cx _ -> to_int (J.EUn (J.Neg, cx)));
1203-
register_bin_prim "caml_eq_float" `Pure (fun cx cy _ ->
1204-
bool (J.EBin (J.EqEqEq, cx, cy)));
1205-
register_bin_prim "caml_neq_float" `Pure (fun cx cy _ ->
1206-
bool (J.EBin (J.NotEqEq, cx, cy)));
1207-
register_bin_prim "caml_ge_float" `Pure (fun cx cy _ -> bool (J.EBin (J.Le, cy, cx)));
1208-
register_bin_prim "caml_le_float" `Pure (fun cx cy _ -> bool (J.EBin (J.Le, cx, cy)));
1209-
register_bin_prim "caml_gt_float" `Pure (fun cx cy _ -> bool (J.EBin (J.Lt, cy, cx)));
1210-
register_bin_prim "caml_lt_float" `Pure (fun cx cy _ -> bool (J.EBin (J.Lt, cx, cy)));
1211-
register_bin_prim "caml_add_float" `Pure (fun cx cy _ -> J.EBin (J.Plus, cx, cy));
1212-
register_bin_prim "caml_sub_float" `Pure (fun cx cy _ -> J.EBin (J.Minus, cx, cy));
1213-
register_bin_prim "caml_mul_float" `Pure (fun cx cy _ -> J.EBin (J.Mul, cx, cy));
1214-
register_bin_prim "caml_div_float" `Pure (fun cx cy _ -> J.EBin (J.Div, cx, cy));
1215-
register_un_prim "caml_neg_float" `Pure (fun cx _ -> J.EUn (J.Neg, cx));
1216-
register_bin_prim "caml_fmod_float" `Pure (fun cx cy _ -> J.EBin (J.Mod, cx, cy));
1217-
register_tern_prims
1218-
[ "caml_array_unsafe_set"
1219-
; "caml_array_unsafe_set_float"
1220-
; "caml_floatarray_unsafe_set"
1221-
; "caml_array_unsafe_set_addr"
1222-
]
1223-
`Mutator
1224-
(fun cx cy cz _ -> J.EBin (J.Eq, Mlvalue.Array.field cx cy, cz));
1225-
register_un_prims [ "caml_alloc_dummy"; "caml_alloc_dummy_float" ] `Pure (fun _ _ ->
1226-
J.array []);
12271112
register_un_prims
12281113
[ "caml_int_of_float"
12291114
; "caml_int32_of_float"
@@ -1233,20 +1118,6 @@ let _ =
12331118
]
12341119
`Pure
12351120
(fun cx _loc -> to_int cx);
1236-
register_un_math_prim "caml_abs_float" "abs";
1237-
register_un_math_prim "caml_acos_float" "acos";
1238-
register_un_math_prim "caml_asin_float" "asin";
1239-
register_un_math_prim "caml_atan_float" "atan";
1240-
register_bin_math_prim "caml_atan2_float" "atan2";
1241-
register_un_math_prim "caml_ceil_float" "ceil";
1242-
register_un_math_prim "caml_cos_float" "cos";
1243-
register_un_math_prim "caml_exp_float" "exp";
1244-
register_un_math_prim "caml_floor_float" "floor";
1245-
register_un_math_prim "caml_log_float" "log";
1246-
register_bin_math_prim "caml_power_float" "pow";
1247-
register_un_math_prim "caml_sin_float" "sin";
1248-
register_un_math_prim "caml_sqrt_float" "sqrt";
1249-
register_un_math_prim "caml_tan_float" "tan";
12501121
register_un_prim "caml_js_from_bool" `Pure (fun cx _ ->
12511122
J.EUn (J.Not, J.EUn (J.Not, cx)));
12521123
register_un_prim "caml_js_to_bool" `Pure (fun cx _ -> to_int cx);
@@ -1311,6 +1182,17 @@ let remove_unused_tail_args ctx exact trampolined args =
13111182
else args
13121183
else args
13131184

1185+
(* var substitution *)
1186+
class subst sub =
1187+
object
1188+
inherit Js_traverse.map as super
1189+
1190+
method expression x =
1191+
match x with
1192+
| EVar v -> ( try sub v with Not_found -> super#expression x)
1193+
| _ -> super#expression x
1194+
end
1195+
13141196
let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t =
13151197
let open Expr_builder in
13161198
match e with
@@ -1532,13 +1414,51 @@ let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t
15321414
let name = Primitive.resolve name_orig in
15331415
match internal_prim name with
15341416
| Some f -> f name l ctx loc
1535-
| None ->
1417+
| None -> (
15361418
if String.starts_with name ~prefix:"%"
15371419
then failwith (Printf.sprintf "Unresolved internal primitive: %s" name);
1538-
let prim = Share.get_prim (runtime_fun ctx) name ctx.Ctx.share in
1539-
let* () = info ~need_loc:true (kind (Primitive.kind name)) in
1540-
let* args = list_map (fun x -> access' ~ctx x) l in
1541-
return (J.call prim args loc))
1420+
match Linker.inline ~name with
1421+
| Some f -> (
1422+
let c = new Js_traverse.rename_variable ~esm:false in
1423+
let f = c#expression f in
1424+
match f with
1425+
| EFun
1426+
( None
1427+
, ( { async = false; generator = false }
1428+
, { list = params; rest = None }
1429+
, [ (Return_statement (Some body, _), _) ]
1430+
, _loc ) )
1431+
when List.length params = List.length l ->
1432+
let* l = list_map (fun x -> access' ~ctx x) l in
1433+
let params =
1434+
List.map params ~f:(fun (x, _) ->
1435+
match x with
1436+
| BindingIdent x -> x
1437+
| BindingPattern _ -> assert false)
1438+
in
1439+
let sub =
1440+
let t = Hashtbl.create (List.length l) in
1441+
List.iter2 params l ~f:(fun p x ->
1442+
let k =
1443+
match p with
1444+
| J.V v -> v
1445+
| _ -> assert false
1446+
in
1447+
Hashtbl.add t k x);
1448+
1449+
fun x ->
1450+
match x with
1451+
| J.S _ -> J.EVar x
1452+
| J.V x -> Hashtbl.find t x
1453+
in
1454+
let r = new subst sub in
1455+
return (r#expression body)
1456+
| _ -> assert false)
1457+
| None ->
1458+
let prim = Share.get_prim (runtime_fun ctx) name ctx.Ctx.share in
1459+
let* () = info ~need_loc:true (kind (Primitive.kind name)) in
1460+
let* args = list_map (fun x -> access' ~ctx x) l in
1461+
return (J.call prim args loc)))
15421462
| Not, [ x ] ->
15431463
let* cx = access' ~ctx x in
15441464
return (J.EBin (J.Minus, one, cx))
@@ -2284,7 +2204,7 @@ let f
22842204
if times () then Format.eprintf " code gen.: %a@." Timer.print t';
22852205
p
22862206

2287-
let init () =
2207+
let reset () =
22882208
Hashtbl.iter
22892209
(fun name (k, _) -> Primitive.register name k None None)
22902210
internal_primitives

compiler/lib/generate.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ val f :
3030
-> Parse_bytecode.Debug.t
3131
-> Javascript.program
3232

33-
val init : unit -> unit
33+
val reset : unit -> unit

0 commit comments

Comments
 (0)