[MLton] ffi improvements
Daniel C. Wang
danwang@CS.Princeton.EDU
Wed, 22 Sep 2004 22:29:37 -0400
Stephen Weeks wrote:
>>I suspect what I want is a slightly more refined interface for the
>>user. I don't see any problem having a Pointer type in the compiler,
>>but I would expect more type-checking in the exposed user
>>interfaces.
>
>
> I agree completely. I was worried that you had a reason for compiler
> mods. Yes, someone should build a nicer front end to the pointer
> stuff using phantom types or whatever to get better type safety.
>
How about this?
I would hope MLTon is smart enough to optimize away all the overheads, but
adding explicit support for this in the compiler/optimizer to use the
typinfo might not be hard.
signature POINTER = sig
type 'a T
type 'a ptr
type 'a seq
structure T : sig
val word8 : Word8.word T
val word16 : Word16.word T
val word32 : Word32.word T
val word64 : Word64.word T
val int8 : Int8.int T
val int16 : Int16.int T
val int32 : Int32.int T
val int64 : Int64.int T
val real32 : Real32.real T
val real64 : Real64.real T
val ptr : 'a T -> 'a ptr T
end
val eq: ('a ptr * 'a ptr) -> bool
val null : 'a ptr
val diff: ('a ptr * 'a ptr) -> word
val get: 'a T -> 'a ptr -> 'a
val set: 'a T -> ('a ptr * 'a) -> unit
(* make a sequence with a bounds *)
val seq : 'a ptr * int -> 'a seq
(* preforms bounds check *)
val getElt: 'a T -> ('a seq * int) -> 'a
val setElt: 'a T -> ('a seq * int * 'a) -> unit
end
functor Pointer(structure P : MLTON_POINTER) :> POINTER =
struct
type 'a ptr = P.t
type 'a T = {get: (P.t * int) -> 'a,
set: (P.t * int * 'a) -> unit}
type 'a seq = (P.t * int)
structure T = struct
val word8 = {get=P.getWord8,set=P.setWord8}
val word16 = {get=P.getWord16,set=P.setWord16}
val word32 = {get=P.getWord32,set=P.setWord32}
val word64 = {get=P.getWord64,set=P.setWord64}
val int8 = {get=P.getInt8,set=P.setInt8}
val int16 = {get=P.getInt16,set=P.setInt16}
val int32 = {get=P.getInt32,set=P.setInt32}
val int64 = {get=P.getInt64,set=P.setInt64}
val real32 = {get=P.getReal32,set=P.setReal32}
val real64 = {get=P.getReal64,set=P.setReal64}
fun ptr x = {get=P.getPointer,set=P.setPointer}
end
fun eq (x,y) = (x=y)
val null = P.null
val diff = P.diff
fun get {get=f,set} = (fn p => f(p,0))
fun set {get,set=f} = (fn (p,v) => f(p,0,v))
fun seq x = x
fun getElt {get,set} ((p,max),i) =
if i > 0 andalso i < max then
get(p,i)
else raise General.Subscript
fun setElt {get,set} ((p,max),i,v) =
if i > 0 andalso i < max then
set(p,i,v)
else raise General.Subscript
end