mirror of
https://github.com/open-goal/jak-project
synced 2026-08-21 23:00:45 -04:00
[decompiler] Handle find-parent-method (#3018)
This change adds a few new features: - Decompiler automatically knows the type of `find-parent-method` use in jak 1 and jak2 when used in a method or virtual state handler. - Decompiler inserts a call to `call-parent-method` or `find-parent-state` - Removed most casts related to these functions There are still a few minor issues around this: - There are still some casts needed when using `post` methods, as `post` is just a `function`, and needs a cast to `(function none)` or similar. It didn't seem easy to change the type of `post`, so I'm not going to worry about it for this PR. It only shows up in like 3 places in jak 2. (and 0 in jak 1) - If "call the handler if it's not #f" logic should probably be another macro. Fixes #805
This commit is contained in:
@@ -2621,7 +2621,9 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
}
|
||||
}
|
||||
|
||||
FormElement* SetFormFormElement::make_set_time(const Env& env, FormPool& pool, FormStack& stack) {
|
||||
FormElement* SetFormFormElement::make_set_time(const Env& /*env*/,
|
||||
FormPool& pool,
|
||||
FormStack& /*stack*/) {
|
||||
auto matcher = match(
|
||||
Matcher::op(GenericOpMatcher::func(Matcher::constant_token("current-time")), {}), m_src);
|
||||
if (matcher.matched) {
|
||||
@@ -3908,6 +3910,39 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
}
|
||||
}
|
||||
|
||||
// detect call-parent-method
|
||||
{
|
||||
const auto& guessed_name = env.func->guessed_name;
|
||||
if (guessed_name.kind == FunctionName::FunctionKind::METHOD) {
|
||||
// detect stuff like: ((find-parent-method...) arg...)
|
||||
auto mr_find_parent =
|
||||
match(Matcher::func(Matcher::symbol("find-parent-method"),
|
||||
{Matcher::symbol(env.func->method_of_type),
|
||||
Matcher::integer(env.func->guessed_name.method_id)}),
|
||||
unstacked.at(0)
|
||||
|
||||
);
|
||||
if (mr_find_parent.matched) {
|
||||
new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("call-parent-method")),
|
||||
arg_forms);
|
||||
}
|
||||
} else if (guessed_name.kind == FunctionName::FunctionKind::V_STATE && arg_forms.size() == 2) {
|
||||
// here, simply detect (find-parent-method...)
|
||||
//
|
||||
auto mr_find_parent = match(Matcher::symbol("find-parent-method"), unstacked.at(0));
|
||||
if (mr_find_parent.matched) {
|
||||
auto state_info =
|
||||
env.dts->ts.lookup_method(guessed_name.type_name, guessed_name.state_name);
|
||||
if (arg_forms.at(0)->to_string(env) == guessed_name.type_name &&
|
||||
arg_forms.at(1)->to_string(env) == std::to_string(state_info.id)) {
|
||||
new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("find-parent-state")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result->push_back(new_form);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user