Skip to content

Commit 67f8f67

Browse files
v0.18~preview.130.50+1016
1 parent 37f00b3 commit 67f8f67

29 files changed

+512
-288
lines changed

src/array.ml

Lines changed: 173 additions & 131 deletions
Large diffs are not rendered by default.

src/array0.ml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ let fill a ~pos ~len v =
199199
if pos < 0 || len < 0 || pos > length a - len
200200
then invalid_arg "Array.fill"
201201
else (unsafe_fill [@kind k1]) a pos len v
202+
;;
203+
204+
let swap t i j =
205+
let elt_i = t.(i) in
206+
let elt_j = t.(j) in
207+
unsafe_set t i elt_j;
208+
unsafe_set t j elt_i
202209
;;]
203210

204211
[@@@array.iter]
@@ -310,10 +317,3 @@ let fill a ~pos ~len v =
310317
[@@@end]
311318

312319
let stable_sort t ~compare = Stdlib.Array.stable_sort t ~cmp:compare
313-
314-
let swap t i j =
315-
let elt_i = t.(i) in
316-
let elt_j = t.(j) in
317-
unsafe_set t i elt_j;
318-
unsafe_set t j elt_i
319-
;;

src/array0.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ val%template fold_right : 'a array -> f:('a -> 'b -> 'b) -> init:'b -> 'b
5858
[@@mode m = (uncontended, shared)]
5959

6060
val stable_sort : 'a array -> compare:('a -> 'a -> int) -> unit
61-
val swap : 'a array -> int -> int -> unit
6261

6362
[%%template:
6463
[@@@kind.default k1 = (value, immediate, immediate64, float64, bits32, bits64, word)]
@@ -73,6 +72,7 @@ val of_list : ('a List0.Constructors.t[@kind k1]) -> 'a array
7372
val sub : 'a. 'a array -> pos:int -> len:int -> 'a array
7473
val append : 'a. 'a array -> 'a array -> 'a array
7574
val fill : 'a. 'a array -> pos:int -> len:int -> 'a -> unit
75+
val swap : 'a. 'a array -> int -> int -> unit
7676

7777
[@@@kind.default k2 = (value, immediate, immediate64, float64, bits32, bits64, word)]
7878

src/array_intf.ml

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,34 @@
11
(** Fixed-length, mutable vector of elements with O(1) [get] and [set] operations. *)
22

33
open! Import
4+
module Option = Option0
5+
module List = List0.Constructors
46

57
module Definitions = struct
68
module type Public = sig
79
type 'a t
810

9-
[%%rederive:
10-
type nonrec 'a t = 'a t
11-
[@@deriving
12-
compare ~localize, equal ~localize, globalize, sexp ~stackify, sexp_grammar]]
13-
1411
include Binary_searchable.S1 with type 'a t := 'a t
1512

1613
include
1714
Indexed_container.S1_with_creators__base
1815
with type 'a t := 'a t
19-
and type 'a t__float64 := 'a t
20-
and type 'a t__bits32 := 'a t
21-
and type 'a t__bits64 := 'a t
22-
and type 'a t__word := 'a t
23-
and type 'a t__immediate := 'a t
24-
and type 'a t__immediate64 := 'a t
16+
and type 'a t__float64 = 'a t
17+
and type 'a t__bits32 = 'a t
18+
and type 'a t__bits64 = 'a t
19+
and type 'a t__word = 'a t
20+
and type 'a t__immediate = 'a t
21+
and type 'a t__immediate64 = 'a t
22+
23+
[%%template:
24+
[@@@kind k = (value, float64, bits32, bits64, word, immediate, immediate64)]
25+
26+
[%%rederive:
27+
type nonrec 'a t = 'a t
28+
[@@kind k]
29+
[@@deriving compare ~localize, equal ~localize, sexp ~stackify, globalize]]]
30+
31+
[%%rederive: type nonrec 'a t = 'a t [@@deriving sexp_grammar]]
2532

2633
include Indexed_container.S1_with_creators with type 'a t := 'a t
2734
include Invariant.S1 with type 'a t := 'a t
@@ -223,54 +230,58 @@ module Definitions = struct
223230
val map2_exn : 'a t -> 'b t -> f:('a -> 'b -> 'c) -> 'c t
224231
val fold2_exn : 'a t -> 'b t -> init:'acc -> f:('acc -> 'a -> 'b -> 'acc) -> 'acc
225232

226-
(** [for_all2_exn t1 t2 ~f] fails if [length t1 <> length t2]. *)
227-
val for_all2_exn : 'a t -> 'b t -> f:('a -> 'b -> bool) -> bool
233+
(** Modifies an array in place, applying [f] to every element of the array *)
234+
val map_inplace : 'a t -> f:('a -> 'a) -> unit
228235

229-
(** [exists2_exn t1 t2 ~f] fails if [length t1 <> length t2]. *)
230-
val exists2_exn : 'a t -> 'b t -> f:('a -> 'b -> bool) -> bool
236+
[%%template:
237+
[@@@kind.default k1 = (value, float64, bits32, bits64, word, immediate, immediate64)]
238+
239+
(** [find_exn f t] returns the first [a] in [t] for which [f t.(i)] is true. It raises
240+
[Stdlib.Not_found] or [Not_found_s] if there is no such [a]. *)
241+
val find_exn : 'a. 'a t -> f:('a -> bool) -> 'a
231242

232243
(** [swap arr i j] swaps the value at index [i] with that at index [j]. *)
233-
val swap : 'a t -> int -> int -> unit
244+
val swap : 'a. 'a t -> int -> int -> unit
234245

235246
(** [rev_inplace t] reverses [t] in place. *)
236-
val rev_inplace : 'a t -> unit
247+
val rev_inplace : 'a. 'a t -> unit
237248

238249
(** [rev t] returns a reversed copy of [t] *)
239-
val rev : 'a t -> 'a t
250+
val rev : 'a. 'a t -> 'a t
240251

241252
(** [of_list_rev l] converts from list then reverses in place. *)
242-
val of_list_rev : 'a list -> 'a t
253+
val of_list_rev : 'a. ('a List.t[@kind k1]) -> 'a t
254+
255+
[@@@kind.default k2 = (value, float64, bits32, bits64, word, immediate, immediate64)]
256+
257+
(** Returns the first evaluation of [f] that returns [Some]. Raises [Stdlib.Not_found]
258+
or [Not_found_s] if [f] always returns [None]. *)
259+
val find_map_exn : 'a 'b. 'a t -> f:('a -> ('b Option.t[@kind k2])) -> 'b
260+
261+
(** [find_mapi_exn] is like [find_map_exn] but passes the index as an argument. *)
262+
val find_mapi_exn : 'a 'b. 'a t -> f:(int -> 'a -> ('b Option.t[@kind k2])) -> 'b
243263

244264
(** [of_list_map l ~f] is the same as [of_list (List.map l ~f)]. *)
245-
val of_list_map : 'a list -> f:('a -> 'b) -> 'b t
265+
val of_list_map : 'a 'b. ('a List.t[@kind k1]) -> f:('a -> 'b) -> 'b t
246266

247267
(** [of_list_mapi l ~f] is the same as [of_list (List.mapi l ~f)]. *)
248-
val of_list_mapi : 'a list -> f:(int -> 'a -> 'b) -> 'b t
268+
val of_list_mapi : 'a 'b. ('a List.t[@kind k1]) -> f:(int -> 'a -> 'b) -> 'b t
249269

250270
(** [of_list_rev_map l ~f] is the same as [of_list (List.rev_map l ~f)]. *)
251-
val of_list_rev_map : 'a list -> f:('a -> 'b) -> 'b t
271+
val of_list_rev_map : 'a 'b. ('a List.t[@kind k1]) -> f:('a -> 'b) -> 'b t
252272

253273
(** [of_list_rev_mapi l ~f] is the same as [of_list (List.rev_mapi l ~f)]. *)
254-
val of_list_rev_mapi : 'a list -> f:(int -> 'a -> 'b) -> 'b t
255-
256-
(** Modifies an array in place, applying [f] to every element of the array *)
257-
val map_inplace : 'a t -> f:('a -> 'a) -> unit
274+
val of_list_rev_mapi : 'a 'b. ('a List.t[@kind k1]) -> f:(int -> 'a -> 'b) -> 'b t
258275

259276
[%%template:
260-
[@@@kind.default k1 = (value, float64, bits32, bits64, word, immediate, immediate64)]
277+
[@@@kind.default k1 k2]
278+
[@@@mode.default m = (global, local)]
261279

262-
(** [find_exn f t] returns the first [a] in [t] for which [f t.(i)] is true. It raises
263-
[Stdlib.Not_found] or [Not_found_s] if there is no such [a]. *)
264-
val find_exn : 'a. 'a t -> f:('a -> bool) -> 'a
265-
266-
[@@@kind.default k2 = (value, float64, bits32, bits64, word, immediate, immediate64)]
267-
268-
(** Returns the first evaluation of [f] that returns [Some]. Raises [Stdlib.Not_found]
269-
or [Not_found_s] if [f] always returns [None]. *)
270-
val find_map_exn : 'a 'b. 'a t -> f:('a -> ('b Option.t[@kind k2])) -> 'b
280+
(** [for_all2_exn t1 t2 ~f] fails if [length t1 <> length t2]. *)
281+
val for_all2_exn : 'a 'b. 'a t -> 'b t -> f:('a -> 'b -> bool) -> bool
271282

272-
(** [find_mapi_exn] is like [find_map_exn] but passes the index as an argument. *)
273-
val find_mapi_exn : 'a 'b. 'a t -> f:(int -> 'a -> ('b Option.t[@kind k2])) -> 'b]
283+
(** [exists2_exn t1 t2 ~f] fails if [length t1 <> length t2]. *)
284+
val exists2_exn : 'a 'b. 'a t -> 'b t -> f:('a -> 'b -> bool) -> bool]]
274285

275286
(** [findi_exn t f] returns the first index [i] of [t] for which [f i t.(i)] is true.
276287
It raises [Stdlib.Not_found] or [Not_found_s] if there is no such element. *)

src/exn.ml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ let () =
2929
;;
3030

3131
let create_s sexp = Sexp sexp
32-
33-
let create_s_uncontended sexp =
34-
let exn = Sexp sexp |> Portability_hacks.magic_portable__needs_mode_crossing_exns in
35-
fun () -> Portability_hacks.magic_uncontended__needs_mode_crossing_exns exn
36-
;;
37-
3832
let create_s_lazy lazy_sexp = Sexp_lazy lazy_sexp
3933

4034
let raise_with_original_backtrace t backtrace =

src/exn.mli

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,6 @@ exception Reraised of string * t
2424
particular exn constructor doesn't matter. *)
2525
val create_s : Sexp.t -> t
2626

27-
(** [create_s_uncontended] returns a function that can be used to obtain uncontended
28-
access to the resulting exception from within a portable function.
29-
30-
The [@ uncontended] below is redundant, as that is the default. It is written for
31-
clarity. *)
32-
val create_s_uncontended : Sexp.t -> unit -> t
33-
3427
(** [create_s_lazy lazy_sexp] is like [create_s], but takes a lazily generated sexp. *)
3528
val create_s_lazy : Sexp.t Lazy.t -> t
3629

src/globalize.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ external globalize_string : string -> string = "caml_obj_dup"
2121

2222
let globalize_unit (() as u) = u
2323

24+
[%%template
25+
[@@@kind k = (float64, bits32, bits64, word, immediate, immediate64, value)]
26+
2427
external globalize_array' : 'a array -> 'a array = "caml_obj_dup"
2528

26-
let globalize_array _ a = globalize_array' a
29+
let globalize_array _ a = globalize_array' a [@@kind k]]
2730

2831
external globalize_floatarray : floatarray -> floatarray = "caml_obj_dup"
2932

src/globalize.mli

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ val globalize_nativeint : nativeint -> nativeint
1818
val globalize_bytes : bytes -> bytes
1919
val globalize_string : string -> string
2020
val globalize_unit : unit -> unit
21-
val globalize_array : ('a -> 'b) -> 'a array -> 'a array
21+
22+
val%template globalize_array : 'a 'b. ('a -> 'b) -> 'a array -> 'a array
23+
[@@kind k = (float64, bits32, bits64, word, immediate, immediate64, value)]
24+
2225
val globalize_floatarray : floatarray -> floatarray
2326
val globalize_lazy_t : ('a -> 'b) -> 'a lazy_t -> 'a lazy_t
2427
val globalize_list : ('a -> 'b) -> 'a list -> 'b list
@@ -30,9 +33,7 @@ val globalize_or_null
3033
-> 'b Basement.Or_null_shim.t
3134

3235
val globalize_result
33-
: ('ok -> 'ok)
34-
-> ('err -> 'err)
35-
-> ('ok, 'err) result
36-
-> ('ok, 'err) result
36+
: 'ok 'err.
37+
('ok -> 'ok) -> ('err -> 'err) -> ('ok, 'err) result -> ('ok, 'err) result
3738

3839
val globalize_ref : ('a -> 'b) -> 'a ref -> 'a ref

src/info0.ml

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module Message = struct
1313
type t =
1414
| Could_not_construct of Sexp.t
1515
| String of string
16-
| Exn of (unit -> exn) Modes.Global.t
16+
| Exn of exn Modes.Global.t
1717
| Sexp of Sexp.t
1818
| Tag_sexp of string * Sexp.t * Source_code_position0.t option
1919
| Tag_t of string * t
@@ -26,7 +26,7 @@ module Message = struct
2626
match t with
2727
| Could_not_construct _ as t -> sexp_of_t t :: ac
2828
| String string -> Atom string :: ac
29-
| Exn { global = exn } -> Exn.sexp_of_t (exn ()) :: ac
29+
| Exn { global = exn } -> Exn.sexp_of_t exn :: ac
3030
| Sexp sexp -> sexp :: ac
3131
| Tag_sexp (tag, sexp, here) ->
3232
List
@@ -53,25 +53,6 @@ module Message = struct
5353
| [ sexp ] -> sexp
5454
| sexps -> Sexp.List sexps
5555
;;
56-
57-
let rec portabilize : t -> t = function
58-
| Exn { global = exn } ->
59-
let exn = exn () in
60-
let copied_exn = Exn.create_s_uncontended (Exn.sexp_of_t exn) in
61-
Exn { global = copied_exn }
62-
| Sexp sexp -> Sexp sexp
63-
| String str -> String str
64-
| Of_list (i, xs) ->
65-
Of_list
66-
( i
67-
, List.map xs ~f:(fun x -> portabilize x |> Modes.Portable.wrap)
68-
|> Modes.Portable.unwrap_list )
69-
| Could_not_construct sexp -> Could_not_construct sexp
70-
| Tag_sexp (sexp, string, src_pos) -> Tag_sexp (sexp, string, src_pos)
71-
| Tag_t (string, t) -> Tag_t (string, portabilize t)
72-
| Tag_arg (string, sexp, t) -> Tag_arg (string, sexp, portabilize t)
73-
| With_backtrace (t, backtrace) -> With_backtrace (portabilize t, backtrace)
74-
;;
7556
end
7657

7758
open Message
@@ -511,13 +492,22 @@ let () =
511492
assert false)
512493
;;
513494

495+
let portabilize (t : t) : t =
496+
match t.global with
497+
(* As an optimization: if the value is already known-portable, there's no need to
498+
force its computation. *)
499+
| Staged_portable x -> { global = Staged_portable x }
500+
| Constant x -> { global = Constant x }
501+
| Staged_nonportable _ -> [%template of_message [@mode portable]] (to_message t)
502+
;;
503+
514504
let to_exn t =
515505
if not (is_computed t)
516-
then Exn t
506+
then Exn (portabilize t)
517507
else (
518508
match to_message t with
519-
| Exn { global = exn } -> exn ()
520-
| _ -> Exn t)
509+
| Exn { global = exn } -> exn
510+
| _ -> Exn (portabilize t))
521511
;;
522512

523513
let of_exn ?backtrace exn =
@@ -531,23 +521,11 @@ let of_exn ?backtrace exn =
531521
| Exn t, None -> t
532522
| Exn t, Some backtrace ->
533523
of_thunked_message (fun () -> With_backtrace (to_message t, backtrace))
534-
| _, None -> of_message (Exn { global = (fun () -> exn) })
524+
| _, None -> of_message (Exn { global = exn })
535525
| _, Some backtrace ->
536526
of_thunked_message (fun () -> With_backtrace (Sexp (Exn.sexp_of_t exn), backtrace))
537527
;;
538528

539-
let portabilize (t : t) : t =
540-
match t.global with
541-
| Staged_portable x ->
542-
(* As an optimization: if the value is already known-portable, there's no need to
543-
force its computation. *)
544-
{ global = Staged_portable x }
545-
| Constant _ | Staged_nonportable _ ->
546-
let message = to_message t in
547-
let message = Message.portabilize message in
548-
[%template of_message [@mode portable]] message
549-
;;
550-
551529
include%template Pretty_printer.Register_pp [@mode portable] (struct
552530
type nonrec t = t
553531

src/info_intf.ml

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module Definitions = struct
5050
type t =
5151
| Could_not_construct of Sexp.t
5252
| String of string
53-
| Exn of (unit -> exn) Modes.Global.t
53+
| Exn of exn Modes.Global.t
5454
| Sexp of Sexp.t
5555
| Tag_sexp of string * Sexp.t * Source_code_position0.t option
5656
| Tag_t of string * t
@@ -209,15 +209,8 @@ module Definitions = struct
209209
(** Constructs a portable info out of a possibly non-portable info. This operation is
210210
less expensive than [err |> sexp_of_t |> create_s], but it's not a no-op.
211211
212-
It's not a no-op for two reasons:
213-
- It forces the computation of the input info.
214-
- It forces any [exn]s contained in the [Info.t] to their sexp representation.
215-
216-
For the latter reason, [of_exn exn |> portabilize |> to_exn] won't return [exn],
217-
unlike [of_exn exn |> to_exn]. Instead, it will return a sexpified version of the
218-
[exn]. We take this approach -- of converting exns to sexps -- mainly because
219-
[exn]s can't safely be moved between domains unless all accesses to them are at
220-
mode contended. *)
212+
It's not a no-op because it needs to force any non-portable computation of the
213+
input info. *)
221214
val portabilize : t -> t
222215
end
223216

0 commit comments

Comments
 (0)