cgen: support larger closure parameters (#13040)
parent
897bbb7da5
commit
de711da774
|
@ -330,6 +330,8 @@ const c_common_macros = '
|
||||||
|
|
||||||
// returns the number of CPU registers that TYPE takes up
|
// returns the number of CPU registers that TYPE takes up
|
||||||
#define _REG_WIDTH(T) (((sizeof(T) + sizeof(void*) - 1) & ~(sizeof(void*) - 1)) / sizeof(void*))
|
#define _REG_WIDTH(T) (((sizeof(T) + sizeof(void*) - 1) & ~(sizeof(void*) - 1)) / sizeof(void*))
|
||||||
|
// parameters of size <= 2 registers are spilled across those two registers; larger types are passed as one pointer to some stack location
|
||||||
|
#define _REG_WIDTH_BOUNDED(T) (_REG_WIDTH(T) <= 2 ? _REG_WIDTH(T) : 1)
|
||||||
|
|
||||||
#define OPTION_CAST(x) (x)
|
#define OPTION_CAST(x) (x)
|
||||||
|
|
||||||
|
|
|
@ -467,7 +467,7 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) {
|
||||||
|
|
||||||
mut size_sb := strings.new_builder(node.decl.params.len * 50)
|
mut size_sb := strings.new_builder(node.decl.params.len * 50)
|
||||||
for param in node.decl.params {
|
for param in node.decl.params {
|
||||||
size_sb.write_string('_REG_WIDTH(${g.typ(param.typ)}) + ')
|
size_sb.write_string('_REG_WIDTH_BOUNDED(${g.typ(param.typ)}) + ')
|
||||||
}
|
}
|
||||||
if g.pref.arch == .amd64 && node.decl.return_type != ast.void_type {
|
if g.pref.arch == .amd64 && node.decl.return_type != ast.void_type {
|
||||||
size_sb.write_string('(_REG_WIDTH(${g.typ(node.decl.return_type)}) > 2) + ')
|
size_sb.write_string('(_REG_WIDTH(${g.typ(node.decl.return_type)}) > 2) + ')
|
||||||
|
|
|
@ -168,3 +168,33 @@ fn test_closures_with_ifstmt() {
|
||||||
assert f(0) == 1
|
assert f(0) == 1
|
||||||
assert g() == 1
|
assert g() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Command {
|
||||||
|
a int = 1234
|
||||||
|
b int = 2345
|
||||||
|
c int = 3456
|
||||||
|
d int = 4567
|
||||||
|
e int = 5678
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mut app := &App{}
|
||||||
|
eprintln('app ptr: ${u64(app)}')
|
||||||
|
f := fn [mut app] (cmd Command) u64 {
|
||||||
|
p := u64(app)
|
||||||
|
println('>> p: $p')
|
||||||
|
println('>> cmd: $cmd')
|
||||||
|
assert cmd.a == 1234
|
||||||
|
assert cmd.b == 2345
|
||||||
|
assert cmd.c == 3456
|
||||||
|
assert cmd.d == 4567
|
||||||
|
assert cmd.e == 5678
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
cmd := Command{}
|
||||||
|
res := f(cmd)
|
||||||
|
println('> res: $res | sizeof Command: ${sizeof(Command)}')
|
||||||
|
assert res == u64(app)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue