Skip to content

Commit 1adc1bc

Browse files
authored
Merge pull request #4072 from BuckleScript/clean_up_method_encoding
clean up method compilation
2 parents 6393339 + b6dbd79 commit 1adc1bc

File tree

12 files changed

+425
-426
lines changed

12 files changed

+425
-426
lines changed

jscomp/core/lam_analysis.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
175175
| Pjs_unsafe_downgrade _
176176
| Pdebugger
177177
| Pjs_fn_run _
178-
| Pjs_fn_method _ | Pjs_fn_runmethod _
178+
| Pjs_fn_method _
179179
(* TODO *)
180180
| Praw_js_code_exp _
181181
| Praw_js_code_stmt _

jscomp/core/lam_compile.ml

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,13 +1432,14 @@ and compile_prim (prim_info : Lam.prim_info) (lambda_cxt : Lam_compile_context.t
14321432
we need mark something that such eta-conversion can not be simplified in some cases
14331433
*)
14341434

1435-
| {primitive = Pjs_unsafe_downgrade (name,loc); args = [obj]}
1436-
when not (Ext_string.ends_with name Literals.setter_suffix)
1435+
| {primitive = Pjs_unsafe_downgrade {name = property;loc; setter }; args = [obj]}
1436+
14371437
->
14381438
(**
14391439
either a getter {[ x #. height ]} or {[ x ## method_call ]}
14401440
*)
1441-
let property = Lam_methname.translate ~loc name in
1441+
assert (not setter);
1442+
14421443
(match compile_lambda {lambda_cxt with continuation = NeedValue Not_tail} obj
14431444
with
14441445
| {value = None} -> assert false
@@ -1451,7 +1452,7 @@ and compile_prim (prim_info : Lam.prim_info) (lambda_cxt : Lam_compile_context.t
14511452
| Some (x, b) ->
14521453
Ext_list.append_one block x, E.dot (E.var b) property in
14531454
Js_output.output_of_block_and_expression lambda_cxt.continuation blocks ret)
1454-
| {primitive = Pjs_fn_run arity; args = args_lambda}
1455+
| {primitive = Pjs_fn_run _; args = args_lambda}
14551456
->
14561457
(* 1. prevent eta-conversion
14571458
by using [App_js_full]
@@ -1463,10 +1464,11 @@ and compile_prim (prim_info : Lam.prim_info) (lambda_cxt : Lam_compile_context.t
14631464
(match args_lambda with
14641465
| [Lprim{
14651466
primitive =
1466-
Pjs_unsafe_downgrade(method_name,loc);
1467-
args = [obj]} as fn;
1468-
arg]
1469-
->
1467+
Pjs_unsafe_downgrade {name = property; loc; setter = true};
1468+
args = args_l} ;
1469+
arg] (** x##name arg could be specialized as a setter *)
1470+
->
1471+
let obj = Ext_list.singleton_exn args_l in
14701472
let need_value_no_return_cxt = {lambda_cxt with continuation = NeedValue Not_tail} in
14711473
let obj_output = compile_lambda need_value_no_return_cxt obj in
14721474
let arg_output = compile_lambda need_value_no_return_cxt arg in
@@ -1482,49 +1484,23 @@ and compile_prim (prim_info : Lam.prim_info) (lambda_cxt : Lam_compile_context.t
14821484
| {value = None}, _ | _, {value = None} -> assert false
14831485
| {block = obj_block; value = Some obj },
14841486
{block = arg_block; value = Some value}
1485-
->
1486-
if Ext_string.ends_with method_name Literals.setter_suffix then
1487-
let property =
1488-
Lam_methname.translate ~loc
1489-
(String.sub method_name 0
1490-
(String.length method_name - Literals.setter_suffix_len)) in
1491-
match Js_ast_util.named_expression obj with
1492-
| None ->
1493-
cont obj_block arg_block None
1494-
(E.seq (E.assign (E.dot obj property) value) E.unit)
1495-
| Some (obj_code, obj)
1496-
->
1497-
cont obj_block arg_block (Some obj_code)
1498-
(E.seq (E.assign (E.dot (E.var obj) property) value) E.unit)
1499-
else
1500-
compile_lambda lambda_cxt
1501-
(Lam.apply fn [arg]
1502-
Location.none (* TODO *) App_js_full))
1487+
->
1488+
match Js_ast_util.named_expression obj with
1489+
| None ->
1490+
cont obj_block arg_block None
1491+
(E.seq (E.assign (E.dot obj property) value) E.unit)
1492+
| Some (obj_code, obj)
1493+
->
1494+
cont obj_block arg_block (Some obj_code)
1495+
(E.seq (E.assign (E.dot (E.var obj) property) value) E.unit)
1496+
)
15031497
| fn :: rest ->
15041498
compile_lambda lambda_cxt
15051499
(Lam.apply fn rest
15061500
Location.none (*TODO*)
15071501
App_js_full)
15081502
| [] -> assert false)
15091503

1510-
| {primitive = Pjs_fn_runmethod arity ; args }
1511-
->
1512-
(match args with
1513-
| (Lprim{primitive = Pjs_unsafe_downgrade (name,loc);
1514-
args = [ _ ]} as fn)
1515-
:: _obj
1516-
:: rest ->
1517-
(* assert (Ident.same id2 id) ; *)
1518-
(* we ignore the computation of [_obj],
1519-
since our ast writer
1520-
{[ obj#.f (x,y)
1521-
]}
1522-
-->
1523-
{[ runmethod2 f obj#.f x y]}
1524-
*)
1525-
compile_lambda lambda_cxt (Lam.apply fn rest loc App_js_full)
1526-
| _ -> assert false)
1527-
15281504
| {primitive = Pjs_fn_method arity; args = args_lambda} ->
15291505
(match args_lambda with
15301506
| [Lfunction{arity = len; params; body} ]

jscomp/core/lam_compile_primitive.ml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,6 @@ let translate loc
121121
| Pdebugger
122122
| Pjs_fn_run _
123123
| Pjs_fn_make _
124-
125-
| Pjs_fn_runmethod _
126124
-> assert false (* already handled by {!Lam_compile} *)
127125
| Pjs_fn_method _ -> assert false
128126
| Pglobal_exception id ->

jscomp/core/lam_convert.ml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i
528528
| "#fn_run" | "#method_run" -> Pjs_fn_run(Ext_pervasives.nat_of_string_exn p.prim_native_name)
529529
| "#fn_mk" -> Pjs_fn_make (Ext_pervasives.nat_of_string_exn p.prim_native_name)
530530
| "#fn_method" -> Pjs_fn_method (Ext_pervasives.nat_of_string_exn p.prim_native_name)
531-
| "#unsafe_downgrade" -> Pjs_unsafe_downgrade (Ext_string.empty,loc)
531+
| "#unsafe_downgrade" -> Pjs_unsafe_downgrade {name = Ext_string.empty; loc ; setter = false}
532532
| _ -> Location.raise_errorf ~loc
533533
"@{<error>Error:@} internal error, using unrecorgnized primitive %s" s
534534
in
@@ -634,11 +634,18 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i
634634
| Lsend (kind, a,b,ls, loc) ->
635635
(* Format.fprintf Format.err_formatter "%a@." Printlambda.lambda b ; *)
636636
(match convert_aux b with
637-
| Lprim {primitive = Pjs_unsafe_downgrade(_,loc); args}
637+
| Lprim {primitive = Pjs_unsafe_downgrade {loc}; args}
638638
->
639639
begin match kind, ls with
640640
| Public (Some name), [] ->
641-
prim ~primitive:(Pjs_unsafe_downgrade (name,loc))
641+
let setter = Ext_string.ends_with name Literals.setter_suffix in
642+
let property =
643+
if setter then
644+
Lam_methname.translate ~loc
645+
(String.sub name 0
646+
(String.length name - Literals.setter_suffix_len))
647+
else Lam_methname.translate ~loc name in
648+
prim ~primitive:(Pjs_unsafe_downgrade {name = property;loc; setter})
642649
~args loc
643650
| _ -> assert false
644651
end

jscomp/core/lam_primitive.ml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,12 @@ type t =
139139
(* Integer to external pointer *)
140140

141141
| Pdebugger
142-
| Pjs_unsafe_downgrade of string * Location.t
142+
| Pjs_unsafe_downgrade of
143+
{
144+
name : string ;
145+
setter : bool;
146+
loc : Location.t;
147+
}
143148
| Pinit_mod
144149
| Pupdate_mod
145150
| Praw_js_code_exp of string
@@ -148,7 +153,7 @@ type t =
148153
| Pjs_fn_make of int
149154
| Pjs_fn_run of int
150155
| Pjs_fn_method of int
151-
| Pjs_fn_runmethod of int
156+
152157

153158
| Pundefined_to_opt
154159
| Pnull_to_opt
@@ -319,12 +324,10 @@ let eq_primitive_approx ( lhs : t) (rhs : t) =
319324
| Pbigstring_set_32 b -> (match rhs with Pbigstring_set_32 b1 -> b = b1 | _ -> false )
320325
| Pbigstring_set_64 b -> (match rhs with Pbigstring_set_64 b1 -> b = b1 | _ -> false )
321326
| Pctconst compile_time_constant -> (match rhs with Pctconst compile_time_constant1 -> Lam_compat.eq_compile_time_constant compile_time_constant compile_time_constant1 | _ -> false)
322-
| Pjs_unsafe_downgrade ( s,_loc) -> (match rhs with Pjs_unsafe_downgrade (s1,_) -> s = s1 | _ -> false)
327+
| Pjs_unsafe_downgrade {name; loc=_; setter } -> (match rhs with Pjs_unsafe_downgrade rhs -> name = rhs.name && setter = rhs.setter | _ -> false)
323328
| Pjs_fn_make i -> (match rhs with Pjs_fn_make i1 -> i = i1 | _ -> false)
324329
| Pjs_fn_run i -> (match rhs with Pjs_fn_run i1 -> i = i1 | _ -> false)
325-
| Pjs_fn_method i -> (match rhs with Pjs_fn_method i1 -> i = i1 | _ -> false )
326-
| Pjs_fn_runmethod i -> (match rhs with Pjs_fn_runmethod i1 -> i = i1 | _ -> false )
327-
330+
| Pjs_fn_method i -> (match rhs with Pjs_fn_method i1 -> i = i1 | _ -> false )
328331
| Pbigarrayref _
329332
| Pbigarrayset _
330333
| Praw_js_function _

jscomp/core/lam_primitive.mli

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,12 @@ type t =
133133
(* Integer to external pointer *)
134134

135135
| Pdebugger
136-
| Pjs_unsafe_downgrade of string * Location.t
136+
| Pjs_unsafe_downgrade of
137+
{
138+
name : string ;
139+
setter : bool;
140+
loc : Location.t;
141+
}
137142
| Pinit_mod
138143
| Pupdate_mod
139144

@@ -143,7 +148,6 @@ type t =
143148
| Pjs_fn_make of int
144149
| Pjs_fn_run of int
145150
| Pjs_fn_method of int
146-
| Pjs_fn_runmethod of int
147151
| Pundefined_to_opt
148152
| Pnull_to_opt
149153
| Pnull_undefined_to_opt

jscomp/core/lam_print.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,11 @@ let primitive ppf (prim : Lam_primitive.t) = match prim with
118118
| Pbytes_of_string -> fprintf ppf "bytes_of_string"
119119
| Pjs_apply -> fprintf ppf "#apply"
120120
| Pjs_runtime_apply -> fprintf ppf "#runtime_apply"
121-
| Pjs_unsafe_downgrade (s,_loc) -> fprintf ppf "##%s" s
121+
| Pjs_unsafe_downgrade {name = s} -> fprintf ppf "##%s" s
122122
| Pjs_function_length -> fprintf ppf "#function_length"
123123
| Pjs_fn_run i -> fprintf ppf "#fn_run_%i" i
124124
| Pjs_fn_make i -> fprintf ppf "js_fn_make_%i" i
125125
| Pjs_fn_method i -> fprintf ppf "js_fn_method_%i" i
126-
| Pjs_fn_runmethod i -> fprintf ppf "js_fn_runmethod_%i" i
127126
| Pdebugger -> fprintf ppf "debugger"
128127
| Praw_js_function _ -> fprintf ppf "[raw.fun]"
129128
| Praw_js_code_exp _ -> fprintf ppf "[raw.exp]"

jscomp/test/class_repr.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,46 @@ if (Caml_oo_curry.js1(590348294, 8, v$1) !== 5) {
176176
];
177177
}
178178

179+
function xx0_init($$class) {
180+
var x = CamlinternalOO.new_variable($$class, "");
181+
var ids = CamlinternalOO.new_methods_variables($$class, shared$2, [
182+
"money",
183+
"a0",
184+
"a1",
185+
"a2"
186+
]);
187+
var incr = ids[0];
188+
var get_money = ids[1];
189+
var money = ids[2];
190+
var a0 = ids[3];
191+
var a1 = ids[4];
192+
var a2 = ids[5];
193+
CamlinternalOO.set_methods($$class, [
194+
get_money,
195+
(function (self$5) {
196+
return self$5[money];
197+
}),
198+
incr,
199+
(function (self$5) {
200+
var copy = Caml_exceptions.caml_set_oo_id(Caml_obj.caml_obj_dup(self$5));
201+
copy[money] = 2 * self$5[x] + Curry._1(self$5[0][get_money], self$5);
202+
copy[a0] = 2;
203+
return copy;
204+
})
205+
]);
206+
return (function (env, self, x$1) {
207+
var self$1 = CamlinternalOO.create_object_opt(self, $$class);
208+
self$1[x] = x$1;
209+
self$1[money] = x$1;
210+
self$1[a0] = 0;
211+
self$1[a1] = 1;
212+
self$1[a2] = 2;
213+
return self$1;
214+
});
215+
}
216+
217+
var xx0 = CamlinternalOO.make_class(shared$2, xx0_init);
218+
179219
exports.x0 = x0;
180220
exports.x = x;
181221
exports.u = u;
@@ -184,4 +224,5 @@ exports.v1 = v1;
184224
exports.v2 = v2;
185225
exports.point = point;
186226
exports.v = v$1;
227+
exports.xx0 = xx0;
187228
/* x0 Not a pure module */

jscomp/test/class_repr.ml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,14 @@ end
9696
let v = new point
9797

9898
let () =
99-
assert (v#get_x5 = 5)
99+
assert (v#get_x5 = 5)
100+
101+
class xx0 (x : float)= object (self)
102+
val money = x
103+
val a0 = 0
104+
val a1 = 1
105+
val a2 = 2
106+
method get_money = money (* Texp_instvar *)
107+
method incr = {< money = 2. *. x +. self#get_money; a0 = 2 >}
108+
(* Texp_instvar *) (* camlinternalOO.copy is inlined here *)
109+
end

0 commit comments

Comments
 (0)