Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
- Represent optional parameters with defaults structurally, removing downstream name-based detection and producing more consistent JavaScript parameter names. https://github.com/rescript-lang/rescript/pull/8580
- Sync the platform npm package's compiler binaries (`packages/@rescript/<platform>/bin`) via dune promotion on every `dune build`, instead of Makefile/CI copy steps that only ran when make did: a plain `dune build` can no longer leave `cli/*.js` and the test harnesses running a stale compiler. https://github.com/rescript-lang/rescript/pull/8560
- Remove unused compiler IR definitions, modules, helpers, error variants, and Typedtree fields. https://github.com/rescript-lang/rescript/pull/8551 https://github.com/rescript-lang/rescript/pull/8555
- Make Lambda-to-Lam conversion structural for lets, switches, static exits, recursive binding groups, exception packing, and eliminated identity operations. Semantic rewrites now happen during Lambda production or in named Lam passes; obsolete conversion state and `Lam_scc` are removed. https://github.com/rescript-lang/rescript/pull/8604
- Remove obsolete Lambda and Lam primitives and align their scalar constant representations. Lambda and Lam now use `int32` integers and matching char, string, float, and bigint cases; Lambda strings carry their parsed output delimiter, assert-false is distinct from integer zero, and dead typedtree integer variants are removed. https://github.com/rescript-lang/rescript/pull/8604
- Make locally abstract value constraints (`let f: type a. t = value`) structural in the parsetree, remove the obsolete `Pexp_newtype` and `Texp_newtype` wrapper metadata, and keep the old encoding confined to the frozen external-PPX bridge. The CMT magic number is bumped to `Caml1999T024`. https://github.com/rescript-lang/rescript/pull/8575
- Eliminate the `Pjs_fn_make`/`Pjs_fn_make_unit` arity-adjustment primitives and the `unsafe_adjust_to_arity` machinery: with structural arity, functions are constructed at their final arity, so the enforcement layer (and the active-pattern currying split it compensated for) is deleted. Generated code improves: no adapter closures for patterns on mutable fields, better constant propagation and name preservation, and recursive modules whose members are plain functions compile statically without the runtime bootstrap. https://github.com/rescript-lang/rescript/pull/8570
- Cleanups enabled by structural arity: remove the unreachable `Too_many_arguments` error and the `?in_function` threading through the type checker that existed only to decorate it; remove the dead `function$`-vs-arrow unification bridge, `Ctype.arity`, and the unused parsetree arity helpers; deduplicate the analysis arrow-flattening helpers. https://github.com/rescript-lang/rescript/pull/8569
Expand Down
2 changes: 0 additions & 2 deletions analysis/src/hint.ml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ let loc_item_to_type_hint ~state ~full:{file; package} loc_item =
| Const_char _ -> "char"
| Const_string _ -> "string"
| Const_float _ -> "float"
| Const_int32 _ -> "int32"
| Const_int64 _ -> "int64"
| Const_bigint _ -> "bigint")
| Typed (_, t, loc_kind) ->
let from_type typ =
Expand Down
2 changes: 0 additions & 2 deletions analysis/src/hover.ml
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,6 @@ let new_hover ~state ~full:{file; package} ~supports_markdown_links loc_item =
| Const_char _ -> "char"
| Const_string _ -> "string"
| Const_float _ -> "float"
| Const_int32 _ -> "int32"
| Const_int64 _ -> "int64"
| Const_bigint _ -> "bigint"))
| Typed (_, t, loc_kind) -> (
let from_type ?docstring ?constructor typ =
Expand Down
6 changes: 0 additions & 6 deletions compiler/core/j.ml
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ and expression_desc =
| Seq of expression * expression
| Cond of expression * expression * expression
| Bin of binop * expression * expression
| FlatCall of expression * expression
(* f.apply(null,args) -- Fully applied guaranteed
TODO: once we know args's shape --
if it's know at compile time, we can turn it into
f(args[0], args[1], ... )
*)
| Call of expression * expression list * Js_call_info.t
(* Analysze over J expression is hard since,
some primitive call is translated
Expand Down
7 changes: 3 additions & 4 deletions compiler/core/js_analyzer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ let rec no_side_effect_expression_desc (x : J.expression_desc) =
| Cond (a, b, c) -> no_side_effect a && no_side_effect b && no_side_effect c
| Call ({expression_desc = Str {txt = "Array.isArray"}}, [e], _) ->
no_side_effect e
| FlatCall _ | Call _ | New _ | Raw_js_code _ (* actually true? *) -> false
| Call _ | New _ | Raw_js_code _ (* actually true? *) -> false
| Await _ -> false
| Spread _ -> false
| Record_rest _ -> false
Expand Down Expand Up @@ -245,9 +245,8 @@ let rec eq_expression ({expression_desc = x0} : J.expression)
eq_expression_list ls0 ls1 && flag0 = flag1 && info0 = info1
| _ -> false)
| Length _ | Is_null_or_undefined _ | String_append _ | Typeof _ | Js_not _
| Js_bnot _ | In _ | Cond _ | FlatCall _ | New _ | Fun _ | Raw_js_code _
| Array _ | Caml_block_tag _ | Object _ | Tagged_template _ | Await _
| Record_rest _ ->
| Js_bnot _ | In _ | Cond _ | New _ | Fun _ | Raw_js_code _ | Array _
| Caml_block_tag _ | Object _ | Tagged_template _ | Await _ | Record_rest _ ->
false
| Spread _ -> false

Expand Down
13 changes: 2 additions & 11 deletions compiler/core/js_dump.ml
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ let rec exp_need_paren ?(arrow = false) (e : J.expression) =
| Length _ | Call _ | Caml_block_tag _ | Seq _ | Static_index _ | Cond _
| Bin _ | Is_null_or_undefined _ | String_index _ | Array_index _
| String_append _ | Var _ | Undefined _ | Null | Str _ | Array _
| Caml_block _ | FlatCall _ | Typeof _ | Number _ | Js_not _ | Js_bnot _
| In _ | Bool _ | New _ ->
| Caml_block _ | Typeof _ | Number _ | Js_not _ | Js_bnot _ | In _ | Bool _
| New _ ->
false
| Await _ -> false
| Spread _ -> false
Expand Down Expand Up @@ -740,15 +740,6 @@ and expression_desc cxt ~(level : int) f x : cxt =
else (
Curry_gen.pp_app_any f;
P.paren_group f 0 (fun _ -> arguments cxt f [e; E.array el]))))
| FlatCall (e, el) ->
P.group f 0 (fun _ ->
let cxt = expression ~level:15 cxt f e in
P.string f L.dot;
P.string f L.apply;
P.paren_group f 1 (fun _ ->
P.string f L.null;
comma_sp f;
expression ~level:1 cxt f el))
| Tagged_template (call_expr, string_args, value_args) ->
let cxt = expression cxt ~level f call_expr in
P.string f "`";
Expand Down
2 changes: 0 additions & 2 deletions compiler/core/js_dump_lit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ let bind = "bind"

let math = "Math"

let apply = "apply"

let null = "null"

let undefined = "undefined"
Expand Down
6 changes: 0 additions & 6 deletions compiler/core/js_exp_make.ml
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,6 @@ let nil : t = {expression_desc = Null; comment = None; source_loc = None}
let call ?comment ~info e0 args : t =
{expression_desc = Call (e0, args, info); comment; source_loc = None}

(* TODO: optimization when es is known at compile time
to be an array
*)
let flat_call ?comment e0 es : t =
{expression_desc = FlatCall (e0, es); comment; source_loc = None}

let tagged_template ?comment call_expr string_args value_args : t =
{
expression_desc = Tagged_template (call_expr, string_args, value_args);
Expand Down
2 changes: 0 additions & 2 deletions compiler/core/js_exp_make.mli
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,6 @@ val not : t -> t

val call : ?comment:string -> info:Js_call_info.t -> t -> t list -> t

val flat_call : ?comment:string -> t -> t -> t

val tagged_template : ?comment:string -> t -> t list -> t list -> t

val new_ : ?comment:string -> J.expression -> J.expression list -> t
Expand Down
4 changes: 0 additions & 4 deletions compiler/core/js_record_fold.ml
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,6 @@ let expression_desc : 'a. ('a, expression_desc) fn =
let st = _self.expression _self st _x1 in
let st = _self.expression _self st _x2 in
st
| FlatCall (_x0, _x1) ->
let st = _self.expression _self st _x0 in
let st = _self.expression _self st _x1 in
st
| Call (_x0, _x1, _x2) ->
let st = _self.expression _self st _x0 in
let st = list _self.expression _self st _x1 in
Expand Down
3 changes: 0 additions & 3 deletions compiler/core/js_record_iter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ let expression_desc : expression_desc fn =
| Bin (_x0, _x1, _x2) ->
_self.expression _self _x1;
_self.expression _self _x2
| FlatCall (_x0, _x1) ->
_self.expression _self _x0;
_self.expression _self _x1
| Call (_x0, _x1, _x2) ->
_self.expression _self _x0;
list _self.expression _self _x1
Expand Down
4 changes: 0 additions & 4 deletions compiler/core/js_record_map.ml
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,6 @@ let expression_desc : expression_desc fn =
let _x1 = _self.expression _self _x1 in
let _x2 = _self.expression _self _x2 in
Bin (_x0, _x1, _x2)
| FlatCall (_x0, _x1) ->
let _x0 = _self.expression _self _x0 in
let _x1 = _self.expression _self _x1 in
FlatCall (_x0, _x1)
| Call (_x0, _x1, _x2) ->
let _x0 = _self.expression _self _x0 in
let _x1 = list _self.expression _self _x1 in
Expand Down
32 changes: 14 additions & 18 deletions compiler/core/lam.ml
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ let switch lam (lam_switch : lambda_switch) : t =
| Switch_int _ | Switch_constructor _ -> None)
in
action_or_switch action
| Lconst (Const_int {i; comment}) ->
| Lconst (Const_int i) ->
(* Because of inlining and dead code, we might be looking at a value of unexpected type
e.g. an integer, so the const case might not be found *)
let i = Int32.to_int i in
Expand All @@ -295,7 +295,7 @@ let switch lam (lam_switch : lambda_switch) : t =
| Lambda.Switch_int ordinal when ordinal = i -> Some action
| Switch_constructor
(Constant {tag_type = Some (Variant_runtime.Int value)})
when comment = None && value = i ->
when value = i ->
Some action
| Switch_int _ | Switch_constructor _ -> None)
in
Expand Down Expand Up @@ -360,10 +360,7 @@ let staticcatch a b c : t = Lstaticcatch (a, b, c)
let staticraise a b : t = Lstaticraise (a, b)

module Lift = struct
let int i : t = Lconst (Const_int {i; comment = None})

(* let int32 i : t =
Lconst ((Const_int32 i)) *)
let int i : t = Lconst (Const_int i)

let bool b = if b then true_ else false_

Expand All @@ -377,7 +374,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t =
match args with
| [Lconst a] -> (
match (prim, a) with
| Pnegint, Const_int {i} -> Lift.int (Int32.neg i)
| Pnegint, Const_int i -> Lift.int (Int32.neg i)
(* | Pfloatofint, ( (Const_int a)) *)
(* -> Lift.float (float_of_int a) *)
| Pintoffloat, Const_float a ->
Expand All @@ -394,7 +391,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t =
| [Lconst a; Lconst b] -> (
match (prim, a, b) with
| Pintcomp cmp, Const_int a, Const_int b ->
Lift.bool (Lam_compat.cmp_int32 cmp a.i b.i)
Lift.bool (Lam_compat.cmp_int32 cmp a b)
| Pfloatcomp cmp, Const_float a, Const_float b ->
(* FIXME: could raise? *)
Lift.bool
Expand All @@ -417,8 +414,8 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t =
| _ -> assert false)
| ( ( Paddint | Psubint | Pmulint | Pdivint | Pmodint | Pandint | Porint
| Pxorint | Plslint | Plsrint | Pasrint ),
Const_int {i = aa},
Const_int {i = bb} ) -> (
Const_int aa,
Const_int bb ) -> (
(* WE SHOULD keep it as [int], to preserve types *)
let int_ = Lift.int in
match prim with
Expand Down Expand Up @@ -446,7 +443,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t =
Lift.string (a ^ b)
| ( (Pstringrefs | Pstringrefu),
Const_string {s = a; delim = None},
Const_int {i = b} ) -> (
Const_int b ) -> (
try Lift.char (Char.code (String.get a (Int32.to_int b)))
with _ -> default ())
| _ -> default ())
Expand Down Expand Up @@ -518,7 +515,8 @@ let rec complete_range (sw_consts : (Lambda.switch_key * _) list) ~(start : int)

let rec eval_const_as_bool (v : Lam_constant.t) : bool option =
match v with
| Const_int {i = x} -> Some (x <> 0l)
| Const_int x -> Some (x <> 0l)
| Const_assertfalse -> Some false
| Const_char x -> Some (x <> 0)
| Const_js_false | Const_js_null | Const_module_alias | Const_js_undefined _
->
Expand All @@ -545,9 +543,9 @@ let if_ (a : t) (b : t) (c : t) : t =
| None -> Lifthenelse (a, b, c))
| _ -> (
match (b, c) with
| _, Lconst (Const_int {comment = Pt_assertfalse}) ->
| _, Lconst Const_assertfalse ->
seq a b (* TODO: we could customize more cases *)
| Lconst (Const_int {comment = Pt_assertfalse}), _ -> seq a c
| Lconst Const_assertfalse, _ -> seq a c
| Lconst Const_js_true, Lconst Const_js_false ->
if has_boolean_type a != None then a else Lifthenelse (a, b, c)
| Lconst Const_js_false, Lconst Const_js_true -> (
Expand All @@ -561,10 +559,8 @@ let if_ (a : t) (b : t) (c : t) : t =
| _ -> (
match a with
| Lprim
{
primitive = Pisout off;
args = [Lconst (Const_int {i = range}); Lvar xx];
} -> (
{primitive = Pisout off; args = [Lconst (Const_int range); Lvar xx]}
-> (
let range = Int32.to_int range in
match c with
| Lswitch
Expand Down
20 changes: 11 additions & 9 deletions compiler/core/lam_analysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
(**used in effect analysis, it is sound but not-complete *)
let not_zero_constant (x : Lam_constant.t) =
match x with
| Const_int {i} -> i <> 0l
| Const_int i -> i <> 0l
| Const_assertfalse -> false
| Const_bigint (_, i) -> i <> "0"
| _ -> false

Expand All @@ -44,6 +45,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
match args with
| [_; Lconst cst] -> not_zero_constant cst
| _ -> false)
| Peliminated _ -> assert false
| Pcreate_extension _ | Ptypeof | Pis_null | Pis_not_none | Psome
| Psome_not_nest | Pis_undefined | Pis_null_undefined | Pnull_to_opt
| Pnull_undefined_to_opt | Pjs_object_create _ | Pimport _
Expand Down Expand Up @@ -84,17 +86,16 @@ let rec no_side_effects (lam : Lam.t) : bool =
| Pisout _
(* Operations on big arrays: (unsafe, #dimensions, kind, layout) *)
(* Compile time constants *)
| Poffsetint _ | Pstringadd | Pfn_arity | Pwrap_exn | Phash
| Phash_mixstring | Phash_mixint | Phash_finalmix
| Poffsetint _ | Pstringadd | Pfn_arity | Phash | Phash_mixstring
| Phash_mixint | Phash_finalmix
| Praw_js_code
{code_info = Exp (Js_function _ | Js_literal _) | Stmt Js_stmt_comment}
->
true
(* A tagged template invokes its tag at runtime, so it always has side
effects. *)
| Ptagged_template | Pjs_apply | Pjs_runtime_apply | Pjs_call _ | Pinit_mod
| Pupdate_mod | Pjs_object_get _ | Pjs_object_set _ | Pdebugger
| Pjs_fn_method
| Ptagged_template | Pjs_apply | Pjs_call _ | Pinit_mod | Pupdate_mod
| Pjs_object_get _ | Pjs_object_set _ | Pdebugger | Pjs_fn_method
(* Await promise *)
| Pawait
(* TODO *)
Expand Down Expand Up @@ -190,9 +191,10 @@ let rec size (lam : Lam.t) =

and size_constant x =
match x with
| Const_int _ | Const_constructor _ | Const_char _ | Const_float _
| Const_bigint _ | Const_pointer _ | Const_js_null | Const_js_undefined _
| Const_module_alias | Const_js_true | Const_js_false ->
| Const_int _ | Const_assertfalse | Const_constructor _ | Const_char _
| Const_float _ | Const_bigint _ | Const_pointer _ | Const_js_null
| Const_js_undefined _ | Const_module_alias | Const_js_true | Const_js_false
->
1
| Const_string _ -> 1
| Const_some s -> size_constant s
Expand Down
37 changes: 23 additions & 14 deletions compiler/core/lam_compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,25 @@ type initialization = J.block
non-toplevel, it will explode code very quickly
*)

(* Semantic SCC already ran in [Lambda_scc.bind_rec]. JS still wants
functions before values so dummy / updateDummy init is well-ordered. *)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is dummy / updateDummy init?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it refers to the code below -- can clean up the comment

let functions_before_values (group : (Ident.t * Lam.t) list) =
if
Ext_list.for_all group (fun (_, x) ->
match x with
| Lfunction _ -> true
| _ -> false)
then group
else
List.sort
(fun (_, lama) (_, lamb) ->
match ((lama : Lam.t), (lamb : Lam.t)) with
| Lfunction _, Lfunction _ -> 0
| Lfunction _, _ -> -1
| _, Lfunction _ -> 1
| _, _ -> 0)
group

let compile output_prefix =
(* When compiling a read from another module, a nested source path like
Other.A.B.make reaches this point as nested module-field reads:
Expand Down Expand Up @@ -553,8 +572,8 @@ let compile output_prefix =
]}
*)
(compile_lambda {cxt with continuation = Declare (Alias, id)} arg, [])
and compile_recursive_lets_aux cxt (id_args : Lam_scc.bindings) : Js_output.t
=
and compile_recursive_lets_aux cxt (id_args : (Ident.t * Lam.t) list) :
Js_output.t =
(* #1716 *)
let output_code, ids =
Ext_list.fold_right id_args (Js_output.dummy, [])
Expand All @@ -570,14 +589,7 @@ let compile output_prefix =
and compile_recursive_lets cxt id_args : Js_output.t =
match id_args with
| [] -> Js_output.dummy
| _ -> (
let id_args_group = Lam_scc.scc_bindings id_args in
match id_args_group with
| [] -> assert false
| first :: rest ->
let acc = compile_recursive_lets_aux cxt first in
Ext_list.fold_left rest acc (fun acc x ->
Js_output.append_output acc (compile_recursive_lets_aux cxt x)))
| _ -> compile_recursive_lets_aux cxt (functions_before_values id_args)
and compile_general_cases :
'a.
make_exp:('a -> J.expression) ->
Expand Down Expand Up @@ -1977,10 +1989,7 @@ let compile output_prefix =
match (direction, finish) with
| ( Upto,
( Lprim
{
primitive = Psubint;
args = [new_finish; Lconst (Const_int {i = 1l})];
}
{primitive = Psubint; args = [new_finish; Lconst (Const_int 1l)]}
| Lprim {primitive = Poffsetint -1; args = [new_finish]} ) ) ->
compile_for id start new_finish Up body lambda_cxt
| _ ->
Expand Down
4 changes: 2 additions & 2 deletions compiler/core/lam_compile_const.ml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ and translate (x : Lam_constant.t) : J.expression =
except for the list constructor [] which is the number 0 *)
if name = "[]" then E.int 0l ~comment:"[]" else E.str name
| Const_constructor {tag_type = Some t} -> E.tag_type t
| Const_int {i; comment} ->
E.int i ?comment:(Lam_constant.string_of_pointer_info comment)
| Const_int i -> E.int i
| Const_assertfalse -> E.int 0l ~comment:"assert_false"
| Const_char i -> Js_of_lam_string.const_char i
| Const_bigint (sign, i) -> E.bigint sign i
| Const_float f -> E.float f (* TODO: preserve float *)
Expand Down
5 changes: 4 additions & 1 deletion compiler/core/lam_compile_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,10 @@ let compile (output_prefix : string) export_idents hoisted (lam : Lambda.lambda)
Ext_log.dwarn ~__POS__ "export idents: %s/%d" id.name id.stamp);
Lam_compile_env.reset ()
in
let lam, may_required_modules = Lam_convert.convert export_ident_sets lam in
let lam, may_required_modules = Lam_convert.convert lam in
let lam =
Lam_pass_collapse_var_aliases.collapse ~exports:export_ident_sets lam
in

let lam = d "initial" lam in
let lam = Lam_pass_deep_flatten.deep_flatten lam in
Expand Down
Loading
Loading