From f6a59c85e8a040dca38d784997a2a9ab65ac9a5a Mon Sep 17 00:00:00 2001 From: Stepan Usatiuk Date: Wed, 27 Dec 2023 00:11:31 +0100 Subject: [PATCH] move stuff to Handle --- src/vm/CMakeLists.txt | 2 +- src/vm/includes/ConsUtils.h | 27 -------- src/vm/includes/Handle.h | 49 ++++++++++++++ src/vm/includes/MemoryContext.h | 26 ++------ src/vm/includes/Parser.h | 2 +- src/vm/includes/VM.h | 45 ++++++------- src/vm/src/ConsUtils.cpp | 54 --------------- src/vm/src/Handle.cpp | 74 +++++++++++++++++++++ src/vm/src/MemoryContext.cpp | 21 +----- src/vm/src/Parser.cpp | 16 ++--- src/vm/src/VM.cpp | 114 ++++++++++++++++---------------- test/vm/GCTest.cpp | 63 ++++++++++-------- test/vm/VMTest.cpp | 13 ++-- test/vm/VMWithParserTest.cpp | 1 - 14 files changed, 257 insertions(+), 250 deletions(-) delete mode 100644 src/vm/includes/ConsUtils.h create mode 100644 src/vm/includes/Handle.h delete mode 100644 src/vm/src/ConsUtils.cpp create mode 100644 src/vm/src/Handle.cpp diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index 067692e..02bc022 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -2,6 +2,6 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_library(vm src/VM.cpp src/Cell.cpp - src/Parser.cpp src/MemoryContext.cpp src/ConsUtils.cpp) + src/Parser.cpp src/MemoryContext.cpp src/Handle.cpp) target_include_directories(vm PUBLIC includes) diff --git a/src/vm/includes/ConsUtils.h b/src/vm/includes/ConsUtils.h deleted file mode 100644 index 3413841..0000000 --- a/src/vm/includes/ConsUtils.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Created by Stepan Usatiuk on 25.12.2023. -// - -#ifndef PSIL_CONSUTILS_H -#define PSIL_CONSUTILS_H - -#include "Cell.h" -#include "MemoryContext.h" - -namespace ConsUtils { - static inline MCHandle car(const MCHandle &cell) { return dynamic_cast(*cell)._car.load(); } - static inline MCHandle cdr(const MCHandle &cell) { return dynamic_cast(*cell)._cdr.load(); } - static inline CellValType val(const MCHandle &cell) { return dynamic_cast(*cell)._val; } - static inline std::string_view strval(const MCHandle &cell) { return dynamic_cast(*cell)._val; } - MCHandle cons(const MCHandle &car, const MCHandle &cdr); - MCHandle pop(MCHandle &from); - void push(MCHandle &to, const MCHandle &what); - void append(MCHandle to, const MCHandle &what); - MCHandle makeNumCell(int64_t val); - MCHandle makeStrCell(std::string val); - void setcar(const MCHandle &to, const MCHandle &car); - void setcdr(const MCHandle &to, const MCHandle &cdr); -};// namespace ConsUtils - - -#endif//PSIL_CONSUTILS_H diff --git a/src/vm/includes/Handle.h b/src/vm/includes/Handle.h new file mode 100644 index 0000000..ca1ea05 --- /dev/null +++ b/src/vm/includes/Handle.h @@ -0,0 +1,49 @@ +// +// Created by Stepan Usatiuk on 26.12.2023. +// + +#ifndef PSIL_HANDLE_H +#define PSIL_HANDLE_H + +#include "Cell.h" + +class MemoryContext; + +class Handle { +public: + friend MemoryContext; + + Handle(Cell *target); + ~Handle(); + + Handle(Handle const &other); + Handle &operator=(Handle other); + + bool operator==(const Handle &rhs) const { + return _target == rhs._target; + } + + Handle car() { return dynamic_cast(*_target)._car.load(); } + Handle cdr() { return dynamic_cast(*_target)._cdr.load(); } + CellValType val() { return dynamic_cast(*_target)._val; } + std::string_view strval() { return dynamic_cast(*_target)._val; } + + + static Handle cons(const Handle &car, const Handle &cdr); + static Handle pop(Handle &from); + static void push(Handle &to, const Handle &what); + static void append(Handle to, const Handle &what); + static Handle makeNumCell(int64_t val); + static Handle makeStrCell(std::string val); + void setcar(const Handle &car); + void setcdr(const Handle &cdr); + +private: + Cell *operator->() const { return _target; } + Cell &operator*() const { return *_target; } + Cell *get() const noexcept { return _target; } + + Cell *_target = nullptr; +}; + +#endif//PSIL_HANDLE_H diff --git a/src/vm/includes/MemoryContext.h b/src/vm/includes/MemoryContext.h index 4c68a08..e00d16c 100644 --- a/src/vm/includes/MemoryContext.h +++ b/src/vm/includes/MemoryContext.h @@ -16,10 +16,13 @@ #include #include "Cell.h" +#include "Handle.h" + +class Handle; class MemoryContext { public: - class Handle; + friend Handle; MemoryContext(); ~MemoryContext(); @@ -73,25 +76,6 @@ public: return newc; } - class Handle { - public: - Handle(Cell *target); - ~Handle(); - - Handle(Handle const &other); - Handle &operator=(Handle other); - - Cell *operator->() const { return _target; } - Cell &operator*() const { return *_target; } - Cell *get() const noexcept { return _target; } - - bool operator==(const Handle &rhs) const { - return _target == rhs._target; - } - - private: - Cell *_target = nullptr; - }; void request_gc_and_wait() { std::unique_lock l(_gc_done_m); @@ -193,8 +177,6 @@ private: std::atomic _gc_thread_stop = false; }; -using MCHandle = MemoryContext::Handle; - extern std::atomic CURRENT_MC; #endif//PSIL_MEMORYCONTEXT_H diff --git a/src/vm/includes/Parser.h b/src/vm/includes/Parser.h index 04e26f9..7fb14d4 100644 --- a/src/vm/includes/Parser.h +++ b/src/vm/includes/Parser.h @@ -19,7 +19,7 @@ struct Cell; class Parser { public: void loadStr(std::string_view input); - MCHandle parseExpr(); + Handle parseExpr(); private: class Tokenizer { diff --git a/src/vm/includes/VM.h b/src/vm/includes/VM.h index 1a43ea5..67147d1 100644 --- a/src/vm/includes/VM.h +++ b/src/vm/includes/VM.h @@ -11,7 +11,6 @@ #include #include "Cell.h" -#include "ConsUtils.h" #include "MemoryContext.h" class VM { @@ -20,40 +19,40 @@ public: void run(); - void loadControl(const MCHandle &h) { _c = h; } + void loadControl(const Handle &h) { _c = h; } void step(); private: - MCHandle _s = ConsUtils::cons(nullptr, nullptr); - MCHandle _e = ConsUtils::cons(nullptr, nullptr); - MCHandle _c = ConsUtils::cons(nullptr, nullptr); - MCHandle _d = ConsUtils::cons(nullptr, nullptr); + Handle _s = Handle::cons(nullptr, nullptr); + Handle _e = Handle::cons(nullptr, nullptr); + Handle _c = Handle::cons(nullptr, nullptr); + Handle _d = Handle::cons(nullptr, nullptr); bool _stop = false; std::istream &_instream; std::ostream &_outstream; - MCHandle NIL = ConsUtils::makeStrCell("NIL"); - MCHandle LDC = ConsUtils::makeStrCell("LDC"); - MCHandle LD = ConsUtils::makeStrCell("LD"); - MCHandle SEL = ConsUtils::makeStrCell("SEL"); - MCHandle JOIN = ConsUtils::makeStrCell("JOIN"); - MCHandle LDF = ConsUtils::makeStrCell("LDF"); - MCHandle AP = ConsUtils::makeStrCell("AP"); - MCHandle RET = ConsUtils::makeStrCell("RET"); - MCHandle DUM = ConsUtils::makeStrCell("DUM"); - MCHandle RAP = ConsUtils::makeStrCell("RAP"); - MCHandle STOP = ConsUtils::makeStrCell("STOP"); + Handle NIL = Handle::makeStrCell("NIL"); + Handle LDC = Handle::makeStrCell("LDC"); + Handle LD = Handle::makeStrCell("LD"); + Handle SEL = Handle::makeStrCell("SEL"); + Handle JOIN = Handle::makeStrCell("JOIN"); + Handle LDF = Handle::makeStrCell("LDF"); + Handle AP = Handle::makeStrCell("AP"); + Handle RET = Handle::makeStrCell("RET"); + Handle DUM = Handle::makeStrCell("DUM"); + Handle RAP = Handle::makeStrCell("RAP"); + Handle STOP = Handle::makeStrCell("STOP"); - MCHandle ADD = ConsUtils::makeStrCell("ADD"); - MCHandle SUB = ConsUtils::makeStrCell("SUB"); + Handle ADD = Handle::makeStrCell("ADD"); + Handle SUB = Handle::makeStrCell("SUB"); - MCHandle READCHAR = ConsUtils::makeStrCell("READCHAR"); - MCHandle PUTCHAR = ConsUtils::makeStrCell("PUTCHAR"); - MCHandle PUTNUM = ConsUtils::makeStrCell("PUTNUM"); + Handle READCHAR = Handle::makeStrCell("READCHAR"); + Handle PUTCHAR = Handle::makeStrCell("PUTCHAR"); + Handle PUTNUM = Handle::makeStrCell("PUTNUM"); - MCHandle CONS = ConsUtils::makeStrCell("CONS"); + Handle CONS = Handle::makeStrCell("CONS"); }; #endif//PSIL_VM_H diff --git a/src/vm/src/ConsUtils.cpp b/src/vm/src/ConsUtils.cpp deleted file mode 100644 index 9afdf17..0000000 --- a/src/vm/src/ConsUtils.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// Created by Stepan Usatiuk on 25.12.2023. -// - -#include "ConsUtils.h" - -#include "MemoryContext.h" - -MCHandle ConsUtils::cons(const MCHandle &car, const MCHandle &cdr) { - auto ret = CURRENT_MC.load()->create_cell(car.get(), cdr.get()); - return ret; -} - -MCHandle ConsUtils::pop(MCHandle &from) { - auto ret = car(from); - from = cdr(from); - return ret; -} - -void ConsUtils::push(MCHandle &to, const MCHandle &what) { - to = cons(what, to); -} - -void ConsUtils::append(MCHandle to, const MCHandle &what) { - assert(to.get() != nullptr); - if (car(to).get() == nullptr) { - setcar(to, what); - return; - } - while (cdr(to).get() != nullptr) to = cdr(to); - setcdr(to, cons(what, nullptr)); -} - -MCHandle ConsUtils::makeNumCell(int64_t val) { - return CURRENT_MC.load()->create_cell(val); -} - -MCHandle ConsUtils::makeStrCell(std::string val) { - return CURRENT_MC.load()->create_cell(std::move(val)); -} - -void ConsUtils::setcar(const MCHandle &to, const MCHandle &car) { - CURRENT_MC.load()->run_dirty([&](std::function dirty) -> void { - dirty(car.get()); - dynamic_cast(*to)._car = car.get(); - }); -} - -void ConsUtils::setcdr(const MCHandle &to, const MCHandle &cdr) { - CURRENT_MC.load()->run_dirty([&](std::function dirty) -> void { - dirty(cdr.get()); - dynamic_cast(*to)._cdr = cdr.get(); - }); -} diff --git a/src/vm/src/Handle.cpp b/src/vm/src/Handle.cpp new file mode 100644 index 0000000..71efa03 --- /dev/null +++ b/src/vm/src/Handle.cpp @@ -0,0 +1,74 @@ +// +// Created by Stepan Usatiuk on 26.12.2023. +// + +#include "Handle.h" + +#include "MemoryContext.h" + +Handle::Handle(Cell *target) : _target(target) { + if (target != nullptr) + CURRENT_MC.load()->add_root(target); +} + +Handle::~Handle() { + if (_target != nullptr) + CURRENT_MC.load()->remove_root(_target); +} + +Handle::Handle(Handle const &other) : _target(other._target) { + if (_target != nullptr) + CURRENT_MC.load()->add_root(_target); +} + +Handle &Handle::operator=(Handle other) { + std::swap(_target, other._target); + return *this; +} + +Handle Handle::cons(const Handle &car, const Handle &cdr) { + auto ret = CURRENT_MC.load()->create_cell(car.get(), cdr.get()); + return ret; +} + +Handle Handle::pop(Handle &from) { + auto ret = from.car(); + from = from.cdr(); + return ret; +} + +void Handle::push(Handle &to, const Handle &what) { + to = cons(what, to); +} + +void Handle::append(Handle to, const Handle &what) { + assert(to.get() != nullptr); + if (to.car().get() == nullptr) { + to.setcar(what); + return; + } + while (to.cdr().get() != nullptr) to = to.cdr(); + to.setcdr(cons(what, nullptr)); +} + +Handle Handle::makeNumCell(int64_t val) { + return CURRENT_MC.load()->create_cell(val); +} + +Handle Handle::makeStrCell(std::string val) { + return CURRENT_MC.load()->create_cell(std::move(val)); +} + +void Handle::setcar(const Handle &car) { + CURRENT_MC.load()->run_dirty([&](std::function dirty) -> void { + dirty(dynamic_cast(*_target)._car); + dynamic_cast(*_target)._car = car.get(); + }); +} + +void Handle::setcdr(const Handle &cdr) { + CURRENT_MC.load()->run_dirty([&](std::function dirty) -> void { + dirty(dynamic_cast(*_target)._cdr); + dynamic_cast(*_target)._cdr = cdr.get(); + }); +} diff --git a/src/vm/src/MemoryContext.cpp b/src/vm/src/MemoryContext.cpp index 9c11321..ff69dae 100644 --- a/src/vm/src/MemoryContext.cpp +++ b/src/vm/src/MemoryContext.cpp @@ -29,25 +29,6 @@ MemoryContext::~MemoryContext() { _gc_thread.join(); } -MemoryContext::Handle::Handle(Cell *target) : _target(target) { - if (target != nullptr) - CURRENT_MC.load()->add_root(target); -} - -MemoryContext::Handle::~Handle() { - if (_target != nullptr) - CURRENT_MC.load()->remove_root(_target); -} - -MemoryContext::Handle::Handle(MemoryContext::Handle const &other) : _target(other._target) { - if (_target != nullptr) - CURRENT_MC.load()->add_root(_target); -} - -MemoryContext::Handle &MemoryContext::Handle::operator=(MemoryContext::Handle other) { - std::swap(_target, other._target); - return *this; -} void MemoryContext::add_root(Cell *c) { { @@ -118,7 +99,6 @@ void MemoryContext::gc_thread_entry() { } _cells.insert(temp_cells.begin(), temp_cells.end()); } - _cells_num = _cells.size(); for (auto const &r: new_roots) { @@ -205,6 +185,7 @@ void MemoryContext::gc_thread_entry() { stop = std::chrono::high_resolution_clock::now(); std::cerr << "Sweep time: " << std::chrono::duration_cast(stop - start).count() << "\n"; + _cells_num = _cells.size(); std::cerr << "GC Freed " << freed << " cells left: " << _cells_num << " \n"; } diff --git a/src/vm/src/Parser.cpp b/src/vm/src/Parser.cpp index 2445e84..71ea998 100644 --- a/src/vm/src/Parser.cpp +++ b/src/vm/src/Parser.cpp @@ -8,7 +8,6 @@ #include #include -#include "ConsUtils.h" #include "MemoryContext.h" #include "VM.h" @@ -17,24 +16,23 @@ void Parser::loadStr(std::string_view input) { _tokenizer.load(input); } -MCHandle Parser::parseExpr() { +Handle Parser::parseExpr() { while (!_tokenizer.empty()) { std::string token = std::string(_tokenizer.peek()); if (token == "(") { _tokenizer.getNext(); - MCHandle out(ConsUtils::cons(nullptr, nullptr)); + Handle out(Handle::cons(nullptr, nullptr)); while (token != ")") { if (token == ".") { _tokenizer.getNext(); - ConsUtils::setcdr(out, parseExpr()); + out.setcdr(parseExpr()); - if (_tokenizer.getNext() != ")") - throw std::invalid_argument("Missing ) after pair"); + if (_tokenizer.getNext() != ")") throw std::invalid_argument("Missing ) after pair"); return out; } - ConsUtils::append(out, parseExpr()); + Handle::append(out, parseExpr()); token = _tokenizer.peek(); } _tokenizer.getNext(); @@ -43,9 +41,9 @@ MCHandle Parser::parseExpr() { token = _tokenizer.getNext(); try { CellValType val = std::stoi(token); - return ConsUtils::makeNumCell(val); + return Handle::makeNumCell(val); } catch (...) { - return ConsUtils::makeStrCell(token); + return Handle::makeStrCell(token); } } } diff --git a/src/vm/src/VM.cpp b/src/vm/src/VM.cpp index afa56e3..c47b94e 100644 --- a/src/vm/src/VM.cpp +++ b/src/vm/src/VM.cpp @@ -6,10 +6,8 @@ #include #include -#include "ConsUtils.h" #include "VM.h" -using namespace ConsUtils; VM::VM(std::istream &instream, std::ostream &outstream) : _instream(instream), _outstream(outstream) {} @@ -18,118 +16,118 @@ void VM::run() { } void VM::step() { - MCHandle poppedH = pop(_c); + Handle poppedH = Handle::pop(_c); if (poppedH == NIL) { - push(_s, nullptr); + Handle::push(_s, nullptr); } else if (poppedH == LDC) { - push(_s, pop(_c)); + Handle::push(_s, Handle::pop(_c)); } else if (poppedH == LD) { - MCHandle poppedH2 = pop(_c); + Handle poppedH2 = Handle::pop(_c); - int64_t frame = val(car(poppedH2)); - int64_t arg = val(cdr(poppedH2)); + int64_t frame = poppedH2.car().val(); + int64_t arg = poppedH2.cdr().val(); assert(frame > 0); assert(arg > 0); - MCHandle curFrame = _e; + Handle curFrame = _e; for (int i = 1; i < frame; i++) { - curFrame = cdr(curFrame); + curFrame = curFrame.cdr(); } - MCHandle curArg = car(curFrame); + Handle curArg = curFrame.car(); for (int i = 1; i < arg; i++) { - curArg = cdr(curArg); + curArg = curArg.cdr(); } - push(_s, car(curArg)); + Handle::push(_s, curArg.car()); } else if (poppedH == SEL) { - MCHandle popped2H = pop(_s); + Handle popped2H = Handle::pop(_s); - MCHandle ct = pop(_c); - MCHandle cf = pop(_c); + Handle ct = Handle::pop(_c); + Handle cf = Handle::pop(_c); - push(_d, _c); - if (val(popped2H) > 0) { + Handle::push(_d, _c); + if (popped2H.val() > 0) { _c = ct; } else { _c = cf; } } else if (poppedH == JOIN) { - _c = pop(_d); + _c = Handle::pop(_d); } else if (poppedH == LDF) { - push(_s, cons(pop(_c), _e)); + Handle::push(_s, Handle::cons(Handle::pop(_c), _e)); } else if (poppedH == AP) { - MCHandle closureH = pop(_s); - MCHandle argsH = pop(_s); + Handle closureH = Handle::pop(_s); + Handle argsH = Handle::pop(_s); - push(_d, _s); - push(_d, _e); - push(_d, _c); + Handle::push(_d, _s); + Handle::push(_d, _e); + Handle::push(_d, _c); - _s = cons(nullptr, nullptr); - _c = car(closureH); - _e = cdr(closureH); - push(_e, argsH); + _s = Handle::cons(nullptr, nullptr); + _c = closureH.car(); + _e = closureH.cdr(); + Handle::push(_e, argsH); } else if (poppedH == RET) { - MCHandle c = pop(_d); - MCHandle e = pop(_d); - MCHandle s = pop(_d); + Handle c = Handle::pop(_d); + Handle e = Handle::pop(_d); + Handle s = Handle::pop(_d); - MCHandle ret = pop(_s); + Handle ret = Handle::pop(_s); _c = c; _e = e; _s = s; - push(_s, ret); + Handle::push(_s, ret); } else if (poppedH == DUM) { - push(_e, nullptr); + Handle::push(_e, nullptr); } else if (poppedH == RAP) { - MCHandle closureH = pop(_s); - MCHandle argsH = pop(_s); + Handle closureH = Handle::pop(_s); + Handle argsH = Handle::pop(_s); - MCHandle origE = cdr(_e); + Handle origE = _e.cdr(); - push(_d, _s); - push(_d, origE); - push(_d, _c); + Handle::push(_d, _s); + Handle::push(_d, origE); + Handle::push(_d, _c); - _s = cons(nullptr, nullptr); - _c = car(closureH); - _e = cdr(closureH); + _s = Handle::cons(nullptr, nullptr); + _c = closureH.car(); + _e = closureH.cdr(); - MCHandle fnEnv = cdr(closureH); - assert(_e.get() == fnEnv.get()); + Handle fnEnv = closureH.cdr(); + // assert(_e.get() == fnEnv.get()); - push(_e, argsH); - setcar(fnEnv, argsH); + Handle::push(_e, argsH); + fnEnv.setcar(argsH); } else if (poppedH == STOP) { _stop = true; } else if (poppedH == ADD) { - int64_t ret = val(pop(_s)) + val(pop(_s)); - push(_s, makeNumCell(ret)); + int64_t ret = Handle::pop(_s).val() + Handle::pop(_s).val(); + Handle::push(_s, Handle::makeNumCell(ret)); } else if (poppedH == SUB) { assert(false); - int64_t ret = val(pop(_s)) + val(pop(_s)); - push(_s, makeNumCell(ret)); + int64_t ret = Handle::pop(_s).val() + Handle::pop(_s).val(); + Handle::push(_s, Handle::makeNumCell(ret)); } else if (poppedH == CONS) { - MCHandle h1 = pop(_s); - MCHandle h2 = pop(_s); + Handle h1 = Handle::pop(_s); + Handle h2 = Handle::pop(_s); - push(_s, cons(h1, h2)); + Handle::push(_s, Handle::cons(h1, h2)); } else if (poppedH == READCHAR) { char c; _instream >> c; - push(_s, makeNumCell(c)); + Handle::push(_s, Handle::makeNumCell(c)); } else if (poppedH == PUTCHAR) { - _outstream << (char) val(pop(_s)); + _outstream << (char) Handle::pop(_s).val(); } else if (poppedH == PUTNUM) { - _outstream << val(pop(_s)); + _outstream << Handle::pop(_s).val(); } else { assert(false); } diff --git a/test/vm/GCTest.cpp b/test/vm/GCTest.cpp index f991a2e..1524f98 100644 --- a/test/vm/GCTest.cpp +++ b/test/vm/GCTest.cpp @@ -4,89 +4,98 @@ #include -#include "ConsUtils.h" #include "MemoryContext.h" -using namespace ConsUtils; - TEST(GCTest, GCTest) { MemoryContext mc; { - MCHandle c = cons(nullptr, nullptr); + Handle c = Handle::cons(nullptr, nullptr); mc.request_gc_and_wait(); - append(c, makeNumCell(1)); - append(c, makeNumCell(2)); + Handle::append(c, Handle::makeNumCell(1)); + Handle::append(c, Handle::makeNumCell(2)); mc.request_gc_and_wait(); - EXPECT_EQ(val(car(c)), 1); - EXPECT_EQ(val(car(cdr(c))), 2); + EXPECT_EQ(c.car().val(), 1); + EXPECT_EQ(c.cdr().car().val(), 2); } mc.request_gc_and_wait(); mc.request_gc_and_wait(); - mc.request_gc_and_wait(); EXPECT_EQ(mc.cell_count(), 0); { - MCHandle c = cons(nullptr, nullptr); + Handle c = Handle::cons(nullptr, nullptr); mc.request_gc_and_wait(); - push(c, makeNumCell(1)); - push(c, makeNumCell(2)); + Handle::push(c, Handle::makeNumCell(1)); + Handle::push(c, Handle::makeNumCell(2)); mc.request_gc_and_wait(); - EXPECT_EQ(val(car(c)), 2); - EXPECT_EQ(val(car(cdr(c))), 1); + EXPECT_EQ(c.car().val(), 2); + EXPECT_EQ(c.cdr().car().val(), 1); } mc.request_gc_and_wait(); mc.request_gc_and_wait(); - mc.request_gc_and_wait(); EXPECT_EQ(mc.cell_count(), 0); } TEST(GCTest, GCTestAppend) { MemoryContext mc; for (int i = 0; i < 25000; i++) { - MCHandle c = cons(nullptr, nullptr); + Handle c = Handle::cons(nullptr, nullptr); mc.request_gc(); - append(c, makeNumCell(1)); + Handle::append(c, Handle::makeNumCell(1)); mc.request_gc(); - EXPECT_EQ(val(car(c)), 1); + EXPECT_EQ(c.car().val(), 1); } mc.request_gc_and_wait(); mc.request_gc_and_wait(); - mc.request_gc_and_wait(); EXPECT_EQ(mc.cell_count(), 0); } TEST(GCTest, GCTestPop) { MemoryContext mc; { - MCHandle c = cons(nullptr, nullptr); + Handle c = Handle::cons(nullptr, nullptr); static constexpr int test_size = 20000; for (int i = 0; i < test_size; i++) { mc.request_gc(); - push(c, makeNumCell(i)); + Handle::push(c, Handle::makeNumCell(i)); } for (int i = test_size - 1; i >= 0; i--) { mc.request_gc(); - EXPECT_EQ(i, val(pop(c))); + EXPECT_EQ(i, Handle::pop(c).val()); } } mc.request_gc_and_wait(); mc.request_gc_and_wait(); - mc.request_gc_and_wait(); EXPECT_EQ(mc.cell_count(), 0); } TEST(GCTest, GCTestAppend2) { MemoryContext mc; - MCHandle c = cons(nullptr, nullptr); + Handle c = Handle::cons(nullptr, nullptr); static constexpr int test_size = 2000; for (int i = 0; i < test_size; i++) { mc.request_gc(); - append(c, makeNumCell(i)); + Handle::append(c, Handle::makeNumCell(i)); } for (int i = 0; i < test_size; i++) { mc.request_gc(); - EXPECT_EQ(i, val(pop(c))); + EXPECT_EQ(i, Handle::pop(c).val()); + } + mc.request_gc_and_wait(); + mc.request_gc_and_wait(); + EXPECT_EQ(mc.cell_count(), 0); +} + +TEST(GCTest, GCTestAppend3) { + MemoryContext mc; + for (int i = 0; i < 250000; i++) { + Handle c = Handle::cons(nullptr, nullptr); + Handle::append(c, Handle::makeNumCell(1)); + Handle::append(c, Handle::makeNumCell(2)); + mc.request_gc(); + Handle n = c.cdr(); + c.setcdr(nullptr); + EXPECT_EQ(n.car().val(), 2); + EXPECT_EQ(c.car().val(), 1); } mc.request_gc_and_wait(); mc.request_gc_and_wait(); - mc.request_gc_and_wait(); EXPECT_EQ(mc.cell_count(), 0); } diff --git a/test/vm/VMTest.cpp b/test/vm/VMTest.cpp index b4fb91f..de49595 100644 --- a/test/vm/VMTest.cpp +++ b/test/vm/VMTest.cpp @@ -1,6 +1,5 @@ #include -#include "ConsUtils.h" #include "VM.h" TEST(VMTest, BasicHello) { @@ -9,12 +8,12 @@ TEST(VMTest, BasicHello) { { MemoryContext mc; VM vm(ssin, ssout); - MCHandle newc(ConsUtils::cons(nullptr, nullptr)); - ConsUtils::append(newc, ConsUtils::makeStrCell("NIL")); - ConsUtils::append(newc, ConsUtils::makeStrCell("LDC")); - ConsUtils::append(newc, ConsUtils::makeNumCell('h')); - ConsUtils::append(newc, ConsUtils::makeStrCell("PUTCHAR")); - ConsUtils::append(newc, ConsUtils::makeStrCell("STOP")); + Handle newc(Handle::cons(nullptr, nullptr)); + Handle::append(newc, Handle::makeStrCell("NIL")); + Handle::append(newc, Handle::makeStrCell("LDC")); + Handle::append(newc, Handle::makeNumCell('h')); + Handle::append(newc, Handle::makeStrCell("PUTCHAR")); + Handle::append(newc, Handle::makeStrCell("STOP")); vm.loadControl(newc); vm.run(); } diff --git a/test/vm/VMWithParserTest.cpp b/test/vm/VMWithParserTest.cpp index f1f04d8..cd60e93 100644 --- a/test/vm/VMWithParserTest.cpp +++ b/test/vm/VMWithParserTest.cpp @@ -63,7 +63,6 @@ TEST(VMWithParserTest, RecFunction) { } mc.request_gc_and_wait(); mc.request_gc_and_wait(); - mc.request_gc_and_wait(); EXPECT_EQ(mc.cell_count(), 0); ssout.flush(); EXPECT_EQ(ssout.str(), "6765");