bytecode-improvements #3

Merged
andre merged 3 commits from bytecode-improvements into master 2026-04-29 11:40:46 -05:00
7 changed files with 44 additions and 25 deletions
Showing only changes of commit 751b4bd547 - Show all commits

View File

@@ -73,7 +73,8 @@ target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings})
# tests # tests
# #
add_executable(${PROJECT_NAME}-bytecode-test src/bytecode/tests.cc) add_executable(${PROJECT_NAME}-bytecode-test src/bytecode/tests.cc
src/bytecode/constant.hh)
target_link_libraries(${PROJECT_NAME}-bytecode-test lib${PROJECT_NAME} gtest_main) target_link_libraries(${PROJECT_NAME}-bytecode-test lib${PROJECT_NAME} gtest_main)
add_test(NAME tyche_bytecode_test COMMAND ${PROJECT_NAME}-bytecode-test) add_test(NAME tyche_bytecode_test COMMAND ${PROJECT_NAME}-bytecode-test)

View File

@@ -11,8 +11,7 @@
Improvements: Improvements:
- [x] Fixed int type (based on opcode) - [x] Fixed int type (based on opcode)
- [ ] Constant type (only floats and strings for now) - [x] Constant type (only floats and strings for now)
- [ ] Debug output bytecode format
After some additional development: After some additional development:
- [ ] Bytecode debugging info - [ ] Bytecode debugging info

View File

@@ -39,16 +39,17 @@ uint32_t Bytecode::n_functions() const
return cache_.n_functions; return cache_.n_functions;
} }
float Bytecode::get_constant_float(uint32_t idx) const ConstantValue Bytecode::get_constant(uint32_t idx) const
{ {
uint32_t constant_idx = byte_array_.get_uint32(cache_.constants_idx_addr + (idx * CONST_RECORD_SZ)); uint32_t constant_idx = byte_array_.get_uint32(cache_.constants_idx_addr + (idx * CONST_RECORD_SZ));
return byte_array_.get_float(cache_.constants_start_addr + constant_idx); switch ((ConstantType) byte_array_.get_byte(cache_.constants_start_addr + constant_idx)) {
} case CONST_TYPE_FLOAT:
return byte_array_.get_float(cache_.constants_start_addr + constant_idx + 1);
std::string Bytecode::get_constant_string(uint32_t idx) const case CONST_TYPE_STRING:
{ return byte_array_.get_string(cache_.constants_start_addr + constant_idx + 1).first;
uint32_t constant_idx = byte_array_.get_uint32(cache_.constants_idx_addr + (idx * CONST_RECORD_SZ)); default:
return byte_array_.get_string(cache_.constants_start_addr + constant_idx).first; throw BytecodeParsingError("Invalid bytecode format (invalid constant type)");
}
} }
Bytecode::FunctionDef Bytecode::get_function_def(uint32_t function_id) const Bytecode::FunctionDef Bytecode::get_function_def(uint32_t function_id) const
@@ -100,9 +101,14 @@ ByteArray Bytecode::generate(BytecodePrototype const& bp)
for (auto const& constant: bp.constants) { for (auto const& constant: bp.constants) {
constant_indexes.append_uint32(idx); constant_indexes.append_uint32(idx);
std::visit(overloaded { std::visit(overloaded {
[&](int32_t i) { raw_constants.append_int32(i); }, [&](float f) {
[&](float f) { raw_constants.append_float(f); }, raw_constants.append_byte(CONST_TYPE_FLOAT);
[&](std::string const& s) { raw_constants.append_string(s); }, raw_constants.append_float(f);
},
[&](std::string const& s) {
raw_constants.append_byte(CONST_TYPE_STRING);
raw_constants.append_string(s);
},
}, constant); }, constant);
idx = raw_constants.size(); idx = raw_constants.size();
} }

View File

@@ -13,8 +13,7 @@ public:
[[nodiscard]] uint32_t n_constants() const; [[nodiscard]] uint32_t n_constants() const;
[[nodiscard]] uint32_t n_functions() const; [[nodiscard]] uint32_t n_functions() const;
[[nodiscard]] float get_constant_float(uint32_t idx) const; [[nodiscard]] ConstantValue get_constant(uint32_t idx) const;
[[nodiscard]] std::string get_constant_string(uint32_t idx) const;
struct FunctionDef { uint16_t n_params, locals; }; struct FunctionDef { uint16_t n_params, locals; };
[[nodiscard]] FunctionDef get_function_def(uint32_t function_id) const; [[nodiscard]] FunctionDef get_function_def(uint32_t function_id) const;

View File

@@ -5,12 +5,11 @@
#include <string> #include <string>
#include <variant> #include <variant>
#include <vector> #include <vector>
#include "constant.hh"
namespace tyche { namespace tyche {
struct BytecodePrototype { struct BytecodePrototype {
using ConstantValue = std::variant<float, std::string>;
struct Function { struct Function {
uint16_t n_pars; uint16_t n_pars;
uint16_t n_locals; uint16_t n_locals;

15
src/bytecode/constant.hh Normal file
View File

@@ -0,0 +1,15 @@
#ifndef TYCHE_CONSTANT_HH
#define TYCHE_CONSTANT_HH
#include <string>
#include <variant>
namespace tyche {
using ConstantValue = std::variant<float, std::string>;
enum ConstantType : uint8_t { CONST_TYPE_FLOAT = 1, CONST_TYPE_STRING = 2 };
}
#endif //TYCHE_CONSTANT_HH

View File

@@ -57,7 +57,7 @@ TEST(Bytecode, Constants)
// index // index
0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // constant index 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // constant index
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // function undex 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // function undex
0x58, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, // raw constants 0x58, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, // raw constants
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // raw code 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // raw code
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -66,11 +66,11 @@ TEST(Bytecode, Constants)
// constant indexes // constant indexes
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
// constant values // constant values
0x33, 0x33, 0x29, 0x42, // float: 42.3f CONST_TYPE_FLOAT, 0x33, 0x33, 0x29, 0x42, // float: 42.3f
'H', 'E', 'L', 'L', 'O', 0x00 CONST_TYPE_STRING, 'H', 'E', 'L', 'L', 'O', 0x00
}; };
ByteArray ba = Bytecode::generate(bp); ByteArray ba = Bytecode::generate(bp);
@@ -142,8 +142,8 @@ TEST(Bytecode, Parsing)
ASSERT_EQ(bc.n_constants(), 2); ASSERT_EQ(bc.n_constants(), 2);
ASSERT_EQ(bc.n_functions(), 2); ASSERT_EQ(bc.n_functions(), 2);
ASSERT_FLOAT_EQ(bc.get_constant_float(0), 3.14f); ASSERT_FLOAT_EQ(std::get<float>(bc.get_constant(0)), 3.14f);
ASSERT_EQ(bc.get_constant_string(1), "HELLO"); ASSERT_EQ(std::get<std::string>(bc.get_constant(1)), "HELLO");
Bytecode::FunctionDef f1 = bc.get_function_def(0); Bytecode::FunctionDef f1 = bc.get_function_def(0);
ASSERT_EQ(f1.n_params, 0); ASSERT_EQ(f1.n_params, 0);