[gcommon decomp] compiler and decompiler fixes (#239)

* wip

* decompile file-io

* a

* fix
This commit is contained in:
water111
2021-02-07 18:21:00 -05:00
committed by GitHub
parent f8b63a3f92
commit e01e065170
31 changed files with 925 additions and 164 deletions
+44 -1
View File
@@ -150,6 +150,30 @@ void clean_up_return(FormPool& pool, ReturnElement* ir) {
}
}
void clean_up_return_final(const Function& f, ReturnElement* ir) {
SetVarElement* dead = dynamic_cast<SetVarElement*>(ir->dead_code->try_as_single_element());
if (!dead) {
dead = dynamic_cast<SetVarElement*>(ir->dead_code->elts().front());
for (int i = 1; i < ir->dead_code->size(); i++) {
if (!dynamic_cast<EmptyElement*>(ir->dead_code->at(i))) {
dead = nullptr;
break;
}
}
}
if (!dead) {
lg::error("failed to recognize dead code after return, got {}",
ir->dead_code->to_string(f.ir2.env));
}
assert(dead);
auto src = dynamic_cast<SimpleExpressionElement*>(dead->src()->try_as_single_element());
assert(src);
assert(src->expr().is_identity() && src->expr().get_arg(0).is_int() &&
src->expr().get_arg(0).get_int() == 0);
ir->dead_code = nullptr;
}
/*!
* Remove the branch in a break (really return-from nonfunction scope)
*/
@@ -1355,8 +1379,22 @@ Form* cfg_to_ir(FormPool& pool, Function& f, const CfgVtx* vtx) {
return result;
} else if (dynamic_cast<const GotoEnd*>(vtx)) {
auto* cvtx = dynamic_cast<const GotoEnd*>(vtx);
// dead code should always be (set! var 0)
auto dead_code = cfg_to_ir(pool, f, cvtx->unreachable_block);
// auto dead = dynamic_cast<SetVarElement*>(dead_code->try_as_single_element());
// if (!dead) {
// lg::error("failed to recognize dead code after return, got {}",
// dead_code->to_string(f.ir2.env));
// }
// assert(dead);
// auto src = dynamic_cast<SimpleExpressionElement*>(dead->src()->try_as_single_element());
// assert(src);
// assert(src->expr().is_identity() && src->expr().get_arg(0).is_int() &&
// src->expr().get_arg(0).get_int() == 0);
auto result = pool.alloc_single_element_form<ReturnElement>(
nullptr, cfg_to_ir(pool, f, cvtx->body), cfg_to_ir(pool, f, cvtx->unreachable_block));
nullptr, cfg_to_ir(pool, f, cvtx->body), dead_code);
clean_up_return(pool, dynamic_cast<ReturnElement*>(result->try_as_single_element()));
return result;
} else if (dynamic_cast<const Break*>(vtx)) {
@@ -1433,6 +1471,11 @@ void build_initial_forms(Function& function) {
if (as_cne) {
clean_up_cond_no_else_final(function, as_cne);
}
auto as_return = dynamic_cast<ReturnElement*>(form);
if (as_return) {
clean_up_return_final(function, as_return);
}
});
function.ir2.top_form = result;