Turn the stack data structure to hierarchical stack frame
This commit is contained in:
parent
b7d51f647f
commit
213ce07f34
9 changed files with 63 additions and 55 deletions
|
@ -56,6 +56,8 @@ Result<GcRootList*> Arena::gc_root(GcRootList* node) {
|
|||
}
|
||||
|
||||
Result<PodObject*> Arena::gc_pod(PodObject* obj) {
|
||||
if (obj == 0) return 0;
|
||||
|
||||
switch (obj->header.tag) {
|
||||
case Tag::Nil:
|
||||
return gc_nil((PodNil*)obj);
|
||||
|
@ -89,8 +91,8 @@ Result<PodObject*> Arena::gc_pod(PodObject* obj) {
|
|||
return gc_stdlib_function((PodStdlibFunction*)obj);
|
||||
case Tag::Module:
|
||||
return gc_module((PodModule*)obj);
|
||||
case Tag::Stack:
|
||||
return gc_stack((PodStack*)obj);
|
||||
case Tag::StackFrame:
|
||||
return gc_stack((PodStackFrame*)obj);
|
||||
case Tag::Error:
|
||||
return gc_error((PodError*)obj);
|
||||
}
|
||||
|
@ -251,9 +253,10 @@ Result<PodObject*> Arena::gc_module(PodModule* obj) {
|
|||
return nobj;
|
||||
}
|
||||
|
||||
Result<PodObject*> Arena::gc_stack(PodStack* obj) {
|
||||
auto nobj = TRY(alloc<PodStack>(sizeof(OffPtr<PodObject>) * obj->size));
|
||||
nobj->header.tag = Tag::Stack;
|
||||
Result<PodObject*> Arena::gc_stack(PodStackFrame* obj) {
|
||||
auto nobj = TRY(alloc<PodStackFrame>(sizeof(OffPtr<PodObject>) * obj->size));
|
||||
nobj->header.tag = Tag::StackFrame;
|
||||
nobj->parent = TRY(gc_pod(obj->parent.get()));
|
||||
nobj->size = obj->size;
|
||||
nobj->top = obj->top;
|
||||
for (uint64_t i = 0; i < obj->top; i++) {
|
||||
|
|
|
@ -159,7 +159,7 @@ class Arena {
|
|||
Result<PodObject*> gc_function(PodFunction* obj);
|
||||
Result<PodObject*> gc_stdlib_function(PodStdlibFunction* obj);
|
||||
Result<PodObject*> gc_module(PodModule* obj);
|
||||
Result<PodObject*> gc_stack(PodStack* obj);
|
||||
Result<PodObject*> gc_stack(PodStackFrame* obj);
|
||||
Result<PodObject*> gc_error(PodError* obj);
|
||||
|
||||
void add_root(GcRootList* node) { _gcroot.insert(node); }
|
||||
|
|
|
@ -42,8 +42,8 @@ Result<Value> Value::create(PodObject* obj) {
|
|||
return Value(TRY(StdlibFunction::create((PodStdlibFunction*)obj)));
|
||||
case Tag::Module:
|
||||
return Value(TRY(Module::create((PodModule*)obj)));
|
||||
case Tag::Stack:
|
||||
return Value(TRY(Stack::create((PodStack*)obj)));
|
||||
case Tag::StackFrame:
|
||||
return Value(TRY(StackFrame::create((PodStackFrame*)obj)));
|
||||
case Tag::Error:
|
||||
return Value(TRY(Error::create((PodError*)obj)));
|
||||
};
|
||||
|
@ -302,17 +302,33 @@ Result<short> Module::cmp(const Module& rhs) const {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<Value> Stack::copy_value() const {
|
||||
return Value(Stack(TRY(_value.copy())));
|
||||
Result<StackFrame> StackFrame::create(uint64_t size) {
|
||||
auto nil = Value(TRY(Nil::create()));
|
||||
auto pod = TRY(arena_alloc<PodStackFrame>(sizeof(OffPtr<PodObject>) * size));
|
||||
pod->header.tag = Tag::StackFrame;
|
||||
|
||||
pod->parent = nil.pod();
|
||||
pod->size = size;
|
||||
pod->top = 0;
|
||||
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
pod->data[i] = 0;
|
||||
}
|
||||
|
||||
return StackFrame(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
|
||||
Result<Value> Stack::get(uint64_t idx) const {
|
||||
Result<Value> StackFrame::copy_value() const {
|
||||
return Value(StackFrame(TRY(_value.copy())));
|
||||
}
|
||||
|
||||
Result<Value> StackFrame::get(uint64_t idx) const {
|
||||
if (idx >= _value->top) return ERROR(KeyError);
|
||||
|
||||
return Value::create(_value->data[idx].get());
|
||||
}
|
||||
|
||||
Result<void> Stack::set(uint64_t idx, const Value& val) {
|
||||
Result<void> StackFrame::set(uint64_t idx, const Value& val) {
|
||||
if (idx >= _value->size) return ERROR(KeyError);
|
||||
|
||||
if (idx >= _value->top) {
|
||||
|
@ -323,7 +339,7 @@ Result<void> Stack::set(uint64_t idx, const Value& val) {
|
|||
return Result<void>();
|
||||
}
|
||||
|
||||
Result<void> Stack::settop(uint64_t idx) {
|
||||
Result<void> StackFrame::settop(uint64_t idx) {
|
||||
uint64_t top = _value->top;
|
||||
for (uint64_t i = std::min(top, idx); i < std::max(top, idx); i++) {
|
||||
_value->data[i] = 0;
|
||||
|
|
|
@ -32,7 +32,7 @@ class Dict;
|
|||
class ByteArray;
|
||||
class Writer;
|
||||
class Opcode;
|
||||
class Stack;
|
||||
class StackFrame;
|
||||
class Error;
|
||||
class Function;
|
||||
class StdlibFunction;
|
||||
|
@ -100,7 +100,7 @@ class Object {
|
|||
virtual Result<short> cmp(const char* rhs) const {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
virtual Result<short> cmp(const Stack& rhs) const {
|
||||
virtual Result<short> cmp(const StackFrame& rhs) const {
|
||||
return ERROR(NotImplemented);
|
||||
}
|
||||
virtual Result<short> cmp(const Error& rhs) const {
|
||||
|
@ -1086,23 +1086,25 @@ class Module : public Object {
|
|||
GcRoot<PodModule> _value;
|
||||
};
|
||||
|
||||
class Stack : public Object {
|
||||
class StackFrame : public Object {
|
||||
public:
|
||||
Stack() {}
|
||||
Stack(Stack&& rhs) : _value(std::move(rhs._value)) {}
|
||||
Stack(GcRoot<PodStack>&& val) : _value(std::move(val)) {}
|
||||
StackFrame() {}
|
||||
StackFrame(StackFrame&& rhs) : _value(std::move(rhs._value)) {}
|
||||
StackFrame(GcRoot<PodStackFrame>&& val) : _value(std::move(val)) {}
|
||||
|
||||
virtual Tag tag() const final { return Tag::Stack; }
|
||||
virtual Tag tag() const final { return Tag::StackFrame; }
|
||||
virtual PodObject* pod() const final { return _value.get(); }
|
||||
virtual Result<short> cmp(const Object& rhs) const final {
|
||||
return -TRY(rhs.cmp(*this));
|
||||
}
|
||||
virtual Result<short> cmp(const Stack& rhs) const final { return 0; }
|
||||
virtual Result<short> cmp(const StackFrame& rhs) const final { return 0; }
|
||||
|
||||
virtual void move(Object* obj) final { new (obj) Stack(std::move(_value)); }
|
||||
virtual void move(Object* obj) final {
|
||||
new (obj) StackFrame(std::move(_value));
|
||||
}
|
||||
|
||||
static Result<Stack> create(PodStack* obj) {
|
||||
return Stack(TRY(MkGcRoot(obj)));
|
||||
static Result<StackFrame> create(PodStackFrame* obj) {
|
||||
return StackFrame(TRY(MkGcRoot(obj)));
|
||||
}
|
||||
|
||||
using Object::get;
|
||||
|
@ -1111,19 +1113,7 @@ class Stack : public Object {
|
|||
Result<void> settop(uint64_t idx);
|
||||
uint64_t gettop() { return _value->top; }
|
||||
|
||||
static Result<Stack> create(uint64_t size) {
|
||||
auto pod = TRY(arena_alloc<PodStack>(sizeof(OffPtr<PodObject>) * size));
|
||||
pod->header.tag = Tag::Stack;
|
||||
|
||||
pod->size = size;
|
||||
pod->top = 0;
|
||||
|
||||
for (uint64_t i = 0; i < size; i++) {
|
||||
pod->data[i] = 0;
|
||||
}
|
||||
|
||||
return Stack(TRY(MkGcRoot(pod)));
|
||||
}
|
||||
static Result<StackFrame> create(uint64_t size);
|
||||
|
||||
Result<Array> slice(uint64_t start, uint64_t end) {
|
||||
if (start > end || end > gettop()) return ERROR(IndexOutOfRange);
|
||||
|
@ -1139,10 +1129,10 @@ class Stack : public Object {
|
|||
}
|
||||
|
||||
virtual Result<Value> copy_value() const final;
|
||||
Result<Stack> copy() const;
|
||||
Result<StackFrame> copy() const;
|
||||
|
||||
private:
|
||||
GcRoot<PodStack> _value;
|
||||
GcRoot<PodStackFrame> _value;
|
||||
};
|
||||
|
||||
class Error : public Object {
|
||||
|
|
|
@ -237,7 +237,7 @@ Result<Expression> Compiler::compile_expr(Context& context, const Value& expr) {
|
|||
case Tag::Function:
|
||||
case Tag::StdlibFunction:
|
||||
case Tag::Module:
|
||||
case Tag::Stack:
|
||||
case Tag::StackFrame:
|
||||
case Tag::Error:
|
||||
return ERROR(TypeMismatch);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ enum class Tag : uint8_t {
|
|||
Function,
|
||||
StdlibFunction,
|
||||
Module,
|
||||
Stack,
|
||||
StackFrame,
|
||||
Error,
|
||||
};
|
||||
|
||||
|
@ -192,10 +192,11 @@ class PodModule final : public PodObject {
|
|||
OffPtr<PodObject> fun;
|
||||
};
|
||||
|
||||
class PodStack final : public PodObject {
|
||||
class PodStackFrame final : public PodObject {
|
||||
public:
|
||||
PodStack() : PodObject(Tag::Stack) {};
|
||||
PodStackFrame() : PodObject(Tag::StackFrame) {};
|
||||
|
||||
OffPtr<PodObject> parent;
|
||||
uint64_t size;
|
||||
uint64_t top;
|
||||
OffPtr<PodObject> data[];
|
||||
|
|
14
src/vm.hpp
14
src/vm.hpp
|
@ -5,15 +5,15 @@
|
|||
class VM {
|
||||
public:
|
||||
VM() {}
|
||||
VM(Stack&& stack, Stack&& callstack)
|
||||
VM(StackFrame&& stack, StackFrame&& callstack)
|
||||
: _stack(std::move(stack)), _callstack(std::move(callstack)) {}
|
||||
VM(VM&& vm)
|
||||
: _stack(std::move(vm._stack)), _callstack(std::move(vm._callstack)) {}
|
||||
VM(const VM&) = delete;
|
||||
|
||||
static Result<VM> create() {
|
||||
auto stack = TRY(Stack::create(16 * 1024));
|
||||
auto callstack = TRY(Stack::create(16 * 1024));
|
||||
auto stack = TRY(StackFrame::create(16 * 1024));
|
||||
auto callstack = TRY(StackFrame::create(16 * 1024));
|
||||
return VM(std::move(stack), std::move(callstack));
|
||||
}
|
||||
|
||||
|
@ -48,13 +48,11 @@ class VM {
|
|||
Result<Value> getreg(uint64_t idx);
|
||||
Result<void> setreg(uint64_t idx, const Value& value);
|
||||
|
||||
Result<Dict> globals() {
|
||||
return _globals.copy();
|
||||
}
|
||||
Result<Dict> globals() { return _globals.copy(); }
|
||||
|
||||
private:
|
||||
Stack _stack;
|
||||
Stack _callstack;
|
||||
StackFrame _stack;
|
||||
StackFrame _callstack;
|
||||
Function _fun;
|
||||
Array _code;
|
||||
Array _constants;
|
||||
|
|
|
@ -39,8 +39,8 @@ Result<String> Writer::write_one(const Value& obj) {
|
|||
return write_stdlib_function(*obj.to<StdlibFunction>());
|
||||
case Tag::Module:
|
||||
return write_module(*obj.to<Module>());
|
||||
case Tag::Stack:
|
||||
return write_stack(*obj.to<Stack>());
|
||||
case Tag::StackFrame:
|
||||
return write_stack(*obj.to<StackFrame>());
|
||||
case Tag::Error:
|
||||
return write_error(*obj.to<Error>());
|
||||
};
|
||||
|
@ -376,7 +376,7 @@ Result<String> Writer::write_module(const Module& val) {
|
|||
return res;
|
||||
}
|
||||
|
||||
Result<String> Writer::write_stack(const Stack& val) {
|
||||
Result<String> Writer::write_stack(const StackFrame& val) {
|
||||
return TRY(String::create("#<stack>"));
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ class Writer {
|
|||
Result<String> write_function(const Function& val);
|
||||
Result<String> write_stdlib_function(const StdlibFunction& val);
|
||||
Result<String> write_module(const Module& val);
|
||||
Result<String> write_stack(const Stack& val);
|
||||
Result<String> write_stack(const StackFrame& val);
|
||||
Result<String> write_error(const Error& val);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue