mirror of
https://github.com/open-goal/jak-project
synced 2026-07-10 23:22:17 -04:00
[Decompiler] Decompile let (#309)
* test * fix bug * fix tests for let * missing formatting fix
This commit is contained in:
+257
-79
@@ -120,9 +120,9 @@ void Form::apply_form(const std::function<void(Form*)>& f) {
|
||||
}
|
||||
}
|
||||
|
||||
void Form::collect_vars(RegAccessSet& vars) const {
|
||||
void Form::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
for (auto e : m_elements) {
|
||||
e->collect_vars(vars);
|
||||
e->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ bool SimpleExpressionElement::is_sequence_point() const {
|
||||
throw std::runtime_error("Should not check if a SimpleExpressionElement is a sequence point");
|
||||
}
|
||||
|
||||
void SimpleExpressionElement::collect_vars(RegAccessSet& vars) const {
|
||||
void SimpleExpressionElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
m_expr.collect_vars(vars);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ void StoreElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void StoreElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void StoreElement::collect_vars(RegAccessSet& vars) const {
|
||||
void StoreElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
return m_op->collect_vars(vars);
|
||||
}
|
||||
|
||||
@@ -239,8 +239,10 @@ void LoadSourceElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
m_addr->apply_form(f);
|
||||
}
|
||||
|
||||
void LoadSourceElement::collect_vars(RegAccessSet& vars) const {
|
||||
m_addr->collect_vars(vars);
|
||||
void LoadSourceElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
m_addr->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadSourceElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -263,7 +265,7 @@ void SimpleAtomElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void SimpleAtomElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void SimpleAtomElement::collect_vars(RegAccessSet& vars) const {
|
||||
void SimpleAtomElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
return m_atom.collect_vars(vars);
|
||||
}
|
||||
|
||||
@@ -301,12 +303,14 @@ bool SetVarElement::is_sequence_point() const {
|
||||
return m_is_sequence_point;
|
||||
}
|
||||
|
||||
void SetVarElement::collect_vars(RegAccessSet& vars) const {
|
||||
void SetVarElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (m_var_info.is_dead_set || m_var_info.is_dead_false) {
|
||||
return;
|
||||
}
|
||||
vars.insert(m_dst);
|
||||
m_src->collect_vars(vars);
|
||||
if (recursive) {
|
||||
m_src->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void SetVarElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -350,7 +354,7 @@ void StoreInSymbolElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void StoreInSymbolElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void StoreInSymbolElement::collect_vars(RegAccessSet& vars) const {
|
||||
void StoreInSymbolElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
m_value.collect_vars(vars);
|
||||
}
|
||||
|
||||
@@ -374,7 +378,7 @@ void StoreInPairElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void StoreInPairElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void StoreInPairElement::collect_vars(RegAccessSet& vars) const {
|
||||
void StoreInPairElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
m_value.collect_vars(vars);
|
||||
vars.insert(m_pair);
|
||||
}
|
||||
@@ -438,9 +442,11 @@ bool SetFormFormElement::is_sequence_point() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetFormFormElement::collect_vars(RegAccessSet& vars) const {
|
||||
m_src->collect_vars(vars);
|
||||
m_dst->collect_vars(vars);
|
||||
void SetFormFormElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
m_src->collect_vars(vars, recursive);
|
||||
m_dst->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void SetFormFormElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -463,7 +469,7 @@ void AtomicOpElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void AtomicOpElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void AtomicOpElement::collect_vars(RegAccessSet& vars) const {
|
||||
void AtomicOpElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
m_op->collect_vars(vars);
|
||||
}
|
||||
|
||||
@@ -493,7 +499,7 @@ void AsmOpElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void AsmOpElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void AsmOpElement::collect_vars(RegAccessSet& vars) const {
|
||||
void AsmOpElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
m_op->collect_vars(vars);
|
||||
}
|
||||
|
||||
@@ -552,7 +558,7 @@ void ConditionElement::invert() {
|
||||
m_kind = get_condition_opposite(m_kind);
|
||||
}
|
||||
|
||||
void ConditionElement::collect_vars(RegAccessSet& vars) const {
|
||||
void ConditionElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
for (auto src : m_src) {
|
||||
if (src.has_value() && src->is_var()) {
|
||||
vars.insert(src->var());
|
||||
@@ -580,7 +586,7 @@ void FunctionCallElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void FunctionCallElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void FunctionCallElement::collect_vars(RegAccessSet& vars) const {
|
||||
void FunctionCallElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
return m_op->collect_vars(vars);
|
||||
}
|
||||
|
||||
@@ -610,7 +616,7 @@ void BranchElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void BranchElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void BranchElement::collect_vars(RegAccessSet& vars) const {
|
||||
void BranchElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
return m_op->collect_vars(vars);
|
||||
}
|
||||
|
||||
@@ -628,6 +634,14 @@ void BranchElement::get_modified_regs(RegSet& regs) const {
|
||||
// ReturnElement
|
||||
/////////////////////////////
|
||||
|
||||
ReturnElement::ReturnElement(Form* _return_code, Form* _dead_code)
|
||||
: return_code(_return_code), dead_code(_dead_code) {
|
||||
return_code->parent_element = this;
|
||||
if (dead_code) {
|
||||
dead_code->parent_element = this;
|
||||
}
|
||||
}
|
||||
|
||||
goos::Object ReturnElement::to_form_internal(const Env& env) const {
|
||||
std::vector<goos::Object> forms;
|
||||
forms.push_back(pretty_print::to_symbol("return"));
|
||||
@@ -653,10 +667,12 @@ void ReturnElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
}
|
||||
}
|
||||
|
||||
void ReturnElement::collect_vars(RegAccessSet& vars) const {
|
||||
return_code->collect_vars(vars);
|
||||
if (dead_code) {
|
||||
dead_code->collect_vars(vars);
|
||||
void ReturnElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
return_code->collect_vars(vars, recursive);
|
||||
if (dead_code) {
|
||||
dead_code->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,6 +687,12 @@ void ReturnElement::get_modified_regs(RegSet& regs) const {
|
||||
// BreakElement
|
||||
/////////////////////////////
|
||||
|
||||
BreakElement::BreakElement(Form* _return_code, Form* _dead_code)
|
||||
: return_code(_return_code), dead_code(_dead_code) {
|
||||
return_code->parent_element = this;
|
||||
dead_code->parent_element = this;
|
||||
}
|
||||
|
||||
goos::Object BreakElement::to_form_internal(const Env& env) const {
|
||||
std::vector<goos::Object> forms;
|
||||
forms.push_back(pretty_print::to_symbol("break"));
|
||||
@@ -690,9 +712,11 @@ void BreakElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
dead_code->apply_form(f);
|
||||
}
|
||||
|
||||
void BreakElement::collect_vars(RegAccessSet& vars) const {
|
||||
return_code->collect_vars(vars);
|
||||
dead_code->collect_vars(vars);
|
||||
void BreakElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
return_code->collect_vars(vars, recursive);
|
||||
dead_code->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void BreakElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -705,6 +729,15 @@ void BreakElement::get_modified_regs(RegSet& regs) const {
|
||||
// CondWithElseElement
|
||||
/////////////////////////////
|
||||
|
||||
CondWithElseElement::CondWithElseElement(std::vector<Entry> _entries, Form* _else_ir)
|
||||
: entries(std::move(_entries)), else_ir(_else_ir) {
|
||||
for (auto& e : entries) {
|
||||
e.condition->parent_element = this;
|
||||
e.body->parent_element = this;
|
||||
}
|
||||
else_ir->parent_element = this;
|
||||
}
|
||||
|
||||
goos::Object CondWithElseElement::to_form_internal(const Env& env) const {
|
||||
// for now we only turn it into an if statement if both cases won't require a begin at the top
|
||||
// level. I think it is more common to write these as a two-case cond instead of an if with begin.
|
||||
@@ -750,12 +783,14 @@ void CondWithElseElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
else_ir->apply_form(f);
|
||||
}
|
||||
|
||||
void CondWithElseElement::collect_vars(RegAccessSet& vars) const {
|
||||
for (auto& entry : entries) {
|
||||
entry.condition->collect_vars(vars);
|
||||
entry.body->collect_vars(vars);
|
||||
void CondWithElseElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
for (auto& entry : entries) {
|
||||
entry.condition->collect_vars(vars, recursive);
|
||||
entry.body->collect_vars(vars, recursive);
|
||||
}
|
||||
else_ir->collect_vars(vars, recursive);
|
||||
}
|
||||
else_ir->collect_vars(vars);
|
||||
}
|
||||
|
||||
void CondWithElseElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -779,13 +814,18 @@ void EmptyElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
}
|
||||
|
||||
void EmptyElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
void EmptyElement::collect_vars(RegAccessSet&) const {}
|
||||
void EmptyElement::collect_vars(RegAccessSet&, bool) const {}
|
||||
void EmptyElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
/////////////////////////////
|
||||
// WhileElement
|
||||
/////////////////////////////
|
||||
|
||||
WhileElement::WhileElement(Form* _condition, Form* _body) : condition(_condition), body(_body) {
|
||||
condition->parent_element = this;
|
||||
body->parent_element = this;
|
||||
}
|
||||
|
||||
void WhileElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
// note - this is done in program order, rather than print order. Not sure if this makes sense.
|
||||
f(this);
|
||||
@@ -806,9 +846,11 @@ void WhileElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
condition->apply_form(f);
|
||||
}
|
||||
|
||||
void WhileElement::collect_vars(RegAccessSet& vars) const {
|
||||
body->collect_vars(vars);
|
||||
condition->collect_vars(vars);
|
||||
void WhileElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
body->collect_vars(vars, recursive);
|
||||
condition->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void WhileElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -820,6 +862,11 @@ void WhileElement::get_modified_regs(RegSet& regs) const {
|
||||
// UntilElement
|
||||
/////////////////////////////
|
||||
|
||||
UntilElement::UntilElement(Form* _condition, Form* _body) : condition(_condition), body(_body) {
|
||||
condition->parent_element = this;
|
||||
body->parent_element = this;
|
||||
}
|
||||
|
||||
void UntilElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
// note - this is done in program order, rather than print order. Not sure if this makes sense.
|
||||
f(this);
|
||||
@@ -840,9 +887,11 @@ void UntilElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
condition->apply_form(f);
|
||||
}
|
||||
|
||||
void UntilElement::collect_vars(RegAccessSet& vars) const {
|
||||
body->collect_vars(vars);
|
||||
condition->collect_vars(vars);
|
||||
void UntilElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
body->collect_vars(vars, recursive);
|
||||
condition->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void UntilElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -854,6 +903,13 @@ void UntilElement::get_modified_regs(RegSet& regs) const {
|
||||
// ShortCircuitElement
|
||||
/////////////////////////////
|
||||
|
||||
ShortCircuitElement::ShortCircuitElement(std::vector<Entry> _entries)
|
||||
: entries(std::move(_entries)) {
|
||||
for (auto& entry : entries) {
|
||||
entry.condition->parent_element = this;
|
||||
}
|
||||
}
|
||||
|
||||
void ShortCircuitElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
f(this);
|
||||
for (auto& x : entries) {
|
||||
@@ -896,10 +952,12 @@ goos::Object ShortCircuitElement::to_form_internal(const Env& env) const {
|
||||
return pretty_print::build_list(forms);
|
||||
}
|
||||
|
||||
void ShortCircuitElement::collect_vars(RegAccessSet& vars) const {
|
||||
void ShortCircuitElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
// vars.insert(final_result); // todo - this might be unused.
|
||||
for (auto& entry : entries) {
|
||||
entry.condition->collect_vars(vars);
|
||||
if (recursive) {
|
||||
for (auto& entry : entries) {
|
||||
entry.condition->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -913,6 +971,13 @@ void ShortCircuitElement::get_modified_regs(RegSet& regs) const {
|
||||
// CondNoElseElement
|
||||
/////////////////////////////
|
||||
|
||||
CondNoElseElement::CondNoElseElement(std::vector<Entry> _entries) : entries(std::move(_entries)) {
|
||||
for (auto& entry : entries) {
|
||||
entry.condition->parent_element = this;
|
||||
entry.body->parent_element = this;
|
||||
}
|
||||
}
|
||||
|
||||
goos::Object CondNoElseElement::to_form_internal(const Env& env) const {
|
||||
if (entries.size() == 1 && entries.front().body->is_single_element()) {
|
||||
// print as an if statement if we can put the body in a single form.
|
||||
@@ -958,10 +1023,12 @@ void CondNoElseElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
}
|
||||
}
|
||||
|
||||
void CondNoElseElement::collect_vars(RegAccessSet& vars) const {
|
||||
for (auto& e : entries) {
|
||||
e.condition->collect_vars(vars);
|
||||
e.body->collect_vars(vars);
|
||||
void CondNoElseElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
for (auto& e : entries) {
|
||||
e.condition->collect_vars(vars, recursive);
|
||||
e.body->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,7 +1056,7 @@ void AbsElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void AbsElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void AbsElement::collect_vars(RegAccessSet& vars) const {
|
||||
void AbsElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
vars.insert(source);
|
||||
}
|
||||
|
||||
@@ -1021,7 +1088,7 @@ void AshElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void AshElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void AshElement::collect_vars(RegAccessSet& vars) const {
|
||||
void AshElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
vars.insert(value);
|
||||
vars.insert(shift_amount);
|
||||
}
|
||||
@@ -1050,8 +1117,10 @@ void TypeOfElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
value->apply_form(f);
|
||||
}
|
||||
|
||||
void TypeOfElement::collect_vars(RegAccessSet& vars) const {
|
||||
value->collect_vars(vars);
|
||||
void TypeOfElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
value->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeOfElement::get_modified_regs(RegSet&) const {}
|
||||
@@ -1077,7 +1146,7 @@ void ConditionalMoveFalseElement::apply(const std::function<void(FormElement*)>&
|
||||
|
||||
void ConditionalMoveFalseElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void ConditionalMoveFalseElement::collect_vars(RegAccessSet& vars) const {
|
||||
void ConditionalMoveFalseElement::collect_vars(RegAccessSet& vars, bool) const {
|
||||
vars.insert(dest);
|
||||
vars.insert(old_value);
|
||||
vars.insert(source);
|
||||
@@ -1112,13 +1181,15 @@ GenericOperator GenericOperator::make_compare(IR2_Condition::Kind kind) {
|
||||
return op;
|
||||
}
|
||||
|
||||
void GenericOperator::collect_vars(RegAccessSet& vars) const {
|
||||
void GenericOperator::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
switch (m_kind) {
|
||||
case Kind::FIXED_OPERATOR:
|
||||
case Kind::CONDITION_OPERATOR:
|
||||
return;
|
||||
case Kind::FUNCTION_EXPR:
|
||||
m_function->collect_vars(vars);
|
||||
if (recursive) {
|
||||
m_function->collect_vars(vars, recursive);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
assert(false);
|
||||
@@ -1324,6 +1395,7 @@ goos::Object GenericElement::to_form_internal(const Env& env) const {
|
||||
std::vector<goos::Object> result;
|
||||
result.push_back(m_head.to_form(env));
|
||||
for (auto x : m_elts) {
|
||||
assert(x->parent_element);
|
||||
result.push_back(x->to_form(env));
|
||||
}
|
||||
return pretty_print::build_list(result);
|
||||
@@ -1345,10 +1417,12 @@ void GenericElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
}
|
||||
}
|
||||
|
||||
void GenericElement::collect_vars(RegAccessSet& vars) const {
|
||||
m_head.collect_vars(vars);
|
||||
for (auto x : m_elts) {
|
||||
x->collect_vars(vars);
|
||||
void GenericElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
m_head.collect_vars(vars, recursive);
|
||||
for (auto x : m_elts) {
|
||||
x->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1382,8 +1456,10 @@ void CastElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
m_source->apply_form(f);
|
||||
}
|
||||
|
||||
void CastElement::collect_vars(RegAccessSet& vars) const {
|
||||
m_source->collect_vars(vars);
|
||||
void CastElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
m_source->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void CastElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -1421,14 +1497,16 @@ DerefToken DerefToken::make_expr_placeholder() {
|
||||
return x;
|
||||
}
|
||||
|
||||
void DerefToken::collect_vars(RegAccessSet& vars) const {
|
||||
void DerefToken::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
switch (m_kind) {
|
||||
case Kind::INTEGER_CONSTANT:
|
||||
case Kind::FIELD_NAME:
|
||||
case Kind::EXPRESSION_PLACEHOLDER:
|
||||
break;
|
||||
case Kind::INTEGER_EXPRESSION:
|
||||
m_expr->collect_vars(vars);
|
||||
if (recursive) {
|
||||
m_expr->collect_vars(vars, recursive);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
@@ -1527,6 +1605,7 @@ DerefElement::DerefElement(Form* base, bool is_addr_of, std::vector<DerefToken>
|
||||
}
|
||||
|
||||
goos::Object DerefElement::to_form_internal(const Env& env) const {
|
||||
assert(m_base->parent_element);
|
||||
std::vector<goos::Object> forms = {pretty_print::to_symbol(m_is_addr_of ? "&->" : "->"),
|
||||
m_base->to_form(env)};
|
||||
for (auto& tok : m_tokens) {
|
||||
@@ -1550,10 +1629,12 @@ void DerefElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
}
|
||||
}
|
||||
|
||||
void DerefElement::collect_vars(RegAccessSet& vars) const {
|
||||
m_base->collect_vars(vars);
|
||||
for (auto& tok : m_tokens) {
|
||||
tok.collect_vars(vars);
|
||||
void DerefElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
m_base->collect_vars(vars, recursive);
|
||||
for (auto& tok : m_tokens) {
|
||||
tok.collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1564,6 +1645,11 @@ void DerefElement::get_modified_regs(RegSet& regs) const {
|
||||
}
|
||||
}
|
||||
|
||||
void DerefElement::set_base(Form* new_base) {
|
||||
m_base = new_base;
|
||||
m_base->parent_element = this;
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
// DynamicMethodAccess
|
||||
/////////////////////////////
|
||||
@@ -1580,7 +1666,7 @@ void DynamicMethodAccess::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void DynamicMethodAccess::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void DynamicMethodAccess::collect_vars(RegAccessSet& vars) const {
|
||||
void DynamicMethodAccess::collect_vars(RegAccessSet& vars, bool) const {
|
||||
vars.insert(m_source);
|
||||
}
|
||||
|
||||
@@ -1596,7 +1682,13 @@ ArrayFieldAccess::ArrayFieldAccess(RegisterAccess source,
|
||||
: m_source(source),
|
||||
m_deref_tokens(deref_tokens),
|
||||
m_expected_stride(expected_stride),
|
||||
m_constant_offset(constant_offset) {}
|
||||
m_constant_offset(constant_offset) {
|
||||
for (auto& token : m_deref_tokens) {
|
||||
if (token.kind() == DerefToken::Kind::INTEGER_EXPRESSION) {
|
||||
token.expr()->parent_element = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goos::Object ArrayFieldAccess::to_form_internal(const Env& env) const {
|
||||
std::vector<goos::Object> elts;
|
||||
@@ -1621,10 +1713,12 @@ void ArrayFieldAccess::apply_form(const std::function<void(Form*)>& f) {
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayFieldAccess::collect_vars(RegAccessSet& vars) const {
|
||||
void ArrayFieldAccess::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
vars.insert(m_source);
|
||||
for (auto& tok : m_deref_tokens) {
|
||||
tok.collect_vars(vars);
|
||||
if (recursive) {
|
||||
for (auto& tok : m_deref_tokens) {
|
||||
tok.collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1657,8 +1751,10 @@ void GetMethodElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
m_in->apply_form(f);
|
||||
}
|
||||
|
||||
void GetMethodElement::collect_vars(RegAccessSet& vars) const {
|
||||
m_in->collect_vars(vars);
|
||||
void GetMethodElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
m_in->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void GetMethodElement::get_modified_regs(RegSet& regs) const {
|
||||
@@ -1677,7 +1773,7 @@ goos::Object StringConstantElement::to_form_internal(const Env&) const {
|
||||
|
||||
void StringConstantElement::apply(const std::function<void(FormElement*)>&) {}
|
||||
void StringConstantElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
void StringConstantElement::collect_vars(RegAccessSet&) const {}
|
||||
void StringConstantElement::collect_vars(RegAccessSet&, bool) const {}
|
||||
void StringConstantElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
/////////////////////////////
|
||||
@@ -1691,7 +1787,7 @@ goos::Object ConstantTokenElement::to_form_internal(const Env&) const {
|
||||
|
||||
void ConstantTokenElement::apply(const std::function<void(FormElement*)>&) {}
|
||||
void ConstantTokenElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
void ConstantTokenElement::collect_vars(RegAccessSet&) const {}
|
||||
void ConstantTokenElement::collect_vars(RegAccessSet&, bool) const {}
|
||||
void ConstantTokenElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
/////////////////////////////
|
||||
@@ -1702,13 +1798,17 @@ ConstantFloatElement::ConstantFloatElement(float value) : m_value(value) {}
|
||||
|
||||
void ConstantFloatElement::apply(const std::function<void(FormElement*)>&) {}
|
||||
void ConstantFloatElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
void ConstantFloatElement::collect_vars(RegAccessSet&) const {}
|
||||
void ConstantFloatElement::collect_vars(RegAccessSet&, bool) const {}
|
||||
void ConstantFloatElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
goos::Object ConstantFloatElement::to_form_internal(const Env&) const {
|
||||
return pretty_print::float_representation(m_value);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
// StorePlainDeref
|
||||
/////////////////////////////
|
||||
|
||||
StorePlainDeref::StorePlainDeref(DerefElement* dst,
|
||||
SimpleExpression expr,
|
||||
int my_idx,
|
||||
@@ -1736,15 +1836,19 @@ void StorePlainDeref::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void StorePlainDeref::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void StorePlainDeref::collect_vars(RegAccessSet& vars) const {
|
||||
void StorePlainDeref::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
m_expr.collect_vars(vars);
|
||||
m_dst->collect_vars(vars);
|
||||
m_dst->collect_vars(vars, recursive);
|
||||
}
|
||||
|
||||
void StorePlainDeref::get_modified_regs(RegSet& regs) const {
|
||||
m_dst->get_modified_regs(regs);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
// StoreArrayAccess
|
||||
/////////////////////////////
|
||||
|
||||
StoreArrayAccess::StoreArrayAccess(ArrayFieldAccess* dst,
|
||||
SimpleExpression expr,
|
||||
int my_idx,
|
||||
@@ -1765,15 +1869,19 @@ void StoreArrayAccess::apply_form(const std::function<void(Form*)>& f) {
|
||||
m_dst->apply_form(f);
|
||||
}
|
||||
|
||||
void StoreArrayAccess::collect_vars(RegAccessSet& vars) const {
|
||||
void StoreArrayAccess::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
m_expr.collect_vars(vars);
|
||||
m_dst->collect_vars(vars);
|
||||
m_dst->collect_vars(vars, recursive);
|
||||
}
|
||||
|
||||
void StoreArrayAccess::get_modified_regs(RegSet& regs) const {
|
||||
m_dst->get_modified_regs(regs);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
// DecompiledDataElement
|
||||
/////////////////////////////
|
||||
|
||||
DecompiledDataElement::DecompiledDataElement(goos::Object description)
|
||||
: m_description(std::move(description)) {}
|
||||
|
||||
@@ -1787,8 +1895,78 @@ void DecompiledDataElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
|
||||
void DecompiledDataElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
|
||||
void DecompiledDataElement::collect_vars(RegAccessSet&) const {}
|
||||
void DecompiledDataElement::collect_vars(RegAccessSet&, bool) const {}
|
||||
|
||||
void DecompiledDataElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
/////////////////////////////
|
||||
// LetElement
|
||||
/////////////////////////////
|
||||
|
||||
LetElement::LetElement(Form* body, bool star) : m_body(body), m_star(star) {
|
||||
m_body->parent_element = this;
|
||||
}
|
||||
|
||||
void LetElement::add_def(RegisterAccess dst, Form* value) {
|
||||
value->parent_element = this;
|
||||
m_entries.push_back({dst, value});
|
||||
}
|
||||
|
||||
void LetElement::make_let_star() {
|
||||
m_star = true;
|
||||
}
|
||||
|
||||
goos::Object LetElement::to_form_internal(const Env& env) const {
|
||||
std::vector<goos::Object> outer = {pretty_print::to_symbol(m_star ? "let*" : "let")};
|
||||
|
||||
std::vector<goos::Object> def_list;
|
||||
|
||||
for (auto& entry : m_entries) {
|
||||
def_list.push_back(pretty_print::build_list(entry.dest.to_form(env), entry.src->to_form(env)));
|
||||
}
|
||||
|
||||
outer.push_back(pretty_print::build_list(def_list));
|
||||
m_body->inline_forms(outer, env);
|
||||
return pretty_print::build_list(outer);
|
||||
}
|
||||
|
||||
void LetElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
f(this);
|
||||
for (auto& entry : m_entries) {
|
||||
entry.src->apply(f);
|
||||
}
|
||||
m_body->apply(f);
|
||||
}
|
||||
|
||||
void LetElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
for (auto& entry : m_entries) {
|
||||
entry.src->apply_form(f);
|
||||
}
|
||||
m_body->apply_form(f);
|
||||
}
|
||||
|
||||
void LetElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
for (auto& entry : m_entries) {
|
||||
vars.insert(entry.dest);
|
||||
}
|
||||
m_body->collect_vars(vars, recursive);
|
||||
}
|
||||
|
||||
void LetElement::get_modified_regs(RegSet& regs) const {
|
||||
for (auto& entry : m_entries) {
|
||||
regs.insert(entry.dest.reg());
|
||||
}
|
||||
m_body->get_modified_regs(regs);
|
||||
}
|
||||
|
||||
void LetElement::add_entry(const Entry& e) {
|
||||
e.src->parent_element = this;
|
||||
m_entries.push_back(e);
|
||||
}
|
||||
|
||||
void LetElement::set_body(Form* new_body) {
|
||||
m_body = new_body;
|
||||
m_body->parent_element = this;
|
||||
}
|
||||
|
||||
} // namespace decompiler
|
||||
|
||||
Reference in New Issue
Block a user