recognize dotimes (#310)

This commit is contained in:
water111 2021-03-05 21:46:39 -05:00 committed by GitHub
parent 65ffe83468
commit b352dcefa9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 408 additions and 337 deletions

View file

@ -148,6 +148,7 @@ class SimpleAtom {
return m_int;
}
bool is_int() const { return m_kind == Kind::INTEGER_CONSTANT; };
bool is_int(s64 integer) const { return is_int() && get_int() == integer; }
bool is_sym_ptr() const { return m_kind == Kind::SYMBOL_PTR; };
bool is_sym_val() const { return m_kind == Kind::SYMBOL_VAL; };
bool is_empty_list() const { return m_kind == Kind::EMPTY_LIST; };

View file

@ -1969,4 +1969,74 @@ void LetElement::set_body(Form* new_body) {
m_body->parent_element = this;
}
/////////////////////////////
// DoTimesElement
/////////////////////////////
DoTimesElement::DoTimesElement(RegisterAccess var_init,
RegisterAccess var_check,
RegisterAccess var_inc,
Form* check_value,
Form* body)
: m_var_init(var_init),
m_var_check(var_check),
m_var_inc(var_inc),
m_check_value(check_value),
m_body(body) {
m_body->parent_element = this;
m_check_value->parent_element = this;
assert(m_var_inc.reg() == m_var_check.reg());
assert(m_var_init.reg() == m_var_inc.reg());
}
goos::Object DoTimesElement::to_form_internal(const Env& env) const {
std::vector<goos::Object> outer = {
pretty_print::to_symbol("dotimes"),
pretty_print::build_list(m_var_init.to_form(env), m_check_value->to_form(env))};
m_body->inline_forms(outer, env);
return pretty_print::build_list(outer);
}
void DoTimesElement::apply(const std::function<void(FormElement*)>& f) {
f(this);
m_check_value->apply(f);
m_body->apply(f);
}
void DoTimesElement::apply_form(const std::function<void(Form*)>& f) {
m_check_value->apply_form(f);
m_body->apply_form(f);
}
void DoTimesElement::collect_vars(RegAccessSet& vars, bool recursive) const {
vars.insert(m_var_init);
vars.insert(m_var_check);
vars.insert(m_var_inc);
if (recursive) {
m_body->collect_vars(vars, recursive);
m_check_value->collect_vars(vars, recursive);
}
}
void DoTimesElement::get_modified_regs(RegSet& regs) const {
regs.insert(m_var_inc.reg());
m_body->get_modified_regs(regs);
m_check_value->get_modified_regs(regs);
}
std::optional<SimpleAtom> form_as_atom(const Form* f) {
auto as_single = f->try_as_single_element();
auto as_atom = dynamic_cast<SimpleAtomElement*>(as_single);
if (as_atom) {
return as_atom->atom();
}
auto as_se = dynamic_cast<SimpleExpressionElement*>(as_single);
if (as_se && as_se->expr().is_identity()) {
return as_se->expr().get_arg(0);
}
return {};
}
} // namespace decompiler

View file

@ -1162,6 +1162,25 @@ class LetElement : public FormElement {
bool m_star = false;
};
class DoTimesElement : public FormElement {
public:
DoTimesElement(RegisterAccess var_init,
RegisterAccess var_check,
RegisterAccess var_inc,
Form* check_value,
Form* body);
goos::Object to_form_internal(const Env& env) const override;
void apply(const std::function<void(FormElement*)>& f) override;
void apply_form(const std::function<void(Form*)>& f) override;
void collect_vars(RegAccessSet& vars, bool recursive) const override;
void get_modified_regs(RegSet& regs) const override;
private:
RegisterAccess m_var_init, m_var_check, m_var_inc;
Form* m_check_value = nullptr;
Form* m_body = nullptr;
};
/*!
* A Form is a wrapper around one or more FormElements.
* This is done for two reasons:
@ -1306,4 +1325,6 @@ class FormPool {
std::vector<Form*> m_forms;
std::vector<FormElement*> m_elements;
};
std::optional<SimpleAtom> form_as_atom(const Form* f);
} // namespace decompiler

View file

@ -123,6 +123,13 @@ Matcher Matcher::set(const Matcher& dst, const Matcher& src) {
return m;
}
Matcher Matcher::while_loop(const Matcher& condition, const Matcher& body) {
Matcher m;
m.m_kind = Kind::WHILE_LOOP;
m.m_sub_matchers = {condition, body};
return m;
}
bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out) const {
switch (m_kind) {
case Kind::ANY:
@ -432,6 +439,22 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out) const {
return true;
} break;
case Kind::WHILE_LOOP: {
auto as_while = dynamic_cast<WhileElement*>(input->try_as_single_element());
if (!as_while) {
return false;
}
if (!m_sub_matchers.at(0).do_match(as_while->condition, maps_out)) {
return false;
}
if (!m_sub_matchers.at(1).do_match(as_while->body, maps_out)) {
return false;
}
return true;
} break;
default:
assert(false);
return false;

View file

@ -45,6 +45,7 @@ class Matcher {
static Matcher if_with_else(const Matcher& condition,
const Matcher& true_case,
const Matcher& false_case);
static Matcher while_loop(const Matcher& condition, const Matcher& body);
enum class Kind {
ANY_REG, // matching any register
@ -62,6 +63,7 @@ class Matcher {
ANY_LABEL,
SYMBOL,
IF_WITH_ELSE,
WHILE_LOOP,
INVALID
};

View file

@ -1,6 +1,7 @@
#include <algorithm>
#include "insert_lets.h"
#include "decompiler/IR2/GenericElementMatcher.h"
namespace decompiler {
@ -79,6 +80,101 @@ Form* lca_form(Form* a, Form* b, const Env& env) {
// fmt::print("{}\n\n", result->to_string(env));
return result;
}
bool is_constant_int(const Form* f, int val) {
auto as_atom = form_as_atom(f);
return as_atom && as_atom->is_int(val);
}
FormElement* rewrite_as_dotimes(LetElement* in, const Env& env, FormPool& pool) {
// dotimes OpenGOAL:
/*
(defmacro dotimes (var &rest body)
"Loop like for (int i = 0; i < end; i++)"
`(let ((,(first var) 0))
(while (< ,(first var) ,(second var))
,@body
(+1! ,(first var))
)
,@(cddr var)
)
)
*/
// should have this anyway, but double check so we don't throw this away.
if (in->entries().size() != 1) {
return nullptr;
}
// look for setting a var to zero.
auto ra = in->entries().at(0).dest;
auto var = env.get_variable_name(ra);
if (!is_constant_int(in->entries().at(0).src, 0)) {
return nullptr;
}
// still have to check body for the increment and have to check that the lt operates on the right
// thing.
Matcher while_matcher =
Matcher::while_loop(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::LT),
{Matcher::any_reg(0), Matcher::any(1)}),
Matcher::any(2));
auto mr = match(while_matcher, in->body());
if (!mr.matched) {
return nullptr;
}
// check the lt operation:
auto lt_var = mr.maps.regs.at(0);
assert(lt_var);
if (env.get_variable_name(*lt_var) != var) {
return nullptr; // wrong variable checked
}
// check the body
auto body = mr.maps.forms.at(2);
auto last_in_body = body->elts().back();
// kind hacky
Form fake_form;
fake_form.elts().push_back(last_in_body);
Matcher increment_matcher =
Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::ADDITION_IN_PLACE),
{Matcher::any_reg(0), Matcher::integer(1)});
auto int_mr = match(increment_matcher, &fake_form);
if (!int_mr.matched) {
return nullptr;
}
auto inc_var = int_mr.maps.regs.at(0);
assert(inc_var);
if (env.get_variable_name(*inc_var) != var) {
return nullptr; // wrong variable incremented
}
// success! here we commit to modifying this:
// first, remove the increment
body->pop_back();
return pool.alloc_element<DoTimesElement>(in->entries().at(0).dest, *lt_var, *inc_var,
mr.maps.forms.at(1), body);
}
/*!
* Attempt to rewrite a let as another form. If it cannot be rewritten, this will return nullptr.
*/
FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool) {
auto as_dotimes = rewrite_as_dotimes(in, env, pool);
if (as_dotimes) {
return as_dotimes;
}
// nothing matched.
return nullptr;
}
} // namespace
LetStats insert_lets(const Function& func, Env& env, FormPool& pool, Form* top_level_form) {
@ -296,7 +392,19 @@ LetStats insert_lets(const Function& func, Env& env, FormPool& pool, Form* top_l
group.first->claim_all_children();
}
// Part 8: (todo) recognize loops and stuff.
// Part 8: recognize loop forms
top_level_form->apply_form([&](Form* f) {
for (auto& elt : f->elts()) {
auto as_let = dynamic_cast<LetElement*>(elt);
if (as_let) {
auto rewritten = rewrite_let(as_let, env, pool);
if (rewritten) {
rewritten->parent_form = f;
elt = rewritten;
}
}
}
});
// Part 9: compact recursive lets:
bool changed = true;

View file

@ -255,10 +255,7 @@
;; definition for function ref
(defun ref ((lst object) (index int))
(let
((count 0))
(while (< count index) (nop!) (nop!) (set! lst (cdr lst)) (+! count 1))
)
(dotimes (count index) (nop!) (nop!) (set! lst (cdr lst)))
(car lst)
)
@ -901,15 +898,11 @@
(defun mem-copy! ((dst pointer) (src pointer) (size int))
(let
((result dst))
(let
((i 0))
(while
(< i size)
(set! (-> (the-as (pointer int8) dst)) (-> (the-as (pointer uint8) src)))
(&+! dst 1)
(&+! src 1)
(+! i 1)
)
(dotimes
(i size)
(set! (-> (the-as (pointer int8) dst)) (-> (the-as (pointer uint8) src)))
(&+! dst 1)
(&+! src 1)
)
result
)
@ -961,15 +954,11 @@
(defun mem-set32! ((dst pointer) (size int) (value int))
(let
((result dst))
(let
((i 0))
(while
(< i size)
(set! (-> (the-as (pointer int32) dst)) value)
(&+! dst 4)
(nop!)
(+! i 1)
)
(dotimes
(i size)
(set! (-> (the-as (pointer int32) dst)) value)
(&+! dst 4)
(nop!)
)
result
)
@ -979,21 +968,17 @@
(defun mem-or! ((dst pointer) (src pointer) (size int))
(let
((result dst))
(let
((i 0))
(while
(< i size)
(set!
(-> (the-as (pointer int8) dst))
(logior
(-> (the-as (pointer uint8) dst))
(-> (the-as (pointer uint8) src))
)
(dotimes
(i size)
(set!
(-> (the-as (pointer int8) dst))
(logior
(-> (the-as (pointer uint8) dst))
(-> (the-as (pointer uint8) src))
)
(&+! dst 1)
(&+! src 1)
(+! i 1)
)
(&+! dst 1)
(&+! src 1)
)
result
)
@ -1029,20 +1014,16 @@
;; definition (debug) for function mem-print
(defun-debug mem-print ((data (pointer uint32)) (word-count int))
(let
((current-qword 0))
(while
(< current-qword (sar word-count 2))
(format
0
"~X: ~X ~X ~X ~X~%"
(&-> data (shl current-qword 2))
(-> data (shl current-qword 2))
(-> data (+ (shl current-qword 2) 1))
(-> data (+ (shl current-qword 2) 2))
(-> data (+ (shl current-qword 2) 3))
)
(+! current-qword 1)
(dotimes
(current-qword (sar word-count 2))
(format
0
"~X: ~X ~X ~X ~X~%"
(&-> data (shl current-qword 2))
(-> data (shl current-qword 2))
(-> data (+ (shl current-qword 2) 1))
(-> data (+ (shl current-qword 2) 2))
(-> data (+ (shl current-qword 2) 3))
)
)
#f
@ -1053,14 +1034,10 @@
;; definition for function print-tree-bitmask
(defun print-tree-bitmask ((bits int) (count int))
(let
((i 0))
(while
(< i count)
(if (zero? (logand bits 1)) (format #t " ") (format #t "| "))
(set! bits (shr bits 1))
(+! i 1)
)
(dotimes
(i count)
(if (zero? (logand bits 1)) (format #t " ") (format #t "| "))
(set! bits (shr bits 1))
)
#f
)

View file

@ -650,13 +650,7 @@ TEST_F(FormRegressionTest, ExprRef) {
std::string type = "(function object int object)";
std::string expected =
"(begin\n"
" (let\n"
" ((v1-0 0))\n"
" (while (< v1-0 arg1) (nop!) (nop!) (set! arg0 (cdr arg0)) (+! v1-0 1))\n"
" )\n"
" (car arg0)\n"
" )";
"(begin (dotimes (v1-0 arg1) (nop!) (nop!) (set! arg0 (cdr arg0))) (car arg0))";
test_with_expr(func, type, expected, true, "");
}
@ -1862,15 +1856,11 @@ TEST_F(FormRegressionTest, ExprMemCopy) {
std::string expected =
"(let\n"
" ((v0-0 arg0))\n"
" (let\n"
" ((v1-0 0))\n"
" (while\n"
" (< v1-0 arg2)\n"
" (set! (-> (the-as (pointer int8) arg0)) (-> (the-as (pointer uint8) arg1)))\n"
" (&+! arg0 1)\n"
" (&+! arg1 1)\n"
" (+! v1-0 1)\n"
" )\n"
" (dotimes\n"
" (v1-0 arg2)\n"
" (set! (-> (the-as (pointer int8) arg0)) (-> (the-as (pointer uint8) arg1)))\n"
" (&+! arg0 1)\n"
" (&+! arg1 1)\n"
" )\n"
" v0-0\n"
" )";
@ -1905,15 +1895,11 @@ TEST_F(FormRegressionTest, ExprMemSet32) {
std::string expected =
"(let\n"
" ((v0-0 arg0))\n"
" (let\n"
" ((v1-0 0))\n"
" (while\n"
" (< v1-0 arg1)\n"
" (set! (-> (the-as (pointer int32) arg0)) arg2)\n"
" (&+! arg0 4)\n"
" (nop!)\n"
" (+! v1-0 1)\n"
" )\n"
" (dotimes\n"
" (v1-0 arg1)\n"
" (set! (-> (the-as (pointer int32) arg0)) arg2)\n"
" (&+! arg0 4)\n"
" (nop!)\n"
" )\n"
" v0-0\n"
" )";
@ -1951,21 +1937,17 @@ TEST_F(FormRegressionTest, ExprMemOr) {
std::string expected =
"(let\n"
" ((v0-0 arg0))\n"
" (let\n"
" ((v1-0 0))\n"
" (while\n"
" (< v1-0 arg2)\n"
" (set!\n"
" (-> (the-as (pointer int8) arg0))\n"
" (logior\n"
" (-> (the-as (pointer uint8) arg0))\n"
" (-> (the-as (pointer uint8) arg1))\n"
" )\n"
" (dotimes\n"
" (v1-0 arg2)\n"
" (set!\n"
" (-> (the-as (pointer int8) arg0))\n"
" (logior\n"
" (-> (the-as (pointer uint8) arg0))\n"
" (-> (the-as (pointer uint8) arg1))\n"
" )\n"
" (&+! arg0 1)\n"
" (&+! arg1 1)\n"
" (+! v1-0 1)\n"
" )\n"
" (&+! arg0 1)\n"
" (&+! arg1 1)\n"
" )\n"
" v0-0\n"
" )";
@ -2171,14 +2153,10 @@ TEST_F(FormRegressionTest, ExprPrintTreeBitmask) {
std::string expected =
"(begin\n"
" (let\n"
" ((s4-0 0))\n"
" (while\n"
" (< s4-0 arg1)\n"
" (if (zero? (logand arg0 1)) (format #t \" \") (format #t \"| \"))\n"
" (set! arg0 (shr arg0 1))\n"
" (+! s4-0 1)\n"
" )\n"
" (dotimes\n"
" (s4-0 arg1)\n"
" (if (zero? (logand arg0 1)) (format #t \" \") (format #t \"| \"))\n"
" (set! arg0 (shr arg0 1))\n"
" )\n"
" #f\n"
" )";
@ -2494,15 +2472,13 @@ TEST_F(FormRegressionTest, StringLt) {
" ((method-of-type string length) arg1)\n"
" )\n"
" )\n"
" (v1-4 0)\n"
" )\n"
" (while\n"
" (< v1-4 s4-1)\n"
" (dotimes\n"
" (v1-4 s4-1)\n"
" (cond\n"
" ((< (-> arg0 data v1-4) (-> arg1 data v1-4)) (return #t))\n"
" ((< (-> arg1 data v1-4) (-> arg0 data v1-4)) (return #f))\n"
" )\n"
" (+! v1-4 1)\n"
" )\n"
" )\n"
" #f\n"

View file

@ -545,148 +545,107 @@ TEST_F(FormRegressionTest, ExprArrayMethod2) {
" ((v1-1 (-> arg0 content-type symbol)))\n"
" (cond\n"
" ((= v1-1 (quote int32))\n"
" (let\n"
" ((s5-0 0))\n"
" (while\n"
" (< s5-0 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-0) \"~D\" \" ~D\")\n"
" (-> (the-as (array int32) arg0) s5-0)\n"
" )\n"
" (+! s5-0 1)\n"
" (dotimes\n"
" (s5-0 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-0) \"~D\" \" ~D\")\n"
" (-> (the-as (array int32) arg0) s5-0)\n"
" )\n"
" )\n"
" )\n"
" ((= v1-1 (quote uint32))\n"
" (let\n"
" ((s5-1 0))\n"
" (while\n"
" (< s5-1 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-1) \"~D\" \" ~D\")\n"
" (-> (the-as (array uint32) arg0) s5-1)\n"
" )\n"
" (+! s5-1 1)\n"
" (dotimes\n"
" (s5-1 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-1) \"~D\" \" ~D\")\n"
" (-> (the-as (array uint32) arg0) s5-1)\n"
" )\n"
" )\n"
" )\n"
" ((= v1-1 (quote int64))\n"
" (let\n"
" ((s5-2 0))\n"
" (while\n"
" (< s5-2 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-2) \"~D\" \" ~D\")\n"
" (-> (the-as (array int64) arg0) s5-2)\n"
" )\n"
" (+! s5-2 1)\n"
" (dotimes\n"
" (s5-2 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-2) \"~D\" \" ~D\")\n"
" (-> (the-as (array int64) arg0) s5-2)\n"
" )\n"
" )\n"
" )\n"
" ((= v1-1 (quote uint64))\n"
" (let\n"
" ((s5-3 0))\n"
" (while\n"
" (< s5-3 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-3) \"#x~X\" \" #x~X\")\n"
" (-> (the-as (array uint64) arg0) s5-3)\n"
" )\n"
" (+! s5-3 1)\n"
" (dotimes\n"
" (s5-3 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-3) \"#x~X\" \" #x~X\")\n"
" (-> (the-as (array uint64) arg0) s5-3)\n"
" )\n"
" )\n"
" )\n"
" ((= v1-1 (quote int8))\n"
" (let\n"
" ((s5-4 0))\n"
" (while\n"
" (< s5-4 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-4) \"~D\" \" ~D\")\n"
" (-> (the-as (array int8) arg0) s5-4)\n"
" )\n"
" (+! s5-4 1)\n"
" (dotimes\n"
" (s5-4 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-4) \"~D\" \" ~D\")\n"
" (-> (the-as (array int8) arg0) s5-4)\n"
" )\n"
" )\n"
" )\n"
" ((= v1-1 (quote uint8))\n"
" (let\n"
" ((s5-5 0))\n"
" (while\n"
" (< s5-5 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-5) \"~D\" \" ~D\")\n"
" (-> (the-as (array uint8) arg0) s5-5)\n"
" )\n"
" (+! s5-5 1)\n"
" (dotimes\n"
" (s5-5 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-5) \"~D\" \" ~D\")\n"
" (-> (the-as (array uint8) arg0) s5-5)\n"
" )\n"
" )\n"
" )\n"
" ((= v1-1 (quote int16))\n"
" (let\n"
" ((s5-6 0))\n"
" (while\n"
" (< s5-6 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-6) \"~D\" \" ~D\")\n"
" (-> (the-as (array int16) arg0) s5-6)\n"
" )\n"
" (+! s5-6 1)\n"
" (dotimes\n"
" (s5-6 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-6) \"~D\" \" ~D\")\n"
" (-> (the-as (array int16) arg0) s5-6)\n"
" )\n"
" )\n"
" )\n"
" ((= v1-1 (quote uint16))\n"
" (let\n"
" ((s5-7 0))\n"
" (while\n"
" (< s5-7 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-7) \"~D\" \" ~D\")\n"
" (-> (the-as (array uint16) arg0) s5-7)\n"
" )\n"
" (+! s5-7 1)\n"
" (dotimes\n"
" (s5-7 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-7) \"~D\" \" ~D\")\n"
" (-> (the-as (array uint16) arg0) s5-7)\n"
" )\n"
" )\n"
" )\n"
" (else\n"
" (cond\n"
" ((or (= v1-1 (quote uint128)) (= v1-1 (quote int128)))\n"
" (let\n"
" ((s5-8 0))\n"
" (while\n"
" (< s5-8 (-> arg0 length))\n"
" (dotimes\n"
" (s5-8 (-> arg0 length))\n"
" (let\n"
" ((t9-10 format) (a0-21 #t) (a1-11 (if (zero? s5-8) \"#x~X\" \" #x~X\")))\n"
" (let\n"
" ((t9-10 format) (a0-21 #t) (a1-11 (if (zero? s5-8) \"#x~X\" \" #x~X\")))\n"
" (let\n"
" ((v1-42 (+ (shl s5-8 4) (the-as int (the-as (array uint128) arg0))))\n"
" )\n"
" (.lq a2-8 12 v1-42)\n"
" )\n"
" (t9-10 a0-21 a1-11 a2-8)\n"
" ((v1-42 (+ (shl s5-8 4) (the-as int (the-as (array uint128) arg0)))))\n"
" (.lq a2-8 12 v1-42)\n"
" )\n"
" (+! s5-8 1)\n"
" (t9-10 a0-21 a1-11 a2-8)\n"
" )\n"
" )\n"
" )\n"
" (else\n"
" (let\n"
" ((s5-9 0))\n"
" (while\n"
" (< s5-9 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-9) \"~D\" \" ~D\")\n"
" (-> (the-as (array int32) arg0) s5-9)\n"
" )\n"
" (+! s5-9 1)\n"
" (dotimes\n"
" (s5-9 (-> arg0 length))\n"
" (format\n"
" #t\n"
" (if (zero? s5-9) \"~D\" \" ~D\")\n"
" (-> (the-as (array int32) arg0) s5-9)\n"
" )\n"
" )\n"
" )\n"
@ -696,30 +655,22 @@ TEST_F(FormRegressionTest, ExprArrayMethod2) {
" )\n"
" (cond\n"
" ((= (-> arg0 content-type) float)\n"
" (let\n"
" ((s5-10 0))\n"
" (while\n"
" (< s5-10 (-> arg0 length))\n"
" (if\n"
" (zero? s5-10)\n"
" (format #t \"~f\" (-> (the-as (array float) arg0) s5-10))\n"
" (format #t \" ~f\" (-> (the-as (array float) arg0) s5-10))\n"
" )\n"
" (+! s5-10 1)\n"
" (dotimes\n"
" (s5-10 (-> arg0 length))\n"
" (if\n"
" (zero? s5-10)\n"
" (format #t \"~f\" (-> (the-as (array float) arg0) s5-10))\n"
" (format #t \" ~f\" (-> (the-as (array float) arg0) s5-10))\n"
" )\n"
" )\n"
" )\n"
" (else\n"
" (let\n"
" ((s5-11 0))\n"
" (while\n"
" (< s5-11 (-> arg0 length))\n"
" (if\n"
" (zero? s5-11)\n"
" (format #t \"~A\" (-> (the-as (array basic) arg0) s5-11))\n"
" (format #t \" ~A\" (-> (the-as (array basic) arg0) s5-11))\n"
" )\n"
" (+! s5-11 1)\n"
" (dotimes\n"
" (s5-11 (-> arg0 length))\n"
" (if\n"
" (zero? s5-11)\n"
" (format #t \"~A\" (-> (the-as (array basic) arg0) s5-11))\n"
" (format #t \" ~A\" (-> (the-as (array basic) arg0) s5-11))\n"
" )\n"
" )\n"
" )\n"
@ -1222,118 +1173,72 @@ TEST_F(FormRegressionTest, ExprArrayMethod3) {
" ((v1-1 (-> arg0 content-type symbol)))\n"
" (cond\n"
" ((= v1-1 (quote int32))\n"
" (let\n"
" ((s5-0 0))\n"
" (while\n"
" (< s5-0 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-0 (-> (the-as (array int32) arg0) s5-0))\n"
" (+! s5-0 1)\n"
" )\n"
" (dotimes\n"
" (s5-0 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-0 (-> (the-as (array int32) arg0) s5-0))\n"
" )\n"
" )\n"
" ((= v1-1 (quote uint32))\n"
" (let\n"
" ((s5-1 0))\n"
" (while\n"
" (< s5-1 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-1 (-> (the-as (array uint32) arg0) s5-1))\n"
" (+! s5-1 1)\n"
" )\n"
" (dotimes\n"
" (s5-1 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-1 (-> (the-as (array uint32) arg0) s5-1))\n"
" )\n"
" )\n"
" ((= v1-1 (quote int64))\n"
" (let\n"
" ((s5-2 0))\n"
" (while\n"
" (< s5-2 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-2 (-> (the-as (array int64) arg0) s5-2))\n"
" (+! s5-2 1)\n"
" )\n"
" (dotimes\n"
" (s5-2 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-2 (-> (the-as (array int64) arg0) s5-2))\n"
" )\n"
" )\n"
" ((= v1-1 (quote uint64))\n"
" (let\n"
" ((s5-3 0))\n"
" (while\n"
" (< s5-3 (-> arg0 length))\n"
" (format\n"
" #t\n"
" \"~T [~D] #x~X~%\"\n"
" s5-3\n"
" (-> (the-as (array uint64) arg0) s5-3)\n"
" )\n"
" (+! s5-3 1)\n"
" )\n"
" (dotimes\n"
" (s5-3 (-> arg0 length))\n"
" (format #t \"~T [~D] #x~X~%\" s5-3 (-> (the-as (array uint64) arg0) s5-3))\n"
" )\n"
" )\n"
" ((= v1-1 (quote int8))\n"
" (let\n"
" ((s5-4 0))\n"
" (while\n"
" (< s5-4 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-4 (-> (the-as (array int8) arg0) s5-4))\n"
" (+! s5-4 1)\n"
" )\n"
" (dotimes\n"
" (s5-4 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-4 (-> (the-as (array int8) arg0) s5-4))\n"
" )\n"
" )\n"
" ((= v1-1 (quote uint8))\n"
" (let\n"
" ((s5-5 0))\n"
" (while\n"
" (< s5-5 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-5 (-> (the-as (array int8) arg0) s5-5))\n"
" (+! s5-5 1)\n"
" )\n"
" (dotimes\n"
" (s5-5 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-5 (-> (the-as (array int8) arg0) s5-5))\n"
" )\n"
" )\n"
" ((= v1-1 (quote int16))\n"
" (let\n"
" ((s5-6 0))\n"
" (while\n"
" (< s5-6 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-6 (-> (the-as (array int16) arg0) s5-6))\n"
" (+! s5-6 1)\n"
" )\n"
" (dotimes\n"
" (s5-6 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-6 (-> (the-as (array int16) arg0) s5-6))\n"
" )\n"
" )\n"
" ((= v1-1 (quote uint16))\n"
" (let\n"
" ((s5-7 0))\n"
" (while\n"
" (< s5-7 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-7 (-> (the-as (array uint16) arg0) s5-7))\n"
" (+! s5-7 1)\n"
" )\n"
" (dotimes\n"
" (s5-7 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-7 (-> (the-as (array uint16) arg0) s5-7))\n"
" )\n"
" )\n"
" (else\n"
" (cond\n"
" ((or (= v1-1 (quote int128)) (= v1-1 (quote uint128)))\n"
" (let\n"
" ((s5-8 0))\n"
" (while\n"
" (< s5-8 (-> arg0 length))\n"
" (dotimes\n"
" (s5-8 (-> arg0 length))\n"
" (let\n"
" ((t9-14 format) (a0-25 #t) (a1-15 \"~T [~D] #x~X~%\") (a2-13 s5-8))\n"
" (let\n"
" ((t9-14 format) (a0-25 #t) (a1-15 \"~T [~D] #x~X~%\") (a2-13 s5-8))\n"
" (let\n"
" ((v1-42 (+ (shl s5-8 4) (the-as int (the-as (array uint128) arg0))))\n"
" )\n"
" (.lq a3-10 12 v1-42)\n"
" )\n"
" (t9-14 a0-25 a1-15 a2-13 a3-10)\n"
" ((v1-42 (+ (shl s5-8 4) (the-as int (the-as (array uint128) arg0)))))\n"
" (.lq a3-10 12 v1-42)\n"
" )\n"
" (+! s5-8 1)\n"
" (t9-14 a0-25 a1-15 a2-13 a3-10)\n"
" )\n"
" )\n"
" )\n"
" (else\n"
" (let\n"
" ((s5-9 0))\n"
" (while\n"
" (< s5-9 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-9 (-> arg0 s5-9))\n"
" (+! s5-9 1)\n"
" )\n"
" (dotimes\n"
" (s5-9 (-> arg0 length))\n"
" (format #t \"~T [~D] ~D~%\" s5-9 (-> arg0 s5-9))\n"
" )\n"
" )\n"
" )\n"
@ -1342,23 +1247,15 @@ TEST_F(FormRegressionTest, ExprArrayMethod3) {
" )\n"
" (cond\n"
" ((= (-> arg0 content-type) float)\n"
" (let\n"
" ((s5-10 0))\n"
" (while\n"
" (< s5-10 (-> arg0 length))\n"
" (format #t \"~T [~D] ~f~%\" s5-10 (-> (the-as (array float) arg0) s5-10))\n"
" (+! s5-10 1)\n"
" )\n"
" (dotimes\n"
" (s5-10 (-> arg0 length))\n"
" (format #t \"~T [~D] ~f~%\" s5-10 (-> (the-as (array float) arg0) s5-10))\n"
" )\n"
" )\n"
" (else\n"
" (let\n"
" ((s5-11 0))\n"
" (while\n"
" (< s5-11 (-> arg0 length))\n"
" (format #t \"~T [~D] ~A~%\" s5-11 (-> (the-as (array basic) arg0) s5-11))\n"
" (+! s5-11 1)\n"
" )\n"
" (dotimes\n"
" (s5-11 (-> arg0 length))\n"
" (format #t \"~T [~D] ~A~%\" s5-11 (-> (the-as (array basic) arg0) s5-11))\n"
" )\n"
" )\n"
" )\n"

View file

@ -932,20 +932,16 @@ TEST_F(FormRegressionTest, ExprMethod0DeadPool) {
" (set! (-> s3-0 child) #f)\n"
" (set! (-> s3-0 self) s3-0)\n"
" (set! (-> s3-0 ppointer) (&-> s3-0 self))\n"
" (let\n"
" ((s2-1 0))\n"
" (while\n"
" (< s2-1 arg2)\n"
" (let\n"
" ((s1-0 (-> s3-0 child))\n"
" (v1-5 ((method-of-type process new) arg0 process (quote dead) arg3))\n"
" )\n"
" (let ((a0-3 v1-5)) (set! (-> s3-0 child) (if a0-3 (-> a0-3 ppointer))))\n"
" (let ((a0-4 s3-0)) (set! (-> v1-5 parent) (if a0-4 (-> a0-4 ppointer))))\n"
" (set! (-> v1-5 pool) s3-0)\n"
" (set! (-> v1-5 brother) s1-0)\n"
" (dotimes\n"
" (s2-1 arg2)\n"
" (let\n"
" ((s1-0 (-> s3-0 child))\n"
" (v1-5 ((method-of-type process new) arg0 process (quote dead) arg3))\n"
" )\n"
" (+! s2-1 1)\n"
" (let ((a0-3 v1-5)) (set! (-> s3-0 child) (if a0-3 (-> a0-3 ppointer))))\n"
" (let ((a0-4 s3-0)) (set! (-> v1-5 parent) (if a0-4 (-> a0-4 ppointer))))\n"
" (set! (-> v1-5 pool) s3-0)\n"
" (set! (-> v1-5 brother) s1-0)\n"
" )\n"
" )\n"
" s3-0\n"