Skip to content

Commit

Permalink
type specialize min/max operations and also warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
bobzhang committed Dec 25, 2017
1 parent 5780267 commit 8a76d82
Show file tree
Hide file tree
Showing 38 changed files with 447 additions and 131 deletions.
4 changes: 2 additions & 2 deletions jscomp/all.depend
Original file line number Diff line number Diff line change
Expand Up @@ -593,8 +593,8 @@ core/lam_compile_global.cmx : core/ocaml_types.cmx core/lam_module_ident.cmx \
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 \
core/js_exp_make.cmx common/js_config.cmx core/j.cmx ext/ext_list.cmx \
common/bs_warnings.cmx core/lam_dispatch_primitive.cmi
core/js_exp_make.cmx common/js_config.cmx core/js_analyzer.cmx core/j.cmx \
ext/ext_list.cmx common/bs_warnings.cmx core/lam_dispatch_primitive.cmi
core/lam_bounded_vars.cmx : core/lam.cmx ext/ident_hashtbl.cmx \
ext/ext_list.cmx core/lam_bounded_vars.cmi
core/lam_beta_reduce.cmx : core/lam_util.cmx core/lam_stats.cmx \
Expand Down
11 changes: 0 additions & 11 deletions jscomp/core/lam.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1934,17 +1934,6 @@ let convert exports lam : _ * _ =
| _ -> assert false
end

| Lprim ( Pfield (id, _),
[Lprim (Pgetglobal ({name = "Pervasives"} ), _,_)],loc
)
->
let args = Ext_list.map convert_aux args in
begin match Ocaml_stdlib_slots.pervasives.(id) , args with
| "^", [ l; r ]
->
prim ~primitive:Pstringadd ~args:[l;r] loc
| _ -> apply (convert_aux fn) args loc App_na
end
(*
| Lfunction(kind,params,Lprim(prim,inner_args,inner_loc))
when List.for_all2_no_exn (fun x y ->
Expand Down
38 changes: 38 additions & 0 deletions jscomp/core/lam_dispatch_primitive.ml
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ let translate loc (prim_name : string)
-> Js_long.float_of_bits args
| "caml_int64_bswap"
-> Js_long.swap args
| "caml_int64_min"
-> Js_long.min args
| "caml_int64_max"
-> Js_long.max args
| "caml_int32_float_of_bits"
| "caml_int32_bits_of_float"
| "caml_classify_float"
Expand Down Expand Up @@ -574,6 +578,37 @@ let translate loc (prim_name : string)
| [e] -> E.is_caml_block e
| _ -> assert false
end

| "caml_int_min"
| "caml_float_min"
| "caml_string_min"
| "caml_nativeint_min"
| "caml_int32_min"

->
begin match args with
| [a;b] ->
if Js_analyzer.is_okay_to_duplicate a && Js_analyzer.is_okay_to_duplicate b then
E.econd (E.js_comp Clt a b) a b
else
call Js_runtime_modules.obj_runtime
| _ -> assert false
end
| "caml_int_max"
| "caml_float_max"
| "caml_string_max"
| "caml_nativeint_max"
| "caml_int32_max"
->
begin match args with
| [a;b] ->
if Js_analyzer.is_okay_to_duplicate a && Js_analyzer.is_okay_to_duplicate b then
E.econd (E.js_comp Cgt a b) a b
else
call Js_runtime_modules.obj_runtime
| _ -> assert false
end

| "caml_obj_dup"
| "caml_update_dummy"
| "caml_obj_truncate"
Expand All @@ -583,6 +618,9 @@ let translate loc (prim_name : string)
| "caml_nativeint_compare"
->
call Js_runtime_modules.obj_runtime

| "caml_min"
| "caml_max"
| "caml_compare"
| "caml_equal"
| "caml_notequal"
Expand Down
2 changes: 0 additions & 2 deletions jscomp/others/.depend
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ bs_internalAVLtree.cmj :
bs_internalMutableAVLSet.cmj : bs_internalAVLset.cmj
bs_Hash.cmj : bs_Hash.cmi
bs_Queue.cmj : bs_Array.cmj bs_Queue.cmi
bs_internalLinkList.cmj :
bs_LinkList.cmj : bs_Array.cmj bs.cmj
bs_List.cmj : bs_Array.cmj bs_List.cmi
bs_internalBucketsType.cmj : bs_Array.cmj
bs_internalSetBuckets.cmj : bs_internalBucketsType.cmj bs_Array.cmj bs.cmj
Expand Down
7 changes: 4 additions & 3 deletions jscomp/runtime/caml_int64.ml
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ let gt x y =


let le x y = Pervasives.not (gt x y)

let min x y = if lt x y then x else y
let max x y = if gt x y then x else y

let to_float ({hi; lo} : t) =
Nativeint.to_float ( hi *~ [%raw{|0x100000000|}] +~ lo)
Expand Down Expand Up @@ -306,7 +307,7 @@ let rec of_float (x : float) : t =


external log2 : float = "Math.LN2" [@@bs.val]
external max : float -> float -> float = "Math.max" [@@bs.val]
(* external maxFloat : float -> float -> float = "Math.max" [@@bs.val] *)

let rec div self other =
match self, other with
Expand Down Expand Up @@ -348,7 +349,7 @@ let rec div self other =
let rem = ref self in
(* assert false *)
while ge !rem other do
let approx = ref ( max 1.
let approx = ref ( Pervasives.max 1.
(floor (to_float !rem /. to_float other) )) in
let log2 = ceil (log !approx /. log2) in
let delta =
Expand Down
2 changes: 2 additions & 0 deletions jscomp/runtime/caml_int64.mli
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ val neq : comparison
val lt : comparison
val gt : comparison
val le : comparison
val min : t -> t -> t
val max : t -> t -> t

val to_float : t -> float
val of_float : float -> t
Expand Down
31 changes: 31 additions & 0 deletions jscomp/runtime/caml_obj.ml
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,37 @@ let caml_update_dummy x y =
if y_tag <> 0 then
Obj.set_tag x y_tag

type 'a selector = 'a -> 'a -> 'a
(* Bs_obj.set_length x (Bs_obj.length y) *)
(* [set_length] seems redundant here given that it is initialized as an array
*)
let caml_int_compare (x : int) (y: int) : int =
if x < y then -1 else if x = y then 0 else 1

(* could be replaced by [Math.min], but it seems those built-ins are slower *)
let caml_int_min (x : int) (y : int) : int =
if x < y then x else y
let caml_float_min (x : float) y =
if x < y then x else y
let caml_string_min (x : string) y =
if x < y then x else y
let caml_nativeint_min (x : nativeint) y =
if x < y then x else y
let caml_int32_min (x : int32) y =
if x < y then x else y

let caml_int_max (x : int) (y : int) : int =
if x > y then x else y
let caml_float_max (x : float) y =
if x > y then x else y
let caml_string_max (x : string) y =
if x > y then x else y
let caml_nativeint_max (x : nativeint) y =
if x > y then x else y
let caml_int32_max (x : int32) y =
if x > y then x else y


let caml_string_compare (x : string) (y: string) : int =
if x < y then -1 else if x = y then 0 else 1

Expand Down Expand Up @@ -291,3 +316,9 @@ let caml_greaterthan a b = caml_compare a b > 0
let caml_lessequal a b = caml_compare a b <= 0

let caml_lessthan a b = caml_compare a b < 0

let caml_min (x : Obj.t) y =
if caml_compare x y <= 0 then x else y

let caml_max (x : Obj.t) y =
if caml_compare x y >= 0 then x else y
16 changes: 16 additions & 0 deletions jscomp/runtime/caml_obj.mli
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,19 @@ val caml_greaterthan : eq
val caml_lessthan : eq
val caml_lessequal : eq

type 'a selector = 'a -> 'a -> 'a

val caml_int_min : int selector
val caml_float_min : float selector
val caml_string_min : string selector
val caml_nativeint_min : nativeint selector
val caml_int32_min : int32 selector

val caml_int_max : int selector
val caml_float_max : float selector
val caml_string_max : string selector
val caml_nativeint_max : nativeint selector
val caml_int32_max : int32 selector

val caml_min : Obj.t selector
val caml_max : Obj.t selector
9 changes: 9 additions & 0 deletions jscomp/stdlib/pervasives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,14 @@ external ( <= ) : 'a -> 'a -> bool = "%lessequal"
external ( >= ) : 'a -> 'a -> bool = "%greaterequal"
external compare : 'a -> 'a -> int = "%compare"

#if BS then
external min : 'a -> 'a -> 'a = "%bs_min"
external max : 'a -> 'a -> 'a = "%bs_max"
#else
let min x y = if x <= y then x else y
let max x y = if x >= y then x else y

#end
external ( == ) : 'a -> 'a -> bool = "%eq"
external ( != ) : 'a -> 'a -> bool = "%noteq"

Expand Down Expand Up @@ -174,13 +179,17 @@ external bytes_blit : bytes -> int -> bytes -> int -> int -> unit
external bytes_unsafe_to_string : bytes -> string = "%bytes_to_string"
external bytes_unsafe_of_string : string -> bytes = "%bytes_of_string"

#if BS then
external (^) : string -> string -> string = "#string_append"
#else
let ( ^ ) s1 s2 =
let l1 = string_length s1 and l2 = string_length s2 in
let s = bytes_create (l1 + l2) in
string_blit s1 0 s 0 l1;
string_blit s2 0 s l1 l2;
bytes_unsafe_to_string s

#end
(* Character operations -- more in module Char *)

external int_of_char : char -> int = "%identity"
Expand Down
9 changes: 9 additions & 0 deletions jscomp/stdlib/pervasives.mli
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ external compare : 'a -> 'a -> int = "%compare"
required by the {!Set.Make} and {!Map.Make} functors, as well as
the {!List.sort} and {!Array.sort} functions. *)

#if BS then
external min : 'a -> 'a -> 'a = "%bs_min"
external max : 'a -> 'a -> 'a = "%bs_max"
#else
val min : 'a -> 'a -> 'a
(** Return the smaller of the two arguments.
The result is unspecified if one of the arguments contains
Expand All @@ -105,6 +109,7 @@ val max : 'a -> 'a -> 'a
The result is unspecified if one of the arguments contains
the float value [nan]. *)

#end
external ( == ) : 'a -> 'a -> bool = "%eq"
(** [e1 == e2] tests for physical equality of [e1] and [e2].
On mutable types such as references, arrays, byte sequences, records with
Expand Down Expand Up @@ -502,7 +507,11 @@ external classify_float : float -> fpclass = "caml_classify_float"
More string operations are provided in module {!String}.
*)

#if BS then
external (^) : string -> string -> string = "#string_append"
#else
val ( ^ ) : string -> string -> string
#end
(** String concatenation. *)


Expand Down
3 changes: 2 additions & 1 deletion jscomp/test/.depend
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ bs_hashset_int_test.cmj : mt.cmj ../others/bs.cmj array_data_util.cmj
bs_hashtbl_string_test.cmj : ../stdlib/hashtbl.cmj ../others/bs.cmj
bs_ignore_effect.cmj : mt.cmj
bs_ignore_test.cmj : ../runtime/js.cmj
bs_link_list_test.cmj : mt.cmj ../runtime/js.cmj ../others/bs.cmj
bs_list_test.cmj : mt.cmj ../runtime/js.cmj ../others/bs.cmj
bs_map_int_test.cmj : mt.cmj ../others/bs.cmj
bs_map_test.cmj : ../runtime/js.cmj ../others/bs.cmj
bs_min_max_test.cmj : ../stdlib/pervasives.cmj
bs_mutable_set_test.cmj : ../runtime/js.cmj \
../others/bs_internalMutableAVLSet.cmj
bs_node_string_buffer_test.cmj : ../others/node.cmj ../runtime/js.cmj
Expand Down
1 change: 1 addition & 0 deletions jscomp/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ OTHERS := test_literals a test_ari test_export2 test_internalOO test_obj_simple_
bs_hashset_int_test\
array_data_util\
bs_list_test\
bs_min_max_test\
# bs_uncurry_test
# needs Lam to get rid of Uncurry arity first
# simple_derive_test
Expand Down
27 changes: 27 additions & 0 deletions jscomp/test/bs_min_max_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict';

var Caml_obj = require("../../lib/js/caml_obj.js");

function f(x, y) {
return Caml_obj.caml_int_compare(x + y | 0, y + x | 0);
}

function f2(x, y) {
return Caml_obj.caml_int_compare(x + y | 0, y);
}

var f3 = Caml_obj.caml_int_compare;

function f4(x, y) {
if (x < y) {
return x;
} else {
return y;
}
}

exports.f = f;
exports.f2 = f2;
exports.f3 = f3;
exports.f4 = f4;
/* No side effect */
16 changes: 16 additions & 0 deletions jscomp/test/bs_min_max_test.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@


let f x y =
Pervasives.compare (x + y) ( y + x)

let f2 x y =
Pervasives.compare (x + y) y

let f3 x y =
Pervasives.compare (x : int) y

external min : 'a -> 'a -> 'a = "%bs_min"


let f4 x y =
min (x : int) y
2 changes: 1 addition & 1 deletion jscomp/test/flow_parser_reg_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function from_lb_p(source, start, _end) {
],
/* _end : record */[
/* line */_end[/* pos_lnum */1],
/* column */Pervasives.max(0, _end[/* pos_cnum */3] - _end[/* pos_bol */2] | 0),
/* column */Caml_obj.caml_int_max(0, _end[/* pos_cnum */3] - _end[/* pos_bol */2] | 0),
/* offset */_end[/* pos_cnum */3]
]
];
Expand Down
6 changes: 3 additions & 3 deletions jscomp/test/gpr_405_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var Curry = require("../../lib/js/curry.js");
var Hashtbl = require("../../lib/js/hashtbl.js");
var Pervasives = require("../../lib/js/pervasives.js");
var Caml_obj = require("../../lib/js/caml_obj.js");
var Caml_builtin_exceptions = require("../../lib/js/caml_builtin_exceptions.js");

function Make(funarg) {
Expand Down Expand Up @@ -67,7 +67,7 @@ function Make(funarg) {
var successor = successors[0];
if (find_default(already_processed, successor)) {
var x = find_default(on_the_stack, successor) ? Curry._2(H[/* find */6], n_labels, successor) : Curry._2(H[/* find */6], l_labels, successor);
Curry._3(H[/* add */4], l_labels, top$1, Pervasives.max(Curry._2(H[/* find */6], l_labels, top$1), x));
Curry._3(H[/* add */4], l_labels, top$1, Caml_obj.caml_int_max(Curry._2(H[/* find */6], l_labels, top$1), x));
_successors = successors[1];
continue ;

Expand Down Expand Up @@ -97,7 +97,7 @@ function Make(funarg) {
var match = rest_of_stack$1[0];
var new_top = match[0];
Curry._3(H[/* add */4], on_the_stack, top$1, /* false */0);
Curry._3(H[/* add */4], l_labels, new_top, Pervasives.max(Curry._2(H[/* find */6], l_labels, top$1), Curry._2(H[/* find */6], l_labels, new_top)));
Curry._3(H[/* add */4], l_labels, new_top, Caml_obj.caml_int_max(Curry._2(H[/* find */6], l_labels, top$1), Curry._2(H[/* find */6], l_labels, new_top)));
_rest_of_stack = rest_of_stack$1[1];
_top = new_top;
_successors = match[1];
Expand Down
6 changes: 3 additions & 3 deletions jscomp/test/mario_game.js
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ function update_player(player, keys, context) {
if (!player$1[/* jumping */4] && player$1[/* grounded */5]) {
player$1[/* jumping */4] = /* true */1;
player$1[/* grounded */5] = /* false */0;
player$1[/* vel */2][/* y */1] = Pervasives.max(player$1[/* vel */2][/* y */1] - (5.7 + Math.abs(player$1[/* vel */2][/* x */0]) * 0.25), -6);
player$1[/* vel */2][/* y */1] = Caml_obj.caml_float_max(player$1[/* vel */2][/* y */1] - (5.7 + Math.abs(player$1[/* vel */2][/* x */0]) * 0.25), -6);
return /* () */0;
} else {
return 0;
Expand Down Expand Up @@ -1052,7 +1052,7 @@ function update_vel$1(obj) {
obj[/* vel */2][/* y */1] = 0;
return /* () */0;
} else if (obj[/* params */0][/* has_gravity */0]) {
obj[/* vel */2][/* y */1] = Pervasives.min(obj[/* vel */2][/* y */1] + 0.2 + Math.abs(obj[/* vel */2][/* y */1]) * 0.01, 4.5);
obj[/* vel */2][/* y */1] = Caml_obj.caml_float_min(obj[/* vel */2][/* y */1] + 0.2 + Math.abs(obj[/* vel */2][/* y */1]) * 0.01, 4.5);
return /* () */0;
} else {
return 0;
Expand Down Expand Up @@ -1545,7 +1545,7 @@ function make$3(param, param$1) {

function calc_viewport_point(cc, vc, mc) {
var vc_half = vc / 2;
return Pervasives.min(Pervasives.max(cc - vc_half, 0), Pervasives.min(mc - vc, Math.abs(cc - vc_half)));
return Caml_obj.caml_float_min(Caml_obj.caml_float_max(cc - vc_half, 0), Caml_obj.caml_float_min(mc - vc, Math.abs(cc - vc_half)));
}

function in_viewport(v, pos) {
Expand Down
Loading

0 comments on commit 8a76d82

Please sign in to comment.