Commit Graph

24 Commits

Author SHA1 Message Date
Aryadev Chavali
08c9726333 Fixed bug with converting (h)word to (h)word in terms of endian
While it helped with understanding to use unions as a safe way to
access the underlying bits, this shift based mechanism actually makes
more sense at a glance, particularly by utilising WORD_NTH_BYTE
2024-04-28 20:57:41 +05:30
Aryadev Chavali
40907e5113 Reworked (de)serialising routines for instructions
No longer relying on darr_t or anything other than the C runtime and
aliases.  This means it should be *even easier* to target this via FFI
from other languages without having to initialise my custom made
structures!  Furthermore I've removed any form of allocation in the
library so FFI callers don't need to manage memory in any way.
Instead we rely on the caller allocating the correct amount of memory
for the functions to work, with basic error handling if that doesn't
happen.

In the case of inst_read_bytecode, error reporting occurs by making
the return of a function an integer.  If the integer is positive it is
the number of bytes read from the buffer.  If negative it flags a
possible error, which is a member of read_err_t.

prog_read_bytecode has been split into two functions: prog_read_header
and prog_read_instructions.  prog_read_instructions works under the
assumption that the program's header has been filled, e.g. via
prog_read_header.  prog_read_header returns 0 if there's not enough
space in the buffer or if the start_address is greater than the count.
prog_read_instructions returns a custom structure which contains an
byte position as well as an error enum, allowing for finer error
reporting.

In the case of inst_write_bytecode via the assumption that the caller
allocated the correct memory there is no need for error reporting.
For prog_write_bytecode if an error occurs due to

In the case of inst_read_bytecode we return the number
2024-04-27 17:43:06 +05:30
Aryadev Chavali
43d14d05cf Refactor type word -> word_t 2024-04-25 11:07:37 +05:30
Aryadev Chavali
9c0125542e Refactored type hword -> hword_t 2024-04-25 10:59:45 +05:30
Aryadev Chavali
1dfdbb3cd0 Refactor type byte -> byte_t
Simpler to read as a type.  This style will allow me to define signed
versions of the base types as simpler names than what they are
currently.
2024-04-25 10:48:51 +05:30
Aryadev Chavali
81caa577fe Fixed static_assert message in inst_print 2024-04-25 03:01:41 +05:30
Aryadev Chavali
a4b057f20a Refactored inst.c and runtime.c for OPCODE_IS_TYPE change
Pretty simple, there are fewer opcode types that use signed types than
unsigned so it was a pretty simple rename.
2024-04-25 02:55:54 +05:30
Aryadev Chavali
71b0b793af prog_t no longer has a header
This "header" is now embedded directly into the struct.  The semantic
of a header never really matters in the actual runtime anyway, it's
only for bytecode (de)serialising.
2024-04-25 01:19:43 +05:30
Aryadev Chavali
5d6cf212e7 Moved prog_t.count -> prog_t.prog_header_t.count 2024-04-16 18:21:39 +06:30
Aryadev Chavali
3b912495de Created custom functions to convert (h)words to and from bytecode format
Instead of using endian.h that is not portable AND doesn't work with
C++, I'll just write my own using a forced union based type punning
trick.

I've decided to use little endian for the format as well: it seems to
be used by most desktop computers so it should make these functions
faster to run for most CPUs.
2024-04-14 03:54:54 +06:30
Aryadev Chavali
e2667eda65 Fix problems with running programs due to mismatched endian
Basically ensure we're converting to big endian when writing bytecode
and converting from big endian when reading bytecode.
2024-04-12 17:34:17 +06:30
Aryadev Chavali
72585772ef Fixing build problems due to endian.h
Have to define _DEFAULT_SOURCE before you can use the endian
conversion functions.  As most standard library headers use
features.h, and _DEFAULT_SOURCE must be defined before features.h is
included, we have to include base.h before other headers.
2024-04-12 17:32:58 +06:30
Aryadev Chavali
33e1d2ab72 Added some TODOs to lib/inst.c to enforce endian 2024-04-09 21:23:30 +06:30
Aryadev Chavali
fe7f26256b Defined a program structure
Essentially a "program header", followed by a count, followed by
instructions.

Provides a stronger format for bytecode files and allows for better
bounds checking on instructions.
2023-11-03 19:07:10 +00:00
Aryadev Chavali
86977fe3c1 Introduced instructions to engage with a call stack
Essentially you may "call" an absolute program address, which pushes
the current address onto the call stack.  CALL_STACK does the same
thing but the absolute program address is taken from the data stack.
RET pops an address off the call stack then jumps to that address.
2023-11-02 21:01:21 +00:00
Aryadev Chavali
114fb82990 Removed instruction OP_JUMP_REGISTER
Not necessary when you can just push the relevant word onto the stack
then just do OP_JUMP_STACK.
2023-11-02 20:41:36 +00:00
Aryadev Chavali
46e5abbac9 Added instructions for MALLOC_STACK and SUB
MALLOC_STACK is a stack based version of MALLOC, SUB does subtraction.
2023-11-01 22:55:41 +00:00
Aryadev Chavali
0649b3f380 Added stack based versions of MSET and MGET
Essentially they use the stack for their one and only operand.  This
allows user level control, in particular it allows for loops to work
correctly while using these operands.
2023-11-01 22:07:08 +00:00
Aryadev Chavali
cb1cfde0c4 Added instruction to get the size of some allocation
This will allow for more library level code to be written.  For
example, say you wanted to write a generic byte level reversal
algorithm for dynamically sized allocations.  Getting the size of the
allocation would be fundamental to this operation.
2023-11-01 21:45:47 +00:00
Aryadev Chavali
eda49755bc Added instructions for allocating, setting, getting and deleting heap memory
One may allocate any number of (bytes|hwords|words), set or get some
index from allocated memory, and delete heap memory.

The idea is that all the relevant datums will be on the stack, so no
register usage.  This means no instructions should use register space
at all (other than POP, which I'm debating about currently).  Register
space is purely for users.
2023-11-01 21:38:52 +00:00
Aryadev Chavali
4be04d2518 Introduced a new mathematical operator MULT
Thankfully multiplication, like addition, is the same under 2s
complement as it is for unsigned numbers.  So I just need to implement
those versions to be fine.
2023-11-01 18:08:11 +00:00
Aryadev Chavali
693ec7a9d0 Changed inst bytecode methods for new register system
As registers may be theoretically infinite in number, we should use
the largest size possible when referring to them in bytecode (a word).
2023-11-01 17:54:15 +00:00
Aryadev Chavali
727081f99a Removed OP_EQ signed versions as they're useless
A negative number under 2s complement can never be equal to its
positive as the top bit *must* be on.  If two numbers are equivalent
bit-by-bit then they are equal for both signed and unsigned numbers.
2023-11-01 14:23:48 +00:00
Aryadev Chavali
5d800d4366 Moved inst module to lib
As it has no dependencies on vm specifically, and it's more necessary
for any vendors who wish to target the virtual machine, it makes more
sense for inst to be a lib module rather than a vm module.
2023-10-31 21:14:14 +00:00