1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

native: implement miscellaneous features (#18044)

This commit is contained in:
Spydr 2023-04-25 00:19:15 +02:00 committed by GitHub
parent 88b29ae178
commit 3622544695
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 18 deletions

View File

@ -1314,27 +1314,14 @@ pub fn (mut a Amd64) gen_exit(mut g Gen, node ast.Expr) {
}
pub fn (mut g Gen) gen_amd64_exit(expr ast.Expr) {
// ret value
match expr {
ast.CallExpr {
right := expr.return_type
g.n_error('native exit builtin: Unsupported call ${right}')
}
ast.Ident {
g.mov_var_to_reg(.edi, expr as ast.Ident)
}
ast.IntegerLiteral {
g.mov(.edi, expr.val.int())
}
else {
g.n_error('native builtin exit expects a numeric argument')
}
}
g.expr(expr)
g.mov_reg(.rdi, .rax)
if g.pref.os == .windows {
g.mov_reg(.rcx, .rdi)
g.apicall('ExitProcess')
} else {
g.mov(.eax, g.nsyscall_exit())
g.mov(.rax, g.nsyscall_exit())
g.syscall()
}
g.trap() // should never be reached, just in case
@ -3396,11 +3383,22 @@ pub fn (mut g Gen) allocate_array(name string, size int, items int) int {
return pos
}
pub fn (mut g Gen) allocate_var_two_step(name string, size int, initial_val int) int {
// TODO: replace int by i64 or bigger
g.allocate_var(name, size - 8, 0)
return g.allocate_var(name, 8, initial_val)
}
pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) int {
if g.pref.arch == .arm64 {
// TODO
return 0
}
if size > 8 {
return g.allocate_var_two_step(name, size, initial_val)
}
padding := (size - g.stack_var_pos % size) % size
n := g.stack_var_pos + size + padding
is_far_var := n > 0x80 || n < -0x7f
@ -3412,6 +3410,12 @@ pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) int {
g.write8(0xc6)
g.write8(0x45 + far_var_offset)
}
2 {
// WORD
g.write8(0x66)
g.write8(0xc7)
g.write8(0x45 + far_var_offset)
}
4 {
// DWORD
g.write8(0xc7)
@ -3442,6 +3446,9 @@ pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) int {
1 {
g.write8(initial_val)
}
2 {
g.write16(initial_val)
}
4 {
g.write32(initial_val)
}

View File

@ -839,6 +839,14 @@ pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, typ ast.Type, name string)
g.gen_print(str, fd)
}
}
ast.Nil {
str := '0x0'
if newline {
g.gen_print(str + '\n', fd)
} else {
g.gen_print(str, fd)
}
}
ast.CharLiteral {
str := g.eval_escape_codes(expr.val)
if newline {
@ -1196,7 +1204,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
words := node.val.split(' ')
for word in words {
if word.len != 2 {
g.n_error('opcodes format: xx xx xx xx')
g.n_error('opcodes format: xx xx xx xx\nhash statements are not allowed with the native backend, use the C backend for extended C interoperability.')
}
b := unsafe { C.strtol(&char(word.str), 0, 16) }
// b := word.u8()
@ -1542,6 +1550,9 @@ fn (mut g Gen) expr(node ast.Expr) {
g.movabs(.rax, i64(node.val.u64()))
// g.gen_print_reg(.rax, 3, fd)
}
ast.Nil {
g.movabs(.rax, 0)
}
ast.PostfixExpr {
g.postfix_expr(node)
}

View File

@ -2,6 +2,7 @@ fn main() {
test_eq_ne()
test_lt_gt()
test_ref_deref()
test_nil()
println("ok")
}
@ -66,3 +67,16 @@ fn test_ref_deref() {
assert *c == b
assert **c == *b
}
fn test_nil() {
unsafe {
a := voidptr(nil)
b := voidptr(0)
assert a == b
assert a == 0
assert b == nil
println(nil) // currently outputs '0x0' -> should this be 'nil'?
}
}

View File

@ -1 +1,2 @@
0x0
ok