(* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh * Jagannathan, and Stephen Weeks. * Copyright (C) 1997-2000 NEC Research Institute. * * MLton is released under a BSD-style license. * See the file MLton-LICENSE for details. *) functor PackWord (S: sig type word val wordSize: int val isBigEndian: bool val subArr: Word8.word array * SeqIndex.int -> word val subVec: Word8.word vector * SeqIndex.int -> word val update: Word8.word array * SeqIndex.int * word -> unit val bswap: word -> word val toLarge: word -> LargeWord.word val toLargeX: word -> LargeWord.word val fromLarge: LargeWord.word -> word end): PACK_WORD_EXTRA = struct open S val bytesPerElem = Int.div (wordSize, 8) fun offset (i, n) = let val () = if Primitive.Controls.safe andalso (Int.geu (Int.+ (Int.* (bytesPerElem, i), Int.- (bytesPerElem, 1)), n)) then raise Subscript else () in SeqIndex.fromInt i end handle Overflow => raise Subscript val subArrRev = bswap o subArr val subVecRev = bswap o subVec fun updateRev (a, i, w) = update (a, i, bswap w) val (subA, subV, updA) = if isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian then (subArr, subVec, update) else (subArrRev, subVecRev, updateRev) fun unsafeUpdate (a, i, w) = let val i = SeqIndex.fromInt i val a = Word8Array.toPoly a in updA (a, i, fromLarge w) end fun update (a, i, w) = let val i = offset (i, Word8Array.length a) val a = Word8Array.toPoly a in updA (a, i, fromLarge w) end local fun make (sub, length, toPoly) (av, i) = let val i = offset (i, length av) in sub (toPoly av, i) end in val subArr = toLarge o (make (subA, Word8Array.length, Word8Array.toPoly)) val subArrX = toLargeX o (make (subA, Word8Array.length, Word8Array.toPoly)) val subVec = toLarge o (make (subV, Word8Vector.length, Word8Vector.toPoly)) val subVecX = toLargeX o (make (subV, Word8Vector.length, Word8Vector.toPoly)) end local fun make (sub, length, toPoly) (av, i) = let val i = SeqIndex.fromInt i in sub (toPoly av, i) end in val unsafeSubArr = toLarge o (make (subA, Word8Array.length, Word8Array.toPoly)) val unsafeSubArrX = toLargeX o (make (subA, Word8Array.length, Word8Array.toPoly)) val unsafeSubVec = toLarge o (make (subV, Word8Vector.length, Word8Vector.toPoly)) val unsafeSubVecX = toLargeX o (make (subV, Word8Vector.length, Word8Vector.toPoly)) end end structure PackWord8Big: PACK_WORD_EXTRA = PackWord (val isBigEndian = true open Primitive.PackWord8 open Word8) structure PackWord8Little: PACK_WORD_EXTRA = PackWord (val isBigEndian = false open Primitive.PackWord8 open Word8) structure PackWord8Host: PACK_WORD_EXTRA = PackWord (val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian open Primitive.PackWord8 open Word8) structure PackWord16Big: PACK_WORD_EXTRA = PackWord (val isBigEndian = true open Primitive.PackWord16 open Word16) structure PackWord16Little: PACK_WORD_EXTRA = PackWord (val isBigEndian = false open Primitive.PackWord16 open Word16) structure PackWord16Host: PACK_WORD_EXTRA = PackWord (val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian open Primitive.PackWord16 open Word16) structure PackWord32Big: PACK_WORD_EXTRA = PackWord (val isBigEndian = true open Primitive.PackWord32 open Word32) structure PackWord32Little: PACK_WORD_EXTRA = PackWord (val isBigEndian = false open Primitive.PackWord32 open Word32) structure PackWord32Host: PACK_WORD_EXTRA = PackWord (val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian open Primitive.PackWord32 open Word32) structure PackWord64Big: PACK_WORD_EXTRA = PackWord (val isBigEndian = true open Primitive.PackWord64 open Word64) structure PackWord64Little: PACK_WORD_EXTRA = PackWord (val isBigEndian = false open Primitive.PackWord64 open Word64) structure PackWord64Host: PACK_WORD_EXTRA = PackWord (val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian open Primitive.PackWord64 open Word64) local structure PackWord = struct local structure S = Word_ChooseWordN (type 'a t = Word8.word array * SeqIndex.t -> 'a val fWord8 = Primitive.PackWord8.subArr val fWord16 = Primitive.PackWord16.subArr val fWord32 = Primitive.PackWord32.subArr val fWord64 = Primitive.PackWord64.subArr) in val subArr = S.f end local structure S = Word_ChooseWordN (type 'a t = Word8.word vector * SeqIndex.t -> 'a val fWord8 = Primitive.PackWord8.subVec val fWord16 = Primitive.PackWord16.subVec val fWord32 = Primitive.PackWord32.subVec val fWord64 = Primitive.PackWord64.subVec) in val subVec = S.f end local structure S = Word_ChooseWordN (type 'a t = Word8.word array * SeqIndex.t * 'a -> unit val fWord8 = Primitive.PackWord8.update val fWord16 = Primitive.PackWord16.update val fWord32 = Primitive.PackWord32.update val fWord64 = Primitive.PackWord64.update) in val update = S.f end end in structure PackWordBig: PACK_WORD_EXTRA = PackWord (val isBigEndian = true open PackWord open Word) structure PackWordLittle: PACK_WORD_EXTRA = PackWord (val isBigEndian = false open PackWord open Word) structure PackWordHost: PACK_WORD_EXTRA = PackWord (val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian open PackWord open Word) end local structure PackLargeWord = struct local structure S = LargeWord_ChooseWordN (type 'a t = Word8.word array * SeqIndex.t -> 'a val fWord8 = Primitive.PackWord8.subArr val fWord16 = Primitive.PackWord16.subArr val fWord32 = Primitive.PackWord32.subArr val fWord64 = Primitive.PackWord64.subArr) in val subArr = S.f end local structure S = LargeWord_ChooseWordN (type 'a t = Word8.word vector * SeqIndex.t -> 'a val fWord8 = Primitive.PackWord8.subVec val fWord16 = Primitive.PackWord16.subVec val fWord32 = Primitive.PackWord32.subVec val fWord64 = Primitive.PackWord64.subVec) in val subVec = S.f end local structure S = LargeWord_ChooseWordN (type 'a t = Word8.word array * SeqIndex.t * 'a -> unit val fWord8 = Primitive.PackWord8.update val fWord16 = Primitive.PackWord16.update val fWord32 = Primitive.PackWord32.update val fWord64 = Primitive.PackWord64.update) in val update = S.f end end in structure PackLargeWordBig: PACK_WORD_EXTRA = PackWord (val isBigEndian = true open PackLargeWord open LargeWord) structure PackLargeWordLittle: PACK_WORD_EXTRA = PackWord (val isBigEndian = false open PackLargeWord open LargeWord) structure PackLargeWordHost: PACK_WORD_EXTRA = PackWord (val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian open PackLargeWord open LargeWord) end