https://gitlab.com/tezos/tezos
Raw File
Tip revision: 9a116357e4e3910b7a35d6b98e88662600d1c904 authored by martoon on 23 November 2023, 13:43:23 UTC
MIR: Catch panics in tzt-runner
Tip revision: 9a11635
saturation_repr.ml
(*****************************************************************************)
(*                                                                           *)
(* Open Source License                                                       *)
(* Copyright (c) 2020 Nomadic Labs, <contact@nomadic-labs.com>               *)
(*                                                                           *)
(* Permission is hereby granted, free of charge, to any person obtaining a   *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense,  *)
(* and/or sell copies of the Software, and to permit persons to whom the     *)
(* Software is furnished to do so, subject to the following conditions:      *)
(*                                                                           *)
(* The above copyright notice and this permission notice shall be included   *)
(* in all copies or substantial portions of the Software.                    *)
(*                                                                           *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL   *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING   *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER       *)
(* DEALINGS IN THE SOFTWARE.                                                 *)
(*                                                                           *)
(*****************************************************************************)

(* let () = assert (Sys.int_size = 63) *)

type _ t = int

type mul_safe

type may_saturate

let may_saturate : _ t -> may_saturate t = fun x -> x

let to_int x = x

let ( < ) : _ t -> _ t -> bool = Compare.Int.( < )

let ( <= ) : _ t -> _ t -> bool = Compare.Int.( <= )

let ( > ) : _ t -> _ t -> bool = Compare.Int.( > )

let ( >= ) : _ t -> _ t -> bool = Compare.Int.( >= )

let ( = ) : _ t -> _ t -> bool = Compare.Int.( = )

let equal = ( = )

let ( <> ) : _ t -> _ t -> bool = Compare.Int.( <> )

let max : _ t -> _ t -> _ t = fun x y -> if x >= y then x else y

let min : _ t -> _ t -> _ t = fun x y -> if x >= y then y else x

let compare : _ t -> _ t -> _ t = Compare.Int.compare

let saturated = max_int

let of_int_opt t = if t >= 0 && t < saturated then Some t else None

let of_z_opt z =
  match Z.to_int z with int -> of_int_opt int | exception Z.Overflow -> None

let to_z x = Z.of_int x

let saturate_if_undef = function None -> saturated | Some x -> x

let safe_int x = of_int_opt x |> saturate_if_undef

let numbits x =
  let x = ref x and n = ref 0 in
  (let y = !x lsr 32 in
   if y <> 0 then (
     n := !n + 32 ;
     x := y )) ;
  (let y = !x lsr 16 in
   if y <> 0 then (
     n := !n + 16 ;
     x := y )) ;
  (let y = !x lsr 8 in
   if y <> 0 then (
     n := !n + 8 ;
     x := y )) ;
  (let y = !x lsr 4 in
   if y <> 0 then (
     n := !n + 4 ;
     x := y )) ;
  (let y = !x lsr 2 in
   if y <> 0 then (
     n := !n + 2 ;
     x := y )) ;
  if !x lsr 1 <> 0 then !n + 2 else !n + !x

let zero = 0

let one = 1

let small_enough z =
  (* The following literal triggers an error if compiled under 32-bit
     architectures, please do not modify it. This is a static way to
     ensure that this file is compiled under a 64-bit architecture. *)
  z land 0x7fffffff80000000 = 0

let mul_safe x = if small_enough x then Some x else None

let mul_safe_exn x =
  if small_enough x then x
  else failwith (Format.sprintf "mul_safe_exn: %d must be below 2147483648" x)

let mul_safe_of_int_exn x =
  Option.bind (of_int_opt x) mul_safe
  |> function
  | None ->
      failwith
        (Format.sprintf "mul_safe_of_int_exn: %d must be below 2147483648" x)
  | Some x ->
      x

(* If [x] is positive, shifting to the right will produce a number
   which is positive and is less than [x]. *)
let shift_right x y = (x :> int) lsr y

let mul x y =
  (* assert (x >= 0 && y >= 0); *)
  match x with
  | 0 ->
      0
  | x ->
      if small_enough x && small_enough y then x * y
      else if Compare.Int.(y > saturated / x) then saturated
      else x * y

let mul_fast x y = x * y

let scale_fast x y =
  if x = 0 then 0
  else if small_enough y then x * y
  else if Compare.Int.(y > saturated / x) then saturated
  else x * y

let add x y =
  let z = x + y in
  if Compare.Int.(z >= 0) then z else saturated

let succ x = add one x

let sub x y = Compare.Int.max (x - y) 0

let sub_opt x y =
  let s = x - y in
  if Compare.Int.(s >= 0) then Some s else None

(* Notice that Z.erem does not behave as mod on negative numbers.
   Fortunately, the inhabitant of [t] are non-negative. *)
let erem x y = x mod y

let ediv x y = x / y

let t_to_z_exn z =
  match of_z_opt z with
  | None ->
      (* since the encoding is applied to values of type [t]. *) assert false
  | Some x ->
      x

let z_encoding = Data_encoding.(check_size 9 (conv to_z t_to_z_exn z))

let n_encoding = Data_encoding.(check_size 9 (conv to_z t_to_z_exn n))

let pp fmt x = Format.pp_print_int fmt x
back to top