-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ikarus loop support #74
Conversation
+ naked calls + loop traps GothicKit#58
Thanks! Hm I can't see an easy way to fix this right now but I don't like that mod-specific things are hardcoded into the base VM implementation. I'll do some tests to verify everything works correctly and then we can merge it but expect some changes to the VM later so that things like this can be achieved in a more generic way. |
I understand, also we can discuss it in this PR. In principle game needs to have a "trap" callback on some of case opcode::pushv:
sym = find_symbol_by_index(instr.symbol);
if (sym == nullptr) {
throw vm_exception {"pushv: no symbol found for index"};
}
if ((_m_loop_end_sym == sym || _m_loop_break_sym==sym || _m_loop_continue_sym==sym) && _m_loop_trap) {
_m_loop_trap(*sym);
} else {
push_reference(sym, 0);
}
break; Ideas so far:
|
Yeah I think that's not the way to go about it. It would require a lot of new code and inserting instruction (for example) wouldn't really work easily since jumps reference a static offset from the beginning of the binary so we'd have to re-assign each jump address if an instruction is added which also includes function calls :/
I do like the idea here. Maybe it could work like a debugger watch where you set a callback which is invoked whenever the symbol is read from or written to. This would be relatively simple and you could still call functions in the VM from within the callback. This would probably still require naked call support which I'm totally happy with adding. Also this could be really nice for debugging scripts. |
include/phoenix/vm.hh
Outdated
if constexpr (sizeof...(P) > 0 && !std::is_same_v<naked_call, R>) { | ||
check_external_params<0, P...>(params); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand correctly that you never want to take any parameters or return any values to the VM when using a naked call? In that case, this I feel like this should be a separate function since it uses basically none of the logic of override_function
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typically naked-calls are special case, so explicit parameter pooling is good match for feature; yet must admit that for loop it's not mandatory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay so then let's split that logic out into a override_function_naked
routine like this:
void override_function_naked(std::string_view name, std::function<void(vm&)> callback) {
auto* sym = find_symbol_by_name(name);
if (sym == nullptr)
throw vm_exception {"symbol not found"};
if (sym->is_external())
throw vm_exception {"symbol is already an external"};
_m_function_overrides[sym->address()] = [callback, sym](vm& machine) {
callback(machine);
};
}
That makes this considerably easier to read I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've set for solution in-between;
add new override for override_function(..., std::function<naked_call(vm&))
- so code can be decoupled.
decide not to introduce new name, as on user end phoenix::naked_call
is already a strong hint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, looks good to me :)
Concept:
CONTINUE
,BREAK
andEND
are tracked in VM (guarded by flag), assuming that it's more efficient than virtual functions based approach.repeat
functionrepeat
function