Skip to content

Commit 7969b56

Browse files
author
Hongbo Zhang
committed
tweak ... lambda_exports...
1 parent a8e5ca4 commit 7969b56

14 files changed

+149
-56
lines changed

jscomp/lam_analysis.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ let is_closed_by set lam =
452452
Ident_map.is_empty (free_variables set (Ident_map.empty ) lam )
453453

454454

455+
(** A bit consverative , it should be empty *)
455456
let is_closed lam =
456-
Ident_map.is_empty (free_variables Ident_set.empty Ident_map.empty lam)
457+
Ident_map.for_all (fun k _ -> Ident.global k)
458+
(free_variables Ident_set.empty Ident_map.empty lam)
457459

jscomp/lam_analysis.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ val is_closed : Lambda.lambda -> bool
4141

4242

4343

44+
4445
type stats =
4546
{
4647
mutable top : bool ;
@@ -57,6 +58,7 @@ type stats =
5758
}
5859

5960
val param_map_of_list : Ident.t list -> stats Ident_map.t
61+
6062
val free_variables : Ident_set.t -> stats Ident_map.t -> Lambda.lambda -> stats Ident_map.t
6163

6264
val small_inline_size : int

jscomp/lam_compile.ml

Lines changed: 104 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,108 @@ let rec
8181
| _ ->
8282
f (E.ml_var_dot id name)
8383
)
84+
(* TODO: how nested module call would behave,
85+
In the future, we should keep in track of if
86+
it is fully applied from [Lapply]
87+
Seems that the module dependency is tricky..
88+
should we depend on [Pervasives] or not?
89+
90+
we can not do this correctly for the return value,
91+
however we can inline the definition in Pervasives
92+
TODO:
93+
[Pervasives.print_endline]
94+
[Pervasives.prerr_endline]
95+
@param id external module id
96+
@param number the index of the external function
97+
@param env typing environment
98+
@param args arguments
99+
*)
100+
101+
and get_exp_with_args (cxt : Lam_compile_defs.cxt) lam args_lambda
102+
(id : Ident.t) (pos : int) env : Js_output.t =
103+
let args_code, args =
104+
List.fold_right
105+
(fun (x : Lambda.lambda) (args_code, args) ->
106+
match x with
107+
| Lprim (Pgetglobal i, [] ) ->
108+
(* when module is passed as an argument - unpack to an array
109+
for the function, generative module or functor can be a function,
110+
however it can not be global -- global can only module
111+
*)
112+
113+
args_code, (Lam_compile_global.get_exp (i, env, true) :: args)
114+
| _ ->
115+
begin match compile_lambda {cxt with st = NeedValue; should_return = False} x with
116+
| {block = a; value = Some b} ->
117+
(a @ args_code), (b :: args )
118+
| _ -> assert false
119+
end
120+
) args_lambda ([], []) in
121+
122+
Lam_compile_env.find_and_add_if_not_exist (id,pos) env ~not_found:(fun id ->
123+
(** This can not happen since this id should be already consulted by type checker
124+
Worst case
125+
{[
126+
E.index m (pos + 1)
127+
]}
128+
shift by one (due to module encoding)
129+
*)
130+
Js_output.handle_block_return cxt.st cxt.should_return lam args_code @@
131+
E.str ~pure:false (Printf.sprintf "Err %s %d %d"
132+
id.name
133+
id.flags
134+
pos
135+
))
136+
137+
~found:(fun {id; name;arity; closed_lambda ; _} ->
138+
match closed_lambda with
139+
| Some (Lfunction (_, params, body))
140+
when Ext_list.same_length params args_lambda ->
141+
compile_lambda cxt
142+
(Lam_beta_reduce.propogate_beta_reduce cxt.meta params body args_lambda)
143+
| _ ->
144+
Js_output.handle_block_return cxt.st cxt.should_return lam args_code @@
145+
(match id, name, args with
146+
| {name = "Pervasives"; _}, "^", [ e0 ; e1] ->
147+
E.string_append e0 e1
148+
| {name = "Pervasives"; _}, "string_of_int", [e]
149+
-> E.int_to_string e
150+
| {name = "Pervasives"; _}, "print_endline", ([ _ ] as args) ->
151+
E.seq (E.dump Log args) (E.unit ())
152+
| {name = "Pervasives"; _}, "prerr_endline", ([ _ ] as args) ->
153+
E.seq (E.dump Error args) (E.unit ())
154+
| _ ->
155+
156+
157+
let rec aux (acc : J.expression)
158+
(arity : Lam_stats.function_arities) args (len : int) =
159+
match arity, len with
160+
| _, 0 ->
161+
acc (** All arguments consumed so far *)
162+
| Determin (a, (x,_) :: rest, b), len ->
163+
let x =
164+
if x = 0
165+
then 1
166+
else x in (* Relax when x = 0 *)
167+
if len >= x
168+
then
169+
let first_part, continue = (Ext_list.take x args) in
170+
aux
171+
(E.call ~info:{arity=Full} acc first_part)
172+
(Determin (a, rest, b))
173+
continue (len - x)
174+
else acc
175+
(* alpha conversion now? --
176+
Since we did an alpha conversion before so it is not here
177+
*)
178+
| Determin (a, [], b ), _ ->
179+
(* can not happen, unless it's an exception ? *)
180+
E.call acc args
181+
| NA, _ ->
182+
E.call acc args
183+
in
184+
aux (E.ml_var_dot id name) arity args (List.length args ))
185+
)
84186

85187
and compile_let flag (cxt : Lam_compile_defs.cxt) id (arg : Lambda.lambda) : Js_output.t =
86188

@@ -315,28 +417,8 @@ and
315417
(Lapply (an, (args' @ args), (Lam_util.mk_apply_info NA)))
316418
(* External function calll *)
317419
| Lapply(Lprim(Pfield n, [ Lprim(Pgetglobal id,[])]), args_lambda,_info) ->
318-
let [@warning "-8" (* non-exhaustive pattern*)] (args_code,args) =
319-
args_lambda
320-
|> List.map
321-
(
322-
fun (x : Lambda.lambda) ->
323-
match x with
324-
| Lprim (Pgetglobal i, []) ->
325-
(* when module is passed as an argument - unpack to an array
326-
for the function, generative module or functor can be a function,
327-
however it can not be global -- global can only module
328-
*)
329-
[], Lam_compile_global.get_exp (i, env,true)
330-
| _ ->
331-
begin
332-
match compile_lambda
333-
{cxt with st = NeedValue ; should_return = False} x with
334-
| {block = a; value = Some b} -> a,b
335-
| _ -> assert false
336-
end)
337-
|> List.split in
338-
Js_output.handle_block_return st should_return lam (List.concat args_code )
339-
(Lam_compile_global.get_exp_with_args id n env args)
420+
421+
get_exp_with_args cxt lam args_lambda(* args_code *) id n env (* args *)
340422

341423

342424
| Lapply(fn,args_lambda, info) ->

jscomp/lam_compile_global.mli

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@
2424

2525
val get_exp : Lam_compile_env.key -> J.expression
2626

27-
(*
28-
@param id external module id
29-
@param number the index of the external function
30-
@param env typing environment
31-
@param args arguments
32-
*)
33-
val get_exp_with_args : Ident.t -> int -> Env.t -> J.expression list -> J.expression
27+
3428

3529
val query_lambda : Ident.t -> Env.t -> Lambda.lambda

jscomp/lam_compile_group.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ let lambda_as_module
354354
(lam : Lambda.lambda) =
355355
begin
356356
Lam_current_unit.set_file filename ;
357-
Lam_current_unit.iset_debug_file "pervasives.ml";
357+
Lam_current_unit.set_debug_file "pervasives.ml";
358358
Ext_pervasives.with_file_as_chan
359359
(Ext_filename.chop_extension ~loc:__LOC__ filename ^ ".js")
360360
(fun chan -> Js_dump.dump_program (compile ~filename false env sigs lam) chan)

jscomp/lam_stats_util.ml

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -256,16 +256,28 @@ let export_to_cmj
256256
then Some lambda
257257
else None
258258
else
259-
if Lam_analysis.size lambda < Lam_analysis.small_inline_size
260-
&&
261-
Lam_analysis.is_closed lambda
262-
(* global need re-assocate when do the beta reduction *)
263-
then
264-
begin
265-
Ext_log.dwarn __LOC__ "%s recorded for inlining @." x.name ;
266-
Some lambda
267-
end
268-
else None in
259+
let lam_size = Lam_analysis.size lambda in
260+
(* let is_closed = Lam_analysis.is_closed lambda in *)
261+
let free_variables =
262+
Lam_analysis.free_variables Ident_set.empty Ident_map.empty
263+
lambda in
264+
if lam_size < Lam_analysis.small_inline_size &&
265+
Ident_map.is_empty free_variables
266+
(* global need re-assocate when do the beta reduction *)
267+
then
268+
begin
269+
Ext_log.dwarn __LOC__ "%s recorded for inlining @." x.name ;
270+
Some lambda
271+
end
272+
else
273+
begin
274+
Ext_log.dwarn __LOC__ "%s : %d : {%s} not inlined @."
275+
x.name lam_size
276+
(String.concat ", " @@
277+
List.map (fun x -> x.Ident.name) @@ Ident_map.keys free_variables) ;
278+
None
279+
end
280+
in
269281
String_map.add x.name Js_cmj_format.{arity ; closed_lambda } acc
270282
)
271283
String_map.empty

jscomp/stdlib/buffer.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ function add_substring(b, s, offset, len) {
117117
}
118118

119119
function add_subbytes(b, s, offset, len) {
120-
return add_substring(b, Bytes.unsafe_to_string(s), offset, len);
120+
return add_substring(b, Caml_string.bytes_to_string(s), offset, len);
121121
}
122122

123123
function add_string(b, s) {
@@ -132,7 +132,7 @@ function add_string(b, s) {
132132
}
133133

134134
function add_bytes(b, s) {
135-
return add_string(b, Bytes.unsafe_to_string(s));
135+
return add_string(b, Caml_string.bytes_to_string(s));
136136
}
137137

138138
function add_buffer(b, bs) {

jscomp/stdlib/camlinternalFormat.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
'use strict';
33

44
var Bytes = require("./bytes");
5+
var Caml_io = require("../runtime/caml_io");
56
var Caml_float = require("../runtime/caml_float");
67
var Pervasives = require("./pervasives");
78
var Caml_exceptions = require("../runtime/caml_exceptions");
@@ -4435,7 +4436,7 @@ function output_acc(o, _acc) {
44354436
return acc[2](o);
44364437
case 7 :
44374438
output_acc(o, acc[1]);
4438-
return Pervasives.flush(o);
4439+
return Caml_io.caml_ml_flush(o);
44394440
case 8 :
44404441
output_acc(o, acc[1]);
44414442
return Pervasives.invalid_arg(acc[2]);
@@ -4448,7 +4449,8 @@ function output_acc(o, _acc) {
44484449
return Pervasives.output_string(o, acc[2]);
44494450
case 2 :
44504451
output_acc(o, acc[1]);
4451-
return Pervasives.output_char(o, acc[2]);
4452+
var prim = acc[2];
4453+
return Caml_io.caml_ml_output_char(o, prim);
44524454

44534455
}
44544456
};

jscomp/stdlib/digest.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Generated CODE, PLEASE EDIT WITH CARE
22
'use strict';
33

4-
var Bytes = require("./bytes");
54
var Pervasives = require("./pervasives");
65
var Caml_exceptions = require("../runtime/caml_exceptions");
76
var Char = require("./char");
@@ -14,7 +13,7 @@ function string(str) {
1413
}
1514

1615
function bytes(b) {
17-
return string(Bytes.unsafe_to_string(b));
16+
return string(Caml_string.bytes_to_string(b));
1817
}
1918

2019
function substring(str, ofs, len) {
@@ -27,7 +26,7 @@ function substring(str, ofs, len) {
2726
}
2827

2928
function subbytes(b, ofs, len) {
30-
return substring(Bytes.unsafe_to_string(b), ofs, len);
29+
return substring(Caml_string.bytes_to_string(b), ofs, len);
3130
}
3231

3332
function file(filename) {

jscomp/stdlib/format.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Generated CODE, PLEASE EDIT WITH CARE
22
'use strict';
33

4+
var Caml_io = require("../runtime/caml_io");
45
var Caml_exceptions = require("../runtime/caml_exceptions");
56
var Pervasives = require("./pervasives");
67
var Caml_primitive = require("../runtime/caml_primitive");
@@ -1063,7 +1064,7 @@ function pp_set_formatter_out_channel(state, os) {
10631064
return Pervasives.output_substring(os, param, param$1, param$2);
10641065
};
10651066
state[18] = function () {
1066-
return Pervasives.flush(os);
1067+
return Caml_io.caml_ml_flush(os);
10671068
};
10681069
state[19] = function (param) {
10691070
return display_newline(state, param);
@@ -1168,7 +1169,7 @@ function formatter_of_out_channel(oc) {
11681169
return make_formatter(function (param, param$1, param$2) {
11691170
return Pervasives.output_substring(oc, param, param$1, param$2);
11701171
}, function () {
1171-
return Pervasives.flush(oc);
1172+
return Caml_io.caml_ml_flush(oc);
11721173
});
11731174
}
11741175

jscomp/stdlib/marshal.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Generated CODE, PLEASE EDIT WITH CARE
22
'use strict';
33

4-
var Bytes = require("./bytes");
54
var Pervasives = require("./pervasives");
65
var Caml_primitive = require("../runtime/caml_primitive");
6+
var Caml_string = require("../runtime/caml_string");
77

88
function to_buffer(buff, ofs, len, v, flags) {
99
if (ofs < 0 || len < 0 || ofs > buff.length - len) {
@@ -45,7 +45,7 @@ function from_bytes(buff, ofs) {
4545
}
4646

4747
function from_string(buff, ofs) {
48-
return from_bytes(Bytes.unsafe_of_string(buff), ofs);
48+
return from_bytes(Caml_string.bytes_of_string(buff), ofs);
4949
}
5050

5151
function to_channel(prim, prim$1, prim$2) {

jscomp/stdlib/scanf.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ var file_buffer_size = [
155155
];
156156

157157
function scan_close_at_end(ic) {
158-
Pervasives.close_in(ic);
158+
Caml_primitive.caml_ml_close_channel(ic);
159159
throw Caml_exceptions.End_of_file;
160160
}
161161

jscomp/test/ext_string.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ function escaped(s) {
131131
};
132132
};
133133
if (needs_escape(0)) {
134-
return Caml_string.bytes_to_string(Ext_bytes.escaped(Bytes.unsafe_of_string(s)));
134+
return Caml_string.bytes_to_string(Ext_bytes.escaped(Caml_string.bytes_of_string(s)));
135135
}
136136
else {
137137
return s;

jscomp/test/test_bytes.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
// Generated CODE, PLEASE EDIT WITH CARE
22
'use strict';
33

4-
var Bytes = require("../stdlib/bytes");
54
var Caml_string = require("../runtime/caml_string");
65

76
function f(v) {
8-
return Bytes.unsafe_to_string(v);
7+
return Caml_string.bytes_to_string(v);
98
}
109

1110
function ff(v) {

0 commit comments

Comments
 (0)