aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-09-14 01:45:31 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commit35200031e88c65da6a0bde563f20d95c1dd4f464 (patch)
treeb1159960ca7ba78a42f6ef203f99d2b1a1c26641 /src
parent7d663615b2a44715e7447a40cae467d7d4e38b9c (diff)
Use struct for bytecode header instead of pointer arithmetic
Diffstat (limited to 'src')
-rw-r--r--src/bytecode/bytecode.c24
-rw-r--r--src/compiler.c3
-rw-r--r--src/program.c25
-rw-r--r--src/std/misc.c54
4 files changed, 79 insertions, 27 deletions
diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c
index c968743..0a2b157 100644
--- a/src/bytecode/bytecode.c
+++ b/src/bytecode/bytecode.c
@@ -42,20 +42,24 @@ CHECK_RESULT int buffer_append_header(Buffer *program_data) {
|u8 |Major version|The major version of the bytecode. Updates in this is a breaking change. |
|u8 |Minor version|The minor version of the bytecode. Updates in this are backwards compatible.|
|u8 |Patch version|The patch version of the bytecode. Updates in this are only minor bug fixes.|
+ |u8 |Endian |Endian of the program. 0 = little endian, 1 = big endian. |
The versions in the header only changes for every release, not every change.
*/
- const u32 magic_number = AMAL_BYTECODE_MAGIC_NUMBER;
- const u8 major_version = AMAL_BYTECODE_MAJOR_VERSION;
- const u8 minor_version = AMAL_BYTECODE_MINOR_VERSION;
- const u8 patch_version = AMAL_BYTECODE_PATCH_VERSION;
-
- return_if_error(buffer_append(program_data, &magic_number, 4));
- return_if_error(buffer_append(program_data, &major_version, 1));
- return_if_error(buffer_append(program_data, &minor_version, 1));
- return_if_error(buffer_append(program_data, &patch_version, 1));
-
+ BytecodeHeader header;
+ header.magic_number = AMAL_BYTECODE_MAGIC_NUMBER;
+ header.major_version = AMAL_BYTECODE_MAJOR_VERSION;
+ header.minor_version = AMAL_BYTECODE_MINOR_VERSION;
+ header.patch_version = AMAL_BYTECODE_PATCH_VERSION;
+#if defined(AMAL_LITTLE_ENDIAN)
+ header.endian = 0;
+#elif defined(AMAL_BIG_ENDIAN)
+ header.magic_number = byteswap32(header.magic_number);
+ header.endian = 1;
+#endif
+
+ return_if_error(buffer_append(program_data, &header, sizeof(header)));
return 0;
}
diff --git a/src/compiler.c b/src/compiler.c
index 6e6bc4b..c10ccc9 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -432,8 +432,7 @@ static CHECK_RESULT int validate_main_func(FileScopeReference *main_file_scope,
}
static void amal_compiler_parsers_set_bytecode_offsets(amal_compiler *self) {
- /* magic number + major version + minor version + patch version */
- u32 offset = sizeof(u32) + sizeof(u8) + sizeof(u8) + sizeof(u8);
+ u32 offset = sizeof(BytecodeHeader);
Parser **parser = buffer_begin(&self->parsers);
Parser **parser_end = buffer_end(&self->parsers);
for(; parser != parser_end; ++parser) {
diff --git a/src/program.c b/src/program.c
index 5c07c5d..1a53b53 100644
--- a/src/program.c
+++ b/src/program.c
@@ -186,31 +186,26 @@ static usize bytes_left_to_read(amal_program *self) {
}
static CHECK_RESULT int amal_program_read_header(amal_program *self) {
- u32 magic_number;
- u8 major_version;
- u8 minor_version;
- u8 patch_version;
+ BytecodeHeader header;
- if(bytes_left_to_read(self) < sizeof(u32) + sizeof(u8) * 3)
+ if(bytes_left_to_read(self) < sizeof(header))
return AMAL_PROGRAM_INVALID_HEADER;
- am_memcpy(&magic_number, &self->data.data[self->read_index], sizeof(magic_number));
- self->read_index += sizeof(u32);
- am_memcpy(&major_version, &self->data.data[self->read_index], sizeof(major_version));
- self->read_index += sizeof(u8);
- am_memcpy(&minor_version, &self->data.data[self->read_index], sizeof(minor_version));
- self->read_index += sizeof(u8);
- am_memcpy(&patch_version, &self->data.data[self->read_index], sizeof(patch_version));
- self->read_index += sizeof(u8);
+ am_memcpy(&header, self->data.data + self->read_index, sizeof(header));
+ self->read_index += sizeof(header);
+#ifdef AMAL_BIG_ENDIAN
+ header.magic_number = byteswap32(header.magic_number);
+ #error TODO: Support big endian for program decoding
+#endif
- if(magic_number != AMAL_BYTECODE_MAGIC_NUMBER)
+ if(header.magic_number != AMAL_BYTECODE_MAGIC_NUMBER)
return AMAL_PROGRAM_INVALID_MAGIC_NUMBER;
/*
A program is only incompatible if the major version is newer than the version that is used to run it.
TODO: Implement backwards compatible reads, starting from when the program bytecode breaks backwards compatibility
*/
- if(major_version > AMAL_BYTECODE_MAJOR_VERSION)
+ if(header.major_version > AMAL_BYTECODE_MAJOR_VERSION)
return AMAL_PROGRAM_INCOMPATIBLE;
return AMAL_PROGRAM_OK;
diff --git a/src/std/misc.c b/src/std/misc.c
new file mode 100644
index 0000000..f53797d
--- /dev/null
+++ b/src/std/misc.c
@@ -0,0 +1,54 @@
+#include "../../include/std/misc.h"
+
+#if defined(_MSC_VER)
+u16 byteswap16(u16 value) {
+ return _byteswap_ushort(value);
+}
+
+u32 byteswap32(u32 value) {
+ return _byteswap_ulong(value);
+}
+
+u64 byteswap64(u64 value) {
+ return _byteswap_uint64(value);
+}
+#elif defined(__GNUC__)
+u16 byteswap16(u16 value) {
+ return __builtin_bswap16(value);
+}
+u32 byteswap32(u32 value) {
+ return __builtin_bswap32(value);
+}
+u64 byteswap64(u64 value) {
+ return __builtin_bswap64(value);
+}
+#else
+u16 byteswap16(u16 value) {
+ u16 result = 0;
+ result |= (value & 0x00FF) << 8;
+ result |= (value & 0xFF00) >> 8;
+ return result;
+}
+
+u32 byteswap32(u32 value) {
+ u32 result = 0;
+ result |= (value & 0x000000FF) << 24;
+ result |= (value & 0x0000FF00) << 8;
+ result |= (value & 0x00FF0000) >> 8;
+ result |= (value & 0xFF000000) >> 24;
+ return result;
+}
+
+u64 byteswap64(u64 value) {
+ u64 result = 0;
+ result |= (value & 0x00000000000000FF) << 56;
+ result |= (value & 0x000000000000FF00) << 40;
+ result |= (value & 0x0000000000FF0000) << 24;
+ result |= (value & 0x00000000FF000000) << 8;
+ result |= (value & 0x000000FF00000000) >> 8;
+ result |= (value & 0x0000FF0000000000) >> 24;
+ result |= (value & 0x00FF000000000000) >> 40;
+ result |= (value & 0xFF00000000000000) >> 56;
+ return result;
+}
+#endif