Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
hhugo committed Sep 27, 2024
1 parent 54fcfcd commit 23f902f
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 18 deletions.
3 changes: 3 additions & 0 deletions compiler/lib/config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,7 @@ let target () =
| (`JavaScript | `Wasm) as t -> t

let set_target (t : [ `JavaScript | `Wasm ]) =
(match t with
| `JavaScript -> Targetint.set_num_bits 32
| `Wasm -> Targetint.set_num_bits 31);
target_ := (t :> [ `JavaScript | `Wasm | `None ])
2 changes: 1 addition & 1 deletion compiler/lib/eval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ let eval_prim x =
| None -> None)
| "caml_sys_const_word_size", [ _ ] -> Some (Int (Targetint.of_int_exn 32))
| "caml_sys_const_int_size", [ _ ] ->
Some (Int (Targetint.of_int_exn Targetint.num_bits))
Some (Int (Targetint.of_int_exn (Targetint.num_bits ())))
| "caml_sys_const_big_endian", [ _ ] -> Some (Int Targetint.zero)
| "caml_sys_const_naked_pointers_checked", [ _ ] -> Some (Int Targetint.zero)
| _ -> None)
Expand Down
4 changes: 2 additions & 2 deletions compiler/lib/generate.ml
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,9 @@ let unsigned x =
in
if pos_int32 then x else unsigned' x

let one = int 1
let one = J.ENum (J.Num.of_targetint Targetint.one)

let zero = int 0
let zero = J.ENum (J.Num.of_targetint Targetint.zero)

let plus_int x y =
match x, y with
Expand Down
51 changes: 37 additions & 14 deletions compiler/lib/targetint.ml
Original file line number Diff line number Diff line change
@@ -1,32 +1,45 @@
type t = Int32.t

let num_bits = 32
let num_bits_ = ref 0

let offset = 32 - num_bits
let set_num_bits x = num_bits_ := x

let num_bits () =
match !num_bits_ with
| (31 | 32) as x -> x
| x -> failwith (Printf.sprintf "Targetint.num_bits %d unsupported" x)

let offset () = 32 - num_bits ()

let equal = Int32.equal

let compare = Int32.compare

let wrap i = if offset = 0 then i else Int32.(shift_right (shift_left i offset) offset)
let wrap i =
let offset = offset () in
if offset = 0 then i else Int32.(shift_right (shift_left i offset) offset)

let min_int = if offset = 0 then Int32.min_int else Int32.shift_right Int32.min_int offset
let min_int () =
let offset = offset () in
if offset = 0 then Int32.min_int else Int32.shift_right Int32.min_int offset

let min_int_i = Int32.to_int min_int
let min_int_i () = Int32.to_int (min_int ())

let max_int = if offset = 0 then Int32.max_int else Int32.shift_right_logical (-1l) offset
let max_int () =
let offset = offset () in
if offset = 0 then Int32.max_int else Int32.shift_right_logical (-1l) offset

let max_int_i = Int32.to_int max_int
let max_int_i () = Int32.to_int (max_int ())

let to_string x = Int32.to_string x

let to_float x = Int32.to_float x

let of_float x = wrap (Int32.of_float x)

let neg x = if equal x min_int then x else Int32.neg x
let neg x = if equal x (min_int ()) then x else Int32.neg x

let abs x = if equal x min_int then x else Int32.abs x
let abs x = if equal x (min_int ()) then x else Int32.abs x

let int_binop f x y = wrap (f x y)

Expand Down Expand Up @@ -61,14 +74,17 @@ let shift_left = shift_op Int32.shift_left
let shift_right = shift_op Int32.shift_right

let shift_right_logical a b =
let offset = offset () in
if offset = 0
then shift_op Int32.shift_right_logical a b
else shift_op Int32.shift_right_logical (Int32.logand a 0x7fffffffl) b

let is_zero x = equal x 0l

let of_int_exn (x : int) =
if x < min_int_i || x > max_int_i then failwith "of_int_exn" else Int32.of_int x
if x < min_int_i () || x > max_int_i () then failwith "of_int_exn" else Int32.of_int x

let to_int32 x = x

let to_int_exn x =
if Sys.int_size < 32
Expand All @@ -80,7 +96,7 @@ let to_int_exn x =

let of_string x =
let x = Int32.of_string x in
if x < min_int || x > max_int then failwith "of_string" else x
if x < min_int () || x > max_int () then failwith "of_string" else x

external ( < ) : int32 -> int32 -> bool = "%lessthan"

Expand Down Expand Up @@ -111,18 +127,25 @@ let convert_warning_on_overflow ~to_int32 ~of_int32 ~equal ~to_dec ~to_hex x =

let of_int_warning_on_overflow i =
convert_warning_on_overflow
~to_int32:Int32.of_int
~to_int32:(fun i -> wrap (Int32.of_int i))
~of_int32:Int32.to_int
~equal:Int_replace_polymorphic_compare.( = )
~to_dec:(Printf.sprintf "%d")
~to_hex:(Printf.sprintf "%x")
i

let of_int32_warning_on_overflow i = i
let of_int32_warning_on_overflow n =
convert_warning_on_overflow
~to_int32:(fun i -> wrap i)
~of_int32:Fun.id
~equal:Int32.equal
~to_dec:(Printf.sprintf "%ld")
~to_hex:(Printf.sprintf "%lx")
n

let of_nativeint_warning_on_overflow n =
convert_warning_on_overflow
~to_int32:Nativeint.to_int32
~to_int32:(fun i -> wrap (Nativeint.to_int32 i))
~of_int32:Nativeint.of_int32
~equal:Nativeint.equal
~to_dec:(Printf.sprintf "%nd")
Expand Down
6 changes: 5 additions & 1 deletion compiler/lib/targetint.mli
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ val to_int_exn : t -> int

val to_float : t -> float

val to_int32 : t -> int32

val of_string : string -> t

val of_float : float -> t
Expand Down Expand Up @@ -64,8 +66,10 @@ val ( <> ) : t -> t -> bool

val is_zero : t -> bool

val num_bits : int
val num_bits : unit -> int

val zero : t

val one : t

val set_num_bits : int -> unit
1 change: 1 addition & 0 deletions compiler/tests-compiler/macro.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ let print_macro_transformed source =
print_endline (Buffer.contents buffer))

let print_macro_transformed source =
Jsoo.Targetint.set_num_bits 32;
try print_macro_transformed source with Failure s -> Format.printf "failure: %s%!" s

let%expect_test "BLOCK()" =
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-num/test_int31.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ let () = Printexc.record_backtrace false
let min_int31 = Int32.(neg (shift_left 1l 30))
let max_int31 = Int32.(sub (shift_left 1l 30) 1l)

module Int31 = Js_of_ocaml_compiler.Targetint
let () = Int31.set_num_bits 31

let in_range i =
Int32.(min_int31 <= i && i <= max_int31)

Expand Down

0 comments on commit 23f902f

Please sign in to comment.