Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FunC: enable asserts and fix try/catch stack corruption #699

Merged
merged 4 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crypto/func/abscode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ TmpVar::TmpVar(var_idx_t _idx, int _cls, TypeExpr* _type, SymDef* sym, const Src
if (!_type) {
v_type = TypeExpr::new_hole();
}
if (cls == _Named) {
undefined = true;
}
}

void TmpVar::set_location(const SrcLocation& loc) {
Expand Down
26 changes: 13 additions & 13 deletions crypto/func/analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ int CodeBlob::split_vars(bool strict) {
}
std::vector<TypeExpr*> comp_types;
int k = var.v_type->extract_components(comp_types);
assert(k <= 254 && n <= 0x7fff00);
assert((unsigned)k == comp_types.size());
func_assert(k <= 254 && n <= 0x7fff00);
func_assert((unsigned)k == comp_types.size());
if (k != 1) {
var.coord = ~((n << 8) + k);
for (int i = 0; i < k; i++) {
auto v = create_var(vars[j].cls, comp_types[i], 0, vars[j].where.get());
assert(v == n + i);
assert(vars[v].idx == v);
func_assert(v == n + i);
func_assert(vars[v].idx == v);
vars[v].name = vars[j].name;
vars[v].coord = ((int)j << 8) + i + 1;
}
Expand All @@ -75,9 +75,9 @@ bool CodeBlob::compute_used_code_vars() {
}

bool CodeBlob::compute_used_code_vars(std::unique_ptr<Op>& ops_ptr, const VarDescrList& var_info, bool edit) const {
assert(ops_ptr);
func_assert(ops_ptr);
if (!ops_ptr->next) {
assert(ops_ptr->cl == Op::_Nop);
func_assert(ops_ptr->cl == Op::_Nop);
return ops_ptr->set_var_info(var_info);
}
return compute_used_code_vars(ops_ptr->next, var_info, edit) | ops_ptr->compute_used_vars(*this, edit);
Expand Down Expand Up @@ -346,7 +346,7 @@ bool Op::std_compute_used_vars(bool disabled) {
}

bool Op::compute_used_vars(const CodeBlob& code, bool edit) {
assert(next);
func_assert(next);
const VarDescrList& next_var_info = next->var_info;
if (cl == _Nop) {
return set_var_info_except(next_var_info, left);
Expand Down Expand Up @@ -379,7 +379,7 @@ bool Op::compute_used_vars(const CodeBlob& code, bool edit) {
case _Let: {
// left = right
std::size_t cnt = next_var_info.count_used(left);
assert(left.size() == right.size());
func_assert(left.size() == right.size());
auto l_it = left.cbegin(), r_it = right.cbegin();
VarDescrList new_var_info{next_var_info};
new_var_info -= left;
Expand Down Expand Up @@ -500,7 +500,7 @@ bool Op::compute_used_vars(const CodeBlob& code, bool edit) {
}
changes = (new_var_info.size() == n);
} while (changes <= edit);
assert(left.size() == 1);
func_assert(left.size() == 1);
bool last = new_var_info.count_used(left) == 0;
new_var_info += left;
if (last) {
Expand Down Expand Up @@ -655,7 +655,7 @@ bool prune_unreachable(std::unique_ptr<Op>& ops) {
ops = std::move(op.block0);
return false;
}
reach = true;
reach = (op.cl != Op::_Again);
break;
}
case Op::_TryCatch: {
Expand Down Expand Up @@ -684,7 +684,7 @@ void CodeBlob::prune_unreachable_code() {

void CodeBlob::fwd_analyze() {
VarDescrList values;
assert(ops && ops->cl == Op::_Import);
func_assert(ops && ops->cl == Op::_Import);
for (var_idx_t i : ops->left) {
values += i;
if (vars[i].v_type->is_int()) {
Expand Down Expand Up @@ -765,7 +765,7 @@ VarDescrList Op::fwd_analyze(VarDescrList values) {
break;
case _Let: {
std::vector<VarDescr> old_val;
assert(left.size() == right.size());
func_assert(left.size() == right.size());
for (std::size_t i = 0; i < right.size(); i++) {
const VarDescr* ov = values[right[i]];
if (!ov && verbosity >= 5) {
Expand All @@ -780,7 +780,7 @@ VarDescrList Op::fwd_analyze(VarDescrList values) {
}
std::cerr << std::endl;
}
// assert(ov);
// func_assert(ov);
if (ov) {
old_val.push_back(*ov);
} else {
Expand Down
109 changes: 109 additions & 0 deletions crypto/func/auto-tests/tests/try-func.fc
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
int foo(int x) method_id(11) {
try {
if (x == 7) {
throw(44);
}
return x;
} catch (_, _) {
return 2;
}
}

int foo_inline(int x) inline method_id(12) {
try {
if (x == 7) {
throw(44);
}
return x;
} catch (_, _) {
return 2;
}
}

int foo_inlineref(int x) inline_ref method_id(13) {
try {
if (x == 7) {
throw(44);
}
return x;
} catch (_, _) {
return 2;
}
}

int test(int x, int y, int z) method_id(1) {
y = foo(y);
return x * 100 + y * 10 + z;
}

int test_inline(int x, int y, int z) method_id(2) {
y = foo_inline(y);
return x * 100 + y * 10 + z;
}

int test_inlineref(int x, int y, int z) method_id(3) {
y = foo_inlineref(y);
return x * 100 + y * 10 + z;
}

int foo_inline_big(
int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, int x10,
int x11, int x12, int x13, int x14, int x15, int x16, int x17, int x18, int x19, int x20
) inline method_id(14) {
try {
if (x1 == 7) {
throw(44);
}
return x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20;
} catch (_, _) {
return 1;
}
}

int test_inline_big(int x, int y, int z) method_id(4) {
y = foo_inline_big(
y, y + 1, y + 2, y + 3, y + 4, y + 5, y + 6, y + 7, y + 8, y + 9,
y + 10, y + 11, y + 12, y + 13, y + 14, y + 15, y + 16, y + 17, y + 18, y + 19);
return x * 1000000 + y * 1000 + z;
}

int foo_big(
int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, int x10,
int x11, int x12, int x13, int x14, int x15, int x16, int x17, int x18, int x19, int x20
) method_id(15) {
try {
if (x1 == 7) {
throw(44);
}
return x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20;
} catch (_, _) {
return 1;
}
}

int test_big(int x, int y, int z) method_id(5) {
y = foo_big(
y, y + 1, y + 2, y + 3, y + 4, y + 5, y + 6, y + 7, y + 8, y + 9,
y + 10, y + 11, y + 12, y + 13, y + 14, y + 15, y + 16, y + 17, y + 18, y + 19);
return x * 1000000 + y * 1000 + z;
}

() main() {
}

{-
method_id | in | out
TESTCASE | 1 | 1 2 3 | 123
TESTCASE | 1 | 3 8 9 | 389
TESTCASE | 1 | 3 7 9 | 329
TESTCASE | 2 | 1 2 3 | 123
TESTCASE | 2 | 3 8 9 | 389
TESTCASE | 2 | 3 7 9 | 329
TESTCASE | 3 | 1 2 3 | 123
TESTCASE | 3 | 3 8 9 | 389
TESTCASE | 3 | 3 7 9 | 329
TESTCASE | 4 | 4 8 9 | 4350009
TESTCASE | 4 | 4 7 9 | 4001009
TESTCASE | 5 | 4 8 9 | 4350009
TESTCASE | 5 | 4 7 9 | 4001009
-}
Loading