diff --git a/jscomp/lam_analysis.ml b/jscomp/lam_analysis.ml index 812970e0f3..7f32b0570c 100644 --- a/jscomp/lam_analysis.ml +++ b/jscomp/lam_analysis.ml @@ -306,10 +306,149 @@ and eq_primitive (p : Lambda.primitive) (p1 : Lambda.primitive) = try p = p1 with _ -> false -let is_closed_by map lam = - Lambda.IdentSet.for_all Ident.global - (Lambda.IdentSet.diff (Lambda.free_variables lam) map ) + +type stats = + { + mutable top : bool ; + (* all appearances are in the top, substitution is fine + whether it is pure or not + {[ + (fun x y + -> x + y + (f x )) (32) (console.log('hi'), 33) + ]} + since in ocaml, the application order is intentionally undefined, + note if [times] is not one, this field does not make sense + *) + mutable times : int ; + } +type env = + { top : bool ; + loop : bool + } + +let no_substitute = { top = false; loop = true } +let fresh_env = {top = true; loop = false } +let fresh_stats () = { top = true; times = 0 } + +let param_map_of_list lst = + List.fold_left (fun acc l -> Ident_map.add l (fresh_stats ()) acc) Ident_map.empty lst + +(** Sanity check, remove all varaibles in [local_set] in the last pass *) + +let free_variables (export_idents : Ident_set.t ) (params : stats Ident_map.t ) lam = + let fv = ref params in + let local_set = ref export_idents in + + let local_add k = + local_set := Ident_set.add k !local_set in + let local_add_list ks = + local_set := + List.fold_left (fun acc k -> Ident_set.add k acc) !local_set ks + in + let loop_use = 100 in + let map_use {top; loop} v = + (* relies on [identifier] uniquely bound *) + let times = if loop then loop_use else 1 in + if Ident_set.mem v !local_set then () + else begin match Ident_map.find v !fv with + | exception Not_found + -> fv := Ident_map.add v { top ; times } !fv + | v -> + v.times <- v.times + times ; + v.top <- v.top && top + end + in + let new_env lam (env : env) = + if env.top then + if no_side_effects lam + then env + else { env with top = false} + else env + in + let rec iter (top : env) (lam : Lambda.lambda) = + match lam with + | Lvar v -> map_use top v + | Lconst _ -> () + | Lapply(fn, args, _) -> + iter top fn; + let top = new_env fn top in + List.iter (iter top ) args + | Lprim(_p, args) -> + (* Check: can top be propoaged for all primitives *) + List.iter (iter top) args + | Lfunction(_kind, params, body) -> + local_add_list params; + iter no_substitute body + | Llet(_let_kind, id, arg, body) -> + local_add id ; + iter top arg; iter no_substitute body + | Lletrec(decl, body) -> + local_set := List.fold_left (fun acc (id, _) -> + Ident_set.add id acc) !local_set decl; + List.iter (fun (_, exp) -> iter no_substitute exp) decl; + iter no_substitute body + | Lswitch(arg, sw) -> + iter top arg; + let top = new_env arg top in + List.iter (fun (key, case) -> iter top case) sw.sw_consts; + List.iter (fun (key, case) -> iter top case) sw.sw_blocks; + + begin match sw.sw_failaction with + | None -> () + | Some x -> + let nconsts = List.length sw.sw_consts in + let nblocks = List.length sw.sw_blocks in + + if nconsts < sw.sw_numconsts && nblocks < sw.sw_numblocks then + iter no_substitute x + else + iter top x + end + + | Lstringswitch (arg,cases,default) -> + iter top arg ; + let top = new_env arg top in + List.iter (fun (_,act) -> iter top act) cases ; + begin match default with + | None -> () + | Some x -> iter top x + end + | Lstaticraise (_,args) -> + List.iter (iter no_substitute ) args + | Lstaticcatch(e1, (_,vars), e2) -> + iter no_substitute e1; + local_add_list vars; + iter no_substitute e2 + | Ltrywith(e1, exn, e2) -> + iter top e1; iter no_substitute e2 + | Lifthenelse(e1, e2, e3) -> + iter top e1; + let top = new_env e1 top in + iter top e2; iter top e3 + | Lsequence(e1, e2) -> + iter top e1; iter no_substitute e2 + | Lwhile(e1, e2) -> + iter no_substitute e1; iter no_substitute e2 (* in the loop, no substitution any way *) + | Lfor(v, e1, e2, dir, e3) -> + local_add v ; + iter no_substitute e1; iter no_substitute e2; iter no_substitute e3 + | Lassign(id, e) -> + map_use top id ; + iter top e + | Lsend (_k, met, obj, args, _) -> + iter no_substitute met ; + iter no_substitute obj; + List.iter (iter no_substitute) args + | Levent (lam, evt) -> + iter top lam + | Lifused (v, e) -> + iter no_substitute e in + iter fresh_env lam ; !fv + + +let is_closed_by set lam = + Ident_map.is_empty (free_variables set (Ident_map.empty ) lam ) let is_closed lam = - Lambda.IdentSet.for_all Ident.global (Lambda.free_variables lam) + Ident_map.is_empty (free_variables Ident_set.empty Ident_map.empty lam) diff --git a/jscomp/lam_analysis.mli b/jscomp/lam_analysis.mli index 0f28739a00..c1853d9255 100644 --- a/jscomp/lam_analysis.mli +++ b/jscomp/lam_analysis.mli @@ -33,10 +33,31 @@ val eq_lambda : Lambda.lambda -> Lambda.lambda -> bool (** [is_closed_by map lam] return [true] if all unbound variables belongs to the given [map] *) -val is_closed_by : Lambda.IdentSet.t -> Lambda.lambda -> bool +val is_closed_by : (* Lambda. *) Ident_set.t -> Lambda.lambda -> bool val is_closed : Lambda.lambda -> bool + + + +type stats = + { + mutable top : bool ; + (* all appearances are in the top, substitution is fine + whether it is pure or not + {[ + (fun x y + -> x + y + (f x )) (32) (console.log('hi'), 33) + ]} + since in ocaml, the application order is intentionally undefined, + note if [times] is not one, this field does not make sense + *) + mutable times : int ; + } + +val param_map_of_list : Ident.t list -> stats Ident_map.t +val free_variables : Ident_set.t -> stats Ident_map.t -> Lambda.lambda -> stats Ident_map.t + val small_inline_size : int val exit_inline_size : int diff --git a/jscomp/lam_beta_reduce.ml b/jscomp/lam_beta_reduce.ml index 6af05bea52..f49deccab2 100644 --- a/jscomp/lam_beta_reduce.ml +++ b/jscomp/lam_beta_reduce.ml @@ -228,6 +228,61 @@ let propogate_beta_reduce Lam_util.refine_let param arg l) rest_bindings new_body +let propogate_beta_reduce_with_map + (meta : Lam_stats.meta) (map : Lam_analysis.stats Ident_map.t ) params body args = + let rest_bindings, rev_new_params = + List.fold_left2 + (fun (rest_bindings, acc) old_param (arg : Lambda.lambda) -> + match arg with + | Lconst _ + | Lvar _ -> rest_bindings , arg :: acc + | Lprim (Pgetglobal ident, []) + (* TODO: we can pass Global, but you also need keep track of it*) + -> + let p = Ident.rename old_param in + (p,arg) :: rest_bindings , (Lambda.Lvar p) :: acc + + | _ -> + if Lam_analysis.no_side_effects arg then + begin match Ident_map.find old_param map with + | exception Not_found -> assert false + | {top = true ; times = 0 } + | {top = true ; times = 1 } + -> + rest_bindings, arg :: acc + | _ -> + let p = Ident.rename old_param in + (p,arg) :: rest_bindings , (Lambda.Lvar p) :: acc + end + else + let p = Ident.rename old_param in + (p,arg) :: rest_bindings , (Lambda.Lvar p) :: acc + ) ([],[]) params args in + let new_body = rewrite (Ext_hashtbl.of_list2 (List.rev params) (rev_new_params)) body in + List.fold_right + (fun (param, (arg : Lambda.lambda)) l -> + let arg = + match arg with + | Lvar v -> + begin + match Hashtbl.find meta.ident_tbl v with + | exception Not_found -> () + | ident_info -> + Hashtbl.add meta.ident_tbl param ident_info + end; + arg + | Lprim (Pgetglobal ident, []) -> + (* It's not completeness, its to make it sound.. *) + Lam_compile_global.query_lambda ident meta.env + (* alias meta param ident (Module (Global ident)) Strict *) + | Lprim (Pmakeblock (_, _, Immutable ) , ls) -> + Hashtbl.replace meta.ident_tbl param + (Lam_util.kind_of_lambda_block ls ); (** *) + arg + | _ -> arg in + Lam_util.refine_let param arg l) + rest_bindings new_body + diff --git a/jscomp/lam_beta_reduce.mli b/jscomp/lam_beta_reduce.mli index 94aaac7a00..e603826fc7 100644 --- a/jscomp/lam_beta_reduce.mli +++ b/jscomp/lam_beta_reduce.mli @@ -49,3 +49,9 @@ val propogate_beta_reduce : val refresh : Lambda.lambda -> Lambda.lambda + +val propogate_beta_reduce_with_map : + Lam_stats.meta -> + Lam_analysis.stats Ident_map.t -> + Ident_map.key list -> + Lambda.lambda -> Lambda.lambda list -> Lambda.lambda diff --git a/jscomp/lam_pass_collect.ml b/jscomp/lam_pass_collect.ml index e8e2c4d4c5..30d9ade549 100644 --- a/jscomp/lam_pass_collect.ml +++ b/jscomp/lam_pass_collect.ml @@ -99,7 +99,7 @@ let collect_helper (meta : Lam_stats.meta) (lam : Lambda.lambda) = collect l | x -> collect x ; - if Lambda.IdentSet.mem ident meta.export_idents then + if Ident_set.mem ident meta.export_idents then annotate meta rec_flag ident (Lam_stats_util.get_arity meta x ) lam diff --git a/jscomp/lam_pass_exits.ml b/jscomp/lam_pass_exits.ml index 5e1fe95b90..7ee5ad7f41 100644 --- a/jscomp/lam_pass_exits.ml +++ b/jscomp/lam_pass_exits.ml @@ -106,7 +106,8 @@ let count_helper (lam : Lambda.lambda) : (int, int ref) Hashtbl.t = | Levent(l, _) -> count l | Lifused(_, l) -> count l - and count_default sw = match sw.sw_failaction with + and count_default sw = + match sw.sw_failaction with | None -> () | Some al -> let nconsts = List.length sw.sw_consts diff --git a/jscomp/lam_pass_remove_alias.ml b/jscomp/lam_pass_remove_alias.ml index 6011393762..039b65541f 100644 --- a/jscomp/lam_pass_remove_alias.ml +++ b/jscomp/lam_pass_remove_alias.ml @@ -39,7 +39,7 @@ let simplify_alias since we aliased k, so it's safe to remove it? *) let v = simpl l in - if Lambda.IdentSet.mem k meta.export_idents + if Ident_set.mem k meta.export_idents then Llet(kind, k, g, v) (* in this case it is preserved, but will still be simplified @@ -125,32 +125,43 @@ let simplify_alias simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) end else - if lam_size < Lam_analysis.small_inline_size && - (Lam_analysis.is_closed_by meta.export_idents _m - || not (Lambda.IdentSet.mem v meta.export_idents)) - - then - if rec_flag = Rec then - begin - (* Ext_log.dwarn __LOC__ "beta rec.. %s/%d@." v.name v.stamp ; *) - Lam_beta_reduce.propogate_beta_reduce meta params body args - end + if lam_size < Lam_analysis.small_inline_size then + let param_fresh_map = Lam_analysis.param_map_of_list params in + let param_map = + Lam_analysis.free_variables meta.export_idents param_fresh_map body in + let old_count = List.length params in + let new_count = Ident_map.cardinal param_map in + if + ( + not (Ident_set.mem v meta.export_idents) + || old_count = new_count + ) + + then + if rec_flag = Rec then + begin + (* Ext_log.dwarn __LOC__ "beta rec.. %s/%d@." v.name v.stamp ; *) + (* Lam_beta_reduce.propogate_beta_reduce meta params body args *) + Lam_beta_reduce.propogate_beta_reduce_with_map meta param_map params body args + end + else + begin + (* Ext_log.dwarn __LOC__ "beta nonrec..[%d] [%a] %s/%d@." *) + (* (List.length args) *) + (* Printlambda.lambda body *) + (* v.name v.stamp ; *) + simpl (Lam_beta_reduce.propogate_beta_reduce_with_map meta param_map params body args) + + end + else + Lapply ( simpl l1, List.map simpl args, info) else begin - (* Ext_log.dwarn __LOC__ "beta nonrec..[%d] [%a] %s/%d@." *) - (* (List.length args) *) - (* Printlambda.lambda body *) - (* v.name v.stamp ; *) - simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args) - + (* Ext_log.dwarn __LOC__ "%s/%d: %d @." *) + (* v.name v.stamp lam_size *) + (* ; *) + Lapply ( simpl l1, List.map simpl args, info) end - else - begin - (* Ext_log.dwarn __LOC__ "%s/%d: %d @." *) - (* v.name v.stamp lam_size *) - (* ; *) - Lapply ( simpl l1, List.map simpl args, info) - end else begin (* Ext_log.dwarn __LOC__ "%d vs %d @." (List.length args) (List.length params); *) diff --git a/jscomp/lam_stats.ml b/jscomp/lam_stats.ml index 5299b4461a..d907801d3b 100644 --- a/jscomp/lam_stats.ml +++ b/jscomp/lam_stats.ml @@ -88,7 +88,7 @@ type ident_info = { type meta = { env : Env.t; filename : string ; - export_idents : Lambda.IdentSet.t ; + export_idents : Ident_set.t ; exports : Ident.t list ; alias_tbl : alias_tbl; diff --git a/jscomp/lam_stats.mli b/jscomp/lam_stats.mli index 336be674ec..3d7cdf5537 100644 --- a/jscomp/lam_stats.mli +++ b/jscomp/lam_stats.mli @@ -90,7 +90,7 @@ type ident_info = { type meta = { env : Env.t; filename : string ; - export_idents : Lambda.IdentSet.t ; + export_idents : Ident_set.t ; exports : Ident.t list ; alias_tbl : alias_tbl; exit_codes : int Hash_set.hashset; diff --git a/jscomp/lam_stats_util.ml b/jscomp/lam_stats_util.ml index 4aaf57e587..67e136617b 100644 --- a/jscomp/lam_stats_util.ml +++ b/jscomp/lam_stats_util.ml @@ -252,7 +252,7 @@ let export_to_cmj let closed_lambda = if Lam_inline_util.maybe_functor x.name then - if Lam_analysis.is_closed lambda + if Lam_analysis.is_closed lambda (* TODO: seriealize more*) then Some lambda else None else None in diff --git a/jscomp/lam_util.ml b/jscomp/lam_util.ml index c594e589d4..6edd0ab9c8 100644 --- a/jscomp/lam_util.ml +++ b/jscomp/lam_util.ml @@ -208,7 +208,7 @@ let alias (meta : Lam_stats.meta) (k:Ident.t) (v:Ident.t) *) begin match let_kind with | Alias -> - if not @@ Lambda.IdentSet.mem k meta.export_idents + if not @@ Ident_set.mem k meta.export_idents then Hashtbl.add meta.alias_tbl k v (** For [export_idents], we don't want to do such simplification @@ -290,13 +290,13 @@ let dump env filename pred lam = let ident_set_of_list ls = List.fold_left - (fun acc k -> Lambda.IdentSet.add k acc ) - Lambda.IdentSet.empty ls + (fun acc k -> Ident_set.add k acc ) + Ident_set.empty ls let print_ident_set fmt s = Format.fprintf fmt "@[{%a}@]@." (fun fmt s -> - Lambda.IdentSet.iter (fun e -> Format.fprintf fmt "@[%a@],@ " Ident.print e) s + Ident_set.iter (fun e -> Format.fprintf fmt "@[%a@],@ " Ident.print e) s ) s diff --git a/jscomp/lam_util.mli b/jscomp/lam_util.mli index fd0d4f9ca0..7889b6b7b0 100644 --- a/jscomp/lam_util.mli +++ b/jscomp/lam_util.mli @@ -51,8 +51,8 @@ val sort_dag_args : J.expression Ident_map.t -> Ident.t list option val dump : Env.t -> string -> bool -> Lambda.lambda -> Lambda.lambda -val ident_set_of_list : Ident.t list -> Lambda.IdentSet.t +val ident_set_of_list : Ident.t list -> Ident_set.t -val print_ident_set : Format.formatter -> Lambda.IdentSet.t -> unit +val print_ident_set : Format.formatter -> Ident_set.t -> unit val mk_apply_info : ?loc:Location.t -> Lambda.apply_status -> Lambda.apply_info diff --git a/jscomp/stdlib/camlinternalFormat.js b/jscomp/stdlib/camlinternalFormat.js index 04ccf49e2d..f92e79a745 100644 --- a/jscomp/stdlib/camlinternalFormat.js +++ b/jscomp/stdlib/camlinternalFormat.js @@ -6773,8 +6773,7 @@ function fmt_ebb_of_string(legacy_behavior, str) { var sub_str = $$String.sub(str, str_ind, ind - str_ind + 1); var beg_ind = ind + 1; var match$1 = parse_literal(beg_ind, beg_ind, end_ind); - var end_ind$1 = ind + 1; - var match$2 = parse_literal(str_ind, str_ind, end_ind$1); + var match$2 = parse_literal(str_ind, str_ind, ind + 1); var sub_fmt = match$2[1]; var sub_format = [ /* Format */0, @@ -7823,8 +7822,7 @@ function fmt_ebb_of_string(legacy_behavior, str) { "invalid format %S: at character number %d, %s is incompatible with '%c' in sub-format %S" ])(str, pct_ind, option, symb, subfmt); }; - var end_ind = str.length; - return parse_literal(0, 0, end_ind); + return parse_literal(0, 0, str.length); } function format_of_string_fmtty(str, fmtty) { diff --git a/jscomp/stdlib/camlinternalOO.js b/jscomp/stdlib/camlinternalOO.js index 9c1c76f2ec..e680da7c53 100644 --- a/jscomp/stdlib/camlinternalOO.js +++ b/jscomp/stdlib/camlinternalOO.js @@ -159,8 +159,7 @@ function find(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -422,8 +421,7 @@ function find$1(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -523,8 +521,7 @@ function get_method_label(table, name) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } diff --git a/jscomp/stdlib/format.js b/jscomp/stdlib/format.js index 4e8d5f1eb7..b08b2823c0 100644 --- a/jscomp/stdlib/format.js +++ b/jscomp/stdlib/format.js @@ -378,14 +378,13 @@ function enqueue_advance(state, tok) { } function enqueue_string_as(state, size, s) { - var tok = [ - /* Pp_text */0, - s - ]; return enqueue_advance(state, [ /* record */0, size, - tok, + [ + /* Pp_text */0, + s + ], size ]); } @@ -486,16 +485,14 @@ function scan_push(state, b, tok) { function pp_open_box_gen(state, indent, br_ty) { ++ state[14]; if (state[14] < state[15]) { - var tok = [ - /* Pp_begin */3, - indent, - br_ty - ]; - var size = -state[13]; var elem = [ /* record */0, - size, - tok, + -state[13], + [ + /* Pp_begin */3, + indent, + br_ty + ], 0 ]; return scan_push(state, /* false */0, elem); @@ -741,16 +738,14 @@ function pp_print_if_newline(state, _) { function pp_print_break(state, width, offset) { if (state[14] < state[15]) { - var tok = [ - /* Pp_break */1, - width, - offset - ]; - var size = -state[13]; var elem = [ /* record */0, - size, - tok, + -state[13], + [ + /* Pp_break */1, + width, + offset + ], width ]; return scan_push(state, /* true */1, elem); @@ -771,21 +766,19 @@ function pp_print_cut(state, _) { function pp_open_tbox(state, _) { ++ state[14]; if (state[14] < state[15]) { - var tok_001 = [ - /* Pp_tbox */0, - [ - 0, - /* [] */0 - ] - ]; - var tok = [ - /* Pp_tbegin */4, - tok_001 - ]; var elem = [ /* record */0, 0, - tok, + [ + /* Pp_tbegin */4, + [ + /* Pp_tbox */0, + [ + 0, + /* [] */0 + ] + ] + ], 0 ]; return enqueue_advance(state, elem); @@ -819,16 +812,14 @@ function pp_close_tbox(state, _) { function pp_print_tbreak(state, width, offset) { if (state[14] < state[15]) { - var tok = [ - /* Pp_tbreak */2, - width, - offset - ]; - var size = -state[13]; var elem = [ /* record */0, - size, - tok, + -state[13], + [ + /* Pp_tbreak */2, + width, + offset + ], width ]; return scan_push(state, /* true */1, elem); diff --git a/jscomp/stdlib/scanf.js b/jscomp/stdlib/scanf.js index 17eff29251..124b14e52e 100644 --- a/jscomp/stdlib/scanf.js +++ b/jscomp/stdlib/scanf.js @@ -214,12 +214,11 @@ function open_in(fname) { } else { var ic = Pervasives.open_in(fname); - var param = [ - /* From_file */0, - fname, - ic - ]; - return from_ic(scan_close_at_end, param, ic); + return from_ic(scan_close_at_end, [ + /* From_file */0, + fname, + ic + ], ic); } } @@ -229,12 +228,11 @@ function open_in_bin(fname) { } else { var ic = Pervasives.open_in_bin(fname); - var param = [ - /* From_file */0, - fname, - ic - ]; - return from_ic(scan_close_at_end, param, ic); + return from_ic(scan_close_at_end, [ + /* From_file */0, + fname, + ic + ], ic); } } @@ -1870,11 +1868,10 @@ function make_scanf(ib, _fmt, readers) { } catch (exn){ if (exn[1] === Caml_exceptions.Failure) { - var s$1 = exn[2]; throw [ 0, Scan_failure, - s$1 + exn[2] ]; } else { @@ -1889,11 +1886,11 @@ function make_scanf(ib, _fmt, readers) { case 14 : var fmtty = fmt[2]; scan_caml_string(width_of_pad_opt(fmt[1]), ib); - var s$2 = token(ib); + var s$1 = token(ib); var match$2; try { - var match$3 = CamlinternalFormat.fmt_ebb_of_string(/* None */0, s$2); - var match$4 = CamlinternalFormat.fmt_ebb_of_string(/* None */0, s$2); + var match$3 = CamlinternalFormat.fmt_ebb_of_string(/* None */0, s$1); + var match$4 = CamlinternalFormat.fmt_ebb_of_string(/* None */0, s$1); match$2 = [ /* tuple */0, CamlinternalFormat.type_format(match$3[1], CamlinternalFormatBasics.erase_rel(fmtty)), @@ -1902,11 +1899,10 @@ function make_scanf(ib, _fmt, readers) { } catch (exn$1){ if (exn$1[1] === Caml_exceptions.Failure) { - var s$3 = exn$1[2]; throw [ 0, Scan_failure, - s$3 + exn$1[2] ]; } else { @@ -1918,7 +1914,7 @@ function make_scanf(ib, _fmt, readers) { [ /* Format */0, match$2[1], - s$2 + s$1 ], make_scanf(ib, CamlinternalFormatBasics.concat_fmt(match$2[2], fmt[3]), readers) ]; @@ -1966,7 +1962,7 @@ function make_scanf(ib, _fmt, readers) { /* Some */0, match$6[1] ], width, ib); - var s$4 = token(ib); + var s$2 = token(ib); var str_rest_001$1 = match$6[2]; var str_rest_002$1 = rest$1[2]; var str_rest$1 = [ @@ -1976,7 +1972,7 @@ function make_scanf(ib, _fmt, readers) { ]; return [ /* Cons */0, - s$4, + s$2, make_scanf(ib, str_rest$1, readers) ]; } @@ -1986,10 +1982,10 @@ function make_scanf(ib, _fmt, readers) { if (exit$1 === 1) { var width$1 = width_of_pad_opt(width_opt); scan_chars_in_char_set(char_set, /* None */0, width$1, ib); - var s$5 = token(ib); + var s$3 = token(ib); return [ /* Cons */0, - s$5, + s$3, make_scanf(ib, rest$1, readers) ]; } @@ -2188,11 +2184,10 @@ function bscanf_format(ib, format, f) { } catch (exn){ if (exn[1] === Caml_exceptions.Failure) { - var s = exn[2]; throw [ 0, Scan_failure, - s + exn[2] ]; } else { diff --git a/jscomp/stdlib/sys.js b/jscomp/stdlib/sys.js index 2eb3f8883e..480f3266c0 100644 --- a/jscomp/stdlib/sys.js +++ b/jscomp/stdlib/sys.js @@ -41,14 +41,12 @@ var Break = [ function catch_break(on) { if (on) { - var sig_beh_001 = function () { - throw Break; - }; - var sig_beh = [ - /* Signal_handle */0, - sig_beh_001 - ]; - return Caml_primitive.caml_install_signal_handler(sigint, sig_beh); + return Caml_primitive.caml_install_signal_handler(sigint, [ + /* Signal_handle */0, + function () { + throw Break; + } + ]); } else { return Caml_primitive.caml_install_signal_handler(sigint, /* Signal_default */0); diff --git a/jscomp/test/.depend b/jscomp/test/.depend index d166ac122a..8868afd683 100644 --- a/jscomp/test/.depend +++ b/jscomp/test/.depend @@ -122,6 +122,8 @@ map_test.cmo : test_map_find.cmo test_inline_map2.cmi test_inline_map.cmi \ map_test.cmx : test_map_find.cmx test_inline_map2.cmx test_inline_map.cmx \ ../stdlib/string.cmx ../stdlib/pervasives.cmx mt.cmx ../stdlib/map.cmx \ ../stdlib/list.cmx map_test.cmi +module_parameter_test.cmo : ../stdlib/string.cmi mt.cmo +module_parameter_test.cmx : ../stdlib/string.cmx mt.cmx mt.cmo : ../stdlib/list.cmi mt.cmx : ../stdlib/list.cmx number_lexer.cmo : ../stdlib/sys.cmi ../stdlib/lexing.cmi @@ -474,6 +476,8 @@ map_test.cmo : test_map_find.cmo test_inline_map2.cmi test_inline_map.cmi \ map_test.cmj : test_map_find.cmj test_inline_map2.cmj test_inline_map.cmj \ ../stdlib/string.cmj ../stdlib/pervasives.cmj mt.cmj ../stdlib/map.cmj \ ../stdlib/list.cmj map_test.cmi +module_parameter_test.cmo : ../stdlib/string.cmi mt.cmo +module_parameter_test.cmj : ../stdlib/string.cmj mt.cmj mt.cmo : ../stdlib/list.cmi mt.cmj : ../stdlib/list.cmj number_lexer.cmo : ../stdlib/sys.cmi ../stdlib/lexing.cmi diff --git a/jscomp/test/int_map.js b/jscomp/test/int_map.js index 6323af895c..e44a060e3b 100644 --- a/jscomp/test/int_map.js +++ b/jscomp/test/int_map.js @@ -144,8 +144,7 @@ function find(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -161,8 +160,7 @@ function find(x, _param) { function mem(x, param) { if (param) { - var y = param[2]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(x, param[2]); return +(c === 0 || mem(x, c < 0 ? param[1] : param[4])); } else { @@ -594,9 +592,7 @@ function compare(cmp, m1, m2) { var e1 = _e1; if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(e1[1], e2[1]); if (c !== 0) { return c; } @@ -628,9 +624,7 @@ function equal(cmp, m1, m2) { var equal_aux = function (e1, e2) { if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - return +(x === y && cmp(e1[2], e2[2]) && equal_aux(cons_enum(e1[3], e1[4]), cons_enum(e2[3], e2[4]))); + return +(e1[1] === e2[1] && cmp(e1[2], e2[2]) && equal_aux(cons_enum(e1[3], e1[4]), cons_enum(e2[3], e2[4]))); } else { return /* false */0; diff --git a/jscomp/test/map_test.js b/jscomp/test/map_test.js index 07faeb2792..d4a8c407d9 100644 --- a/jscomp/test/map_test.js +++ b/jscomp/test/map_test.js @@ -154,9 +154,7 @@ function compare(cmp, m1, m2) { var e1 = _e1; if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(e1[1], e2[1]); if (c !== 0) { return c; } diff --git a/jscomp/test/module_parameter_test.d.ts b/jscomp/test/module_parameter_test.d.ts new file mode 100644 index 0000000000..a316edfc6b --- /dev/null +++ b/jscomp/test/module_parameter_test.d.ts @@ -0,0 +1,6 @@ +export var u: (v : any) => any ; +export var N: any ; +export var v0: any ; +export var v: (x : any) => any ; +export var suites: any ; + diff --git a/jscomp/test/module_parameter_test.js b/jscomp/test/module_parameter_test.js new file mode 100644 index 0000000000..5d2e27d881 --- /dev/null +++ b/jscomp/test/module_parameter_test.js @@ -0,0 +1,92 @@ +// Generated CODE, PLEASE EDIT WITH CARE +"use strict"; + +var Mt = require("./mt"); +var $$String = require("../stdlib/string"); + +function u(v) { + return v; +} + +var s = [ + 0, + $$String.make, + $$String.init, + $$String.copy, + $$String.sub, + $$String.fill, + $$String.blit, + $$String.concat, + $$String.iter, + $$String.iteri, + $$String.map, + $$String.mapi, + $$String.trim, + $$String.escaped, + $$String.index, + $$String.rindex, + $$String.index_from, + $$String.rindex_from, + $$String.contains, + $$String.contains_from, + $$String.rcontains_from, + $$String.uppercase, + $$String.lowercase, + $$String.capitalize, + $$String.uncapitalize, + $$String.compare +]; + +var N = [ + 0, + s +]; + +var v0 = 1; + +function v(x) { + return x.length; +} + +var suites_001 = [ + /* tuple */0, + "const", + function () { + return [ + /* Eq */0, + 1, + v0 + ]; + } +]; + +var suites_002 = [ + /* :: */0, + [ + /* tuple */0, + "other", + function () { + return [ + /* Eq */0, + 3, + v("abc") + ]; + } + ], + /* [] */0 +]; + +var suites = [ + /* :: */0, + suites_001, + suites_002 +]; + +Mt.from_pair_suites("module_parameter_test.ml", suites); + +exports.u = u; +exports.N = N; +exports.v0 = v0; +exports.v = v; +exports.suites = suites; +/* Not a pure module */ diff --git a/jscomp/test/module_parameter_test.ml b/jscomp/test/module_parameter_test.ml new file mode 100644 index 0000000000..a266198f7e --- /dev/null +++ b/jscomp/test/module_parameter_test.ml @@ -0,0 +1,23 @@ +module type X = module type of String + + +let u (v : (module X)) = v + +module N = +struct + let s = u (module String) +end + +let v0 = + let module V = (val N.s : X ) in V.length "x" + +let v x = + let module V = (val N.s : X ) in V.length x + + +let suites = Mt.[ + "const", (fun _ -> Eq(1,v0)); + "other", (fun _ -> Eq(3,v "abc")) +] + +;; Mt.from_pair_suites __FILE__ suites diff --git a/jscomp/test/small_inline_test.d.ts b/jscomp/test/small_inline_test.d.ts index c2b0e67c84..9896298e98 100644 --- a/jscomp/test/small_inline_test.d.ts +++ b/jscomp/test/small_inline_test.d.ts @@ -4,4 +4,7 @@ export var hello2: (y : any, f : any) => any ; export var hello3: (y : any, f : any) => any ; export var hello4: (y : any, f : any) => any ; export var hello5: (y : any, f : any) => any ; +export var f: (x : any) => any ; +export var ff: (x : any, y : any) => any ; +export var fff: (x : any, y : any) => any ; diff --git a/jscomp/test/small_inline_test.js b/jscomp/test/small_inline_test.js index fe5de487db..ec7e5d841a 100644 --- a/jscomp/test/small_inline_test.js +++ b/jscomp/test/small_inline_test.js @@ -26,10 +26,35 @@ function hello5(y, f) { return f(y); } +function f(_x) { + while(true) { + var x = _x; + _x = x + 4; + }; +} + +function ff(_x, _y) { + while(true) { + var y = _y; + var x = _x; + _y = x + 1; + _x = y; + }; +} + +function fff(_, _$1) { + while(true) { + + }; +} + exports.$pipe$great = $pipe$great; exports.hello1 = hello1; exports.hello2 = hello2; exports.hello3 = hello3; exports.hello4 = hello4; exports.hello5 = hello5; +exports.f = f; +exports.ff = ff; +exports.fff = fff; /* No side effect */ diff --git a/jscomp/test/small_inline_test.ml b/jscomp/test/small_inline_test.ml index 3fe9c681f5..b845c8299a 100644 --- a/jscomp/test/small_inline_test.ml +++ b/jscomp/test/small_inline_test.ml @@ -16,3 +16,11 @@ let hello4 y f = y |> f let hello5 y f = hello1 y f + +let rec f x = f (x + 1) + +let rec ff x y = ff y ( x + 1) + +let rec fff x y = fff y x + + diff --git a/jscomp/test/test.mllib b/jscomp/test/test.mllib index 3d8fa4b32f..21b09d3523 100644 --- a/jscomp/test/test.mllib +++ b/jscomp/test/test.mllib @@ -153,4 +153,5 @@ lib_js_test small_inline_test ari_regress_test record_with_test -complex_if_test \ No newline at end of file +complex_if_test +module_parameter_test \ No newline at end of file diff --git a/jscomp/test/test_for_map.js b/jscomp/test/test_for_map.js index b2e91933dc..a6a9026d8b 100644 --- a/jscomp/test/test_for_map.js +++ b/jscomp/test/test_for_map.js @@ -144,8 +144,7 @@ function find(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -161,8 +160,7 @@ function find(x, _param) { function mem(x, param) { if (param) { - var y = param[2]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(x, param[2]); return +(c === 0 || mem(x, c < 0 ? param[1] : param[4])); } else { @@ -594,9 +592,7 @@ function compare(cmp, m1, m2) { var e1 = _e1; if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(e1[1], e2[1]); if (c !== 0) { return c; } @@ -628,9 +624,7 @@ function equal(cmp, m1, m2) { var equal_aux = function (e1, e2) { if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - return +(x === y && cmp(e1[2], e2[2]) && equal_aux(cons_enum(e1[3], e1[4]), cons_enum(e2[3], e2[4]))); + return +(e1[1] === e2[1] && cmp(e1[2], e2[2]) && equal_aux(cons_enum(e1[3], e1[4]), cons_enum(e2[3], e2[4]))); } else { return /* false */0; diff --git a/jscomp/test/test_internalOO.js b/jscomp/test/test_internalOO.js index 738cfccc4e..407bab017d 100644 --- a/jscomp/test/test_internalOO.js +++ b/jscomp/test/test_internalOO.js @@ -185,8 +185,7 @@ function find(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -202,8 +201,7 @@ function find(x, _param) { function mem(x, param) { if (param) { - var y = param[2]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(x, param[2]); return +(c === 0 || mem(x, c < 0 ? param[1] : param[4])); } else { @@ -635,9 +633,7 @@ function compare(cmp, m1, m2) { var e1 = _e1; if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(e1[1], e2[1]); if (c !== 0) { return c; } @@ -669,9 +665,7 @@ function equal(cmp, m1, m2) { var equal_aux = function (e1, e2) { if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - return +(Caml_string.caml_string_compare(x, y) === 0 && cmp(e1[2], e2[2]) && equal_aux(cons_enum(e1[3], e1[4]), cons_enum(e2[3], e2[4]))); + return +(Caml_string.caml_string_compare(e1[1], e2[1]) === 0 && cmp(e1[2], e2[2]) && equal_aux(cons_enum(e1[3], e1[4]), cons_enum(e2[3], e2[4]))); } else { return /* false */0; @@ -889,8 +883,7 @@ function find$1(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -906,8 +899,7 @@ function find$1(x, _param) { function mem$1(x, param) { if (param) { - var y = param[2]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(x, param[2]); return +(c === 0 || mem$1(x, c < 0 ? param[1] : param[4])); } else { @@ -1339,9 +1331,7 @@ function compare$1(cmp, m1, m2) { var e1 = _e1; if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(e1[1], e2[1]); if (c !== 0) { return c; } @@ -1373,9 +1363,7 @@ function equal$1(cmp, m1, m2) { var equal_aux = function (e1, e2) { if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - return +(Caml_string.caml_string_compare(x, y) === 0 && cmp(e1[2], e2[2]) && equal_aux(cons_enum$1(e1[3], e1[4]), cons_enum$1(e2[3], e2[4]))); + return +(Caml_string.caml_string_compare(e1[1], e2[1]) === 0 && cmp(e1[2], e2[2]) && equal_aux(cons_enum$1(e1[3], e1[4]), cons_enum$1(e2[3], e2[4]))); } else { return /* false */0; @@ -1593,8 +1581,7 @@ function find$2(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -1610,8 +1597,7 @@ function find$2(x, _param) { function mem$2(x, param) { if (param) { - var y = param[2]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(x, param[2]); return +(c === 0 || mem$2(x, c < 0 ? param[1] : param[4])); } else { @@ -2043,9 +2029,7 @@ function compare$2(cmp, m1, m2) { var e1 = _e1; if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(e1[1], e2[1]); if (c !== 0) { return c; } @@ -2077,9 +2061,7 @@ function equal$2(cmp, m1, m2) { var equal_aux = function (e1, e2) { if (e1) { if (e2) { - var y = e2[1]; - var x = e1[1]; - return +(x === y && cmp(e1[2], e2[2]) && equal_aux(cons_enum$2(e1[3], e1[4]), cons_enum$2(e2[3], e2[4]))); + return +(e1[1] === e2[1] && cmp(e1[2], e2[2]) && equal_aux(cons_enum$2(e1[3], e1[4]), cons_enum$2(e2[3], e2[4]))); } else { return /* false */0; diff --git a/jscomp/test/test_map_find.js b/jscomp/test/test_map_find.js index 4f87d23417..94519468b4 100644 --- a/jscomp/test/test_map_find.js +++ b/jscomp/test/test_map_find.js @@ -127,8 +127,7 @@ function find(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_primitive.caml_int_compare(x, y); + var c = Caml_primitive.caml_int_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -297,8 +296,7 @@ function find$1(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } diff --git a/jscomp/test/test_string_map.js b/jscomp/test/test_string_map.js index 2eb92bc2b9..40ef1154d7 100644 --- a/jscomp/test/test_string_map.js +++ b/jscomp/test/test_string_map.js @@ -124,8 +124,7 @@ function find(x, _param) { while(true) { var param = _param; if (param) { - var y = param[2]; - var c = Caml_string.caml_string_compare(x, y); + var c = Caml_string.caml_string_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } diff --git a/jscomp/test/ticker.js b/jscomp/test/ticker.js index 773e6f2864..46266385c5 100644 --- a/jscomp/test/ticker.js +++ b/jscomp/test/ticker.js @@ -275,8 +275,7 @@ function find(x, _param) { while(true) { var param = _param; if (param) { - var prim = param[2]; - var c = Caml_primitive.caml_compare(x, prim); + var c = Caml_primitive.caml_compare(x, param[2]); if (c) { _param = c < 0 ? param[1] : param[4]; } @@ -292,8 +291,7 @@ function find(x, _param) { function mem(x, param) { if (param) { - var prim = param[2]; - var c = Caml_primitive.caml_compare(x, prim); + var c = Caml_primitive.caml_compare(x, param[2]); return +(c === 0 || mem(x, c < 0 ? param[1] : param[4])); } else { @@ -725,9 +723,7 @@ function compare(cmp, m1, m2) { var e1 = _e1; if (e1) { if (e2) { - var prim = e2[1]; - var prim$1 = e1[1]; - var c = Caml_primitive.caml_compare(prim$1, prim); + var c = Caml_primitive.caml_compare(e1[1], e2[1]); if (c !== 0) { return c; } @@ -759,9 +755,7 @@ function equal(cmp, m1, m2) { var equal_aux = function (e1, e2) { if (e1) { if (e2) { - var prim = e2[1]; - var prim$1 = e1[1]; - return +(Caml_primitive.caml_compare(prim$1, prim) === 0 && cmp(e1[2], e2[2]) && equal_aux(cons_enum(e1[3], e1[4]), cons_enum(e2[3], e2[4]))); + return +(Caml_primitive.caml_compare(e1[1], e2[1]) === 0 && cmp(e1[2], e2[2]) && equal_aux(cons_enum(e1[3], e1[4]), cons_enum(e2[3], e2[4]))); } else { return /* false */0;