mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
[Decompiler] Clean Up (#271)
* clean up * fix up until generic ops * finish kernel * documentation * types * add missing file
This commit is contained in:
parent
1b5b9a2469
commit
db48d94270
|
@ -232,6 +232,11 @@ class SimpleExpression {
|
||||||
goos::Object to_form(const std::vector<DecompilerLabel>& labels, const Env& env) const;
|
goos::Object to_form(const std::vector<DecompilerLabel>& labels, const Env& env) const;
|
||||||
bool operator==(const SimpleExpression& other) const;
|
bool operator==(const SimpleExpression& other) const;
|
||||||
bool is_identity() const { return m_kind == Kind::IDENTITY; }
|
bool is_identity() const { return m_kind == Kind::IDENTITY; }
|
||||||
|
bool is_var() const { return is_identity() && get_arg(0).is_var(); }
|
||||||
|
const Variable& var() const {
|
||||||
|
assert(is_var());
|
||||||
|
return get_arg(0).var();
|
||||||
|
}
|
||||||
void get_regs(std::vector<Register>* out) const;
|
void get_regs(std::vector<Register>* out) const;
|
||||||
TP_Type get_type(const TypeState& input, const Env& env, const DecompilerTypeSystem& dts) const;
|
TP_Type get_type(const TypeState& input, const Env& env, const DecompilerTypeSystem& dts) const;
|
||||||
TP_Type get_type_int2(const TypeState& input,
|
TP_Type get_type_int2(const TypeState& input,
|
||||||
|
|
|
@ -106,10 +106,8 @@ FormElement* SetVarConditionOp::get_as_form(FormPool& pool, const Env& env) cons
|
||||||
FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||||
if (env.has_type_analysis()) {
|
if (env.has_type_analysis()) {
|
||||||
if (m_addr.is_identity() && m_addr.get_arg(0).is_sym_val()) {
|
if (m_addr.is_identity() && m_addr.get_arg(0).is_sym_val()) {
|
||||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_value.as_expr(),
|
return pool.alloc_element<StoreInSymbolElement>(m_addr.get_arg(0).get_str(),
|
||||||
m_my_idx);
|
m_value.as_expr(), m_my_idx);
|
||||||
auto src = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_addr, m_my_idx);
|
|
||||||
return pool.alloc_element<SetFormFormElement>(src, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IR2_RegOffset ro;
|
IR2_RegOffset ro;
|
||||||
|
@ -120,22 +118,9 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||||
(input_type.typespec() == TypeSpec("object") ||
|
(input_type.typespec() == TypeSpec("object") ||
|
||||||
input_type.typespec() == TypeSpec("pair"))) {
|
input_type.typespec() == TypeSpec("pair"))) {
|
||||||
if (ro.offset == 2) {
|
if (ro.offset == 2) {
|
||||||
auto base = pool.alloc_single_element_form<SimpleExpressionElement>(
|
return pool.alloc_element<StoreInPairElement>(false, ro.var, m_value.as_expr(), m_my_idx);
|
||||||
nullptr, SimpleAtom::make_var(ro.var).as_expr(), m_my_idx);
|
|
||||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(
|
|
||||||
nullptr, m_value.as_expr(), m_my_idx);
|
|
||||||
auto addr = pool.alloc_single_element_form<GenericElement>(
|
|
||||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::CDR), base);
|
|
||||||
auto fr = pool.alloc_element<SetFormFormElement>(addr, val);
|
|
||||||
return fr;
|
|
||||||
} else if (ro.offset == -2) {
|
} else if (ro.offset == -2) {
|
||||||
auto base = pool.alloc_single_element_form<SimpleExpressionElement>(
|
return pool.alloc_element<StoreInPairElement>(true, ro.var, m_value.as_expr(), m_my_idx);
|
||||||
nullptr, SimpleAtom::make_var(ro.var).as_expr(), m_my_idx);
|
|
||||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(
|
|
||||||
nullptr, m_value.as_expr(), m_my_idx);
|
|
||||||
auto addr = pool.alloc_single_element_form<GenericElement>(
|
|
||||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::CAR), base);
|
|
||||||
return pool.alloc_element<SetFormFormElement>(addr, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,14 +145,14 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||||
|
|
||||||
// we pass along the register offset because code generation seems to be a bit
|
// we pass along the register offset because code generation seems to be a bit
|
||||||
// different in different cases.
|
// different in different cases.
|
||||||
auto source = pool.alloc_single_element_form<ArrayFieldAccess>(
|
auto source = pool.alloc_element<ArrayFieldAccess>(
|
||||||
nullptr, ro.var, tokens, input_type.get_multiplier(), ro.offset);
|
ro.var, tokens, input_type.get_multiplier(), ro.offset);
|
||||||
|
|
||||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(
|
// auto val = pool.alloc_single_element_form<SimpleExpressionElement>(
|
||||||
nullptr, m_value.as_expr(), m_my_idx);
|
// nullptr, m_value.as_expr(), m_my_idx);
|
||||||
|
|
||||||
assert(!rd.addr_of);
|
assert(!rd.addr_of);
|
||||||
return pool.alloc_element<SetFormFormElement>(source, val);
|
return pool.alloc_element<StoreArrayAccess>(source, m_value.as_expr(), m_my_idx, ro.var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,8 +168,6 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||||
auto rd = env.dts->ts.reverse_field_lookup(rd_in);
|
auto rd = env.dts->ts.reverse_field_lookup(rd_in);
|
||||||
|
|
||||||
if (rd.success) {
|
if (rd.success) {
|
||||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(
|
|
||||||
nullptr, m_value.as_expr(), m_my_idx);
|
|
||||||
auto source = pool.alloc_single_element_form<SimpleExpressionElement>(
|
auto source = pool.alloc_single_element_form<SimpleExpressionElement>(
|
||||||
nullptr, SimpleAtom::make_var(ro.var).as_expr(), m_my_idx);
|
nullptr, SimpleAtom::make_var(ro.var).as_expr(), m_my_idx);
|
||||||
std::vector<DerefToken> tokens;
|
std::vector<DerefToken> tokens;
|
||||||
|
@ -192,13 +175,13 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||||
tokens.push_back(to_token(x));
|
tokens.push_back(to_token(x));
|
||||||
}
|
}
|
||||||
assert(!rd.addr_of);
|
assert(!rd.addr_of);
|
||||||
auto addr =
|
auto addr = pool.alloc_element<DerefElement>(source, rd.addr_of, tokens);
|
||||||
pool.alloc_single_element_form<DerefElement>(nullptr, source, rd.addr_of, tokens);
|
return pool.alloc_element<StorePlainDeref>(addr, m_value.as_expr(), m_my_idx, ro.var,
|
||||||
return pool.alloc_element<SetFormFormElement>(addr, val);
|
std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string cast_type;
|
||||||
if (input_type.typespec() == TypeSpec("pointer") && ro.offset == 0) {
|
if (input_type.typespec() == TypeSpec("pointer") && ro.offset == 0) {
|
||||||
std::string cast_type;
|
|
||||||
switch (m_size) {
|
switch (m_size) {
|
||||||
case 1:
|
case 1:
|
||||||
cast_type = "int8";
|
cast_type = "int8";
|
||||||
|
@ -220,11 +203,10 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||||
nullptr, SimpleAtom::make_var(ro.var).as_expr(), m_my_idx);
|
nullptr, SimpleAtom::make_var(ro.var).as_expr(), m_my_idx);
|
||||||
auto cast_source = pool.alloc_single_element_form<CastElement>(
|
auto cast_source = pool.alloc_single_element_form<CastElement>(
|
||||||
nullptr, TypeSpec("pointer", {TypeSpec(cast_type)}), source);
|
nullptr, TypeSpec("pointer", {TypeSpec(cast_type)}), source);
|
||||||
auto deref = pool.alloc_single_element_form<DerefElement>(nullptr, cast_source, false,
|
auto deref =
|
||||||
std::vector<DerefToken>());
|
pool.alloc_element<DerefElement>(cast_source, false, std::vector<DerefToken>());
|
||||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(
|
return pool.alloc_element<StorePlainDeref>(deref, m_value.as_expr(), m_my_idx, ro.var,
|
||||||
nullptr, m_value.as_expr(), m_my_idx);
|
TypeSpec("pointer", {TypeSpec(cast_type)}));
|
||||||
return pool.alloc_element<SetFormFormElement>(deref, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,6 +319,50 @@ bool SetVarElement::active() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StoreInSymbolElement::StoreInSymbolElement(std::string sym_name, SimpleExpression value, int my_idx)
|
||||||
|
: m_sym_name(std::move(sym_name)), m_value(std::move(value)), m_my_idx(my_idx) {}
|
||||||
|
|
||||||
|
goos::Object StoreInSymbolElement::to_form_internal(const Env& env) const {
|
||||||
|
return pretty_print::build_list("set!", m_sym_name, m_value.to_form(env.file->labels, env));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreInSymbolElement::apply(const std::function<void(FormElement*)>& f) {
|
||||||
|
f(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreInSymbolElement::apply_form(const std::function<void(Form*)>&) {}
|
||||||
|
|
||||||
|
void StoreInSymbolElement::collect_vars(VariableSet& vars) const {
|
||||||
|
m_value.collect_vars(vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreInSymbolElement::get_modified_regs(RegSet&) const {}
|
||||||
|
|
||||||
|
StoreInPairElement::StoreInPairElement(bool is_car,
|
||||||
|
Variable pair,
|
||||||
|
SimpleExpression value,
|
||||||
|
int my_idx)
|
||||||
|
: m_is_car(is_car), m_pair(pair), m_value(value), m_my_idx(my_idx) {}
|
||||||
|
|
||||||
|
goos::Object StoreInPairElement::to_form_internal(const Env& env) const {
|
||||||
|
return pretty_print::build_list(
|
||||||
|
"set!", pretty_print::build_list(m_is_car ? "car" : "cdr", m_pair.to_form(env)),
|
||||||
|
m_value.to_form(env.file->labels, env));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreInPairElement::apply(const std::function<void(FormElement*)>& f) {
|
||||||
|
f(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreInPairElement::apply_form(const std::function<void(Form*)>&) {}
|
||||||
|
|
||||||
|
void StoreInPairElement::collect_vars(VariableSet& vars) const {
|
||||||
|
m_value.collect_vars(vars);
|
||||||
|
vars.insert(m_pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreInPairElement::get_modified_regs(RegSet&) const {}
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// SetFormFormElement
|
// SetFormFormElement
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
@ -335,6 +379,7 @@ goos::Object SetFormFormElement::to_form_internal(const Env& env) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFormFormElement::apply(const std::function<void(FormElement*)>& f) {
|
void SetFormFormElement::apply(const std::function<void(FormElement*)>& f) {
|
||||||
|
f(this);
|
||||||
m_src->apply(f);
|
m_src->apply(f);
|
||||||
m_dst->apply(f);
|
m_dst->apply(f);
|
||||||
}
|
}
|
||||||
|
@ -1598,4 +1643,69 @@ void ConstantTokenElement::apply_form(const std::function<void(Form*)>&) {}
|
||||||
void ConstantTokenElement::collect_vars(VariableSet&) const {}
|
void ConstantTokenElement::collect_vars(VariableSet&) const {}
|
||||||
void ConstantTokenElement::get_modified_regs(RegSet&) const {}
|
void ConstantTokenElement::get_modified_regs(RegSet&) const {}
|
||||||
|
|
||||||
|
StorePlainDeref::StorePlainDeref(DerefElement* dst,
|
||||||
|
SimpleExpression expr,
|
||||||
|
int my_idx,
|
||||||
|
Variable base_var,
|
||||||
|
std::optional<TypeSpec> cast_type)
|
||||||
|
: m_dst(dst),
|
||||||
|
m_expr(std::move(expr)),
|
||||||
|
m_my_idx(my_idx),
|
||||||
|
m_base_var(std::move(base_var)),
|
||||||
|
m_cast_type(cast_type) {}
|
||||||
|
goos::Object StorePlainDeref::to_form_internal(const Env& env) const {
|
||||||
|
if (!m_cast_type.has_value()) {
|
||||||
|
return pretty_print::build_list("set!", m_dst->to_form(env),
|
||||||
|
m_expr.to_form(env.file->labels, env));
|
||||||
|
} else {
|
||||||
|
return pretty_print::build_list(
|
||||||
|
"set!", pretty_print::build_list("the-as", m_cast_type->print(), m_dst->to_form(env)),
|
||||||
|
m_expr.to_form(env.file->labels, env));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void StorePlainDeref::apply(const std::function<void(FormElement*)>& f) {
|
||||||
|
f(this);
|
||||||
|
m_dst->apply(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StorePlainDeref::apply_form(const std::function<void(Form*)>&) {}
|
||||||
|
|
||||||
|
void StorePlainDeref::collect_vars(VariableSet& vars) const {
|
||||||
|
m_expr.collect_vars(vars);
|
||||||
|
m_dst->collect_vars(vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StorePlainDeref::get_modified_regs(RegSet& regs) const {
|
||||||
|
m_dst->get_modified_regs(regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreArrayAccess::StoreArrayAccess(ArrayFieldAccess* dst,
|
||||||
|
SimpleExpression expr,
|
||||||
|
int my_idx,
|
||||||
|
Variable array_src)
|
||||||
|
: m_dst(dst), m_expr(expr), m_my_idx(my_idx), m_base_var(array_src) {}
|
||||||
|
|
||||||
|
goos::Object StoreArrayAccess::to_form_internal(const Env& env) const {
|
||||||
|
return pretty_print::build_list("set!", m_dst->to_form(env),
|
||||||
|
m_expr.to_form(env.file->labels, env));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreArrayAccess::apply(const std::function<void(FormElement*)>& f) {
|
||||||
|
f(this);
|
||||||
|
m_dst->apply(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreArrayAccess::apply_form(const std::function<void(Form*)>& f) {
|
||||||
|
m_dst->apply_form(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreArrayAccess::collect_vars(VariableSet& vars) const {
|
||||||
|
m_expr.collect_vars(vars);
|
||||||
|
m_dst->collect_vars(vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreArrayAccess::get_modified_regs(RegSet& regs) const {
|
||||||
|
m_dst->get_modified_regs(regs);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace decompiler
|
} // namespace decompiler
|
||||||
|
|
|
@ -43,9 +43,16 @@ class FormElement {
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects);
|
bool allow_side_effects);
|
||||||
|
bool is_popped() const { return m_popped; }
|
||||||
|
|
||||||
|
void mark_popped() {
|
||||||
|
assert(!m_popped);
|
||||||
|
m_popped = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Form;
|
friend class Form;
|
||||||
|
bool m_popped = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -61,8 +68,6 @@ class SimpleExpressionElement : public FormElement {
|
||||||
void apply_form(const std::function<void(Form*)>& f) override;
|
void apply_form(const std::function<void(Form*)>& f) override;
|
||||||
bool is_sequence_point() const override;
|
bool is_sequence_point() const override;
|
||||||
void collect_vars(VariableSet& vars) const override;
|
void collect_vars(VariableSet& vars) const override;
|
||||||
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
|
||||||
// void push_to_stack(const Env& env, FormStack& stack) override;
|
|
||||||
void update_from_stack(const Env& env,
|
void update_from_stack(const Env& env,
|
||||||
FormPool& pool,
|
FormPool& pool,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
|
@ -219,13 +224,11 @@ class SimpleAtomElement : public FormElement {
|
||||||
void collect_vars(VariableSet& vars) const override;
|
void collect_vars(VariableSet& vars) const override;
|
||||||
void get_modified_regs(RegSet& regs) const override;
|
void get_modified_regs(RegSet& regs) const override;
|
||||||
const SimpleAtom& atom() const { return m_atom; }
|
const SimpleAtom& atom() const { return m_atom; }
|
||||||
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
|
||||||
void update_from_stack(const Env& env,
|
void update_from_stack(const Env& env,
|
||||||
FormPool& pool,
|
FormPool& pool,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) override;
|
bool allow_side_effects) override;
|
||||||
// void push_to_stack(const Env& env, FormStack& stack) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SimpleAtom m_atom;
|
SimpleAtom m_atom;
|
||||||
|
@ -246,11 +249,6 @@ class SetVarElement : public FormElement {
|
||||||
bool is_sequence_point() const override;
|
bool is_sequence_point() const override;
|
||||||
void collect_vars(VariableSet& vars) const override;
|
void collect_vars(VariableSet& vars) const override;
|
||||||
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
||||||
void update_from_stack(const Env& env,
|
|
||||||
FormPool& pool,
|
|
||||||
FormStack& stack,
|
|
||||||
std::vector<FormElement*>* result,
|
|
||||||
bool allow_side_effects) override;
|
|
||||||
void get_modified_regs(RegSet& regs) const override;
|
void get_modified_regs(RegSet& regs) const override;
|
||||||
bool active() const override;
|
bool active() const override;
|
||||||
|
|
||||||
|
@ -276,6 +274,39 @@ class SetVarElement : public FormElement {
|
||||||
SetVarInfo m_var_info;
|
SetVarInfo m_var_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StoreInSymbolElement : public FormElement {
|
||||||
|
public:
|
||||||
|
StoreInSymbolElement(std::string sym_name, SimpleExpression value, int my_idx);
|
||||||
|
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(VariableSet& vars) const override;
|
||||||
|
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
||||||
|
void get_modified_regs(RegSet& regs) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_sym_name;
|
||||||
|
SimpleExpression m_value;
|
||||||
|
int m_my_idx = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StoreInPairElement : public FormElement {
|
||||||
|
public:
|
||||||
|
StoreInPairElement(bool is_car, Variable pair, SimpleExpression value, int my_idx);
|
||||||
|
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(VariableSet& vars) const override;
|
||||||
|
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
||||||
|
void get_modified_regs(RegSet& regs) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_is_car = false;
|
||||||
|
Variable m_pair;
|
||||||
|
SimpleExpression m_value;
|
||||||
|
int m_my_idx = -1;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Like SetVar, but sets a form to another form.
|
* Like SetVar, but sets a form to another form.
|
||||||
* This is intended to be used with stores.
|
* This is intended to be used with stores.
|
||||||
|
@ -298,6 +329,7 @@ class SetFormFormElement : public FormElement {
|
||||||
Form* dst() { return m_dst; }
|
Form* dst() { return m_dst; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int m_real_push_count = 0;
|
||||||
Form* m_dst = nullptr;
|
Form* m_dst = nullptr;
|
||||||
Form* m_src = nullptr;
|
Form* m_src = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -341,7 +373,8 @@ class AsmOpElement : public FormElement {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* A "condition" like (< a b). This can be used as a boolean value directly: (set! a (< b c))
|
* A "condition" like (< a b). This can be used as a boolean value directly: (set! a (< b c))
|
||||||
* or it can be used as a branch condition: (if (< a b)).
|
* or it can be used as a branch condition: (if (< a b)). As a result, it implements both push
|
||||||
|
* and update.
|
||||||
*
|
*
|
||||||
* In the first case, it can be either a conditional move or actually branching. GOAL seems to use
|
* In the first case, it can be either a conditional move or actually branching. GOAL seems to use
|
||||||
* the branching when sometimes it could have used the conditional move, and for now, we don't
|
* the branching when sometimes it could have used the conditional move, and for now, we don't
|
||||||
|
@ -892,10 +925,13 @@ class DerefElement : public FormElement {
|
||||||
bool allow_side_effects) override;
|
bool allow_side_effects) override;
|
||||||
void get_modified_regs(RegSet& regs) const override;
|
void get_modified_regs(RegSet& regs) const override;
|
||||||
|
|
||||||
|
void inline_nested();
|
||||||
|
|
||||||
bool is_addr_of() const { return m_is_addr_of; }
|
bool is_addr_of() const { return m_is_addr_of; }
|
||||||
const Form* base() const { return m_base; }
|
const Form* base() const { return m_base; }
|
||||||
Form* base() { return m_base; }
|
Form* base() { return m_base; }
|
||||||
const std::vector<DerefToken>& tokens() const { return m_tokens; }
|
const std::vector<DerefToken>& tokens() const { return m_tokens; }
|
||||||
|
void set_base(Form* new_base) { m_base = new_base; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Form* m_base = nullptr;
|
Form* m_base = nullptr;
|
||||||
|
@ -938,6 +974,12 @@ class ArrayFieldAccess : public FormElement {
|
||||||
bool allow_side_effects) override;
|
bool allow_side_effects) override;
|
||||||
void get_modified_regs(RegSet& regs) const override;
|
void get_modified_regs(RegSet& regs) const override;
|
||||||
|
|
||||||
|
void update_with_val(Form* new_val,
|
||||||
|
const Env& env,
|
||||||
|
FormPool& pool,
|
||||||
|
std::vector<FormElement*>* result,
|
||||||
|
bool allow_side_effects);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Variable m_source;
|
Variable m_source;
|
||||||
std::vector<DerefToken> m_deref_tokens;
|
std::vector<DerefToken> m_deref_tokens;
|
||||||
|
@ -1001,6 +1043,46 @@ class ConstantTokenElement : public FormElement {
|
||||||
std::string m_value;
|
std::string m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StorePlainDeref : public FormElement {
|
||||||
|
public:
|
||||||
|
StorePlainDeref(DerefElement* dst,
|
||||||
|
SimpleExpression expr,
|
||||||
|
int my_idx,
|
||||||
|
Variable base_var,
|
||||||
|
std::optional<TypeSpec> cast_type);
|
||||||
|
|
||||||
|
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(VariableSet& vars) const override;
|
||||||
|
void get_modified_regs(RegSet& regs) const override;
|
||||||
|
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DerefElement* m_dst = nullptr;
|
||||||
|
SimpleExpression m_expr;
|
||||||
|
int m_my_idx = -1;
|
||||||
|
Variable m_base_var;
|
||||||
|
std::optional<TypeSpec> m_cast_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StoreArrayAccess : public FormElement {
|
||||||
|
public:
|
||||||
|
StoreArrayAccess(ArrayFieldAccess* dst, SimpleExpression expr, int my_idx, Variable array_src);
|
||||||
|
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(VariableSet& vars) const override;
|
||||||
|
void get_modified_regs(RegSet& regs) const override;
|
||||||
|
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ArrayFieldAccess* m_dst = nullptr;
|
||||||
|
SimpleExpression m_expr;
|
||||||
|
int m_my_idx = -1;
|
||||||
|
Variable m_base_var;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* A Form is a wrapper around one or more FormElements.
|
* A Form is a wrapper around one or more FormElements.
|
||||||
* This is done for two reasons:
|
* This is done for two reasons:
|
||||||
|
@ -1073,6 +1155,14 @@ class Form {
|
||||||
bool has_side_effects();
|
bool has_side_effects();
|
||||||
void get_modified_regs(RegSet& regs) const;
|
void get_modified_regs(RegSet& regs) const;
|
||||||
|
|
||||||
|
bool is_popped() const { return m_elements.at(0)->is_popped(); }
|
||||||
|
|
||||||
|
void mark_popped() {
|
||||||
|
for (auto x : m_elements) {
|
||||||
|
x->mark_popped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FormElement* parent_element = nullptr;
|
FormElement* parent_element = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -233,7 +233,12 @@ void Form::update_children_from_stack(const Env& env,
|
||||||
for (size_t i = 0; i < m_elements.size(); i++) {
|
for (size_t i = 0; i < m_elements.size(); i++) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
// only bother doing the first one.
|
// only bother doing the first one.
|
||||||
m_elements[i]->update_from_stack(env, pool, stack, &new_elts, allow_side_effects);
|
if (!m_elements[i]->is_popped()) {
|
||||||
|
m_elements[i]->update_from_stack(env, pool, stack, &new_elts, allow_side_effects);
|
||||||
|
} else {
|
||||||
|
new_elts.push_back(m_elements[i]);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
new_elts.push_back(m_elements[i]);
|
new_elts.push_back(m_elements[i]);
|
||||||
}
|
}
|
||||||
|
@ -286,6 +291,7 @@ void LoadSourceElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
m_addr->update_children_from_stack(env, pool, stack, allow_side_effects);
|
m_addr->update_children_from_stack(env, pool, stack, allow_side_effects);
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
@ -356,6 +362,8 @@ void SimpleExpressionElement::update_from_stack_fpr_to_gpr(const Env& env,
|
||||||
// set ourself to identity.
|
// set ourself to identity.
|
||||||
m_expr = src.as_expr();
|
m_expr = src.as_expr();
|
||||||
// then go again.
|
// then go again.
|
||||||
|
assert(m_popped);
|
||||||
|
m_popped = false;
|
||||||
update_from_stack(env, pool, stack, result, allow_side_effects);
|
update_from_stack(env, pool, stack, result, allow_side_effects);
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
|
@ -756,6 +764,7 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
switch (m_expr.kind()) {
|
switch (m_expr.kind()) {
|
||||||
case SimpleExpression::Kind::IDENTITY:
|
case SimpleExpression::Kind::IDENTITY:
|
||||||
update_from_stack_identity(env, pool, stack, result, allow_side_effects);
|
update_from_stack_identity(env, pool, stack, result, allow_side_effects);
|
||||||
|
@ -883,6 +892,7 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
|
||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
for (auto x : m_src->elts()) {
|
for (auto x : m_src->elts()) {
|
||||||
assert(x->parent_form == m_src);
|
assert(x->parent_form == m_src);
|
||||||
}
|
}
|
||||||
|
@ -894,6 +904,7 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||||
}
|
}
|
||||||
|
|
||||||
m_src->update_children_from_stack(env, pool, stack, true);
|
m_src->update_children_from_stack(env, pool, stack, true);
|
||||||
|
|
||||||
for (auto x : m_src->elts()) {
|
for (auto x : m_src->elts()) {
|
||||||
assert(x->parent_form == m_src);
|
assert(x->parent_form == m_src);
|
||||||
}
|
}
|
||||||
|
@ -926,23 +937,110 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVarElement::update_from_stack(const Env& env,
|
void SetFormFormElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
||||||
FormPool& pool,
|
// todo - is the order here right?
|
||||||
FormStack& stack,
|
assert(m_popped);
|
||||||
std::vector<FormElement*>* result,
|
assert(m_real_push_count == 0);
|
||||||
bool allow_side_effects) {
|
m_real_push_count++;
|
||||||
m_src->update_children_from_stack(env, pool, stack, allow_side_effects);
|
stack.push_form_element(this, true);
|
||||||
for (auto x : m_src->elts()) {
|
|
||||||
assert(x->parent_form == m_src);
|
|
||||||
}
|
|
||||||
result->push_back(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFormFormElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void StoreInSymbolElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
// todo - is the order here right?
|
auto sym = pool.alloc_single_element_form<ConstantTokenElement>(nullptr, m_sym_name);
|
||||||
m_dst->update_children_from_stack(env, pool, stack, false);
|
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_value, m_my_idx);
|
||||||
m_src->update_children_from_stack(env, pool, stack, false);
|
val->update_children_from_stack(env, pool, stack, true);
|
||||||
stack.push_form_element(this, true);
|
|
||||||
|
auto elt = pool.alloc_element<SetFormFormElement>(sym, val);
|
||||||
|
elt->mark_popped();
|
||||||
|
stack.push_form_element(elt, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreInPairElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
auto op = m_is_car ? FixedOperatorKind::CAR : FixedOperatorKind::CDR;
|
||||||
|
if (m_value.is_var()) {
|
||||||
|
auto vars = std::vector<Variable>({m_value.var(), m_pair});
|
||||||
|
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||||
|
auto addr = pool.alloc_single_element_form<GenericElement>(
|
||||||
|
nullptr, GenericOperator::make_fixed(op), popped.at(1));
|
||||||
|
addr->mark_popped();
|
||||||
|
auto fr = pool.alloc_element<SetFormFormElement>(addr, popped.at(0));
|
||||||
|
fr->mark_popped();
|
||||||
|
stack.push_form_element(fr, true);
|
||||||
|
} else {
|
||||||
|
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_value, m_my_idx);
|
||||||
|
val->mark_popped();
|
||||||
|
auto addr = pool.alloc_single_element_form<GenericElement>(
|
||||||
|
nullptr, GenericOperator::make_fixed(op),
|
||||||
|
pop_to_forms({m_pair}, env, pool, stack, true).at(0));
|
||||||
|
addr->mark_popped();
|
||||||
|
auto fr = pool.alloc_element<SetFormFormElement>(addr, val);
|
||||||
|
fr->mark_popped();
|
||||||
|
stack.push_form_element(fr, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StorePlainDeref::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
|
if (m_expr.is_var()) {
|
||||||
|
auto vars = std::vector<Variable>({m_expr.var(), m_base_var});
|
||||||
|
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||||
|
if (m_cast_type.has_value()) {
|
||||||
|
m_dst->set_base(
|
||||||
|
pool.alloc_single_element_form<CastElement>(nullptr, *m_cast_type, popped.at(1)));
|
||||||
|
} else {
|
||||||
|
m_dst->set_base(popped.at(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dst->mark_popped();
|
||||||
|
m_dst->inline_nested();
|
||||||
|
auto fr = pool.alloc_element<SetFormFormElement>(pool.alloc_single_form(nullptr, m_dst),
|
||||||
|
popped.at(0));
|
||||||
|
fr->mark_popped();
|
||||||
|
stack.push_form_element(fr, true);
|
||||||
|
} else {
|
||||||
|
auto vars = std::vector<Variable>({m_base_var});
|
||||||
|
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||||
|
if (m_cast_type.has_value()) {
|
||||||
|
m_dst->set_base(
|
||||||
|
pool.alloc_single_element_form<CastElement>(nullptr, *m_cast_type, popped.at(1)));
|
||||||
|
} else {
|
||||||
|
m_dst->set_base(popped.at(0));
|
||||||
|
}
|
||||||
|
m_dst->mark_popped();
|
||||||
|
m_dst->inline_nested();
|
||||||
|
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_expr, m_my_idx);
|
||||||
|
val->mark_popped();
|
||||||
|
auto fr = pool.alloc_element<SetFormFormElement>(pool.alloc_single_form(nullptr, m_dst), val);
|
||||||
|
fr->mark_popped();
|
||||||
|
stack.push_form_element(fr, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreArrayAccess::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
|
Form* expr_form = nullptr;
|
||||||
|
Form* array_form = nullptr;
|
||||||
|
if (m_expr.is_var()) {
|
||||||
|
auto vars = std::vector<Variable>({m_expr.var(), m_base_var});
|
||||||
|
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||||
|
m_dst->mark_popped();
|
||||||
|
expr_form = popped.at(0);
|
||||||
|
array_form = popped.at(1);
|
||||||
|
} else {
|
||||||
|
auto vars = std::vector<Variable>({m_base_var});
|
||||||
|
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||||
|
m_dst->mark_popped();
|
||||||
|
expr_form = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_expr, m_my_idx);
|
||||||
|
array_form = popped.at(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<FormElement*> forms_out;
|
||||||
|
m_dst->update_with_val(array_form, env, pool, &forms_out, true);
|
||||||
|
auto form_out = pool.alloc_sequence_form(nullptr, forms_out);
|
||||||
|
|
||||||
|
auto fr = pool.alloc_element<SetFormFormElement>(form_out, expr_form);
|
||||||
|
fr->mark_popped();
|
||||||
|
stack.push_form_element(fr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
|
@ -954,6 +1052,7 @@ void AshElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
auto forms = pop_to_forms({value, shift_amount}, env, pool, stack, allow_side_effects, consumed);
|
auto forms = pop_to_forms({value, shift_amount}, env, pool, stack, allow_side_effects, consumed);
|
||||||
auto new_form = pool.alloc_element<GenericElement>(
|
auto new_form = pool.alloc_element<GenericElement>(
|
||||||
GenericOperator::make_fixed(FixedOperatorKind::ARITH_SHIFT), forms.at(0), forms.at(1));
|
GenericOperator::make_fixed(FixedOperatorKind::ARITH_SHIFT), forms.at(0), forms.at(1));
|
||||||
|
@ -969,6 +1068,7 @@ void AbsElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
auto forms = pop_to_forms({source}, env, pool, stack, allow_side_effects, consumed);
|
auto forms = pop_to_forms({source}, env, pool, stack, allow_side_effects, consumed);
|
||||||
auto new_form = pool.alloc_element<GenericElement>(
|
auto new_form = pool.alloc_element<GenericElement>(
|
||||||
GenericOperator::make_fixed(FixedOperatorKind::ABS), forms.at(0));
|
GenericOperator::make_fixed(FixedOperatorKind::ABS), forms.at(0));
|
||||||
|
@ -984,6 +1084,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
std::vector<Form*> args;
|
std::vector<Form*> args;
|
||||||
auto nargs = m_op->arg_vars().size();
|
auto nargs = m_op->arg_vars().size();
|
||||||
args.resize(nargs, nullptr);
|
args.resize(nargs, nullptr);
|
||||||
|
@ -1272,17 +1373,12 @@ void DerefElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
// todo - update var tokens from stack?
|
// todo - update var tokens from stack?
|
||||||
m_base->update_children_from_stack(env, pool, stack, allow_side_effects);
|
m_base->update_children_from_stack(env, pool, stack, allow_side_effects);
|
||||||
|
|
||||||
// merge nested ->'s
|
// merge nested ->'s
|
||||||
auto as_deref = dynamic_cast<DerefElement*>(m_base->try_as_single_element());
|
inline_nested();
|
||||||
if (as_deref) {
|
|
||||||
if (!m_is_addr_of && !as_deref->is_addr_of()) {
|
|
||||||
m_tokens.insert(m_tokens.begin(), as_deref->tokens().begin(), as_deref->tokens().end());
|
|
||||||
m_base = as_deref->m_base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_tokens.size() >= 3) {
|
if (m_tokens.size() >= 3) {
|
||||||
auto& method_name = m_tokens.at(m_tokens.size() - 1);
|
auto& method_name = m_tokens.at(m_tokens.size() - 1);
|
||||||
|
@ -1332,11 +1428,22 @@ void DerefElement::update_from_stack(const Env& env,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DerefElement::inline_nested() {
|
||||||
|
auto as_deref = dynamic_cast<DerefElement*>(m_base->try_as_single_element());
|
||||||
|
if (as_deref) {
|
||||||
|
if (!m_is_addr_of && !as_deref->is_addr_of()) {
|
||||||
|
m_tokens.insert(m_tokens.begin(), as_deref->tokens().begin(), as_deref->tokens().end());
|
||||||
|
m_base = as_deref->m_base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
// UntilElement
|
// UntilElement
|
||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
void UntilElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void UntilElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
for (auto form : {condition, body}) {
|
for (auto form : {condition, body}) {
|
||||||
FormStack temp_stack(false);
|
FormStack temp_stack(false);
|
||||||
for (auto& entry : form->elts()) {
|
for (auto& entry : form->elts()) {
|
||||||
|
@ -1353,6 +1460,7 @@ void UntilElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stac
|
||||||
}
|
}
|
||||||
|
|
||||||
void WhileElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void WhileElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto form : {body, condition}) {
|
for (auto form : {body, condition}) {
|
||||||
FormStack temp_stack(first && stack.is_root());
|
FormStack temp_stack(first && stack.is_root());
|
||||||
|
@ -1373,40 +1481,43 @@ void WhileElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stac
|
||||||
// CondNoElseElement
|
// CondNoElseElement
|
||||||
///////////////////
|
///////////////////
|
||||||
void CondNoElseElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void CondNoElseElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
if (already_rewritten) {
|
if (already_rewritten) {
|
||||||
stack.push_form_element(this, true);
|
stack.push_form_element(this, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto& entry : entries) {
|
|
||||||
for (auto form : {entry.condition, entry.body}) {
|
|
||||||
FormStack temp_stack(false);
|
|
||||||
for (auto& elt : form->elts()) {
|
|
||||||
elt->push_to_stack(env, pool, temp_stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<FormElement*> new_entries;
|
// the first condition is special
|
||||||
if (form == entry.body && used_as_value) {
|
auto first_condition = entries.front().condition;
|
||||||
new_entries = rewrite_to_get_var(temp_stack, pool, final_destination);
|
// lets evaluate in on the parent stack...
|
||||||
} else {
|
for (auto x : first_condition->elts()) {
|
||||||
new_entries = temp_stack.rewrite(pool);
|
x->push_to_stack(env, pool, stack);
|
||||||
}
|
|
||||||
|
|
||||||
form->clear();
|
|
||||||
for (auto e : new_entries) {
|
|
||||||
form->push_back(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// raise expression.
|
for (auto& entry : entries) {
|
||||||
auto top_condition = entries.front().condition;
|
for (auto form : {entry.condition, entry.body}) {
|
||||||
if (!top_condition->is_single_element()) {
|
if (form == first_condition) {
|
||||||
auto real_condition = top_condition->back();
|
form->clear();
|
||||||
top_condition->pop_back();
|
form->push_back(stack.pop_back(pool));
|
||||||
for (auto x : top_condition->elts()) {
|
} else {
|
||||||
x->push_to_stack(env, pool, stack);
|
FormStack temp_stack(false);
|
||||||
|
for (auto& elt : form->elts()) {
|
||||||
|
elt->push_to_stack(env, pool, temp_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<FormElement*> new_entries;
|
||||||
|
if (form == entry.body && used_as_value) {
|
||||||
|
new_entries = rewrite_to_get_var(temp_stack, pool, final_destination);
|
||||||
|
} else {
|
||||||
|
new_entries = temp_stack.rewrite(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
form->clear();
|
||||||
|
for (auto e : new_entries) {
|
||||||
|
form->push_back(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
top_condition->elts() = {real_condition};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (used_as_value) {
|
if (used_as_value) {
|
||||||
|
@ -1418,6 +1529,7 @@ void CondNoElseElement::push_to_stack(const Env& env, FormPool& pool, FormStack&
|
||||||
}
|
}
|
||||||
|
|
||||||
void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
if (already_rewritten) {
|
if (already_rewritten) {
|
||||||
stack.push_form_element(this, true);
|
stack.push_form_element(this, true);
|
||||||
return;
|
return;
|
||||||
|
@ -1426,20 +1538,32 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac
|
||||||
std::optional<Variable> last_var;
|
std::optional<Variable> last_var;
|
||||||
bool rewrite_as_set = true;
|
bool rewrite_as_set = true;
|
||||||
|
|
||||||
|
// the first condition is special
|
||||||
|
auto first_condition = entries.front().condition;
|
||||||
|
// lets evaluate in on the parent stack...
|
||||||
|
for (auto x : first_condition->elts()) {
|
||||||
|
x->push_to_stack(env, pool, stack);
|
||||||
|
}
|
||||||
|
|
||||||
// process conditions and bodies
|
// process conditions and bodies
|
||||||
for (auto& entry : entries) {
|
for (auto& entry : entries) {
|
||||||
for (auto form : {entry.condition, entry.body}) {
|
for (auto form : {entry.condition, entry.body}) {
|
||||||
FormStack temp_stack(false);
|
if (form == first_condition) {
|
||||||
for (auto& elt : form->elts()) {
|
form->clear();
|
||||||
elt->push_to_stack(env, pool, temp_stack);
|
form->push_back(stack.pop_back(pool));
|
||||||
}
|
} else {
|
||||||
|
FormStack temp_stack(false);
|
||||||
|
for (auto& elt : form->elts()) {
|
||||||
|
elt->push_to_stack(env, pool, temp_stack);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<FormElement*> new_entries;
|
std::vector<FormElement*> new_entries;
|
||||||
new_entries = temp_stack.rewrite(pool);
|
new_entries = temp_stack.rewrite(pool);
|
||||||
|
|
||||||
form->clear();
|
form->clear();
|
||||||
for (auto e : new_entries) {
|
for (auto e : new_entries) {
|
||||||
form->push_back(e);
|
form->push_back(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1500,17 +1624,6 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac
|
||||||
rewrite_to_get_var(else_ir->elts(), pool, *last_var);
|
rewrite_to_get_var(else_ir->elts(), pool, *last_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
// raise expression.
|
|
||||||
auto top_condition = entries.front().condition;
|
|
||||||
if (!top_condition->is_single_element()) {
|
|
||||||
auto real_condition = top_condition->back();
|
|
||||||
top_condition->pop_back();
|
|
||||||
for (auto x : top_condition->elts()) {
|
|
||||||
x->push_to_stack(env, pool, stack);
|
|
||||||
}
|
|
||||||
top_condition->elts() = {real_condition};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rewrite_as_set) {
|
if (rewrite_as_set) {
|
||||||
if (set_unused) {
|
if (set_unused) {
|
||||||
stack.push_form_element(this, true);
|
stack.push_form_element(this, true);
|
||||||
|
@ -1528,6 +1641,7 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac
|
||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
void ShortCircuitElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void ShortCircuitElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
if (!used_as_value.value_or(false)) {
|
if (!used_as_value.value_or(false)) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"ShortCircuitElement::push_to_stack not implemented for result not used case.");
|
"ShortCircuitElement::push_to_stack not implemented for result not used case.");
|
||||||
|
@ -1538,34 +1652,37 @@ void ShortCircuitElement::push_to_stack(const Env& env, FormPool& pool, FormStac
|
||||||
stack.push_form_element(this, true);
|
stack.push_form_element(this, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < int(entries.size()); i++) {
|
|
||||||
auto& entry = entries.at(i);
|
|
||||||
FormStack temp_stack(false);
|
|
||||||
for (auto& elt : entry.condition->elts()) {
|
|
||||||
elt->push_to_stack(env, pool, temp_stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<FormElement*> new_entries;
|
// the first condition is special
|
||||||
if (i == int(entries.size()) - 1) {
|
auto first_condition = entries.front().condition;
|
||||||
new_entries = rewrite_to_get_var(temp_stack, pool, final_result);
|
// lets evaluate in on the parent stack...
|
||||||
} else {
|
for (auto x : first_condition->elts()) {
|
||||||
new_entries = temp_stack.rewrite(pool);
|
x->push_to_stack(env, pool, stack);
|
||||||
}
|
|
||||||
|
|
||||||
entry.condition->clear();
|
|
||||||
for (auto e : new_entries) {
|
|
||||||
entry.condition->push_back(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto top_condition = entries.front().condition;
|
for (int i = 0; i < int(entries.size()); i++) {
|
||||||
if (!top_condition->is_single_element()) {
|
auto& entry = entries.at(i);
|
||||||
auto real_condition = top_condition->back();
|
if (entry.condition == first_condition) {
|
||||||
top_condition->pop_back();
|
entry.condition->clear();
|
||||||
for (auto x : top_condition->elts()) {
|
entry.condition->push_back(stack.pop_back(pool));
|
||||||
x->push_to_stack(env, pool, stack);
|
} else {
|
||||||
|
FormStack temp_stack(false);
|
||||||
|
for (auto& elt : entry.condition->elts()) {
|
||||||
|
elt->push_to_stack(env, pool, temp_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<FormElement*> new_entries;
|
||||||
|
if (i == int(entries.size()) - 1) {
|
||||||
|
new_entries = rewrite_to_get_var(temp_stack, pool, final_result);
|
||||||
|
} else {
|
||||||
|
new_entries = temp_stack.rewrite(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.condition->clear();
|
||||||
|
for (auto e : new_entries) {
|
||||||
|
entry.condition->push_back(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
top_condition->elts() = {real_condition};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(used_as_value.has_value());
|
assert(used_as_value.has_value());
|
||||||
|
@ -1579,6 +1696,7 @@ void ShortCircuitElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool) {
|
bool) {
|
||||||
|
mark_popped();
|
||||||
(void)stack;
|
(void)stack;
|
||||||
if (already_rewritten) {
|
if (already_rewritten) {
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
|
@ -1717,6 +1835,7 @@ FormElement* ConditionElement::make_generic(const Env&,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConditionElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void ConditionElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
std::vector<Form*> source_forms, popped_forms;
|
std::vector<Form*> source_forms, popped_forms;
|
||||||
std::vector<TypeSpec> source_types;
|
std::vector<TypeSpec> source_types;
|
||||||
std::vector<Variable> vars;
|
std::vector<Variable> vars;
|
||||||
|
@ -1766,6 +1885,7 @@ void ConditionElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
std::vector<Form*> source_forms, popped_forms;
|
std::vector<Form*> source_forms, popped_forms;
|
||||||
std::vector<TypeSpec> source_types;
|
std::vector<TypeSpec> source_types;
|
||||||
std::vector<Variable> vars;
|
std::vector<Variable> vars;
|
||||||
|
@ -1811,6 +1931,7 @@ void ConditionElement::update_from_stack(const Env& env,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
FormStack temp_stack(false);
|
FormStack temp_stack(false);
|
||||||
for (auto& elt : return_code->elts()) {
|
for (auto& elt : return_code->elts()) {
|
||||||
elt->push_to_stack(env, pool, temp_stack);
|
elt->push_to_stack(env, pool, temp_stack);
|
||||||
|
@ -1827,6 +1948,7 @@ void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomicOpElement::push_to_stack(const Env& env, FormPool&, FormStack& stack) {
|
void AtomicOpElement::push_to_stack(const Env& env, FormPool&, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
auto as_end = dynamic_cast<const FunctionEndOp*>(m_op);
|
auto as_end = dynamic_cast<const FunctionEndOp*>(m_op);
|
||||||
if (as_end) {
|
if (as_end) {
|
||||||
// we don't want to push this to the stack (for now at least)
|
// we don't want to push this to the stack (for now at least)
|
||||||
|
@ -1851,6 +1973,7 @@ void AtomicOpElement::push_to_stack(const Env& env, FormPool&, FormStack& stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsmOpElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
void AsmOpElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
stack.push_form_element(this, true);
|
stack.push_form_element(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1859,11 +1982,11 @@ void GenericElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool) {
|
bool) {
|
||||||
// TODO improve.
|
mark_popped();
|
||||||
if (m_head.m_kind == GenericOperator::Kind::FUNCTION_EXPR) {
|
if (m_elts.size() == 1) {
|
||||||
m_head.m_function->update_children_from_stack(env, pool, stack, false);
|
// a bit of a hack, but AtomicOpForm uses this for loading car/cdr
|
||||||
} else {
|
// this is safe to do.
|
||||||
m_elts.back()->update_children_from_stack(env, pool, stack, false);
|
m_elts.front()->update_children_from_stack(env, pool, stack, true);
|
||||||
}
|
}
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
@ -1871,6 +1994,7 @@ void GenericElement::update_from_stack(const Env& env,
|
||||||
void GenericElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void GenericElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
(void)env;
|
(void)env;
|
||||||
(void)pool;
|
(void)pool;
|
||||||
|
mark_popped();
|
||||||
stack.push_form_element(this, true);
|
stack.push_form_element(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1883,6 +2007,7 @@ void DynamicMethodAccess::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
auto new_val = stack.pop_reg(m_source, {}, env, allow_side_effects);
|
auto new_val = stack.pop_reg(m_source, {}, env, allow_side_effects);
|
||||||
auto reg0_matcher =
|
auto reg0_matcher =
|
||||||
Matcher::match_or({Matcher::any_reg(0), Matcher::cast("uint", Matcher::any_reg(0))});
|
Matcher::match_or({Matcher::any_reg(0), Matcher::cast("uint", Matcher::any_reg(0))});
|
||||||
|
@ -1927,12 +2052,11 @@ bool is_power_of_two(int in, int* out) {
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void ArrayFieldAccess::update_from_stack(const Env& env,
|
void ArrayFieldAccess::update_with_val(Form* new_val,
|
||||||
FormPool& pool,
|
const Env& env,
|
||||||
FormStack& stack,
|
FormPool& pool,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool) {
|
||||||
auto new_val = stack.pop_reg(m_source, {}, env, allow_side_effects);
|
|
||||||
int power_of_two = 0;
|
int power_of_two = 0;
|
||||||
|
|
||||||
if (m_constant_offset == 0) {
|
if (m_constant_offset == 0) {
|
||||||
|
@ -2077,6 +2201,16 @@ void ArrayFieldAccess::update_from_stack(const Env& env,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArrayFieldAccess::update_from_stack(const Env& env,
|
||||||
|
FormPool& pool,
|
||||||
|
FormStack& stack,
|
||||||
|
std::vector<FormElement*>* result,
|
||||||
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
|
auto new_val = stack.pop_reg(m_source, {}, env, allow_side_effects);
|
||||||
|
update_with_val(new_val, env, pool, result, allow_side_effects);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// CastElement
|
// CastElement
|
||||||
////////////////////////
|
////////////////////////
|
||||||
|
@ -2086,6 +2220,7 @@ void CastElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
m_source->update_children_from_stack(env, pool, stack, allow_side_effects);
|
m_source->update_children_from_stack(env, pool, stack, allow_side_effects);
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
@ -2099,6 +2234,7 @@ void TypeOfElement::update_from_stack(const Env& env,
|
||||||
FormStack& stack,
|
FormStack& stack,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool allow_side_effects) {
|
bool allow_side_effects) {
|
||||||
|
mark_popped();
|
||||||
value->update_children_from_stack(env, pool, stack, allow_side_effects);
|
value->update_children_from_stack(env, pool, stack, allow_side_effects);
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
@ -2108,6 +2244,7 @@ void TypeOfElement::update_from_stack(const Env& env,
|
||||||
////////////////////////
|
////////////////////////
|
||||||
|
|
||||||
void EmptyElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
void EmptyElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
stack.push_form_element(this, true);
|
stack.push_form_element(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2121,6 +2258,7 @@ bool is_symbol_true(const Form* form) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConditionalMoveFalseElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
void ConditionalMoveFalseElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||||
|
mark_popped();
|
||||||
// pop the value and the original
|
// pop the value and the original
|
||||||
auto popped = pop_to_forms({old_value, source}, env, pool, stack, true);
|
auto popped = pop_to_forms({old_value, source}, env, pool, stack, true);
|
||||||
if (!is_symbol_true(popped.at(0))) {
|
if (!is_symbol_true(popped.at(0))) {
|
||||||
|
@ -2136,27 +2274,21 @@ void ConditionalMoveFalseElement::push_to_stack(const Env& env, FormPool& pool,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleAtomElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
|
||||||
stack.push_form_element(this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SimpleAtomElement::update_from_stack(const Env&,
|
void SimpleAtomElement::update_from_stack(const Env&,
|
||||||
FormPool&,
|
FormPool&,
|
||||||
FormStack&,
|
FormStack&,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool) {
|
bool) {
|
||||||
|
mark_popped();
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleExpressionElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
|
||||||
stack.push_form_element(this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StringConstantElement::update_from_stack(const Env&,
|
void StringConstantElement::update_from_stack(const Env&,
|
||||||
FormPool&,
|
FormPool&,
|
||||||
FormStack&,
|
FormStack&,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool) {
|
bool) {
|
||||||
|
mark_popped();
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2165,6 +2297,7 @@ void GetMethodElement::update_from_stack(const Env&,
|
||||||
FormStack&,
|
FormStack&,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool) {
|
bool) {
|
||||||
|
mark_popped();
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2173,6 +2306,7 @@ void CondNoElseElement::update_from_stack(const Env&,
|
||||||
FormStack&,
|
FormStack&,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool) {
|
bool) {
|
||||||
|
mark_popped();
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2181,6 +2315,7 @@ void ConstantTokenElement::update_from_stack(const Env&,
|
||||||
FormStack&,
|
FormStack&,
|
||||||
std::vector<FormElement*>* result,
|
std::vector<FormElement*>* result,
|
||||||
bool) {
|
bool) {
|
||||||
|
mark_popped();
|
||||||
result->push_back(this);
|
result->push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,21 @@ Form* FormStack::unsafe_peek(Register reg, const Env& env) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FormElement* FormStack::pop_back(FormPool& pool) {
|
||||||
|
auto& back = m_stack.back();
|
||||||
|
assert(back.active);
|
||||||
|
back.active = false;
|
||||||
|
if (back.elt) {
|
||||||
|
return back.elt;
|
||||||
|
} else {
|
||||||
|
assert(back.destination.has_value());
|
||||||
|
auto elt = pool.alloc_element<SetVarElement>(*back.destination, back.source,
|
||||||
|
back.sequence_point, back.set_info);
|
||||||
|
back.source->parent_element = elt;
|
||||||
|
return elt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<FormElement*> FormStack::rewrite(FormPool& pool) {
|
std::vector<FormElement*> FormStack::rewrite(FormPool& pool) {
|
||||||
std::vector<FormElement*> result;
|
std::vector<FormElement*> result;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ class FormStack {
|
||||||
const Env& env,
|
const Env& env,
|
||||||
bool allow_side_effects,
|
bool allow_side_effects,
|
||||||
int begin_idx = -1);
|
int begin_idx = -1);
|
||||||
|
FormElement* pop_back(FormPool& pool);
|
||||||
Form* unsafe_peek(Register reg, const Env& env);
|
Form* unsafe_peek(Register reg, const Env& env);
|
||||||
bool is_single_expression();
|
bool is_single_expression();
|
||||||
std::vector<FormElement*> rewrite(FormPool& pool);
|
std::vector<FormElement*> rewrite(FormPool& pool);
|
||||||
|
|
|
@ -502,13 +502,13 @@
|
||||||
(define-extern search-process-tree (function process-tree (function process-tree object) process))
|
(define-extern search-process-tree (function process-tree (function process-tree object) process))
|
||||||
(define-extern execute-process-tree (function process-tree (function object object) kernel-context object))
|
(define-extern execute-process-tree (function process-tree (function object object) kernel-context object))
|
||||||
|
|
||||||
(define-extern previous-brother (function process-tree process-tree))
|
(define-extern previous-brother (function process-tree object))
|
||||||
(define-extern change-parent (function process-tree process-tree process-tree))
|
(define-extern change-parent (function process-tree process-tree process-tree))
|
||||||
(define-extern change-brother (function process-tree process-tree process-tree))
|
(define-extern change-brother (function process-tree process-tree object))
|
||||||
(define-extern change-to-last-brother (function process-tree process-tree))
|
(define-extern change-to-last-brother (function process-tree process-tree))
|
||||||
|
|
||||||
(define-extern *active-pool* process-tree)
|
(define-extern *active-pool* process-tree)
|
||||||
(define-extern kernel-dispatcher (function (function object)))
|
(define-extern kernel-dispatcher (function object))
|
||||||
(define-extern inspect-process-tree (function process-tree int int symbol process-tree))
|
(define-extern inspect-process-tree (function process-tree int int symbol process-tree))
|
||||||
|
|
||||||
(define-extern throw-dispatch (function catch-frame object none))
|
(define-extern throw-dispatch (function catch-frame object none))
|
||||||
|
@ -11014,120 +11014,116 @@
|
||||||
:flag-assert #x900000028
|
:flag-assert #x900000028
|
||||||
)
|
)
|
||||||
|
|
||||||
; ;; progress-h
|
;; progress-h
|
||||||
; (deftype progress (process)
|
(deftype progress (process)
|
||||||
; ((~Tcurrent-debug-string int32 :offset-assert 112)
|
((~Tcurrent-debug-string int32 :offset-assert 112)
|
||||||
; (~Tcurrent-debug-language int32 :offset-assert 116)
|
(~Tcurrent-debug-language int32 :offset-assert 116)
|
||||||
; (~Tcurrent-debug-group int32 :offset-assert 120)
|
(~Tcurrent-debug-group int32 :offset-assert 120)
|
||||||
; (~Tin-out-position int32 :offset-assert 124)
|
(~Tin-out-position int32 :offset-assert 124)
|
||||||
; (~Tdisplay-state uint64 :offset-assert 128)
|
(~Tdisplay-state uint64 :offset-assert 128)
|
||||||
; (~Tnext-display-state uint64 :offset-assert 136)
|
(~Tnext-display-state uint64 :offset-assert 136)
|
||||||
; (~Toption-index int32 :offset-assert 144)
|
(~Toption-index int32 :offset-assert 144)
|
||||||
; (~Tselected-option basic :offset-assert 148)
|
(~Tselected-option basic :offset-assert 148)
|
||||||
; (~Tcompletion-percentage float :offset-assert 152)
|
(~Tcompletion-percentage float :offset-assert 152)
|
||||||
; (~Tready-to-run basic :offset-assert 156)
|
(~Tready-to-run basic :offset-assert 156)
|
||||||
; (~Tdisplay-level-index int32 :offset-assert 160)
|
(~Tdisplay-level-index int32 :offset-assert 160)
|
||||||
; (~Tnext-level-index int32 :offset-assert 164)
|
(~Tnext-level-index int32 :offset-assert 164)
|
||||||
; (~Ttask-index int32 :offset-assert 168)
|
(~Ttask-index int32 :offset-assert 168)
|
||||||
; (~Tin-transition basic :offset-assert 172)
|
(~Tin-transition basic :offset-assert 172)
|
||||||
; (~Tlast-in-transition basic :offset-assert 176)
|
(~Tlast-in-transition basic :offset-assert 176)
|
||||||
; (~Tforce-transition basic :offset-assert 180)
|
(~Tforce-transition basic :offset-assert 180)
|
||||||
; (~Tstat-transition basic :offset-assert 184)
|
(~Tstat-transition basic :offset-assert 184)
|
||||||
; (~Tlevel-transition int32 :offset-assert 188)
|
(~Tlevel-transition int32 :offset-assert 188)
|
||||||
; (~Tlanguage-selection uint64 :offset-assert 192)
|
(~Tlanguage-selection uint64 :offset-assert 192)
|
||||||
; (~Tlanguage-direction basic :offset-assert 200)
|
(~Tlanguage-direction basic :offset-assert 200)
|
||||||
; (~Tlanguage-transition basic :offset-assert 204)
|
(~Tlanguage-transition basic :offset-assert 204)
|
||||||
; (~Tlanguage-x-offset int32 :offset-assert 208)
|
(~Tlanguage-x-offset int32 :offset-assert 208)
|
||||||
; (~Tsides-x-scale float :offset-assert 212)
|
(~Tsides-x-scale float :offset-assert 212)
|
||||||
; (~Tsides-y-scale float :offset-assert 216)
|
(~Tsides-y-scale float :offset-assert 216)
|
||||||
; (~Tleft-x-offset int32 :offset-assert 220)
|
(~Tleft-x-offset int32 :offset-assert 220)
|
||||||
; (~Tright-x-offset int32 :offset-assert 224)
|
(~Tright-x-offset int32 :offset-assert 224)
|
||||||
; (~Tbutton-scale float :offset-assert 228)
|
(~Tbutton-scale float :offset-assert 228)
|
||||||
; (~Tslot-scale float :offset-assert 232)
|
(~Tslot-scale float :offset-assert 232)
|
||||||
; (~Tleft-side-x-scale float :offset-assert 236)
|
(~Tleft-side-x-scale float :offset-assert 236)
|
||||||
; (~Tleft-side-y-scale float :offset-assert 240)
|
(~Tleft-side-y-scale float :offset-assert 240)
|
||||||
; (~Tright-side-x-scale float :offset-assert 244)
|
(~Tright-side-x-scale float :offset-assert 244)
|
||||||
; (~Tright-side-y-scale float :offset-assert 248)
|
(~Tright-side-y-scale float :offset-assert 248)
|
||||||
; (~Tsmall-orb-y-offset int32 :offset-assert 252)
|
(~Tsmall-orb-y-offset int32 :offset-assert 252)
|
||||||
; (~Tbig-orb-y-offset int32 :offset-assert 256)
|
(~Tbig-orb-y-offset int32 :offset-assert 256)
|
||||||
; (~Ttransition-offset int32 :offset-assert 260)
|
(~Ttransition-offset int32 :offset-assert 260)
|
||||||
; (~Ttransition-offset-invert int32 :offset-assert 264)
|
(~Ttransition-offset-invert int32 :offset-assert 264)
|
||||||
; (~Ttransition-percentage float :offset-assert 268)
|
(~Ttransition-percentage float :offset-assert 268)
|
||||||
; (~Ttransition-percentage-invert float :offset-assert 272)
|
(~Ttransition-percentage-invert float :offset-assert 272)
|
||||||
; (~Ttransition-speed float :offset-assert 276)
|
(~Ttransition-speed float :offset-assert 276)
|
||||||
; (~Ttotal-nb-of-power-cells int32 :offset-assert 280)
|
(~Ttotal-nb-of-power-cells int32 :offset-assert 280)
|
||||||
; (~Ttotal-nb-of-orbs int32 :offset-assert 284)
|
(~Ttotal-nb-of-orbs int32 :offset-assert 284)
|
||||||
; (~Ttotal-nb-of-buzzers int32 :offset-assert 288)
|
(~Ttotal-nb-of-buzzers int32 :offset-assert 288)
|
||||||
; (~Tcard-info mc-slot-info :offset-assert 292)
|
(~Tcard-info mc-slot-info :offset-assert 292)
|
||||||
; (~Tlast-option-index-change uint64 :offset-assert 296)
|
(~Tlast-option-index-change uint64 :offset-assert 296)
|
||||||
; (~Tvideo-mode-timeout uint64 :offset-assert 304)
|
(~Tvideo-mode-timeout uint64 :offset-assert 304)
|
||||||
; (~Tdisplay-state-stack UNKNOWN 5 :offset-assert 312)
|
(pad uint8 :offset 731)
|
||||||
; (~Toption-index-stack UNKNOWN 5 :offset-assert 352)
|
; (~Tdisplay-state-stack UNKNOWN 5 :offset-assert 312)
|
||||||
; (~Tdisplay-state-pos int32 :offset-assert 372)
|
; (~Toption-index-stack UNKNOWN 5 :offset-assert 352)
|
||||||
; (~Tnb-of-icons int32 :offset-assert 376)
|
; (~Tdisplay-state-pos int32 :offset-assert 372)
|
||||||
; (~Ticons UNKNOWN 6 :offset-assert 380)
|
; (~Tnb-of-icons int32 :offset-assert 376)
|
||||||
; (~Tmax-nb-of-particles int32 :offset-assert 404)
|
; (~Ticons UNKNOWN 6 :offset-assert 380)
|
||||||
; (~Tnb-of-particles int32 :offset-assert 408)
|
; (~Tmax-nb-of-particles int32 :offset-assert 404)
|
||||||
; (~Tparticles UNKNOWN 40 :offset-assert 412)
|
; (~Tnb-of-particles int32 :offset-assert 408)
|
||||||
; (~Tparticle-state UNKNOWN 40 :offset-assert 572)
|
; (~Tparticles UNKNOWN 40 :offset-assert 412)
|
||||||
; )
|
; (~Tparticle-state UNKNOWN 40 :offset-assert 572)
|
||||||
; :method-count-assert 59
|
)
|
||||||
; :size-assert #x2dc
|
:method-count-assert 59
|
||||||
; :flag-assert #x3b027002dc
|
:size-assert #x2dc
|
||||||
; ;; inherited inspect of process
|
:flag-assert #x3b000002dc
|
||||||
; (:methods
|
;; inherited inspect of process
|
||||||
; (dummy-9 () none 9)
|
(:methods
|
||||||
; (dummy-10 () none 10)
|
(dummy-14 () none 14)
|
||||||
; (dummy-11 () none 11)
|
(dummy-15 () none 15)
|
||||||
; (dummy-12 () none 12)
|
(dummy-16 () none 16)
|
||||||
; (dummy-13 () none 13)
|
(dummy-17 () none 17)
|
||||||
; (dummy-14 () none 14)
|
(dummy-18 () none 18)
|
||||||
; (dummy-15 () none 15)
|
(dummy-19 () none 19)
|
||||||
; (dummy-16 () none 16)
|
(dummy-20 () none 20)
|
||||||
; (dummy-17 () none 17)
|
(dummy-21 () none 21)
|
||||||
; (dummy-18 () none 18)
|
(dummy-22 () none 22)
|
||||||
; (dummy-19 () none 19)
|
(dummy-23 () none 23)
|
||||||
; (dummy-20 () none 20)
|
(dummy-24 () none 24)
|
||||||
; (dummy-21 () none 21)
|
(dummy-25 () none 25)
|
||||||
; (dummy-22 () none 22)
|
(dummy-26 () none 26)
|
||||||
; (dummy-23 () none 23)
|
(dummy-27 () none 27)
|
||||||
; (dummy-24 () none 24)
|
(dummy-28 () none 28)
|
||||||
; (dummy-25 () none 25)
|
(dummy-29 () none 29)
|
||||||
; (dummy-26 () none 26)
|
(dummy-30 () none 30)
|
||||||
; (dummy-27 () none 27)
|
(dummy-31 () none 31)
|
||||||
; (dummy-28 () none 28)
|
(dummy-32 () none 32)
|
||||||
; (dummy-29 () none 29)
|
(dummy-33 () none 33)
|
||||||
; (dummy-30 () none 30)
|
(dummy-34 () none 34)
|
||||||
; (dummy-31 () none 31)
|
(dummy-35 () none 35)
|
||||||
; (dummy-32 () none 32)
|
(dummy-36 () none 36)
|
||||||
; (dummy-33 () none 33)
|
(dummy-37 () none 37)
|
||||||
; (dummy-34 () none 34)
|
(dummy-38 () none 38)
|
||||||
; (dummy-35 () none 35)
|
(dummy-39 () none 39)
|
||||||
; (dummy-36 () none 36)
|
(dummy-40 () none 40)
|
||||||
; (dummy-37 () none 37)
|
(dummy-41 () none 41)
|
||||||
; (dummy-38 () none 38)
|
(dummy-42 () none 42)
|
||||||
; (dummy-39 () none 39)
|
(dummy-43 () none 43)
|
||||||
; (dummy-40 () none 40)
|
(dummy-44 () none 44)
|
||||||
; (dummy-41 () none 41)
|
(dummy-45 () none 45)
|
||||||
; (dummy-42 () none 42)
|
(dummy-46 () none 46)
|
||||||
; (dummy-43 () none 43)
|
(dummy-47 () none 47)
|
||||||
; (dummy-44 () none 44)
|
(dummy-48 () none 48)
|
||||||
; (dummy-45 () none 45)
|
(dummy-49 () none 49)
|
||||||
; (dummy-46 () none 46)
|
(dummy-50 () none 50)
|
||||||
; (dummy-47 () none 47)
|
(dummy-51 () none 51)
|
||||||
; (dummy-48 () none 48)
|
(dummy-52 () none 52)
|
||||||
; (dummy-49 () none 49)
|
(dummy-53 () none 53)
|
||||||
; (dummy-50 () none 50)
|
(dummy-54 () none 54)
|
||||||
; (dummy-51 () none 51)
|
(dummy-55 () none 55)
|
||||||
; (dummy-52 () none 52)
|
(dummy-56 () none 56)
|
||||||
; (dummy-53 () none 53)
|
(dummy-57 () none 57)
|
||||||
; (dummy-54 () none 54)
|
(dummy-58 () none 58)
|
||||||
; (dummy-55 () none 55)
|
)
|
||||||
; (dummy-56 () none 56)
|
)
|
||||||
; (dummy-57 () none 57)
|
|
||||||
; (dummy-58 () none 58)
|
|
||||||
; )
|
|
||||||
; )
|
|
||||||
|
|
||||||
;; rpc-h
|
;; rpc-h
|
||||||
(deftype rpc-buffer (basic)
|
(deftype rpc-buffer (basic)
|
||||||
|
@ -33078,7 +33074,7 @@
|
||||||
;;(define-extern *hud-parts* object) ;; unknown type
|
;;(define-extern *hud-parts* object) ;; unknown type
|
||||||
(define-extern game-option type)
|
(define-extern game-option type)
|
||||||
;;(define-extern progress object) ;; unknown type
|
;;(define-extern progress object) ;; unknown type
|
||||||
;;(define-extern *progress-process* object) ;; unknown type
|
(define-extern *progress-process* process) ;; unknown type
|
||||||
;;(define-extern count-info object) ;; unknown type
|
;;(define-extern count-info object) ;; unknown type
|
||||||
(define-extern task-info-data type)
|
(define-extern task-info-data type)
|
||||||
(define-extern game-count-info type)
|
(define-extern game-count-info type)
|
||||||
|
@ -35375,13 +35371,13 @@
|
||||||
(define-extern main-cheats function)
|
(define-extern main-cheats function)
|
||||||
;;(define-extern *progress-cheat* object) ;; unknown type
|
;;(define-extern *progress-cheat* object) ;; unknown type
|
||||||
(define-extern display-loop function)
|
(define-extern display-loop function)
|
||||||
(define-extern letterbox function)
|
(define-extern letterbox (function none))
|
||||||
;;(define-extern *cheat-temp* object) ;; unknown type
|
;;(define-extern *cheat-temp* object) ;; unknown type
|
||||||
;;(define-extern *master-exit* object) ;; unknown type
|
;;(define-extern *master-exit* object) ;; unknown type
|
||||||
;;(define-extern *last-master-mode* object) ;; unknown type
|
;;(define-extern *last-master-mode* object) ;; unknown type
|
||||||
(define-extern off function)
|
(define-extern off function)
|
||||||
;;(define-extern *screen-filter* object) ;; unknown type
|
;;(define-extern *screen-filter* object) ;; unknown type
|
||||||
(define-extern set-letterbox-frames function)
|
(define-extern set-letterbox-frames (function int none))
|
||||||
(define-extern entity-by-type function)
|
(define-extern entity-by-type function)
|
||||||
;;(define-extern scf-get-timeout object) ;; unknown type
|
;;(define-extern scf-get-timeout object) ;; unknown type
|
||||||
(define-extern pause-allowed? function)
|
(define-extern pause-allowed? function)
|
||||||
|
@ -35767,7 +35763,7 @@
|
||||||
;;(define-extern iron object) ;; unknown type
|
;;(define-extern iron object) ;; unknown type
|
||||||
;;(define-extern wood object) ;; unknown type
|
;;(define-extern wood object) ;; unknown type
|
||||||
;;(define-extern crate-type object) ;; unknown type
|
;;(define-extern crate-type object) ;; unknown type
|
||||||
;;(define-extern hud-arriving object) ;; unknown type
|
(define-extern hud-arriving state) ;; unknown type
|
||||||
;;(define-extern hud-leaving object) ;; unknown type
|
;;(define-extern hud-leaving object) ;; unknown type
|
||||||
;;(define-extern hud-hidden object) ;; unknown type
|
;;(define-extern hud-hidden object) ;; unknown type
|
||||||
;;(define-extern hud-in object) ;; unknown type
|
;;(define-extern hud-in object) ;; unknown type
|
||||||
|
|
|
@ -340,6 +340,11 @@
|
||||||
"(method 0 state)":{
|
"(method 0 state)":{
|
||||||
"args":["allocation", "type-to-make", "name", "code", "trans", "enter", "exit", "event"],
|
"args":["allocation", "type-to-make", "name", "code", "trans", "enter", "exit", "event"],
|
||||||
"vars":{"v0-0":"obj"}
|
"vars":{"v0-0":"obj"}
|
||||||
|
},
|
||||||
|
|
||||||
|
"previous-brother":{
|
||||||
|
"args":["proc"],
|
||||||
|
"vars":{"v1-0":"parent", "v1-2":"child"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
- The types `cpu-thread` and `catch-frame` have a slightly different layout in OpenGOAL to back up x86-64 registers
|
- The types `cpu-thread` and `catch-frame` have a slightly different layout in OpenGOAL to back up x86-64 registers
|
||||||
|
|
||||||
## `gkernel`:
|
## `gkernel`:
|
||||||
- In progress
|
- Many changes for x86-64/OpenGOAL
|
||||||
|
- A few bugs in the game related to `process-tree` vs `(pointer process-tree)`.
|
||||||
|
- `change-brother` is totally wrong, unused, and left out.
|
||||||
|
|
||||||
## `pskernel`: **Done**
|
## `pskernel`: **Done**
|
||||||
- Unimplemented in OpenGOAL. Seems to be debugging hooks into the PS2's kernel. Error strings indicate that there should have been a second related file included that actually contained the debugging handlers, but this file is not present.
|
- Unimplemented in OpenGOAL. Seems to be debugging hooks into the PS2's kernel. Error strings indicate that there should have been a second related file included that actually contained the debugging handlers, but this file is not present.
|
||||||
|
|
24
doc/emacs_config.el
Normal file
24
doc/emacs_config.el
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
;; make gc files use lisp-mode
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.gc\\'" . lisp-mode))
|
||||||
|
;; run setup-goal when we enter lisp mode
|
||||||
|
(add-hook 'lisp-mode-hook 'setup-goal)
|
||||||
|
|
||||||
|
(defun setup-goal ()
|
||||||
|
;; if we are in a gc file, change indent settings for GOAL
|
||||||
|
(when (and (stringp buffer-file-name)
|
||||||
|
(string-match "\\.gc\\'" buffer-file-name))
|
||||||
|
(put 'with-pp 'common-lisp-indent-function 0)
|
||||||
|
(put 'while 'common-lisp-indent-function 1)
|
||||||
|
(put 'rlet 'common-lisp-indent-function 1)
|
||||||
|
(put 'until 'common-lisp-indent-function 1)
|
||||||
|
(put 'countdown 'common-lisp-indent-function 1)
|
||||||
|
(put 'defun-debug 'common-lisp-indent-function 2)
|
||||||
|
(put 'defenum 'common-lisp-indent-function 2)
|
||||||
|
|
||||||
|
;; indent for common lisp, this makes if's look nicer
|
||||||
|
(custom-set-variables '(lisp-indent-function 'common-lisp-indent-function))
|
||||||
|
(autoload 'common-lisp-indent-function "cl-indent" "Common Lisp indent.")
|
||||||
|
;; use spaces, not tabs
|
||||||
|
(setq-default indent-tabs-mode nil)
|
||||||
|
)
|
||||||
|
)
|
File diff suppressed because it is too large
Load diff
|
@ -876,7 +876,7 @@ Val* Compiler::compile_new(const goos::Object& form, const goos::Object& _rest,
|
||||||
auto type = pair_car(*rest);
|
auto type = pair_car(*rest);
|
||||||
rest = &pair_cdr(*rest);
|
rest = &pair_cdr(*rest);
|
||||||
|
|
||||||
if (allocation == "global" || allocation == "debug") {
|
if (allocation == "global" || allocation == "debug" || allocation == "process") {
|
||||||
// allocate on a named heap
|
// allocate on a named heap
|
||||||
return compile_heap_new(form, allocation, type, rest, env);
|
return compile_heap_new(form, allocation, type, rest, env);
|
||||||
} else if (allocation == "static") {
|
} else if (allocation == "static") {
|
||||||
|
|
|
@ -640,10 +640,8 @@ TEST_F(FormRegressionTest, ExprArrayMethod2) {
|
||||||
" )\n"
|
" )\n"
|
||||||
" )\n"
|
" )\n"
|
||||||
" (else\n"
|
" (else\n"
|
||||||
// todo - why doesn't this merge?
|
|
||||||
" (set! v1-40 (or (= v1-1 (quote uint128)) (= v1-1 (quote int128))))\n"
|
|
||||||
" (cond\n"
|
" (cond\n"
|
||||||
" (v1-40\n"
|
" ((or (= v1-1 (quote uint128)) (= v1-1 (quote int128)))\n"
|
||||||
" (set! s5-8 0)\n"
|
" (set! s5-8 0)\n"
|
||||||
" (while\n"
|
" (while\n"
|
||||||
" (< s5-8 (-> arg0 length))\n"
|
" (< s5-8 (-> arg0 length))\n"
|
||||||
|
@ -1309,9 +1307,8 @@ TEST_F(FormRegressionTest, ExprArrayMethod3) {
|
||||||
" )\n"
|
" )\n"
|
||||||
" )\n"
|
" )\n"
|
||||||
" (else\n"
|
" (else\n"
|
||||||
" (set! v1-40 (or (= v1-1 (quote int128)) (= v1-1 (quote uint128))))\n"
|
|
||||||
" (cond\n"
|
" (cond\n"
|
||||||
" (v1-40\n"
|
" ((or (= v1-1 (quote int128)) (= v1-1 (quote uint128)))\n"
|
||||||
" (set! s5-8 0)\n"
|
" (set! s5-8 0)\n"
|
||||||
" (while\n"
|
" (while\n"
|
||||||
" (< s5-8 (-> arg0 length))\n"
|
" (< s5-8 (-> arg0 length))\n"
|
||||||
|
@ -2092,16 +2089,11 @@ TEST_F(FormRegressionTest, ExprValid) {
|
||||||
" (quote #f)\n"
|
" (quote #f)\n"
|
||||||
" )\n"
|
" )\n"
|
||||||
" (else\n"
|
" (else\n"
|
||||||
// todo - why isn't this compacted?
|
|
||||||
" (set!\n"
|
|
||||||
" v1-33\n"
|
|
||||||
" (and\n"
|
|
||||||
" (!= arg1 type)\n"
|
|
||||||
" (not (valid? (rtype-of arg0) type (quote #f) (quote #t) 0))\n"
|
|
||||||
" )\n"
|
|
||||||
" )\n"
|
|
||||||
" (cond\n"
|
" (cond\n"
|
||||||
" (v1-33\n"
|
" ((and\t\n"
|
||||||
|
" (!= arg1 type)\t\n"
|
||||||
|
" (not (valid? (rtype-of arg0) type (quote #f) (quote #t) 0))\t\n"
|
||||||
|
" )\n"
|
||||||
" (if\n"
|
" (if\n"
|
||||||
" arg2\n"
|
" arg2\n"
|
||||||
" (format\n"
|
" (format\n"
|
||||||
|
@ -2483,7 +2475,6 @@ TEST_F(FormRegressionTest, ExprStringToInt) {
|
||||||
" (a0-5 symbol)\n"
|
" (a0-5 symbol)\n"
|
||||||
" (a1-8 (pointer uint8))\n"
|
" (a1-8 (pointer uint8))\n"
|
||||||
" (a1-14 uint)\n"
|
" (a1-14 uint)\n"
|
||||||
" (a1-16 symbol)\n"
|
|
||||||
" (a1-20 uint)\n"
|
" (a1-20 uint)\n"
|
||||||
" (a1-23 uint)\n"
|
" (a1-23 uint)\n"
|
||||||
" (a1-33 symbol)\n"
|
" (a1-33 symbol)\n"
|
||||||
|
@ -2529,15 +2520,11 @@ TEST_F(FormRegressionTest, ExprStringToInt) {
|
||||||
" (set! a1-14 v0-0)\n"
|
" (set! a1-14 v0-0)\n"
|
||||||
" )\n"
|
" )\n"
|
||||||
" (else\n"
|
" (else\n"
|
||||||
" (set!\n"
|
|
||||||
" a1-16\n"
|
|
||||||
" (and\n"
|
|
||||||
" (>= (-> a0-3 0) (the-as uint 97))\n"
|
|
||||||
" (>= (the-as uint 102) (-> a0-3 0))\n"
|
|
||||||
" )\n"
|
|
||||||
" )\n"
|
|
||||||
" (cond\n"
|
" (cond\n"
|
||||||
" (a1-16\n"
|
" ((and\t\n"
|
||||||
|
" (>= (-> a0-3 0) (the-as uint 97))\t\n"
|
||||||
|
" (>= (the-as uint 102) (-> a0-3 0))\t\n"
|
||||||
|
" )\n"
|
||||||
" (set! v0-0 (+ (+ (-> a0-3 0) -87) (the-as uint (shl v0-0 4))))\n"
|
" (set! v0-0 (+ (+ (-> a0-3 0) -87) (the-as uint (shl v0-0 4))))\n"
|
||||||
" (set! a1-20 v0-0)\n"
|
" (set! a1-20 v0-0)\n"
|
||||||
" )\n"
|
" )\n"
|
||||||
|
|
|
@ -534,8 +534,7 @@ TEST_F(FormRegressionTest, RemoveMethod3ProcessTree) {
|
||||||
" (set! a0-5 (quote #t))\n"
|
" (set! a0-5 (quote #t))\n"
|
||||||
" (set! a1-4 \"~Tbrother: ~A~%\")\n"
|
" (set! a1-4 \"~Tbrother: ~A~%\")\n"
|
||||||
" (set! v1-2 (-> arg0 brother))\n"
|
" (set! v1-2 (-> arg0 brother))\n"
|
||||||
" (set! a2-4 (if v1-2 (-> v1-2 0 self)))\n"
|
" (t9-4 a0-5 a1-4 (if v1-2 (-> v1-2 0 self)))\n"
|
||||||
" (t9-4 a0-5 a1-4 a2-4)\n"
|
|
||||||
" (set! t9-5 format)\n"
|
" (set! t9-5 format)\n"
|
||||||
" (set! a0-6 (quote #t))\n"
|
" (set! a0-6 (quote #t))\n"
|
||||||
" (set! a1-5 \"~Tchild: ~A~%\")\n"
|
" (set! a1-5 \"~Tchild: ~A~%\")\n"
|
||||||
|
@ -2533,7 +2532,8 @@ TEST_F(FormRegressionTest, ExprMethod16DeadPoolHeap) {
|
||||||
std::string expected =
|
std::string expected =
|
||||||
"(begin\n"
|
"(begin\n"
|
||||||
" (set! s4-0 (memory-free arg0))\n"
|
" (set! s4-0 (memory-free arg0))\n"
|
||||||
" (set! f0-2 (/ (the float s4-0) (the float (memory-total arg0))))\n"
|
" (set! v1-2 (memory-total arg0))\n"
|
||||||
|
" (set! f0-2 (/ (the float s4-0) (the float v1-2)))"
|
||||||
" (cond\n"
|
" (cond\n"
|
||||||
" ((< f0-2 (l.f L346))\n"
|
" ((< f0-2 (l.f L346))\n"
|
||||||
" (set! arg1 1000)\n"
|
" (set! arg1 1000)\n"
|
||||||
|
|
Loading…
Reference in a new issue