Skip to content

Commit 0bb3c8e

Browse files
authored
Merge pull request #2609 from BuckleScript/gpr_2608
fix #2608
2 parents 35374ea + f7f295e commit 0bb3c8e

11 files changed

+708
-310
lines changed

jscomp/core/bs_conditional_initial.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
let setup_env () =
2727
#if BS_DEBUG then
28-
Js_config.set_debug_file "test_bool_equal.ml";
28+
Js_config.set_debug_file "gpr_2608_test.ml";
2929
#end
3030
Lexer.replace_directive_bool "BS" true;
3131
Lexer.replace_directive_string "BS_VERSION" Bs_version.version

jscomp/core/js_output.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ let output_of_block_and_expression
9090
| Assign n, ReturnFalse -> make (block @ [S.assign n exp])
9191
| EffectCall, ReturnTrue _ -> make (block @ [S.return_stmt exp]) ~finished:True
9292
| (Declare _ | Assign _), ReturnTrue _ ->
93-
make [S.unknown_lambda lam] ~finished:True
94-
| NeedValue, _ -> make block ~value:exp
93+
make [S.unknown_lambda lam] ~finished:True
94+
| NeedValue, (ReturnTrue _ | ReturnFalse) ->
95+
make block ~value:exp
9596

9697
let statement_of_opt_expr (x : J.expression option) : J.statement =
9798
match x with

jscomp/core/lam_compile.ml

Lines changed: 147 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ let rec flat_catches acc (x : Lam.t)
5151
flat_catches ((code,handler,bindings)::acc) l
5252
| _ -> acc, x
5353

54-
let flatten_caches x = flat_catches [] x
54+
let flatten_caches x : (int * Lam.t * Ident.t list ) list * Lam.t =
55+
flat_catches [] x
5556

5657

5758

@@ -101,12 +102,13 @@ type default_case =
101102
non-toplevel, it will explode code very quickly
102103
*)
103104
let rec
104-
compile_external_field
105+
compile_external_field (* Like [List.empty]*)
105106
(cxt : Lam_compile_context.t)
106-
lam
107+
(lam : Lam.t)
107108
(id : Ident.t)
108109
(pos : int)
109-
env : Js_output.t =
110+
(env : Env.t)
111+
: Js_output.t =
110112
let f = Js_output.output_of_expression cxt.st cxt.should_return lam in
111113
match Lam_compile_env.cached_find_ml_id_pos id pos env with
112114
| {id; name; closed_lambda } ->
@@ -151,17 +153,23 @@ let rec
151153

152154
and compile_external_field_apply
153155
(cxt : Lam_compile_context.t)
154-
lam
155-
args_lambda
156+
(lam : Lam.t) (* original lambda*)
157+
(args_lambda : Lam.t list)
156158
(id : Ident.t)
157-
(pos : int) env : Js_output.t =
158-
match Lam_compile_env.cached_find_ml_id_pos
159-
id pos env with
159+
(pos : int)
160+
(env : Env.t) : Js_output.t =
161+
match
162+
Lam_compile_env.cached_find_ml_id_pos
163+
id pos env
164+
with
160165
| {id; name;arity; closed_lambda ; _} ->
161166
let args_code, args =
162167
Ext_list.fold_right
163168
(fun (x : Lam.t) (args_code, args) ->
164-
match compile_lambda {cxt with st = NeedValue; should_return = ReturnFalse} x with
169+
match
170+
compile_lambda
171+
{cxt with st = NeedValue; should_return = ReturnFalse} x
172+
with
165173
| {block = a; value = Some b} ->
166174
(Ext_list.append a args_code), (b :: args )
167175
| _ -> assert false
@@ -223,8 +231,13 @@ and compile_external_field_apply
223231
args (List.length args ))
224232

225233

226-
and compile_let let_kind (cxt : Lam_compile_context.t) id (arg : Lam.t) : Js_output.t =
227-
compile_lambda {cxt with st = Declare (let_kind, id); should_return = ReturnFalse } arg
234+
and compile_let
235+
(let_kind : Lam_compile_context.let_kind)
236+
(cxt : Lam_compile_context.t)
237+
(id : J.ident)
238+
(arg : Lam.t) : Js_output.t =
239+
compile_lambda
240+
{cxt with st = Declare (let_kind, id); should_return = ReturnFalse } arg
228241
(**
229242
The second return values are values which need to be wrapped using
230243
[caml_update_dummy]
@@ -339,7 +352,8 @@ and compile_recursive_let ~all_bindings
339352
| _ -> assert false
340353
end
341354
| Lvar _ ->
342-
compile_lambda {cxt with st = Declare (Alias ,id); should_return = ReturnFalse } arg, []
355+
compile_lambda
356+
{cxt with st = Declare (Alias ,id); should_return = ReturnFalse } arg, []
343357
| _ ->
344358
(* pathological case:
345359
fail to capture taill call?
@@ -362,13 +376,16 @@ and compile_recursive_let ~all_bindings
362376
fun _-> print_endline "hey"; v ()
363377
]}
364378
*)
365-
compile_lambda {cxt with st = Declare (Alias ,id); should_return = ReturnFalse } arg, []
379+
compile_lambda
380+
{cxt with st = Declare (Alias ,id); should_return = ReturnFalse } arg, []
366381

367382
and compile_recursive_lets_aux cxt id_args : Js_output.t =
368383
(* #1716 *)
369-
let output_code, ids = Ext_list.fold_right
384+
let output_code, ids =
385+
Ext_list.fold_right
370386
(fun (ident,arg) (acc, ids) ->
371-
let code, declare_ids = compile_recursive_let ~all_bindings:id_args cxt ident arg in
387+
let code, declare_ids =
388+
compile_recursive_let ~all_bindings:id_args cxt ident arg in
372389
(code ++ acc, Ext_list.append declare_ids ids )
373390
) id_args (Js_output.dummy, [])
374391
in
@@ -388,7 +405,8 @@ and compile_recursive_lets cxt id_args : Js_output.t =
388405
| [ ] -> assert false
389406
| first::rest ->
390407
let acc = compile_recursive_lets_aux cxt first in
391-
List.fold_left (fun acc x -> acc ++ compile_recursive_lets_aux cxt x ) acc rest
408+
List.fold_left
409+
(fun acc x -> acc ++ compile_recursive_lets_aux cxt x ) acc rest
392410
end
393411
and compile_general_cases :
394412
'a .
@@ -456,14 +474,18 @@ and compile_general_cases :
456474
in
457475
let body =
458476
table
459-
|> Ext_list.stable_group (fun (_,lam) (_,lam1) -> Lam_analysis.eq_lambda lam lam1)
477+
|> Ext_list.stable_group
478+
(fun (_,lam) (_,lam1)
479+
-> Lam_analysis.eq_lambda lam lam1)
460480
|> Ext_list.flat_map
461481
(fun group ->
462482
group
463483
|> Ext_list.map_last
464484
(fun last (x,lam) ->
465485
if last
466-
then {J.case = x; body = Js_output.to_break_block (compile_lambda cxt lam) }
486+
then {J.case = x;
487+
body =
488+
Js_output.to_break_block (compile_lambda cxt lam) }
467489
else { case = x; body = [],false }))
468490
(* TODO: we should also group default *)
469491
(* The last clause does not need [break]
@@ -472,11 +494,15 @@ and compile_general_cases :
472494
in
473495
[switch ?default ?declaration v body]
474496

475-
and compile_cases cxt = compile_general_cases (fun x -> E.small_int x) E.int_equal cxt
476-
(fun ?default ?declaration e clauses -> S.int_switch ?default ?declaration e clauses)
497+
and compile_cases cxt =
498+
compile_general_cases (fun x -> E.small_int x) E.int_equal cxt
499+
(fun ?default ?declaration e clauses ->
500+
S.int_switch ?default ?declaration e clauses)
477501

478-
and compile_string_cases cxt = compile_general_cases E.str E.string_equal cxt
479-
(fun ?default ?declaration e clauses -> S.string_switch ?default ?declaration e clauses)
502+
and compile_string_cases cxt =
503+
compile_general_cases E.str E.string_equal cxt
504+
(fun ?default ?declaration e clauses ->
505+
S.string_switch ?default ?declaration e clauses)
480506
(* TODO: optional arguments are not good
481507
for high order currying *)
482508
and
@@ -500,15 +526,15 @@ and
500526

501527

502528
| Lapply{
503-
fn = Lapply{ fn = an; args = args'; status = App_na ; };
529+
fn = Lapply{ fn = an; args = fn_args; status = App_na ; };
504530
args;
505531
status = App_na; loc }
506532
->
507533
(* After inlining we can generate such code,
508534
see {!Ari_regress_test}
509535
*)
510536
compile_lambda cxt
511-
(Lam.apply an (Ext_list.append args' args) loc App_na )
537+
(Lam.apply an (Ext_list.append fn_args args) loc App_na )
512538
(* External function calll *)
513539
| Lapply{ fn =
514540
Lprim{primitive = Pfield (n,_);
@@ -650,43 +676,107 @@ and
650676
(* Invariant: if [should_return], then [st] will not be [NeedValue] *)
651677
->
652678
compile_lambda cxt (Lam.sequand l r )
653-
| _ ->
654-
let l_block,l_expr =
655-
match compile_lambda {cxt with st = NeedValue; should_return = ReturnFalse} l with
656-
| {block = a; value = Some b} -> a, b
657-
| _ -> assert false
658-
in
659-
let r_block, r_expr =
660-
match compile_lambda {cxt with st = NeedValue; should_return = ReturnFalse} r with
661-
| {block = a; value = Some b} -> a, b
662-
| _ -> assert false
663-
in
664-
let args_code = Ext_list.append l_block r_block in
665-
let exp = E.and_ l_expr r_expr in
666-
Js_output.output_of_block_and_expression st should_return lam args_code exp
679+
| {should_return = ReturnFalse } ->
680+
let new_cxt = {cxt with st = NeedValue} in
681+
match
682+
compile_lambda new_cxt l with
683+
| { value = None } -> assert false
684+
| {block = l_block; value = Some l_expr} ->
685+
match compile_lambda new_cxt r
686+
with
687+
| { value = None } -> assert false
688+
| {block = []; value = Some r_expr}
689+
->
690+
Js_output.output_of_block_and_expression
691+
st
692+
should_return lam l_block (E.and_ l_expr r_expr)
693+
| { block = r_block; value = Some r_expr} ->
694+
begin match cxt.st with
695+
| Assign v ->
696+
(* Refernece Js_output.output_of_block_and_expression *)
697+
Js_output.make
698+
(
699+
l_block @
700+
[S.if_ l_expr (r_block @ [ S.assign v r_expr])
701+
~else_:[S.assign v E.caml_false]
702+
]
703+
)
704+
| Declare (_kind,v) ->
705+
(* Refernece Js_output.output_of_block_and_expression *)
706+
Js_output.make
707+
(
708+
l_block @
709+
[ S.define_variable ~kind:Variable v E.caml_false ;
710+
S.if_ l_expr
711+
(r_block @ [S.assign v r_expr])])
712+
| EffectCall
713+
| NeedValue ->
714+
let v = Ext_ident.create_tmp () in
715+
Js_output.make
716+
(S.define_variable ~kind:Variable v E.caml_false ::
717+
l_block @
718+
[S.if_ l_expr
719+
(r_block @ [
720+
S.assign v r_expr
721+
]
722+
)
723+
]
724+
)
725+
~value:(E.var v)
726+
end
667727
end
668-
669728
| Lprim {primitive = Psequor; args = [l;r]}
670729
->
671730
begin match cxt with
672731
| {should_return = ReturnTrue _ }
673732
(* Invariant: if [should_return], then [st] will not be [NeedValue] *)
674733
->
675734
compile_lambda cxt @@ Lam.sequor l r
676-
| _ ->
677-
let l_block,l_expr =
678-
match compile_lambda {cxt with st = NeedValue; should_return = ReturnFalse} l with
679-
| {block = a; value = Some b} -> a, b
680-
| _ -> assert false
681-
in
682-
let r_block, r_expr =
683-
match compile_lambda {cxt with st = NeedValue; should_return = ReturnFalse} r with
684-
| {block = a; value = Some b} -> a, b
685-
| _ -> assert false
686-
in
687-
let args_code = Ext_list.append l_block r_block in
688-
let exp = E.or_ l_expr r_expr in
689-
Js_output.output_of_block_and_expression st should_return lam args_code exp
735+
| {should_return = ReturnFalse } ->
736+
let new_cxt = {cxt with st = NeedValue} in
737+
match compile_lambda new_cxt l with
738+
| {value = None } -> assert false
739+
| {block = l_block; value = Some l_expr} ->
740+
match compile_lambda new_cxt r with
741+
| {value = None} -> assert false
742+
| {block = []; value = Some r_expr} ->
743+
let exp = E.or_ l_expr r_expr in
744+
Js_output.output_of_block_and_expression
745+
st should_return lam l_block exp
746+
| {block = r_block; value = Some r_expr} ->
747+
begin match cxt.st with
748+
| Assign v ->
749+
(* Reference Js_output.output_of_block_and_expression *)
750+
Js_output.make
751+
(l_block @
752+
[ S.if_ (E.not l_expr)
753+
(r_block @ [
754+
S.assign v r_expr
755+
])
756+
~else_:[S.assign v E.caml_true] ])
757+
| Declare(_kind,v) ->
758+
Js_output.make
759+
(
760+
l_block @
761+
[ S.define_variable ~kind:Variable v E.caml_true;
762+
S.if_ (E.not l_expr)
763+
(r_block @ [S.assign v r_expr])
764+
]
765+
)
766+
| EffectCall
767+
| NeedValue ->
768+
let v = Ext_ident.create_tmp () in
769+
Js_output.make
770+
( l_block @
771+
[S.define_variable ~kind:Variable v E.caml_true;
772+
S.if_ (E.not l_expr)
773+
(r_block @ [
774+
S.assign v r_expr
775+
])
776+
]
777+
)
778+
~value:(E.var v)
779+
end
690780
end
691781
| Lprim {primitive = Pdebugger ; _}
692782
->
@@ -1154,7 +1244,9 @@ and
11541244
when branches are minimial (less than 2)
11551245
*)
11561246
let v = Ext_ident.create_tmp () in
1157-
Js_output.make (S.declare_variable ~kind:Variable v :: compile_whole {cxt with st = Assign v})
1247+
Js_output.make
1248+
(S.declare_variable ~kind:Variable v ::
1249+
compile_whole {cxt with st = Assign v})
11581250
~value:(E.var v)
11591251

11601252
| Declare (kind,id) ->

jscomp/test/.depend

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ gpr_2316_test.cmj : mt.cmj ../runtime/js.cmj
304304
gpr_2474.cmj :
305305
gpr_2487.cmj : ../others/belt.cmj
306306
gpr_2503_test.cmj : mt.cmj ../runtime/js.cmj
307+
gpr_2608_test.cmj : mt.cmj ../stdlib/list.cmj
307308
gpr_405_test.cmj : ../stdlib/hashtbl.cmj gpr_405_test.cmi
308309
gpr_441.cmj :
309310
gpr_459_test.cmj : mt.cmj

jscomp/test/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ OTHERS := test_literals a test_ari test_export2 test_internalOO test_obj_simple_
241241
gpr_2487\
242242
gpr_2503_test\
243243
block_alias_test\
244+
gpr_2608_test\
244245
# bs_uncurry_test
245246
# needs Lam to get rid of Uncurry arity first
246247
# simple_derive_test

jscomp/test/bs_hashtbl_string_test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var hashString = (function (str) {
2323
while(i !== 0) {
2424
hash = (hash * 33) ^ str.charCodeAt(--i);
2525
}
26-
return hash
26+
return hash
2727
}
2828
);
2929

jscomp/test/ext_string_test.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,23 @@ function trim(s) {
5959
var i = 0;
6060
var j = s.length;
6161
while((function () {
62-
var u = s.charCodeAt(i);
63-
return +(i < j && (u === /* "\t" */9 || u === /* "\n" */10 || u === /* " " */32));
62+
var tmp = /* false */0;
63+
if (i < j) {
64+
var u = s.charCodeAt(i);
65+
tmp = +(u === /* "\t" */9 || u === /* "\n" */10 || u === /* " " */32);
66+
}
67+
return tmp;
6468
})()) {
6569
i = i + 1 | 0;
6670
};
6771
var k = j - 1 | 0;
6872
while((function () {
69-
var u = s.charCodeAt(k);
70-
return +(k >= i && (u === /* "\t" */9 || u === /* "\n" */10 || u === /* " " */32));
73+
var tmp = /* false */0;
74+
if (k >= i) {
75+
var u = s.charCodeAt(k);
76+
tmp = +(u === /* "\t" */9 || u === /* "\n" */10 || u === /* " " */32);
77+
}
78+
return tmp;
7179
})()) {
7280
k = k - 1 | 0;
7381
};

0 commit comments

Comments
 (0)