Safe Haskell | None |
---|
This module provides a way to serialize graph-like structures into
lazy ByteString
s. Graph-like structures here are structures that
may reference other locations in the resulting output. The references
are serialized as relative byte offsets.
A simple example:
test1 :: [Word8] test1 = L.unpack $ toLazyByteString id $ do r <-newRegion
l1 <-label
remitWord32le
r 42reference
S4 LE r l1 emitWord32le r 43 test1 == [42,0,0,0,252,255,255,255,43,0,0,0]
- data BuildM a
- toLazyByteString :: ([Region] -> [Region]) -> BuildM () -> ByteString
- data Region
- newRegion :: BuildM Region
- data Label
- label :: Region -> BuildM Label
- makeLabel :: BuildM Label
- placeLabel :: Region -> Label -> BuildM ()
- reference :: Size -> ByteOrder -> Region -> Label -> BuildM ()
- reference' :: Size -> ByteOrder -> (Int -> Int) -> Region -> Label -> BuildM ()
- data Size
- sizeToBytes :: Size -> Int
- data ByteOrder
- offset' :: Size -> ByteOrder -> (Int -> Int) -> Region -> Label -> Label -> BuildM ()
- emitWord8 :: Region -> Word8 -> BuildM ()
- emitWord8s :: Region -> [Word8] -> BuildM ()
- emitWord16le :: Region -> Word16 -> BuildM ()
- emitWord16be :: Region -> Word16 -> BuildM ()
- emitWord16host :: Region -> Word16 -> BuildM ()
- emitWord32le :: Region -> Word32 -> BuildM ()
- emitWord32be :: Region -> Word32 -> BuildM ()
- emitWord32host :: Region -> Word32 -> BuildM ()
- emitWord64le :: Region -> Word64 -> BuildM ()
- emitWord64be :: Region -> Word64 -> BuildM ()
- emitWord64host :: Region -> Word64 -> BuildM ()
- emitInt8 :: Region -> Int8 -> BuildM ()
- emitInt8s :: Region -> [Int8] -> BuildM ()
- emitInt16le :: Region -> Int16 -> BuildM ()
- emitInt16be :: Region -> Int16 -> BuildM ()
- emitInt16host :: Region -> Int16 -> BuildM ()
- emitInt32le :: Region -> Int32 -> BuildM ()
- emitInt32be :: Region -> Int32 -> BuildM ()
- emitInt32host :: Region -> Int32 -> BuildM ()
- emitInt64le :: Region -> Int64 -> BuildM ()
- emitInt64be :: Region -> Int64 -> BuildM ()
- emitInt64host :: Region -> Int64 -> BuildM ()
- emitByteString :: Region -> ByteString -> BuildM ()
- emitLazyByteString :: Region -> ByteString -> BuildM ()
- padTo :: Region -> Int -> Word8 -> BuildM ()
- alignedLabel :: Region -> Int -> BuildM Label
Monad and ByteString construction
Monad for constructing the serialised structure.
:: ([Region] -> [Region]) | Determines the ordering of the regions. If you pass |
-> BuildM () | |
-> ByteString |
Serialise the graph into a lazy ByteString
.
Regions
Emitting Data, Labels, References
makeLabel :: BuildM LabelSource
Create a new label (with no location attached to it).
It is up to the user to ensure that if this label is ever used in a
reference
, then the label must have been placed via placeLabel
.
This is intended for forward references within a region:
example r = do l <- makeLabel reference S4 Host r l ... more stuff ... placeLabel r l ... other stuff ...
placeLabel :: Region -> Label -> BuildM ()Source
Place a label previously created with makeLabel
.
This function must only be called once per label. If the same label is placed multiple times, it is undefined where references to it point to.
:: Size | The size of the reference in bytes. |
-> ByteOrder | Byte order used for encoding the reference. |
-> Region | The region in which the reference will be emitted. |
-> Label | The target label. |
-> BuildM () |
Emit a reference to the given label in the current region.
The reference will be encoded as a signed integer that specifies the relative distance (in bytes) from the current location to the target label.
The current location starts before the reference. A serialised
reference with value 0
therefore refers to itself.
It is up to the user to ensure that references are large enough to
encode the required range. If they are not in range
toLazyByteString
will fail.
:: Size | The size of the reference in bytes. |
-> ByteOrder | Byte order used for encoding the reference. |
-> (Int -> Int) | Offset transformation function. |
-> Region | The region in which the reference will be emitted. |
-> Label | The target label. |
-> BuildM () |
Emit a reference to the given label in the current region.
The calculated offset will be passed to the function being supplied. This can be use for example to change the unit of reference from bytes to, say, words.
Say, you're generating bytecode where each instruction is a
multiple of 4 bytes. Then a reference is known to be a multiple of
4. If our bytecode only uses 16 bit references then it would be
wasteful to store the lowest 2 bits which we know to be zero. We
can implement this transformation by passing (`shiftR` 2)
as
the transformation function.
The size of a reference (1, 2, 4, or 8 bytes).
sizeToBytes :: Size -> IntSource
Translate Size
into matching number of bytes.
The byte ordering to be used when serializing a reference.
:: Size | The size of the reference in bytes. |
-> ByteOrder | Byte order used for encoding the reference. |
-> (Int -> Int) | Offset transformation function. |
-> Region | The region in which the reference will be emitted. |
-> Label | Start label |
-> Label | End label |
-> BuildM () |
Emit the distance between two labels.
If the start label occurs before the end label, then the written integer will be positive, negative otherwise.
For example:
test3 = (toLazyByteString
id $ do r <-newRegion
l1 <-label
remitWord32le
r 42 l2 <- label roffset'
S4 LE id r l1 l2) ==pack
[42,0,0,0,4,0,0,0]
Words
emitWord8s :: Region -> [Word8] -> BuildM ()Source
Emit a list of bytes.
emitWord16host :: Region -> Word16 -> BuildM ()Source
Emit a Word16
in native host order and host endianness.
emitWord32host :: Region -> Word32 -> BuildM ()Source
Emit a Word32
in native host order and host endianness.
emitWord64host :: Region -> Word64 -> BuildM ()Source
Emit a Word64
in native host order and host endianness.
Ints
emitInt16host :: Region -> Int16 -> BuildM ()Source
Emit a Int16
in native host order and host endianness.
emitInt32host :: Region -> Int32 -> BuildM ()Source
Emit a Int32
in native host order and host endianness.
emitInt64host :: Region -> Int64 -> BuildM ()Source
Emit a Int64
in native host order and host endianness.
ByteStrings
emitByteString :: Region -> ByteString -> BuildM ()Source
Emit a strict ByteString
.
emitLazyByteString :: Region -> ByteString -> BuildM ()Source
Emit a lazy ByteString
.
Alignment
Insert padding bytes into given region until its size is a multiple of the expected alignment.