+26
-43
@@ -28,21 +28,14 @@ struct executor::frame executor::frame() const {
|
||||
return m_frames.top();
|
||||
}
|
||||
|
||||
void executor::push_thing(const thing_h& thing) {
|
||||
(*thing)->add_reference();
|
||||
m_stack.push(thing);
|
||||
}
|
||||
|
||||
void executor::push_thing(thing_h&& thing) {
|
||||
(*thing)->add_reference();
|
||||
m_stack.push(std::move(thing));
|
||||
thing_h executor::push_thing(::furvm::thing<>&& thing) {
|
||||
return m_stack.emplace(m_context->emplace_thing(std::move(thing)));
|
||||
}
|
||||
|
||||
thing_h executor::pop_thing() {
|
||||
if (m_frames.top().stackBase >= m_stack.size()) throw stack_underflow();
|
||||
thing_h top = std::move(m_stack.top());
|
||||
m_stack.pop();
|
||||
(*top)->remove_reference();
|
||||
return top;
|
||||
}
|
||||
|
||||
@@ -54,20 +47,12 @@ thing_h executor::thing() const {
|
||||
void executor::store_thing(variable_t variable, const thing_h& thing) {
|
||||
auto& frame = m_frames.top();
|
||||
frame.variables.resize(variable + 1);
|
||||
if (*frame.variables[variable] != nullptr) {
|
||||
(*frame.variables[variable])->remove_reference();
|
||||
}
|
||||
frame.variables[variable] = thing;
|
||||
(*thing)->add_reference();
|
||||
}
|
||||
|
||||
void executor::store_thing(variable_t variable, thing_h&& thing) {
|
||||
auto& frame = m_frames.top();
|
||||
frame.variables.resize(variable + 1);
|
||||
if ((*frame.variables[variable]) != nullptr) {
|
||||
(*frame.variables[variable])->remove_reference();
|
||||
}
|
||||
(*thing)->add_reference();
|
||||
frame.variables[variable] = std::move(thing);
|
||||
}
|
||||
|
||||
@@ -81,13 +66,11 @@ void executor::step() {
|
||||
|
||||
struct frame& frame = m_frames.top();
|
||||
|
||||
instruction_t instr = static_cast<instruction_t>((*frame.mod)->byte(frame.position++));
|
||||
instruction_t instr = static_cast<instruction_t>((*frame.mod).byte(frame.position++));
|
||||
switch (instr) {
|
||||
case instruction_t::NoOperation: break;
|
||||
case instruction_t::PushB2I: {
|
||||
auto thing = m_context->emplace_thing(thing_t::Int32);
|
||||
(*thing)->int32() = (*frame.mod)->byte(frame.position++);
|
||||
push_thing(std::move(thing));
|
||||
push_thing({ thing_t::Int32, m_context->m_thingAllocator })->int32() = frame.mod->byte(frame.position++);
|
||||
} break;
|
||||
case instruction_t::Drop: {
|
||||
pop_thing();
|
||||
@@ -96,81 +79,81 @@ void executor::step() {
|
||||
push_thing(thing());
|
||||
} break;
|
||||
case instruction_t::Clone: {
|
||||
push_thing(std::move(thing::clone(m_context, thing())));
|
||||
push_thing(std::move(thing()->clone()));
|
||||
} break;
|
||||
case instruction_t::Add: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->add(m_context, rhs));
|
||||
push_thing(lhs->add(*rhs));
|
||||
} break;
|
||||
case instruction_t::Sub: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->sub(m_context, rhs));
|
||||
push_thing(lhs->sub(*rhs));
|
||||
} break;
|
||||
case instruction_t::Mul: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->mul(m_context, rhs));
|
||||
push_thing(lhs->mul(*rhs));
|
||||
} break;
|
||||
case instruction_t::Div: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->div(m_context, rhs));
|
||||
push_thing(lhs->div(*rhs));
|
||||
} break;
|
||||
case instruction_t::Mod: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->mod(m_context, rhs));
|
||||
push_thing(lhs->mod(*rhs));
|
||||
} break;
|
||||
case instruction_t::Equals: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->equals(m_context, rhs));
|
||||
push_thing(lhs->equals(*rhs));
|
||||
} break;
|
||||
case instruction_t::NotEquals: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->not_equals(m_context, rhs));
|
||||
push_thing(lhs->not_equals(*rhs));
|
||||
} break;
|
||||
case instruction_t::LessThan: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->less_than(m_context, rhs));
|
||||
push_thing(lhs->less_than(*rhs));
|
||||
} break;
|
||||
case instruction_t::GreaterThan: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->greater_than(m_context, rhs));
|
||||
push_thing(lhs->greater_than(*rhs));
|
||||
} break;
|
||||
case instruction_t::LessEqual: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->less_equals(m_context, rhs));
|
||||
push_thing(lhs->less_equals(*rhs));
|
||||
} break;
|
||||
case instruction_t::GreaterEqual: {
|
||||
auto rhs = pop_thing();
|
||||
auto lhs = pop_thing();
|
||||
push_thing((*lhs)->greater_equals(m_context, rhs));
|
||||
push_thing(lhs->greater_equals(*rhs));
|
||||
} break;
|
||||
case instruction_t::Load: {
|
||||
variable_t variable = static_cast<std::uint16_t>((*frame.mod)->byte(frame.position)) |
|
||||
(static_cast<std::uint16_t>((*frame.mod)->byte(frame.position + 1)) << 8);
|
||||
variable_t variable = static_cast<std::uint16_t>(frame.mod->byte(frame.position)) |
|
||||
(static_cast<std::uint16_t>(frame.mod->byte(frame.position + 1)) << 8);
|
||||
frame.position += 2;
|
||||
push_thing(load_thing(variable));
|
||||
} break;
|
||||
case instruction_t::Store: {
|
||||
variable_t variable = static_cast<std::uint16_t>((*frame.mod)->byte(frame.position)) |
|
||||
(static_cast<std::uint16_t>((*frame.mod)->byte(frame.position + 1)) << 8);
|
||||
variable_t variable = static_cast<std::uint16_t>(frame.mod->byte(frame.position)) |
|
||||
(static_cast<std::uint16_t>(frame.mod->byte(frame.position + 1)) << 8);
|
||||
frame.position += 2;
|
||||
store_thing(variable, std::move(pop_thing()));
|
||||
} break;
|
||||
case instruction_t::Call: {
|
||||
function_id funcId = static_cast<std::uint16_t>((*frame.mod)->byte(frame.position)) |
|
||||
(static_cast<std::uint16_t>((*frame.mod)->byte(frame.position + 1)) << 8);
|
||||
function_id funcId = static_cast<std::uint16_t>(frame.mod->byte(frame.position)) |
|
||||
(static_cast<std::uint16_t>(frame.mod->byte(frame.position + 1)) << 8);
|
||||
frame.position += 2;
|
||||
|
||||
const function_h& function = (*frame.mod)->function_at(funcId);
|
||||
const function_h& function = frame.mod->function_at(funcId);
|
||||
switch (function->type()) {
|
||||
case function_t::Normal: push_frame(frame.mod, function); break;
|
||||
case function_t::Native: function->native()(*this); break;
|
||||
@@ -182,12 +165,12 @@ void executor::step() {
|
||||
}
|
||||
} break;
|
||||
case instruction_t::Jump: {
|
||||
frame.position += (*frame.mod)->byte(frame.position++);
|
||||
frame.position += frame.mod->byte(frame.position++);
|
||||
} break;
|
||||
case instruction_t::JumpNotZero: {
|
||||
byte offset = (*frame.mod)->byte(frame.position++);
|
||||
byte offset = frame.mod->byte(frame.position++);
|
||||
auto cond = pop_thing();
|
||||
if ((*cond)->int32() != 0) frame.position += offset;
|
||||
if (cond->int32() != 0) frame.position += offset;
|
||||
} break;
|
||||
case instruction_t::Return: {
|
||||
pop_frame();
|
||||
|
||||
Reference in New Issue
Block a user