Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
lmichaelis committed Aug 10, 2024
1 parent 7c79999 commit d9f92cd
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 14 deletions.
1 change: 1 addition & 0 deletions include/zenkit/DaedalusVm.hh
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ namespace zenkit {
struct DaedalusCallStackFrame {
DaedalusSymbol const* function;
std::uint32_t program_counter;
std::uint32_t stack_ptr;
std::shared_ptr<DaedalusInstance> context;
};

Expand Down
60 changes: 46 additions & 14 deletions src/DaedalusVm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,31 @@ namespace zenkit {
~StackGuard() {
if (_m_inhibited) return;

switch (_m_type) {
StackGuard::fix(_m_machine, _m_type);
}

/// \brief Inhibits this guard.
///
/// Calling this function will cause the guard to disengage and thus not push a
/// value onto the stack.
void inhibit() {
_m_inhibited = true;
}

static void fix(DaedalusVm* vm, DaedalusDataType type) {
switch (type) {
case DaedalusDataType::FLOAT:
_m_machine->push_float(0);
vm->push_float(0);
break;
case DaedalusDataType::INT:
case DaedalusDataType::FUNCTION:
_m_machine->push_int(0);
vm->push_int(0);
break;
case DaedalusDataType::STRING:
_m_machine->push_string("");
vm->push_string("");
break;
case DaedalusDataType::INSTANCE:
_m_machine->push_instance(nullptr);
vm->push_instance(nullptr);
break;
case DaedalusDataType::VOID:
case DaedalusDataType::CLASS:
Expand All @@ -57,14 +69,6 @@ namespace zenkit {
}
}

/// \brief Inhibits this guard.
///
/// Calling this function will cause the guard to disengage and thus not push a
/// value onto the stack.
void inhibit() {
_m_inhibited = true;
}

private:
DaedalusDataType _m_type;
DaedalusVm* _m_machine;
Expand Down Expand Up @@ -453,11 +457,39 @@ namespace zenkit {
}

void DaedalusVm::push_call(DaedalusSymbol const* sym) {
_m_call_stack.push({sym, _m_pc, _m_instance});
auto var_count = this->find_parameters_for_function(sym).size();
_m_call_stack.push({sym, _m_pc, _m_stack_ptr - static_cast<uint32_t>(var_count), _m_instance});
}

void DaedalusVm::pop_call() {
auto const& call = _m_call_stack.top();

// First, try to fix up the stack.
if (!call.function->has_return()) {
// No special logic needed, there are supposed to be no more stack frames for
// this function, so just reset the stack for the caller.
_m_stack_ptr = call.stack_ptr;
} else {
auto remaining_locals = _m_stack_ptr - call.stack_ptr;
if (remaining_locals == 0) {
// The function is supposed to have a return value, but it does not seem to have one.
// To fix this, we just insert a default value (either 0, "" or NULL).
StackGuard::fix(this, call.function->rtype());
} else if (remaining_locals > 1) {
// Now we have too many items left on the stack. Remove all of them, except the topmost one,
// since that one is supposed to be the return value of the function.
DaedalusStackFrame frame = _m_stack[--_m_stack_ptr];
_m_stack_ptr = call.stack_ptr;
_m_stack[_m_stack_ptr++] = std::move(frame);
}
// else {
// We have exactly one value to be returned (as indicated by the symbol's return type).
// That means, that the compiler did not mess up the stack management, so we can just
// return that value.
// }
}

// Second, reset PC and context, then remove the call stack frame
_m_pc = call.program_counter;
_m_instance = call.context;
_m_call_stack.pop();
Expand Down

0 comments on commit d9f92cd

Please sign in to comment.