Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsafe operations for array uninitialization and raw arrays #207

Merged
merged 27 commits into from
Oct 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
612eede
Rename Prim.Array_uninit to Prim.Array_alloc
MatthewFluet Oct 7, 2017
898d3a6
Update comments in prim.{fun,sig}
MatthewFluet Oct 7, 2017
8663034
Update comments in prim.{fun,sig}
MatthewFluet Oct 7, 2017
eec191d
Refactor translation of Array_toVector in SsaToRssa
MatthewFluet Oct 7, 2017
ee9d072
Remove outdated comment in signature REP_TYPE
MatthewFluet Oct 7, 2017
884d7ef
Export SsaTree2.Type.deVectorOpt
MatthewFluet Oct 7, 2017
1c0b24e
Eliminate awkward `updateMk` fns in Basis Library Sequence functors
MatthewFluet Oct 7, 2017
5e4b00d
Use operations exported by PRIM_SEQUENCE
MatthewFluet Oct 7, 2017
37c73d7
Use operation exported by PRIM_SEQUENCE
MatthewFluet Oct 7, 2017
2ab5d9e
Export unsafeUpdate from {MONO_}ARRAY_SLICE_EXTRA
MatthewFluet Oct 7, 2017
52d266c
Export unsafeAlloc from MONO_ARRAY_EXTRA
MatthewFluet Oct 7, 2017
d3569db
Don't use prims after applying PrimSequence to Array and Vector
MatthewFluet Oct 7, 2017
946385f
Add `Array_uninit: 'a array * SeqInt.int -> unit` primitive
MatthewFluet Oct 10, 2017
1672c55
Add missing Array_copy{Array,Vector} cases to Prim.equals
MatthewFluet Oct 10, 2017
1b87b4b
Add and use SsaTree2.Prod.{allAre,someIs}{Immutable,Mutable} fns
MatthewFluet Oct 11, 2017
098d606
Alphabetize primitives in closure-convert/abstract-value.fun
MatthewFluet Oct 11, 2017
51fc022
Update comments in signature UNSAFE in Basis Library
MatthewFluet Oct 12, 2017
295f9cd
Update Useless optimization to handle Array_uninit primitive
MatthewFluet Oct 16, 2017
426baa1
Add `Array_uninitIsNop: 'a array -> bool` primitive
MatthewFluet Oct 16, 2017
af42741
Fix code formatting
MatthewFluet Oct 16, 2017
1f08772
Move `fromIntForLength` from `functor Sequence` to `structure SeqIndex`
MatthewFluet Oct 16, 2017
9853172
Omit `Size` checks in `Unsafe.*Array.{alloc,create}` functions
MatthewFluet Oct 16, 2017
580da00
Add `Array_allocRaw: SeqIndex.int -> 'a array` primitive
MatthewFluet Oct 16, 2017
e5206bb
Fix unused variable warning
MatthewFluet Oct 20, 2017
81bb827
Generalize to "val Prim.arrayAlloc: {raw: bool} -> 'a Prim.t"
MatthewFluet Oct 20, 2017
5c747df
Fix latent bugs in ConstantProgagation with Array_allocRaw
MatthewFluet Oct 21, 2017
c8c4ef6
Merge branch 'master' of github.com:MLton/mlton into array-uninit
MatthewFluet Oct 21, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions basis-library/arrays-and-vectors/array-slice.sig
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@ signature ARRAY_SLICE_EXTRA =
sig
include ARRAY_SLICE

val uninitIsNop: 'a slice -> bool
val uninit: 'a slice * int -> unit
val unsafeSub: 'a slice * int -> 'a
val unsafeCopy: {dst: 'a Array.array, di: int, src: 'a slice} -> unit
val unsafeCopyVec: {dst: 'a Array.array, di: int, src: 'a VectorSlice.slice} -> unit
val unsafeSlice: 'a array * int * int option -> 'a slice
val unsafeSubslice: 'a slice * int * int option -> 'a slice
val unsafeUninit: 'a slice * int -> unit
val unsafeUpdate: 'a slice * int * 'a -> unit

val concat: 'a slice list -> 'a array
val toList: 'a slice -> 'a list
Expand Down
24 changes: 20 additions & 4 deletions basis-library/arrays-and-vectors/array.sig
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,32 @@ signature ARRAY_EXTRA =

structure ArraySlice: ARRAY_SLICE_EXTRA

val uninit: int -> 'a array
val unsafeUninit: int -> 'a array
val unsafeSub: 'a array * int -> 'a
val unsafeUpdate: 'a array * int * 'a -> unit
val alloc: int -> 'a array
val uninitIsNop: 'a array -> bool
val uninit: 'a array * int -> unit
val unsafeAlloc: int -> 'a array
val unsafeArray: int * 'a -> 'a array
val unsafeCopy: {dst: 'a array, di: int, src: 'a array} -> unit
val unsafeCopyVec: {dst: 'a array, di: int, src: 'a vector} -> unit
val unsafeSub: 'a array * int -> 'a
val unsafeUninit: 'a array * int -> unit
val unsafeUpdate: 'a array * int * 'a -> unit

val concat: 'a array list -> 'a array
val duplicate: 'a array -> 'a array
val toList: 'a array -> 'a list
val unfoldi: int * 'b * (int * 'b -> 'a * 'b) -> 'a array * 'b
val unfold: int * 'b * ('b -> 'a * 'b) -> 'a array * 'b

structure Raw:
sig
type 'a rawarr
val alloc: int -> 'a rawarr
val length: 'a rawarr -> int
val uninit: 'a rawarr * int -> unit
val uninitIsNop: 'a rawarr -> bool
val unsafeAlloc: int -> 'a rawarr
val unsafeToArray: 'a rawarr -> 'a array
val unsafeUninit: 'a rawarr * int -> unit
end
end
36 changes: 32 additions & 4 deletions basis-library/arrays-and-vectors/array.sml
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,50 @@ structure Array: ARRAY_EXTRA =
struct
open Slice
val vector = Primitive.Array.Slice.vector
fun update x = updateMk Primitive.Array.updateUnsafe x
fun unsafeUpdate x = unsafeUpdateMk Primitive.Array.updateUnsafe x
val copyVec = Vector.VectorSlice.copy
val unsafeCopyVec = Vector.VectorSlice.unsafeCopy
fun modifyi f sl = Primitive.Array.Slice.modifyi (wrap2 f) sl
val modify = Primitive.Array.Slice.modify
end

val array = new
val unsafeArray = unsafeNew
val vector = Primitive.Array.vector
fun update x = updateMk Primitive.Array.updateUnsafe x
fun unsafeUpdate x = unsafeUpdateMk Primitive.Array.updateUnsafe x
val copyVec = Vector.copy
val unsafeCopyVec = Vector.unsafeCopy
fun modifyi f sl = Primitive.Array.modifyi (wrap2 f) sl
val modify = Primitive.Array.modify

structure Raw = Primitive.Array.Raw
structure Raw =
struct
type 'a rawarr = 'a Raw.rawarr

fun length a =
if Primitive.Controls.safe
then (SeqIndex.toInt (Raw.length a))
handle Overflow => raise Fail "Raw.length"
else SeqIndex.toIntUnsafe (Raw.length a)

fun alloc n = Raw.alloc (SeqIndex.fromIntForLength n)
fun unsafeAlloc n = Raw.unsafeAlloc (SeqIndex.fromIntUnsafe n)

val uninitIsNop = Raw.uninitIsNop
fun unsafeUninit (a, i) =
Raw.unsafeUninit (a, SeqIndex.fromIntUnsafe i)
fun uninit (a, i) =
if Primitive.Controls.safe
then let
val i =
(SeqIndex.fromInt i)
handle Overflow => raise Subscript
in
Raw.uninit (a, i)
end
else unsafeUninit (a, i)

val unsafeToArray = Primitive.Array.Raw.unsafeToArray
end
end

structure ArraySlice: ARRAY_SLICE_EXTRA = Array.ArraySlice
Expand Down
14 changes: 7 additions & 7 deletions basis-library/arrays-and-vectors/array2.sml
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ structure Array2 : ARRAY2 =
rows = rows,
cols = cols}
in
fun uninit' (rows, cols) =
make (rows, cols, Primitive.Array.uninit)
fun alloc' (rows, cols) =
make (rows, cols, Primitive.Array.alloc)
fun array' (rows, cols, init) =
make (rows, cols, fn size => Primitive.Array.new (size, init))
end
Expand All @@ -135,14 +135,14 @@ structure Array2 : ARRAY2 =
else doit (SeqIndex.fromIntUnsafe rows,
SeqIndex.fromIntUnsafe cols)
in
fun uninit (rows, cols) =
make (rows, cols, fn (rows, cols) => uninit' (rows, cols))
fun alloc (rows, cols) =
make (rows, cols, fn (rows, cols) => alloc' (rows, cols))
fun array (rows, cols, init) =
make (rows, cols, fn (rows, cols) => array' (rows, cols, init))
end

fun array0 (): 'a array =
{array = Primitive.Array.uninit 0,
{array = Primitive.Array.alloc 0,
rows = 0,
cols = 0}

Expand Down Expand Up @@ -192,7 +192,7 @@ structure Array2 : ARRAY2 =
let
val cols = length row1
val a as {array, cols = cols', ...} =
uninit (length rows, cols)
alloc (length rows, cols)
val _ =
List.foldl
(fn (row: 'a list, i) =>
Expand Down Expand Up @@ -300,7 +300,7 @@ structure Array2 : ARRAY2 =

fun tabulate trv (rows, cols, f) =
let
val a = uninit (rows, cols)
val a = alloc (rows, cols)
val () = modifyi trv (fn (r, c, _) => f (r, c)) (wholeRegion a)
in
a
Expand Down
4 changes: 4 additions & 0 deletions basis-library/arrays-and-vectors/mono-array-slice.sig
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ signature MONO_ARRAY_SLICE_EXTRA =
val concat: slice list -> array
val toList: slice -> elem list
val toPoly: slice -> elem ArraySlice.slice
val uninitIsNop: slice -> bool
val uninit: slice * int -> unit
val unsafeSlice: array * int * int option -> slice
val unsafeSub: slice * int -> elem
val unsafeSubslice: slice * int * int option -> slice
val unsafeUninit: slice * int -> unit
val unsafeUpdate: slice * int * elem -> unit
end
7 changes: 6 additions & 1 deletion basis-library/arrays-and-vectors/mono-array.sig
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,19 @@ signature MONO_ARRAY_EXTRA =
and type vector = vector
and type vector_slice = vector_slice

val uninit: int -> array
val alloc: int -> array
val uninitIsNop: array -> bool
val uninit: array * int -> unit

val concat: array list -> array
val duplicate: array -> array
val fromPoly: elem Array.array -> array
val toList: array -> elem list
val toPoly: array -> elem Array.array
val unfoldi: int * 'a * (int * 'a -> elem * 'a) -> array * 'a

val unsafeAlloc: int -> array
val unsafeSub: array * int -> elem
val unsafeUninit: array * int -> unit
val unsafeUpdate: array * int * elem -> unit
end
61 changes: 39 additions & 22 deletions basis-library/arrays-and-vectors/sequence.fun
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ structure SeqIndex =
in
val toInt = S.f
end

fun fromIntForLength n =
if Primitive.Controls.safe
then (fromInt n) handle Overflow => raise Size
else fromIntUnsafe n
end

functor Sequence (S: PRIM_SEQUENCE): SEQUENCE =
Expand All @@ -82,31 +87,27 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE =
(* S.maxLen must be representable as an Int.int already *)
val maxLen = SeqIndex.toInt S.maxLen

fun fromIntForLength n =
if Primitive.Controls.safe
then (SeqIndex.fromInt n) handle Overflow => raise Size
else SeqIndex.fromIntUnsafe n

fun length s =
if Primitive.Controls.safe
then (SeqIndex.toInt (S.length s))
handle Overflow => raise Fail "Sequence.length"
else SeqIndex.toIntUnsafe (S.length s)

fun uninit n = S.uninit (fromIntForLength n)
fun unsafeUninit n = S.unsafeUninit (SeqIndex.fromIntUnsafe n)
fun alloc n = S.alloc (SeqIndex.fromIntForLength n)
fun unsafeAlloc n = S.unsafeAlloc (SeqIndex.fromIntUnsafe n)

fun create n =
let
val {done, sub, update} = S.create (fromIntForLength n)
val {done, sub, update} = S.create (SeqIndex.fromIntForLength n)
in
{done = done,
sub = unwrap1 sub,
update = unwrap2 update}
end

fun unfoldi (n, b, f) = S.unfoldi (fromIntForLength n, b, wrap2 f)
fun unfold (n, b, f) = S.unfold (fromIntForLength n, b, f)
fun unfoldi (n, b, f) = S.unfoldi (SeqIndex.fromIntForLength n, b, wrap2 f)
fun unfold (n, b, f) = S.unfold (SeqIndex.fromIntForLength n, b, f)
fun unsafeUnfold (n, b, f) = S.unfold (SeqIndex.fromIntUnsafe n, b, f)

fun seq0 () = #1 (unfold (0, (), fn _ => raise Fail "Sequence.seq0"))

Expand All @@ -115,6 +116,8 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE =

fun new (n, x) =
#1 (unfold (n, (), fn () => (x, ())))
fun unsafeNew (n, x) =
#1 (unsafeUnfold (n, (), fn () => (x, ())))

fun fromList l =
#1 (unfold (List.length l, l, fn l =>
Expand Down Expand Up @@ -147,19 +150,32 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE =
end
else unsafeSub (sl, i)

fun unsafeUpdateMk updateUnsafe (sl, i, x) =
(S.Slice.unsafeUpdateMk updateUnsafe)
(sl, SeqIndex.fromIntUnsafe i, x)
fun updateMk updateUnsafe (sl, i, x) =
fun unsafeUpdate (sl, i, x) =
S.Slice.unsafeUpdate (sl, SeqIndex.fromIntUnsafe i, x)
fun update (sl, i, x) =
if Primitive.Controls.safe
then let
val i =
(SeqIndex.fromInt i)
handle Overflow => raise Subscript
in
S.Slice.update (sl, i, x)
end
else unsafeUpdate (sl, i, x)

val uninitIsNop = S.Slice.uninitIsNop
fun unsafeUninit (sl, i) =
S.Slice.unsafeUninit (sl, SeqIndex.fromIntUnsafe i)
fun uninit (sl, i) =
if Primitive.Controls.safe
then let
val i =
(SeqIndex.fromInt i)
handle Overflow => raise Subscript
in
(S.Slice.updateMk updateUnsafe) (sl, i, x)
S.Slice.uninit (sl, i)
end
else (unsafeUpdateMk updateUnsafe) (sl, i, x)
else unsafeUninit (sl, i)

fun unsafeCopy {dst, di, src} =
S.Slice.unsafeCopy
Expand Down Expand Up @@ -234,7 +250,7 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE =
handle Overflow => raise Size)
else (fn (sl, s) => s +? S.Slice.length sl)
val n = List.foldl add 0 sls
val a = Primitive.Array.uninit n
val a = Primitive.Array.alloc n
fun loop (di, sls) =
case sls of
[] => S.unsafeFromArray a
Expand All @@ -260,7 +276,7 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE =
else (fn (sl, s) =>
(s +? sepn +? S.Slice.length sl))
val n = List.foldl add (S.Slice.length sl) sls
val a = Primitive.Array.uninit n
val a = Primitive.Array.alloc n
fun loop (di, sls) =
case sls of
[] => raise Fail "Sequence.Slice.concatWith"
Expand Down Expand Up @@ -433,10 +449,11 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE =
in
fun sub (seq, i) = Slice.sub (Slice.full seq, i)
fun unsafeSub (seq, i) = Slice.unsafeSub (Slice.full seq, i)
fun updateMk updateUnsafe (seq, i, x) =
Slice.updateMk updateUnsafe (Slice.full seq, i, x)
fun unsafeUpdateMk updateUnsafe (seq, i, x) =
Slice.unsafeUpdateMk updateUnsafe (Slice.full seq, i, x)
fun update (seq, i, x) = Slice.update (Slice.full seq, i, x)
fun unsafeUpdate (seq, i, x) = Slice.unsafeUpdate (Slice.full seq, i, x)
fun uninitIsNop seq = Slice.uninitIsNop (Slice.full seq)
fun uninit (seq, i) = Slice.uninit (Slice.full seq, i)
fun unsafeUninit (seq, i) = Slice.unsafeUninit (Slice.full seq, i)
fun copy {dst, di, src} =
Slice.copy {dst = dst, di = di, src = Slice.full src}
fun unsafeCopy {dst, di, src} =
Expand Down
20 changes: 9 additions & 11 deletions basis-library/arrays-and-vectors/sequence.sig
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,17 @@ signature SEQUENCE =
and type 'a elt = 'a elt

val maxLen: int
val tabulate: int * (int -> 'a elt) -> 'a sequence
val length: 'a sequence -> int
val sub: 'a sequence * int -> 'a elt
val unsafeSub: 'a sequence * int -> 'a elt
(* updateMk,unsafeUpdateMk:
* ('a sequence * SeqIndex.int * 'a elt -> unit)
* should be primitive unsafe update
*)
val updateMk: ('a sequence * SeqIndex.int * 'a elt -> unit) ->
('a sequence * int * 'a elt) -> unit
val unsafeUpdateMk: ('a sequence * SeqIndex.int * 'a elt -> unit) ->
('a sequence * int * 'a elt) -> unit
val update: 'a sequence * int * 'a elt -> unit
val unsafeUpdate: 'a sequence * int * 'a elt -> unit
val uninitIsNop: 'a sequence -> bool
val uninit: 'a sequence * int -> unit
val unsafeUninit: 'a sequence * int -> unit
val copy: {dst: 'a elt Array.array, di: int, src: 'a sequence} -> unit
val unsafeCopy: {dst: 'a elt Array.array, di: int, src: 'a sequence} -> unit
val tabulate: int * (int -> 'a elt) -> 'a sequence
val appi: (int * 'a elt -> unit) -> 'a sequence -> unit
val app: ('a elt -> unit) -> 'a sequence -> unit
val mapi : (int * 'a elt -> 'b elt) -> 'a sequence -> 'b sequence
Expand All @@ -51,6 +48,7 @@ signature SEQUENCE =
val concat: 'a sequence list -> 'a sequence

(* Extra *)
val alloc: int -> 'a sequence
val append: 'a sequence * 'a sequence -> 'a sequence
val create:
int -> {done: unit -> 'a sequence,
Expand All @@ -60,8 +58,8 @@ signature SEQUENCE =
val new: int * 'a elt -> 'a sequence
val unfoldi: int * 'b * (int * 'b -> 'a elt * 'b) -> 'a sequence * 'b
val unfold: int * 'b * ('b -> 'a elt * 'b) -> 'a sequence * 'b
val uninit: int -> 'a sequence
val unsafeUninit: int -> 'a sequence
val unsafeAlloc: int -> 'a sequence
val unsafeNew: int * 'a elt -> 'a sequence

(* Used to implement Substring/String functions *)
val isPrefix: ('a elt * 'a elt -> bool) -> 'a sequence -> 'a sequence -> bool
Expand Down