diff --git a/doc/BYTECODE b/doc/BYTECODE index c4d7450..81b58da 100644 --- a/doc/BYTECODE +++ b/doc/BYTECODE @@ -14,8 +14,7 @@ The bytecode file is composed of the following sections: Each constant: [0]: Type (0 = string, 1 = real) if string: - [1..4]: string size - [...]: string + [...]: string (NULL terminated) if real [1..4]: real diff --git a/lib/code.c b/lib/code.c index 8d055ae..2265125 100644 --- a/lib/code.c +++ b/lib/code.c @@ -2,6 +2,7 @@ #include #include +#include #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ # error Sorry, big endian architectures are not supported at this time. @@ -15,13 +16,14 @@ #define CONST_START 0x10 struct Code { - uint8_t* bytecode; - size_t bytecode_sz; - uint32_t* const_addr; - uint32_t* fn_addr; + uint8_t const* bytecode; + size_t bytecode_sz; + uint32_t* const_addr; + uint32_t fn_count; + uint32_t* fn_addr; }; -Code* code_new() +Code* code_new(void) { Code* code = xcalloc(1, sizeof(Code)); return code; @@ -29,6 +31,8 @@ Code* code_new() void code_destroy(Code* code) { + free(code->const_addr); + free(code->fn_addr); free(code); } @@ -46,6 +50,7 @@ TYC_RESULT code_load_bytecode(Code* code, uint8_t* bytecode, size_t bytecode_sz) code->bytecode = bytecode; code->bytecode_sz = bytecode_sz; + /* for (size_t i = 0; i < bytecode_sz; ++i) { if (i % 16 == 0) printf("%04X: ", i); @@ -53,32 +58,71 @@ TYC_RESULT code_load_bytecode(Code* code, uint8_t* bytecode, size_t bytecode_sz) if (i % 16 == 15) printf("\n"); } + printf("\n"); + */ + + uint32_t n_consts = code_n_consts(code); + code->const_addr = calloc(n_consts, sizeof(uint32_t)); + uint32_t addr = CONST_START; + for (size_t i = 0; i < n_consts; ++i) { + code->const_addr[i] = addr; + switch (code_const_type(code, i)) { + case TC_STRING: { + uint32_t sz = (uint32_t) strlen((const char*) &bytecode[code->const_addr[i] + 1]); + addr += sz + 2; // 2 = constant type + NULL terminator + break; + } + case TC_REAL: + addr += 5; // 5 = constant type + float + break; + case TC_INVALID_TYPE: + default: + __builtin_unreachable(); + } + } + + addr += 4; // skip debug start address + memcpy(&code->fn_count, &bytecode[addr], sizeof(uint32_t)); // number of functions + addr += 4; + + code->fn_addr = calloc(code->fn_count, sizeof(uint32_t)); + code->fn_addr[0] = addr; + for (size_t i = 1; i < code->fn_count; ++i) { + uint32_t addr_next; + memcpy(&addr_next, &bytecode[addr], sizeof(uint32_t)); + addr = code->fn_addr[i] = addr_next; + } return T_OK; } -size_t code_n_consts(Code const* code) +uint32_t code_n_consts(Code const* code) { - uint32_t n_consts = *(uint32_t*) &code->bytecode[N_CONST_ADDR]; + uint32_t n_consts; memcpy(&n_consts, &code->bytecode[N_CONST_ADDR], sizeof(uint32_t)); return n_consts; } TYC_CONST_TYPE code_const_type(Code const* code, size_t n) { - return TC_REAL; // TODO + uint8_t t = code->bytecode[code->const_addr[n]]; + if (t >= TC_INVALID_TYPE) + return TC_INVALID_TYPE; + return t; } T_REAL code_const_real(Code const* code, size_t n) { - return 0.f; // TODO + float f; + memcpy(&f, &code->bytecode[code->const_addr[n] + 1], sizeof(float)); + return f; } const char* code_const_string(Code const* code, size_t n) { - return ""; // TODO + return (const char*) &code->bytecode[code->const_addr[n] + 1]; } -size_t code_n_functions(Code const* code) +uint32_t code_n_functions(Code const* code) { - return 0; // TODO + return code->fn_count; } diff --git a/lib/compiler.c b/lib/compiler.c index a8fe31b..c192dda 100644 --- a/lib/compiler.c +++ b/lib/compiler.c @@ -35,7 +35,7 @@ TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_ if (!lua_isstring(L, -1)) abort(); - *bytecode_sz = luaL_len(L, -1); + *bytecode_sz = (size_t) luaL_len(L, -1); *bytecode = malloc(*bytecode_sz); memcpy(*bytecode, lua_tostring(L, -1), *bytecode_sz); diff --git a/lib/compiler/compiler.lua b/lib/compiler/compiler.lua index 7dacd15..8b4bb05 100644 --- a/lib/compiler/compiler.lua +++ b/lib/compiler/compiler.lua @@ -107,13 +107,9 @@ local function assemble(proto) bin[pos + 3] = (data >> 24) & 0xff end - local float_to_le_bytes = function(f) - local bytes = {} - local packed = string.pack("= 3.13 && code_const_real(code, 0) <= 3.15); - assert(strcmp(code_const_string(code, 1), "Hello world\n") == 0); + assert(strcmp(code_const_string(code, 1), "Hello world") == 0); assert(code_n_functions(code) == 2); + code_destroy(code); free(bytecode); } } \ No newline at end of file