Skip to content

Commit

Permalink
Merge e00b589 into 0bb3c8e
Browse files Browse the repository at this point in the history
  • Loading branch information
bobzhang committed Mar 12, 2018
2 parents 0bb3c8e + e00b589 commit 73c906d
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 288 deletions.
4 changes: 2 additions & 2 deletions jscomp/all.depend
Expand Up @@ -588,8 +588,8 @@ core/js_output.cmx : core/lam_compile_context.cmx core/lam_analysis.cmx \
core/js_analyzer.cmx core/j.cmx ext/ext_list.cmx core/js_output.cmi
core/lam_compile_global.cmx : core/ocaml_types.cmx core/lam_module_ident.cmx \
core/lam_compile_env.cmx core/lam.cmx core/js_stmt_make.cmx \
core/js_output.cmx core/js_of_lam_module.cmx core/js_exp_make.cmx \
core/j.cmx ext/ext_list.cmx core/lam_compile_global.cmi
core/js_of_lam_module.cmx core/js_exp_make.cmx core/j.cmx \
ext/ext_list.cmx core/lam_compile_global.cmi
core/lam_dispatch_primitive.cmx : core/js_stmt_make.cmx \
core/js_runtime_modules.cmx core/js_of_lam_tuple.cmx \
core/js_of_lam_exception.cmx core/js_of_lam_array.cmx core/js_long.cmx \
Expand Down
103 changes: 47 additions & 56 deletions jscomp/core/js_output.ml
Expand Up @@ -24,11 +24,6 @@








module E = Js_exp_make
module S = Js_stmt_make

Expand All @@ -49,11 +44,6 @@ type continuation = Lam_compile_context.continuation
let make ?value ?(finished=False) block =
{ block ; value ; finished }

let of_stmt ?value ?(finished = False) stmt =
{ block = [stmt] ; value ; finished }

let of_block ?value ?(finished = False) block =
{ block ; value ; finished }

let dummy =
{value = None; block = []; finished = Dummy }
Expand Down Expand Up @@ -94,47 +84,65 @@ let output_of_block_and_expression
| NeedValue, (ReturnTrue _ | ReturnFalse) ->
make block ~value:exp

let statement_of_opt_expr (x : J.expression option) : J.statement =
match x with
| None -> S.empty_stmt
| Some x when Js_analyzer.no_side_effect_expression x ->
S.empty_stmt
(* TODO, pure analysis in lambda instead *)
| Some x -> S.exp x

let rec unroll_block (block : J.block) =

let block_with_opt_expr block (x : J.expression option) : J.block =
match x with
| None -> block
| Some x when Js_analyzer.no_side_effect_expression x -> block
| Some x -> block @ [S.exp x ]

let opt_expr_with_block (x : J.expression option) block : J.block =
match x with
| None -> block
| Some x when Js_analyzer.no_side_effect_expression x -> block
| Some x -> (S.exp x) :: block


let rec unnest_block (block : J.block) : J.block =
match block with
| [{statement_desc = Block block}] -> unroll_block block
| [{statement_desc = Block block}] -> unnest_block block
| _ -> block

let to_block ( x : t) : J.block =
let output_as_block ( x : t) : J.block =
match x with
| {block; value = opt; finished} ->
let block = unroll_block block in
let block = unnest_block block in
if finished = True then block
else
begin match opt with
| None -> block (* TODO, pure analysis in lambda instead *)
| Some x when Js_analyzer.no_side_effect_expression x -> block
| Some x -> block @ [S.exp x ]
end
block_with_opt_expr block opt


let to_break_block (x : t) : J.block * bool =
let block = unnest_block x.block in
match x with
| {finished = True; block ; _ } ->
unroll_block block, false
| {finished = True; _ } ->
block, false
(* value does not matter when [finished] is true
TODO: check if it has side efects
*)
| {block; value = None; finished } ->
let block = unroll_block block in
| { value = None; finished } ->
block, (match finished with | True -> false | (False | Dummy) -> true )

| {block; value = opt; _} ->
let block = unroll_block block in
block @ [statement_of_opt_expr opt], true
| {value = Some _ as opt; _} ->
block_with_opt_expr block opt, true


let rec append (x : t ) (y : t ) : t =
(** TODO: make everything expression make inlining hard, and code not readable?
1. readability dpends on how we print the expression
2. inlining needs generate symbols, which are statements, type mismatch
we need capture [Exp e]
can we call them all [statement]? statement has no value
*)
(* | {block = [{statement_desc = Exp e }]; value = None ; _}, _ *)
(* -> *)
(* append { x with block = []; value = Some e} y *)
(* | _ , {block = [{statement_desc = Exp e }]; value = None ; _} *)
(* -> *)
(* append x { y with block = []; value = Some e} *)

let rec append_output (x : t ) (y : t ) : t =
match x , y with (* ATTTENTION: should not optimize [opt_e2], it has to conform to [NeedValue]*)
| {finished = True; _ }, _ -> x
| _, {block = []; value= None; finished = Dummy } -> x
Expand All @@ -151,34 +159,17 @@ let rec append (x : t ) (y : t ) : t =
{block = []; value = Some (E.seq e1 e2); finished}
(* {block = [S.exp e1]; value = Some e2(\* (E.seq e1 e2) *\); finished} *)

(** TODO: make everything expression make inlining hard, and code not readable?
1. readability pends on how we print the expression
2. inlining needs generate symbols, which are statements, type mismatch
we need capture [Exp e]
can we call them all [statement]? statement has no value
*)
(* | {block = [{statement_desc = Exp e }]; value = None ; _}, _ *)
(* -> *)
(* append { x with block = []; value = Some e} y *)
(* | _ , {block = [{statement_desc = Exp e }]; value = None ; _} *)
(* -> *)
(* append x { y with block = []; value = Some e} *)

| {block = block1; value = opt_e1; _}, {block = block2; value = opt_e2; finished} ->
let block1 = unroll_block block1 in
make (block1 @ (statement_of_opt_expr opt_e1 :: unroll_block block2))
let block1 = unnest_block block1 in
make (block1 @ (opt_expr_with_block opt_e1 @@ unnest_block block2))
?value:opt_e2 ~finished


module Ops = struct
let (++) (x : t ) (y : t ) : t = append x y
end


(* Fold right is more efficient *)
let concat (xs : t list) : t =
Ext_list.fold_right (fun x acc -> append x acc) xs dummy
Ext_list.fold_right (fun x acc -> append_output x acc) xs dummy

let to_string x =
Js_dump.string_of_block (to_block x)
Js_dump.string_of_block (output_as_block x)
35 changes: 19 additions & 16 deletions jscomp/core/js_output.mli
Expand Up @@ -46,6 +46,7 @@ type t = {
value : J.expression option;
finished : finished
}

(** When [finished] is true the block is already terminated,
value does not make sense
[finished] default to false, which is conservative
Expand All @@ -57,29 +58,31 @@ val make :
J.block ->
t

val of_stmt :
?value: J.expression ->
?finished:finished ->
J.statement ->
t

val of_block :
?value:J.expression ->
?finished:finished ->
J.block ->
t

val to_block :
val output_as_block :
t ->
J.block

val to_break_block :
t ->
J.block * bool
(* the second argument is
[true] means [break] needed
When we know the output is gonna finished true
we can reduce
{[
return xx ;
break
]}
into
{[
return ;
]}
*)

val append_output: t -> t -> t

module Ops : sig
val (++) : t -> t -> t
end

val dummy : t

Expand Down

0 comments on commit 73c906d

Please sign in to comment.