Changed fill-column to 80, so more space for comments.
This commit is contained in:
55
lib/base.h
55
lib/base.h
@@ -91,8 +91,7 @@ typedef union
|
|||||||
} data_t;
|
} data_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Enum of type tags for the data_t structure to provide
|
@brief Enum of type tags for the data_t structure to provide context.
|
||||||
context.
|
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -116,11 +115,10 @@ static const hword_t __i = 0xFFFF0000;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Safely subtract SUB from W, where both are words (64 bit
|
@brief Safely subtract SUB from W, where both are words (64 bit integers).
|
||||||
integers).
|
|
||||||
|
|
||||||
@details In case of underflow (i.e. where W - SUB < 0) returns 0
|
@details In case of underflow (i.e. where W - SUB < 0) returns 0 instead of
|
||||||
instead of the underflowed result.
|
the underflowed result.
|
||||||
*/
|
*/
|
||||||
#define WORD_SAFE_SUB(W, SUB) ((W) > (SUB) ? ((W) - (SUB)) : 0)
|
#define WORD_SAFE_SUB(W, SUB) ((W) > (SUB) ? ((W) - (SUB)) : 0)
|
||||||
|
|
||||||
@@ -141,17 +139,15 @@ static const hword_t __i = 0xFFFF0000;
|
|||||||
/**
|
/**
|
||||||
@brief Return the Nth half word of WORD.
|
@brief Return the Nth half word of WORD.
|
||||||
|
|
||||||
@details N should range from 0 to 1 as there are 2 half words in a
|
@details N should range from 0 to 1 as there are 2 half words in a word
|
||||||
word
|
|
||||||
*/
|
*/
|
||||||
#define WORD_NTH_HWORD(WORD, N) (((WORD) >> ((N) * 32)) & 0xFFFFFFFF)
|
#define WORD_NTH_HWORD(WORD, N) (((WORD) >> ((N) * 32)) & 0xFFFFFFFF)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Convert a buffer of bytes to a short
|
@brief Convert a buffer of bytes to a short
|
||||||
|
|
||||||
@details It is assumed that the buffer of bytes are in virtual
|
@details It is assumed that the buffer of bytes are in virtual machine byte
|
||||||
machine byte code format (little endian) and that they are at least
|
code format (little endian) and that they are at least SHORT_SIZE in size.
|
||||||
SHORT_SIZE in size.
|
|
||||||
*/
|
*/
|
||||||
short_t convert_bytes_to_short(const byte_t *buffer);
|
short_t convert_bytes_to_short(const byte_t *buffer);
|
||||||
|
|
||||||
@@ -161,17 +157,16 @@ short_t convert_bytes_to_short(const byte_t *buffer);
|
|||||||
|
|
||||||
@param s: Short to convert
|
@param s: Short to convert
|
||||||
|
|
||||||
@param buffer: Buffer to store into. It is assumed that the buffer
|
@param buffer: Buffer to store into. It is assumed that the buffer has at
|
||||||
has at least SHORT_SIZE space.
|
least SHORT_SIZE space.
|
||||||
*/
|
*/
|
||||||
void convert_short_to_bytes(const short_t s, byte_t *buffer);
|
void convert_short_to_bytes(const short_t s, byte_t *buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Convert a buffer of bytes to a half word.
|
@brief Convert a buffer of bytes to a half word.
|
||||||
|
|
||||||
@details It is assumed that the buffer of bytes are in virtual
|
@details It is assumed that the buffer of bytes are in virtual machine byte
|
||||||
machine byte code format (little endian) and that they are at least
|
code format (little endian) and that they are at least HWORD_SIZE in size.
|
||||||
HWORD_SIZE in size.
|
|
||||||
*/
|
*/
|
||||||
hword_t convert_bytes_to_hword(const byte_t *buffer);
|
hword_t convert_bytes_to_hword(const byte_t *buffer);
|
||||||
|
|
||||||
@@ -181,36 +176,34 @@ hword_t convert_bytes_to_hword(const byte_t *buffer);
|
|||||||
|
|
||||||
@param h: Half word to convert
|
@param h: Half word to convert
|
||||||
|
|
||||||
@param buffer: Buffer to store into. It is assumed that the buffer
|
@param buffer: Buffer to store into. It is assumed that the buffer has at
|
||||||
has at least HWORD_SIZE space.
|
least HWORD_SIZE space.
|
||||||
*/
|
*/
|
||||||
void convert_hword_to_bytes(const hword_t h, byte_t *buffer);
|
void convert_hword_to_bytes(const hword_t h, byte_t *buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Convert a buffer of bytes to a word.
|
@brief Convert a buffer of bytes to a word.
|
||||||
|
|
||||||
@details It is assumed that the buffer of bytes are in virtual
|
@details It is assumed that the buffer of bytes are in virtual machine byte
|
||||||
machine byte code format (little endian) and that they are at least
|
code format (little endian) and that they are at least WORD_SIZE in size.
|
||||||
WORD_SIZE in size.
|
|
||||||
*/
|
*/
|
||||||
word_t convert_bytes_to_word(const byte_t *);
|
word_t convert_bytes_to_word(const byte_t *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Convert a word into a VM byte code format bytes (little
|
@brief Convert a word into a VM byte code format bytes (little endian)
|
||||||
endian)
|
|
||||||
|
|
||||||
@param w: Word to convert
|
@param w: Word to convert
|
||||||
|
|
||||||
@param buffer: Buffer to store into. It is assumed that the buffer
|
@param buffer: Buffer to store into. It is assumed that the buffer has at
|
||||||
has at least WORD_SIZE space.
|
least WORD_SIZE space.
|
||||||
*/
|
*/
|
||||||
void convert_word_to_bytes(const word_t w, byte_t *buffer);
|
void convert_word_to_bytes(const word_t w, byte_t *buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Swap the ordering of bytes within an short
|
@brief Swap the ordering of bytes within an short
|
||||||
|
|
||||||
@details The ordering of the bytes in the short are reversed (2
|
@details The ordering of the bytes in the short are reversed (2 bytes in a
|
||||||
bytes in a short).
|
short).
|
||||||
|
|
||||||
@param s: short to swap
|
@param s: short to swap
|
||||||
*/
|
*/
|
||||||
@@ -219,8 +212,8 @@ short_t short_byteswap(const short_t s);
|
|||||||
/**
|
/**
|
||||||
@brief Swap the ordering of bytes within an half word
|
@brief Swap the ordering of bytes within an half word
|
||||||
|
|
||||||
@details The ordering of the bytes in the half word are reversed (4
|
@details The ordering of the bytes in the half word are reversed (4 bytes in
|
||||||
bytes in a half word).
|
a half word).
|
||||||
|
|
||||||
@param h: Half word to swap
|
@param h: Half word to swap
|
||||||
*/
|
*/
|
||||||
@@ -229,8 +222,8 @@ hword_t hword_byteswap(const hword_t h);
|
|||||||
/**
|
/**
|
||||||
@brief Swap the ordering of bytes within an word
|
@brief Swap the ordering of bytes within an word
|
||||||
|
|
||||||
@details The ordering of the bytes in the word are reversed (8
|
@details The ordering of the bytes in the word are reversed (8 bytes in a
|
||||||
bytes in a word).
|
word).
|
||||||
|
|
||||||
@param w: Word to swap
|
@param w: Word to swap
|
||||||
*/
|
*/
|
||||||
|
|||||||
63
lib/darr.h
63
lib/darr.h
@@ -42,10 +42,10 @@ typedef struct
|
|||||||
/**
|
/**
|
||||||
@brief Get the `IND`th item of type `TYPE` in `DARR_DATA`
|
@brief Get the `IND`th item of type `TYPE` in `DARR_DATA`
|
||||||
|
|
||||||
@details Cast `DARR_DATA` to `TYPE`, taking the `IND`th item.
|
@details Cast `DARR_DATA` to `TYPE`, taking the `IND`th item. NOTE: This is
|
||||||
NOTE: This is unsafe as bound checks are not done i.e. if
|
unsafe as bound checks are not done i.e. if `DARR_DATA` has at least space
|
||||||
`DARR_DATA` has at least space for `IND` * sizeof(`TYPE`) items.
|
for `IND` * sizeof(`TYPE`) items. It is presumed the caller will check
|
||||||
It is presumed the caller will check themselves.
|
themselves.
|
||||||
|
|
||||||
@param[TYPE] Type to cast internal byte array
|
@param[TYPE] Type to cast internal byte array
|
||||||
@param[DARR_DATA] Byte array of darr
|
@param[DARR_DATA] Byte array of darr
|
||||||
@@ -58,24 +58,23 @@ typedef struct
|
|||||||
/**
|
/**
|
||||||
@brief Initialise a dynamic array `darr` with n bytes of space.
|
@brief Initialise a dynamic array `darr` with n bytes of space.
|
||||||
|
|
||||||
@details All properties of `darr` are initialised. `darr`.used is
|
@details All properties of `darr` are initialised. `darr`.used is set to 0,
|
||||||
set to 0, `darr`.available is set to `n` and `darr`.data is set to
|
`darr`.available is set to `n` and `darr`.data is set to a pointer of `n`
|
||||||
a pointer of `n` bytes. NOTE: If `n` = 0 then it is set to
|
bytes. NOTE: If `n` = 0 then it is set to DARR_DEFAULT_SIZE
|
||||||
DARR_DEFAULT_SIZE
|
|
||||||
|
|
||||||
@param[darr] Pointer to darr_t object to initialise
|
@param[darr] Pointer to darr_t object to initialise
|
||||||
@param[n] Number of bytes to allocate. If equal to 0 then
|
@param[n] Number of bytes to allocate. If equal to 0 then considered treated
|
||||||
considered treated as DARR_DEFAULT_SIZE
|
as DARR_DEFAULT_SIZE
|
||||||
*/
|
*/
|
||||||
void darr_init(darr_t *darr, size_t n);
|
void darr_init(darr_t *darr, size_t n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Ensure a dynamic array has at least n bytes of space free.
|
@brief Ensure a dynamic array has at least n bytes of space free.
|
||||||
|
|
||||||
@details If `darr` has n or more bytes free, nothing occurs.
|
@details If `darr` has n or more bytes free, nothing occurs. Otherwise, the
|
||||||
Otherwise, the byte array in `darr` is reallocated such that it has
|
byte array in `darr` is reallocated such that it has at least `n` bytes of
|
||||||
at least `n` bytes of free space. NOTE: `darr` has at least `n`
|
free space. NOTE: `darr` has at least `n` bytes free if and only if
|
||||||
bytes free if and only if `darr`.used + `n` <= `darr`.available
|
`darr`.used + `n` <= `darr`.available
|
||||||
|
|
||||||
@param[darr] Dynamic array to check
|
@param[darr] Dynamic array to check
|
||||||
@param[n] Number of bytes
|
@param[n] Number of bytes
|
||||||
@@ -85,10 +84,9 @@ void darr_ensure_capacity(darr_t *darr, size_t n);
|
|||||||
/**
|
/**
|
||||||
@brief Append a byte to a dynamic array.
|
@brief Append a byte to a dynamic array.
|
||||||
|
|
||||||
@details Append a byte to the end of the byte buffer in a dyamic
|
@details Append a byte to the end of the byte buffer in a dyamic array. If
|
||||||
array. If the dynamic array doesn't have enough free space to fit
|
the dynamic array doesn't have enough free space to fit the byte, it will
|
||||||
the byte, it will reallocate to ensure it can fit it in via
|
reallocate to ensure it can fit it in via darr_ensure_capacity().
|
||||||
darr_ensure_capacity().
|
|
||||||
|
|
||||||
@param[darr] Dynamic arrary to append to
|
@param[darr] Dynamic arrary to append to
|
||||||
@param[b] Byte to append
|
@param[b] Byte to append
|
||||||
@@ -98,10 +96,9 @@ void darr_append_byte(darr_t *darr, byte_t b);
|
|||||||
/**
|
/**
|
||||||
@brief Append an array of n bytes to a dynamic array.
|
@brief Append an array of n bytes to a dynamic array.
|
||||||
|
|
||||||
@details Append an array of bytes to the end of a byte buffer. If
|
@details Append an array of bytes to the end of a byte buffer. If the
|
||||||
the dynamic array doesn't have enough free space to fit all n bytes
|
dynamic array doesn't have enough free space to fit all n bytes it will
|
||||||
it will reallocate to ensure it can fit it in via
|
reallocate to ensure it can fit it in via darr_ensure_capacity().
|
||||||
darr_ensure_capacity().
|
|
||||||
|
|
||||||
@param[darr] Dynamic array to append to
|
@param[darr] Dynamic array to append to
|
||||||
@param[b] Array of bytes to append
|
@param[b] Array of bytes to append
|
||||||
@@ -112,9 +109,9 @@ void darr_append_bytes(darr_t *darr, byte_t *b, size_t n);
|
|||||||
/**
|
/**
|
||||||
@brief Get the nth byte of a dynamic array
|
@brief Get the nth byte of a dynamic array
|
||||||
|
|
||||||
@details Get the nth byte of the dynamic array. 0 based. NOTE: If
|
@details Get the nth byte of the dynamic array. 0 based. NOTE: If the
|
||||||
the dynamic array has less than n bytes used, it will return 0 as a
|
dynamic array has less than n bytes used, it will return 0 as a default
|
||||||
default value, so this is a safe alternative to DARR_AT().
|
value, so this is a safe alternative to DARR_AT().
|
||||||
|
|
||||||
@param[darr] Dynamic array to index
|
@param[darr] Dynamic array to index
|
||||||
@param[n] Index to get byte at
|
@param[n] Index to get byte at
|
||||||
@@ -126,9 +123,9 @@ byte_t *darr_at(darr_t *darr, size_t n);
|
|||||||
/**
|
/**
|
||||||
@brief Write the bytes of a dynamic array to a file pointer
|
@brief Write the bytes of a dynamic array to a file pointer
|
||||||
|
|
||||||
@details Given a dynamic array and a file pointer, write the
|
@details Given a dynamic array and a file pointer, write the internal buffer
|
||||||
internal buffer of bytes to the file pointer. NOTE: The file
|
of bytes to the file pointer. NOTE: The file pointer is assumed to be open
|
||||||
pointer is assumed to be open and suitable for writing.
|
and suitable for writing.
|
||||||
|
|
||||||
@param[darr] Dynamic array to write
|
@param[darr] Dynamic array to write
|
||||||
@param[fp] File pointer to write on
|
@param[fp] File pointer to write on
|
||||||
@@ -138,14 +135,14 @@ void darr_write_file(darr_t *darr, FILE *fp);
|
|||||||
/**
|
/**
|
||||||
@brief Read a file pointer in its entirety into a dynamic array
|
@brief Read a file pointer in its entirety into a dynamic array
|
||||||
|
|
||||||
@details Read a file pointer as a buffer of bytes then return that
|
@details Read a file pointer as a buffer of bytes then return that buffer
|
||||||
buffer wrapped in a darr_t structure. NOTE: the file pointer is
|
wrapped in a darr_t structure. NOTE: the file pointer is assumed to be open
|
||||||
assumed to be open and suitable for reading.
|
and suitable for reading.
|
||||||
|
|
||||||
@param[fp]: File pointer to read
|
@param[fp]: File pointer to read
|
||||||
|
|
||||||
@return Dynamic array structure with available set to the size of
|
@return Dynamic array structure with available set to the size of the
|
||||||
the `buffer` read and `data` set to the buffer of bytes.
|
`buffer` read and `data` set to the buffer of bytes.
|
||||||
*/
|
*/
|
||||||
darr_t darr_read_file(FILE *fp);
|
darr_t darr_read_file(FILE *fp);
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ bool heap_free(heap_t *heap, page_t *page)
|
|||||||
if (cur == page)
|
if (cur == page)
|
||||||
{
|
{
|
||||||
page_delete(cur);
|
page_delete(cur);
|
||||||
// TODO: When does this fragmentation become a performance
|
// TODO: When does this fragmentation become a performance issue?
|
||||||
// issue?
|
|
||||||
DARR_AT(page_t *, heap->page_vec.data, i) = NULL;
|
DARR_AT(page_t *, heap->page_vec.data, i) = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
34
lib/heap.h
34
lib/heap.h
@@ -26,8 +26,8 @@
|
|||||||
/**
|
/**
|
||||||
@brief Some fixed portion of bytes allocated on the heap.
|
@brief Some fixed portion of bytes allocated on the heap.
|
||||||
|
|
||||||
@details A fixed allocation of bytes. Cannot be resized nor can it
|
@details A fixed allocation of bytes. Cannot be resized nor can it be stack
|
||||||
be stack allocated (the usual way) due to flexible array attached.
|
allocated (the usual way) due to flexible array attached.
|
||||||
|
|
||||||
@prop[next] Next page in the linked list
|
@prop[next] Next page in the linked list
|
||||||
@prop[available] Available number of bytes in page
|
@prop[available] Available number of bytes in page
|
||||||
@@ -42,9 +42,8 @@ typedef struct Page
|
|||||||
/**
|
/**
|
||||||
@brief Allocate a new page on the heap with the given properties.
|
@brief Allocate a new page on the heap with the given properties.
|
||||||
|
|
||||||
@details Allocates a new page using malloc with the given size and
|
@details Allocates a new page using malloc with the given size and pointer to
|
||||||
pointer to next page. NOTE: all memory is 0 initialised by
|
next page. NOTE: all memory is 0 initialised by default.
|
||||||
default.
|
|
||||||
|
|
||||||
@param[max] Maximum available memory in page
|
@param[max] Maximum available memory in page
|
||||||
*/
|
*/
|
||||||
@@ -53,9 +52,8 @@ page_t *page_create(size_t max);
|
|||||||
/**
|
/**
|
||||||
@brief Delete a page, freeing its memory
|
@brief Delete a page, freeing its memory
|
||||||
|
|
||||||
@details Free's the memory associated with the page via free().
|
@details Free's the memory associated with the page via free(). NOTE: any
|
||||||
NOTE: any pointers to the page's memory are considered invalid once
|
pointers to the page's memory are considered invalid once this is called.
|
||||||
this is called.
|
|
||||||
|
|
||||||
@param[page] Page to delete
|
@param[page] Page to delete
|
||||||
*/
|
*/
|
||||||
@@ -65,8 +63,8 @@ void page_delete(page_t *page);
|
|||||||
@brief A collection of pages through which generic allocations can
|
@brief A collection of pages through which generic allocations can
|
||||||
occur.
|
occur.
|
||||||
|
|
||||||
@details Collection of pages maintained through a vector of
|
@details Collection of pages maintained through a vector of pointers to
|
||||||
pointers to pages.
|
pages.
|
||||||
|
|
||||||
@prop[page_vec] Vector of pages
|
@prop[page_vec] Vector of pages
|
||||||
*/
|
*/
|
||||||
@@ -80,9 +78,8 @@ typedef struct
|
|||||||
/**
|
/**
|
||||||
@brief Instantiate a new heap structure
|
@brief Instantiate a new heap structure
|
||||||
|
|
||||||
@details Initialises the heap structure given. No heap allocation
|
@details Initialises the heap structure given. No heap allocation occurs
|
||||||
occurs here until a new page is created, so this may be called
|
here until a new page is created, so this may be called safely.
|
||||||
safely.
|
|
||||||
|
|
||||||
@param[heap] Pointer to heap to initialise
|
@param[heap] Pointer to heap to initialise
|
||||||
*/
|
*/
|
||||||
@@ -91,8 +88,8 @@ void heap_create(heap_t *heap);
|
|||||||
/**
|
/**
|
||||||
@brief Allocate a new page on the heap
|
@brief Allocate a new page on the heap
|
||||||
|
|
||||||
@details Creates and joins a new page onto the linked list
|
@details Creates and joins a new page onto the linked list maintained by the
|
||||||
maintained by the heap. heap.end is set to this new page.
|
heap. heap.end is set to this new page.
|
||||||
|
|
||||||
@param[heap] Heap to create a new page on
|
@param[heap] Heap to create a new page on
|
||||||
@param[size] Size of page to allocate
|
@param[size] Size of page to allocate
|
||||||
@@ -104,10 +101,9 @@ page_t *heap_allocate(heap_t *heap, size_t size);
|
|||||||
/**
|
/**
|
||||||
@brief Free a page of memory from the heap
|
@brief Free a page of memory from the heap
|
||||||
|
|
||||||
@details The page given is removed from the linked list of pages
|
@details The page given is removed from the linked list of pages then freed
|
||||||
then freed from the heap via page_delete(). If the page does not
|
from the heap via page_delete(). If the page does not belong to this heap
|
||||||
belong to this heap (O(heap.pages) time) then false is returned,
|
(O(heap.pages) time) then false is returned, otherwise true.
|
||||||
otherwise true.
|
|
||||||
|
|
||||||
@param[heap] Heap to free page from
|
@param[heap] Heap to free page from
|
||||||
@param[page] Page to delete
|
@param[page] Page to delete
|
||||||
|
|||||||
26
lib/inst.h
26
lib/inst.h
@@ -210,10 +210,10 @@ typedef struct
|
|||||||
/**
|
/**
|
||||||
@brief Serialise an instruction into a byte buffer
|
@brief Serialise an instruction into a byte buffer
|
||||||
|
|
||||||
@details Given an instruction and a suitably sized byte buffer,
|
@details Given an instruction and a suitably sized byte buffer, write the
|
||||||
write the bytecode for the instruction into the buffer. NOTE: This
|
bytecode for the instruction into the buffer. NOTE: This function does NOT
|
||||||
function does NOT check the bounds of `bytes` i.e. we assume the
|
check the bounds of `bytes` i.e. we assume the caller has created a suitably
|
||||||
caller has created a suitably sized buffer.
|
sized buffer.
|
||||||
|
|
||||||
@param[inst] Instruction to serialise
|
@param[inst] Instruction to serialise
|
||||||
@param[bytes] Buffer to write on
|
@param[bytes] Buffer to write on
|
||||||
@@ -233,21 +233,19 @@ typedef enum
|
|||||||
/**
|
/**
|
||||||
@brief Deserialise an instruction from a bytecode buffer
|
@brief Deserialise an instruction from a bytecode buffer
|
||||||
|
|
||||||
@details Given a buffer of bytes, deserialise an instruction,
|
@details Given a buffer of bytes, deserialise an instruction, storing the
|
||||||
storing the result in the pointer given. The number of bytes read
|
result in the pointer given. The number of bytes read in the buffer is
|
||||||
in the buffer is returned, which should be opcode_bytecode_size().
|
returned, which should be opcode_bytecode_size(). NOTE: If bytes is not
|
||||||
NOTE: If bytes is not suitably sized for the instruction expected
|
suitably sized for the instruction expected or it is not well formed i.e. not
|
||||||
or it is not well formed i.e. not the right schema then a negative
|
the right schema then a negative number is returned.
|
||||||
number is returned.
|
|
||||||
|
|
||||||
@param[inst] Pointer to instruction which will store result
|
@param[inst] Pointer to instruction which will store result
|
||||||
@param[bytes] Bytecode buffer to deserialise
|
@param[bytes] Bytecode buffer to deserialise
|
||||||
@param[size_bytes] Number of bytes in buffer
|
@param[size_bytes] Number of bytes in buffer
|
||||||
|
|
||||||
@return[int] Number of bytes read. If negative then an error
|
@return[int] Number of bytes read. If negative then an error occurred in
|
||||||
occurred in deserialisation (either buffer was not suitably sized
|
deserialisation (either buffer was not suitably sized or instruction was not
|
||||||
or instruction was not well formed) so any result must be
|
well formed) so any result must be considered invalid.
|
||||||
considered invalid.
|
|
||||||
*/
|
*/
|
||||||
int inst_read_bytecode(inst_t *inst, byte_t *bytes, size_t size_bytes);
|
int inst_read_bytecode(inst_t *inst, byte_t *bytes, size_t size_bytes);
|
||||||
|
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ void test_lib_darr_ensure_capacity_expands(void)
|
|||||||
{10, 10, 10, 20},
|
{10, 10, 10, 20},
|
||||||
{50, 100, 300, 350},
|
{50, 100, 300, 350},
|
||||||
{1 << 20, 2 << 20, 2 << 20, 3 << 20},
|
{1 << 20, 2 << 20, 2 << 20, 3 << 20},
|
||||||
// When we reallocate we allocate MORE than needed (for
|
// When we reallocate we allocate MORE than needed (for amortized
|
||||||
// amortized constant)
|
// constant)
|
||||||
{1, 5, 5, 10},
|
{1, 5, 5, 10},
|
||||||
{85, 100, 40, 200},
|
{85, 100, 40, 200},
|
||||||
{4 << 20, 5 << 20, 1 << 23, 5 << 21},
|
{4 << 20, 5 << 20, 1 << 23, 5 << 21},
|
||||||
|
|||||||
@@ -60,8 +60,7 @@ int main(int argc, char *argv[])
|
|||||||
else if (program.count == 0)
|
else if (program.count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// After reading header, we can allocate the buffer of instrutions
|
// After reading header, we can allocate the buffer of instrutions exactly
|
||||||
// exactly
|
|
||||||
program.instructions = calloc(program.count, sizeof(*program.instructions));
|
program.instructions = calloc(program.count, sizeof(*program.instructions));
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
read_err_prog_t read_err =
|
read_err_prog_t read_err =
|
||||||
|
|||||||
16
vm/runtime.c
16
vm/runtime.c
@@ -98,11 +98,10 @@ err_t vm_execute(vm_t *vm)
|
|||||||
"Code using OPCODE_DATA_TYPE for quick same type opcode "
|
"Code using OPCODE_DATA_TYPE for quick same type opcode "
|
||||||
"conversion may be out of date.");
|
"conversion may be out of date.");
|
||||||
|
|
||||||
// NOTE: We always use the first register to hold the result of
|
// NOTE: We always use the first register to hold the result of this pop.
|
||||||
// this pop.
|
|
||||||
|
|
||||||
// Here we add OP_MOV_BYTE and the data_type_t of the opcode to
|
// Here we add OP_MOV_BYTE and the data_type_t of the opcode to get the
|
||||||
// get the right typed OP_MOV opcode.
|
// right typed OP_MOV opcode.
|
||||||
opcode_t mov_opcode =
|
opcode_t mov_opcode =
|
||||||
OPCODE_DATA_TYPE(instruction.opcode, OP_POP) + OP_MOV_BYTE;
|
OPCODE_DATA_TYPE(instruction.opcode, OP_POP) + OP_MOV_BYTE;
|
||||||
|
|
||||||
@@ -152,8 +151,8 @@ err_t vm_execute(vm_t *vm)
|
|||||||
"conversion may be out of date.");
|
"conversion may be out of date.");
|
||||||
|
|
||||||
data_t datum = {0};
|
data_t datum = {0};
|
||||||
// Here we add OP_POP_BYTE and the data_type_t of the opcode to
|
// Here we add OP_POP_BYTE and the data_type_t of the opcode to get the
|
||||||
// get the right OP_POP opcode.
|
// right OP_POP opcode.
|
||||||
opcode_t pop_opcode =
|
opcode_t pop_opcode =
|
||||||
OPCODE_DATA_TYPE(instruction.opcode, OP_JUMP_IF) + OP_POP_BYTE;
|
OPCODE_DATA_TYPE(instruction.opcode, OP_JUMP_IF) + OP_POP_BYTE;
|
||||||
|
|
||||||
@@ -228,9 +227,8 @@ err_t vm_execute(vm_t *vm)
|
|||||||
|
|
||||||
// 2) create a format string for each datum type possible
|
// 2) create a format string for each datum type possible
|
||||||
|
|
||||||
// TODO: Figure out a way to ensure the ordering of OP_PRINT_* is
|
// TODO: Figure out a way to ensure the ordering of OP_PRINT_* is exactly
|
||||||
// exactly BYTE, SBYTE, SHORT, SSHORT, HWORD, SHWORD, WORD, SWORD
|
// BYTE, SBYTE, SHORT, SSHORT, HWORD, SHWORD, WORD, SWORD via static_assert
|
||||||
// via static_assert
|
|
||||||
|
|
||||||
// lookup table
|
// lookup table
|
||||||
const char *format_strings[] = {
|
const char *format_strings[] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user