cgen: fix closure code gen with if statement in definition (#12028)

pull/12037/head
05st 2021-10-01 08:52:34 -05:00 committed by GitHub
parent cb149bfa00
commit 60ecbec8ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 7 deletions

View File

@ -425,20 +425,17 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) {
return
}
// it may be possible to optimize `memdup` out if the closure never leaves current scope
ctx_var := g.new_tmp_var()
cur_line := g.go_before_stmt(0)
ctx_struct := closure_ctx_struct(node.decl)
g.writeln('$ctx_struct* $ctx_var = ($ctx_struct*) memdup(&($ctx_struct){')
// TODO in case of an assignment, this should only call "__closure_set_data" and "__closure_set_function" (and free the former data)
g.write('__closure_create($node.decl.name, ${node.decl.params.len + 1}, ')
g.writeln('($ctx_struct*) memdup(&($ctx_struct){')
g.indent++
for var in node.inherited_vars {
g.writeln('.$var.name = $var.name,')
}
g.indent--
g.writeln('}, sizeof($ctx_struct));')
g.write('}, sizeof($ctx_struct)))')
g.empty_line = false
g.write(cur_line)
// TODO in case of an assignment, this should only call "__closure_set_data" and "__closure_set_function" (and free the former data)
g.write('__closure_create($node.decl.name, ${node.decl.params.len + 1}, $ctx_var)')
}
fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) {

View File

@ -151,3 +151,20 @@ fn test_go_call_closure() {
assert <-ch == 15
}
*/
fn test_closures_with_ifstmt() {
a := 1
f := fn [a] (x int) int {
if a > x { return 1
} else { return -1
}
}
g := fn [a] () int {
if true {
return 1
}
return 0
}
assert f(0) == 1
assert g() == 1
}