change to uint8_t for bytecode to reduce wasted bytes

This commit is contained in:
2025-06-27 06:07:57 +01:00
parent 358127a145
commit aa65393e2c
11 changed files with 100 additions and 53 deletions

View File

@@ -1,13 +1,15 @@
# Bytecode Specification
all opcodes are uint8_t, and all operands are uint64_t unless marked with an asterisk (*), where it is marked as uint8_t
## OP_LOAD_CONST
loads and initialises a value from the constant buffer into the provided register.
this operation 4 operands.
1. the register to write to.
2. the type of data from the constant buffer.
1. the register to write to. (*)
2. the type of data from the constant buffer. (*)
3. the length of the data in the constant buffer.
4. the offset in the constant buffer.
@@ -19,7 +21,7 @@ this operation takes 3 operands.
1. the length of the variable name.
2. the offset in the constant buffer of the variable name.
3. the register of the given value
3. the register of the given value (*)
## OP_LOAD_NULL
@@ -27,7 +29,7 @@ sets a given register to null.
this operation takes 1 operand.
1. the register to set to null.
1. the register to set to null. (*)
## OP_LOAD_FUNCTION

View File

@@ -17,14 +17,14 @@ size_t translate_parsed_declaration(Translated *translated,
size_t offset =
arena_push(&translated->constants, singleDeclaration->name, length);
push_instruction_code(translated, OP_DECLARE);
push_instruction_byte(translated, OP_DECLARE);
push_instruction_code(translated, length);
push_instruction_code(translated, offset);
push_instruction_code(translated, 0);
push_instruction_byte(translated, 0);
}
if (delcarations.size != 1) {
push_instruction_code(translated, OP_LOAD_NULL);
push_instruction_code(translated, 0);
push_instruction_byte(translated, OP_LOAD_NULL);
push_instruction_byte(translated, 0);
}
return first;
}

View File

@@ -1,22 +1,24 @@
#include "function.h"
#include "../translator.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t translate_parsed_function(Translated *translated,
ParsedFunction *parsedFunction) {
DArray temp_bytecode;
darray_init(&temp_bytecode, sizeof(uint64_t));
DArray main_bytecode = translated->bytecode;
translated->bytecode = temp_bytecode;
DArray _temp_bytecode;
darray_init(&_temp_bytecode, sizeof(uint8_t));
translated->bytecode = _temp_bytecode;
translate_parsed(translated, parsedFunction->body);
size_t function_bytecode_offset =
arena_push(&translated->constants, translated->bytecode.data,
translated->bytecode.size*translated->bytecode.element_size);
size_t function_bytecode_length = translated->bytecode.size;
darray_free(&translated->bytecode, NULL);
translated->bytecode = main_bytecode;
darray_free(&temp_bytecode, NULL);
size_t start = push_instruction_code(translated, OP_LOAD_FUNCTION);
size_t start = push_instruction_byte(translated, OP_LOAD_FUNCTION);
size_t offset = arena_push(&translated->constants, parsedFunction->name,
strlen(parsedFunction->name));
push_instruction_code(translated, offset);

View File

@@ -10,10 +10,10 @@ size_t translate_parsed_number(Translated *translated, char *number_str, size_t
size_t number_pos = arena_push(&translated->constants, number_str, length);
set_registers(translated, to_register+1);
size_t start = push_instruction_code(translated, OP_LOAD_CONST);
push_instruction_code(translated, to_register);
size_t start = push_instruction_byte(translated, OP_LOAD_CONST);
push_instruction_byte(translated, to_register);
push_instruction_code(translated, TYPE_OP_NUMBER);
push_instruction_byte(translated, TYPE_OP_NUMBER);
push_instruction_code(translated,length);
push_instruction_code(translated, number_pos);
return start;

View File

@@ -7,9 +7,9 @@
size_t translate_parsed_string(Translated *translated, ParsedString parsedString) {
size_t string_pos = arena_push(&translated->constants, parsedString.string, parsedString.length);
set_registers(translated, 1);
size_t start = push_instruction_code(translated, OP_LOAD_CONST);
push_instruction_code(translated, 0);
push_instruction_code(translated, TYPE_OP_STRING);
size_t start = push_instruction_byte(translated, OP_LOAD_CONST);
push_instruction_byte(translated, 0);
push_instruction_byte(translated, TYPE_OP_STRING);
push_instruction_code(translated,parsedString.length);
push_instruction_code(translated, string_pos);
return start;

View File

@@ -9,6 +9,12 @@
#include <stdlib.h>
#include <string.h>
void uint64_to_bytes(uint64_t value, uint8_t bytes[8]) {
for (int i = 0; i < 8; i++) {
bytes[i] = (value >> (i * 8)) & 0xFF;
}
}
void arena_init(ConstantArena *arena) {
arena->data = checked_malloc(CHUNK_SIZE);
arena->capacity = CHUNK_SIZE;
@@ -56,25 +62,29 @@ size_t arena_push(ConstantArena *arena, const void *data, size_t length) {
Translated init_translator() {
Translated translated;
translated.registerCount = 0;
darray_init(&translated.bytecode, sizeof(uint64_t));
darray_init(&translated.bytecode, sizeof(uint8_t));
arena_init(&translated.constants);
return translated;
}
void set_instruction_code(Translated *translator, size_t offset,
uint64_t code) {
size_t *ptr = (translator->bytecode.data + offset);
*ptr = code;
}
size_t push_instruction_code(Translated *translator, uint64_t code) {
code = htole64(code);
size_t push_instruction_byte(Translated *translator, uint8_t byte) {
size_t offset = translator->bytecode.size;
darray_push(&translator->bytecode, &code);
darray_push(&translator->bytecode, &byte);
return offset;
}
void set_registers(Translated *translator, size_t count) {
size_t push_instruction_code(Translated *translator, uint64_t code) {
size_t offset = translator->bytecode.size;
uint8_t bytes[8];
uint64_to_bytes(code, bytes);
for (size_t i = 0; i < sizeof(bytes); i++) {
darray_push(&translator->bytecode, &(bytes[i]));
}
return offset;
}
void set_registers(Translated *translator, uint8_t count) {
if (count > translator->registerCount)
translator->registerCount = count;
}
@@ -91,8 +101,8 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
return translate_parsed_number(translated, (char *)parsedValue->data, 0);
case AST_NULL:
set_registers(translated, 1);
size_t output = push_instruction_code(translated, OP_LOAD_NULL);
push_instruction_code(translated, 0);
size_t output = push_instruction_byte(translated, OP_LOAD_NULL);
push_instruction_byte(translated, 0);
return output;
case AST_FUNCTION:
return translate_parsed_function(translated,

View File

@@ -7,8 +7,8 @@
#include <stddef.h>
#include <stdint.h>
typedef enum { OP_LOAD_CONST = 255, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION } OperationType;
typedef enum { TYPE_OP_STRING = 255, TYPE_OP_NUMBER } types;
typedef enum { OP_LOAD_CONST, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION } OperationType;
typedef enum { TYPE_OP_STRING, TYPE_OP_NUMBER } types;
typedef struct {
void *data;
@@ -17,7 +17,7 @@ typedef struct {
} ConstantArena;
typedef struct {
size_t registerCount;
uint8_t registerCount;
DArray bytecode;
ConstantArena constants;
} Translated;
@@ -26,11 +26,11 @@ void *arena_get(ConstantArena *arena, size_t offset);
size_t arena_push(ConstantArena *arena, const void *data, size_t length);
void set_instruction_code(Translated * translator, size_t offset, uint64_t code);
size_t push_instruction_byte(Translated *translator, uint8_t byte);
size_t push_instruction_code(Translated *translator, uint64_t code);
void set_registers(Translated *translator, size_t count);
void set_registers(Translated *translator, uint8_t count);
Translated init_translator();