diff --git a/runtime/alloc.hpp b/runtime/alloc.hpp new file mode 100644 index 0000000..9d4e4e3 --- /dev/null +++ b/runtime/alloc.hpp @@ -0,0 +1,170 @@ +#pragma once + +#include "value.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace sliger::heap { + +struct Array { + std::vector values; +}; + +struct Struct { + std::unordered_map fields; +}; + +enum class AllocType { + Value, + Array, + Struct, +}; + +// clang-format off +template struct AllocTypeType {}; +template <> struct AllocTypeType { using Type = Value; }; +template <> struct AllocTypeType { using Type = Array; }; +template <> struct AllocTypeType { using Type = Struct; }; +// clang-format on + +struct AllocItem { + template inline auto as() & -> AllocTypeType::Type& + { + return std::get::Type>(this->value); + } + template + inline auto as() const& -> const AllocTypeType::Type& + { + return std::get::Type>(this->value); + } + template inline auto as() && -> AllocTypeType::Type&& + { + return std::move( + std::get::Type>(this->value)); + } + template + inline auto as() const&& -> const AllocTypeType::Type&& + { + return std::move( + std::get::Type>(this->value)); + } + + AllocType type; + std::variant value; +}; + +enum class ErrType { + InvalidPtrAccess, + CannotAllocate, +}; + +template struct Res { + Res(T val) + : val(std::forward(val)) + { + } + Res(ErrType err) + : err(err) + { + } + + std::optional val; + std::optional err; +}; + +class Heap { +public: + inline auto can_allocate() const -> bool + { + return this->sel->size() < this->max_size; + } + + inline void collect(const std::vector& ptr_stack_values) + { + this->other->reserve(this->max_size); + for (auto ptr : ptr_stack_values) { + move_item_to_other(ptr); + } + this->sel->clear(); + std::swap(this->sel, this->other); + if (this->sel->size() + 1 >= this->max_size) { + this->max_size *= 2; + this->sel->reserve(this->max_size); + } else if (this->sel->size() * 2 < this->max_size) { + this->max_size /= 2; + this->sel->shrink_to_fit(); + this->sel->reserve(this->max_size); + } + } + + inline auto at(uint32_t ptr) -> Res + { + if (ptr >= this->sel->size()) { + return ErrType::InvalidPtrAccess; + } + return &this->sel->at(ptr); + } + + template auto alloc() -> Res + { + if (not can_allocate()) { + return ErrType::CannotAllocate; + } + auto ptr = static_cast(this->sel->size()); + this->sel->push_back(typename AllocTypeType::Type {}); + return ptr; + } + +private: + inline void move_item_to_other(uint32_t ptr) + { + auto res = at(ptr); + if (!res.val.has_value()) + return; + auto val = res.val.value(); + switch (val->type) { + case AllocType::Value: { + auto& v = val->as(); + if (v.type() == ValueType::Ptr) { + move_item_to_other(v.template as().value); + } + break; + } + case AllocType::Array: { + auto& vs = val->as(); + for (auto& v : vs.values) { + if (v.type() == ValueType::Ptr) { + move_item_to_other( + v.template as().value); + } + } + break; + } + case AllocType::Struct: { + auto& vs = val->as(); + for (auto& [key, v] : vs.fields) { + if (v.type() == ValueType::Ptr) { + move_item_to_other( + v.template as().value); + } + } + break; + } + } + } + + size_t max_size = 4; + + std::vector heap_1; + std::vector heap_2; + + std::vector* sel = &heap_1; + std::vector* other = &heap_2; +}; + +} diff --git a/runtime/vm.hpp b/runtime/vm.hpp index 0fadee4..0ade960 100644 --- a/runtime/vm.hpp +++ b/runtime/vm.hpp @@ -1,5 +1,6 @@ #pragma once +#include "alloc.hpp" #include "arch.hpp" #include "json.hpp" #include "value.hpp" @@ -271,7 +272,7 @@ private: const uint32_t* program; size_t program_size; std::vector stack; - std::vector pool_heap; + heap::Heap heap; SourcePos current_pos = { 0, 1, 1 }; int64_t instruction_counter = 0; diff --git a/surveys/code_coverage/.vscode/settings.json b/surveys/code_coverage/.vscode/settings.json new file mode 100644 index 0000000..2c7ddc5 --- /dev/null +++ b/surveys/code_coverage/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "deno.enable": true, + "deno.lint": true, + "deno.unstable": true +} \ No newline at end of file diff --git a/web/main.ts b/web/main.ts index 6313814..e3ad97d 100644 --- a/web/main.ts +++ b/web/main.ts @@ -22,7 +22,7 @@ async function compileProgram(filepath: string) { const result = await compiler.compileWithDebug(filepath); } -async function runProgramWithDebug(program: string) { +async function runProgramWithDebug(program: number[]) { const connection = await runtime.connect(); connection.send({ type: "run-debug",