x64: pass variables to functions

pull/5408/head
Alexander Medvednikov 2020-06-17 20:18:48 +02:00
parent 9c9f6415da
commit a602673adb
8 changed files with 100 additions and 29 deletions

View File

@ -80,6 +80,12 @@ fn test_orm_sqlite() {
assert users3.len == 2 assert users3.len == 2
assert users3[0].age == 29 assert users3[0].age == 29
assert users3[1].age == 31 assert users3[1].age == 31
//user2 := User{}
//x := sql db {
//insert user2 into User
//}
//db.insert<User>(user2)
} }

View File

@ -118,3 +118,7 @@ pub fn (db DB) exec_none(query string) int {
pub fn (db DB) exec_param(query string, param string) []Row { pub fn (db DB) exec_param(query string, param string) []Row {
} }
*/ */
pub fn (db DB) insert<T>(x T) {
}

View File

@ -819,6 +819,9 @@ pub:
is_array bool is_array bool
} }
pub struct SqlInsertExpr {
}
[inline] [inline]
pub fn (expr Expr) is_blank_ident() bool { pub fn (expr Expr) is_blank_ident() bool {
match expr { match expr {

View File

@ -1573,7 +1573,7 @@ fn (mut g Gen) expr(node ast.Expr) {
g.write('sizeof($styp)') g.write('sizeof($styp)')
} }
ast.SqlExpr { ast.SqlExpr {
g.sql_expr(it) g.sql_select_expr(it)
} }
ast.StringLiteral { ast.StringLiteral {
if it.is_raw { if it.is_raw {

View File

@ -12,7 +12,10 @@ const (
dbtype = 'sqlite' dbtype = 'sqlite'
) )
fn (mut g Gen) sql_expr(node ast.SqlExpr) { fn (mut g Gen) sql_insert_expr(node ast.SqlInsertExpr) {
}
fn (mut g Gen) sql_select_expr(node ast.SqlExpr) {
g.sql_i = 0 g.sql_i = 0
/* /*
`nr_users := sql db { ... }` => `nr_users := sql db { ... }` =>
@ -68,11 +71,11 @@ fn (mut g Gen) sql_expr(node ast.SqlExpr) {
styp := g.typ(node.typ) styp := g.typ(node.typ)
mut elem_type_str := '' mut elem_type_str := ''
if node.is_array { if node.is_array {
// array_User array_tmp;
// for { User tmp; ... array_tmp << tmp; }
sym := g.table.get_type_symbol(node.typ) sym := g.table.get_type_symbol(node.typ)
info := sym.info as table.Array info := sym.info as table.Array
elem_type_str = g.typ(info.elem_type) elem_type_str = g.typ(info.elem_type)
// array_User array_tmp;
// for { User tmp; ... array_tmp << tmp; }
g.writeln('$styp ${tmp}_array = __new_array(0, 10, sizeof($elem_type_str));') g.writeln('$styp ${tmp}_array = __new_array(0, 10, sizeof($elem_type_str));')
g.writeln('while (1) {') g.writeln('while (1) {')
g.writeln('\t$elem_type_str $tmp;') g.writeln('\t$elem_type_str $tmp;')

View File

@ -58,7 +58,7 @@ enum Register {
} }
const ( const (
fn_arg_registers = [x64.Register.rdi, .rsi, .rdx, .rcx, .r8, .r9] fn_arg_registers = [Register.rdi, .rsi, .rdx, .rcx, .r8, .r9]
) )
/* /*
@ -263,7 +263,8 @@ fn (mut g Gen) println(comment string) {
addr := g.debug_pos.hex() addr := g.debug_pos.hex()
// println('$g.debug_pos "$addr"') // println('$g.debug_pos "$addr"')
print(term.red(strings.repeat(`0`, 6 - addr.len) + addr + ' ')) print(term.red(strings.repeat(`0`, 6 - addr.len) + addr + ' '))
for i := g.debug_pos; i < g.buf.len; i++ { for i := g.debug_pos; i < g.buf.len; i++
{
s := g.buf[i].hex() s := g.buf[i].hex()
if s.len == 1 { if s.len == 1 {
print(term.blue('0')) print(term.blue('0'))
@ -318,7 +319,21 @@ fn (mut g Gen) mov_from_reg(var_offset int, reg Register) {
else { verror('mov_from_reg $reg') } else { verror('mov_from_reg $reg') }
} }
g.write8(0xff - var_offset + 1) g.write8(0xff - var_offset + 1)
g.println('mov from reg') g.println('mov DWORD PTR[rbp-$var_offset.hex()],$reg')
}
fn (mut g Gen) mov_rbp_offset(reg Register, var_offset int) {
// 8b 7d f8 mov edi,DWORD PTR [rbp-0x8]
g.write8(0x8b)
match reg {
.edi, .rdi { g.write8(0x7d) }
.rsi { g.write8(0x75) }
.rdx { g.write8(0x55) }
.rcx { g.write8(0x4d) }
else { verror('mov_rbp_offset $reg') }
}
g.write8(0xff - var_offset + 1)
g.println('mov $reg,DWORD PTR[rbp-$var_offset]')
} }
fn (mut g Gen) call(addr int) { fn (mut g Gen) call(addr int) {
@ -372,7 +387,15 @@ pub fn (mut g Gen) sub32(reg Register, val int) {
g.write8(0x81) g.write8(0x81)
g.write8(0xe8 + reg) // TODO rax is different? g.write8(0xe8 + reg) // TODO rax is different?
g.write32(val) g.write32(val)
g.println('sub $reg,0x$val.hex()') g.println('sub32 $reg,0x$val.hex()')
}
pub fn (mut g Gen) sub8(reg Register, val int) {
g.write8(0x48)
g.write8(0x83)
g.write8(0xe8 + reg) // TODO rax is different?
g.write8(val)
g.println('sub8 $reg,0x$val.hex()')
} }
pub fn (mut g Gen) add(reg Register, val int) { pub fn (mut g Gen) add(reg Register, val int) {
@ -383,6 +406,15 @@ pub fn (mut g Gen) add(reg Register, val int) {
g.println('add $reg,0x$val.hex()') g.println('add $reg,0x$val.hex()')
} }
pub fn (mut g Gen) add8(reg Register, val int) {
g.write8(0x48)
g.write8(0x83)
// g.write8(0xe8 + reg) // TODO rax is different?
g.write8(0xc4)
g.write8(val)
g.println('add8 $reg,0x$val.hex()')
}
fn (mut g Gen) leave() { fn (mut g Gen) leave() {
g.write8(0xc9) g.write8(0xc9)
g.println('leave') g.println('leave')
@ -502,8 +534,23 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
// g.mov(.eax, 0) // g.mov(.eax, 0)
for i in 0 .. node.args.len { for i in 0 .. node.args.len {
expr := node.args[i].expr expr := node.args[i].expr
int_lit := expr as ast.IntegerLiteral match expr {
g.mov(fn_arg_registers[i], int_lit.val.int()) ast.IntegerLiteral {
// `foo(2)` => `mov edi,0x2`
int_lit := expr as ast.IntegerLiteral
g.mov(fn_arg_registers[i], int_lit.val.int())
}
ast.Ident {
// `foo(x)` => `mov edi,DWORD PTR [rbp-0x8]`
offset := g.get_var_offset(it.name)
println('i=$i fn name= $name offset=$offset')
println(int(fn_arg_registers[i]))
g.mov_rbp_offset(fn_arg_registers[i], offset)
}
else {
verror('unhandled call_fn node: ' + typeof(expr))
}
}
} }
if node.args.len > 6 { if node.args.len > 6 {
verror('more than 6 args not allowed for now') verror('more than 6 args not allowed for now')
@ -620,7 +667,7 @@ fn (mut g Gen) allocate_var(name string, size, initial_val int) {
// Generate the value assigned to the variable // Generate the value assigned to the variable
g.write32(initial_val) g.write32(initial_val)
// println('allocate_var(size=$size, initial_val=$initial_val)') // println('allocate_var(size=$size, initial_val=$initial_val)')
g.println('mov DWORD [rbp-0x$n],$initial_val (Aallocate var `$name`)') g.println('mov DWORD [rbp-0x$n],$initial_val (Allocate var `$name`)')
} }
fn (mut g Gen) assign_stmt(node ast.AssignStmt) { fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
@ -629,19 +676,19 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
right := node.right[i] right := node.right[i]
name := left.str() name := left.str()
// if left is ast.Ident { // if left is ast.Ident {
// ident := left as ast.Ident // ident := left as ast.Ident
match right { match right {
ast.IntegerLiteral { ast.IntegerLiteral {
g.allocate_var(name, 4, it.val.int()) g.allocate_var(name, 4, it.val.int())
}
ast.InfixExpr {
g.infix_expr(it)
g.allocate_var(name, 4, 0)
}
else {
g.error_with_pos('assign_stmt unhandled expr: ' + typeof(right), right.position())
}
} }
ast.InfixExpr {
g.infix_expr(it)
g.allocate_var(name, 4, 0)
}
else {
g.error_with_pos('assign_stmt unhandled expr: ' + typeof(right), right.position())
}
}
// } // }
} }
} }
@ -712,9 +759,9 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
} }
g.push(.rbp) g.push(.rbp)
g.mov_rbp_rsp() g.mov_rbp_rsp()
if !is_main { // if !is_main {
g.sub32(.rsp, 0x20) g.sub8(.rsp, 0x10)
} // }
if node.args.len > 0 { if node.args.len > 0 {
// g.mov(.r12, 0x77777777) // g.mov(.r12, 0x77777777)
} }
@ -736,9 +783,9 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
// return // return
} }
if !is_main { if !is_main {
g.leave() // g.leave()
// g.add(.rsp, 0x20) g.add8(.rsp, 0x10)
// g.pop(.rbp) g.pop(.rbp)
} }
g.ret() g.ret()
} }

View File

@ -39,11 +39,17 @@ fn foo(a int) {
if a == 3 { if a == 3 {
println('a == 3') println('a == 3')
} }
if a == 7 {
println('a == 7')
}
} }
fn args() { fn args() {
x := 7
println('===args===') println('===args===')
foo(1) foo(1)
foo(x)
foo(2) foo(2)
} }

View File

@ -11,5 +11,7 @@ foo:
a == 1 a == 1
a == 2 a == 2
foo: foo:
a == 7
foo:
a == 3 a == 3