mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
native: inital support for aliased types (#18703)
This commit is contained in:
parent
f122703a43
commit
c4ba47a131
@ -94,6 +94,10 @@ fn (mut c Amd64) main_reg() Register {
|
|||||||
return Amd64Register.rax
|
return Amd64Register.rax
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Amd64) address_size() int {
|
||||||
|
return 8
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) dec(reg Amd64Register) {
|
fn (mut c Amd64) dec(reg Amd64Register) {
|
||||||
c.g.write16(0xff48)
|
c.g.write16(0xff48)
|
||||||
match reg {
|
match reg {
|
||||||
@ -593,44 +597,46 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
|
|||||||
LocalVar {
|
LocalVar {
|
||||||
offset := var.offset - config.offset
|
offset := var.offset - config.offset
|
||||||
is_far_var := offset > 0x80 || offset < -0x7f
|
is_far_var := offset > 0x80 || offset < -0x7f
|
||||||
typ := if config.typ == 0 { var.typ } else { config.typ }
|
raw_type := if config.typ == 0 { var.typ } else { config.typ }
|
||||||
|
typ := c.g.unwrap(raw_type)
|
||||||
|
|
||||||
mut size_str := 'UNKNOWN'
|
mut size_str := 'UNKNOWN'
|
||||||
is_extended_register := int(reg) >= int(Amd64Register.r8)
|
is_extended_register := int(reg) >= int(Amd64Register.r8)
|
||||||
&& int(reg) <= int(Amd64Register.r15)
|
&& int(reg) <= int(Amd64Register.r15)
|
||||||
match typ {
|
|
||||||
ast.i64_type_idx, ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx,
|
if raw_type.is_any_kind_of_pointer() || typ.is_any_kind_of_pointer() {
|
||||||
ast.int_literal_type_idx {
|
c.g.write16(0x8948 + if is_extended_register { 4 } else { 0 })
|
||||||
c.g.write16(0x8948 + if is_extended_register { 4 } else { 0 })
|
size_str = 'QWORD'
|
||||||
size_str = 'QWORD'
|
} else {
|
||||||
}
|
match typ {
|
||||||
ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx {
|
ast.i64_type_idx, ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx,
|
||||||
if is_extended_register {
|
ast.int_literal_type_idx {
|
||||||
c.g.write8(0x44)
|
|
||||||
}
|
|
||||||
c.g.write8(0x89)
|
|
||||||
size_str = 'DWORD'
|
|
||||||
}
|
|
||||||
ast.i16_type_idx, ast.u16_type_idx {
|
|
||||||
c.g.write8(0x66)
|
|
||||||
if is_extended_register {
|
|
||||||
c.g.write8(0x44)
|
|
||||||
}
|
|
||||||
c.g.write8(0x89)
|
|
||||||
size_str = 'WORD'
|
|
||||||
}
|
|
||||||
ast.i8_type_idx, ast.u8_type_idx, ast.char_type_idx, ast.bool_type_idx {
|
|
||||||
if is_extended_register {
|
|
||||||
c.g.write8(0x44)
|
|
||||||
}
|
|
||||||
c.g.write8(0x88)
|
|
||||||
size_str = 'BYTE'
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if typ.is_any_kind_of_pointer() {
|
|
||||||
c.g.write16(0x8948 + if is_extended_register { 4 } else { 0 })
|
c.g.write16(0x8948 + if is_extended_register { 4 } else { 0 })
|
||||||
size_str = 'QWORD'
|
size_str = 'QWORD'
|
||||||
} else {
|
}
|
||||||
|
ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx {
|
||||||
|
if is_extended_register {
|
||||||
|
c.g.write8(0x44)
|
||||||
|
}
|
||||||
|
c.g.write8(0x89)
|
||||||
|
size_str = 'DWORD'
|
||||||
|
}
|
||||||
|
ast.i16_type_idx, ast.u16_type_idx {
|
||||||
|
c.g.write8(0x66)
|
||||||
|
if is_extended_register {
|
||||||
|
c.g.write8(0x44)
|
||||||
|
}
|
||||||
|
c.g.write8(0x89)
|
||||||
|
size_str = 'WORD'
|
||||||
|
}
|
||||||
|
ast.i8_type_idx, ast.u8_type_idx, ast.char_type_idx, ast.bool_type_idx {
|
||||||
|
if is_extended_register {
|
||||||
|
c.g.write8(0x44)
|
||||||
|
}
|
||||||
|
c.g.write8(0x88)
|
||||||
|
size_str = 'BYTE'
|
||||||
|
}
|
||||||
|
else {
|
||||||
ts := c.g.table.sym(typ.idx())
|
ts := c.g.table.sym(typ.idx())
|
||||||
if ts.info is ast.Enum {
|
if ts.info is ast.Enum {
|
||||||
if is_extended_register {
|
if is_extended_register {
|
||||||
@ -639,7 +645,7 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
|
|||||||
c.g.write8(0x89)
|
c.g.write8(0x89)
|
||||||
size_str = 'DWORD'
|
size_str = 'DWORD'
|
||||||
} else {
|
} else {
|
||||||
c.g.n_error('unsupported type for mov_reg_to_var')
|
c.g.n_error('unsupported type for mov_reg_to_var ${ts.info}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -685,7 +691,7 @@ fn (mut c Amd64) mov_int_to_var(var Var, integer int, config VarConfig) {
|
|||||||
}
|
}
|
||||||
LocalVar {
|
LocalVar {
|
||||||
offset := var.offset - config.offset
|
offset := var.offset - config.offset
|
||||||
typ := if config.typ == 0 { var.typ } else { config.typ }
|
typ := c.g.unwrap(if config.typ == 0 { var.typ } else { config.typ })
|
||||||
is_far_var := offset > 0x80 || offset < -0x7f
|
is_far_var := offset > 0x80 || offset < -0x7f
|
||||||
|
|
||||||
match typ {
|
match typ {
|
||||||
@ -1338,116 +1344,119 @@ fn (mut c Amd64) lea(reg Amd64Register, val int) {
|
|||||||
c.g.println('lea ${reg}, ${val}')
|
c.g.println('lea ${reg}, ${val}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Amd64) mov_neg1(reg Amd64Register) {
|
||||||
|
match reg {
|
||||||
|
.rax {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0xc7)
|
||||||
|
c.g.write8(0xc0)
|
||||||
|
c.g.write32(-1)
|
||||||
|
}
|
||||||
|
.rcx {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0xc7)
|
||||||
|
c.g.write8(0xc1)
|
||||||
|
c.g.write32(-1)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c.g.n_error('unhandled mov ${reg}, -1')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.g.println('mov ${reg}, -1')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut c Amd64) clear_reg(reg Amd64Register) {
|
||||||
|
// Optimise to xor reg, reg when val is 0
|
||||||
|
match reg {
|
||||||
|
.eax, .rax {
|
||||||
|
c.g.write8(0x31)
|
||||||
|
c.g.write8(0xc0)
|
||||||
|
}
|
||||||
|
.edi, .rdi {
|
||||||
|
c.g.write8(0x31)
|
||||||
|
c.g.write8(0xff)
|
||||||
|
}
|
||||||
|
.rcx {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0x31)
|
||||||
|
c.g.write8(0xc7)
|
||||||
|
}
|
||||||
|
.rdx {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0x31)
|
||||||
|
c.g.write8(0xd2)
|
||||||
|
}
|
||||||
|
.edx {
|
||||||
|
c.g.write8(0x31)
|
||||||
|
c.g.write8(0xd2)
|
||||||
|
}
|
||||||
|
.rsi {
|
||||||
|
c.g.write8(0x48)
|
||||||
|
c.g.write8(0x31)
|
||||||
|
c.g.write8(0xf6)
|
||||||
|
}
|
||||||
|
.r12 {
|
||||||
|
c.g.write8(0x4d)
|
||||||
|
c.g.write8(0x31)
|
||||||
|
c.g.write8(0xe4)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c.g.n_error('unhandled xor ${reg}, ${reg}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.g.println('xor ${reg}, ${reg}')
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) mov(r Register, val int) {
|
fn (mut c Amd64) mov(r Register, val int) {
|
||||||
reg := r as Amd64Register
|
reg := r as Amd64Register
|
||||||
if val == -1 {
|
match val {
|
||||||
match reg {
|
-1 {
|
||||||
.rax {
|
c.mov_neg1(reg)
|
||||||
c.g.write8(0x48)
|
}
|
||||||
c.g.write8(0xc7)
|
0 {
|
||||||
c.g.write8(0xc0)
|
c.clear_reg(reg)
|
||||||
c.g.write32(-1)
|
}
|
||||||
c.g.println('mov ${reg}, ${val}')
|
else {
|
||||||
}
|
match reg {
|
||||||
.rcx {
|
.eax, .rax {
|
||||||
if val == -1 {
|
c.g.write8(0xb8)
|
||||||
|
}
|
||||||
|
.edi, .rdi {
|
||||||
|
c.g.write8(0xbf)
|
||||||
|
}
|
||||||
|
.rcx {
|
||||||
c.g.write8(0x48)
|
c.g.write8(0x48)
|
||||||
c.g.write8(0xc7)
|
c.g.write8(0xc7)
|
||||||
c.g.write8(0xc1)
|
c.g.write8(0xc1)
|
||||||
c.g.write32(-1)
|
|
||||||
} else {
|
|
||||||
c.g.write8(0xff)
|
|
||||||
c.g.write8(0xff) // mov rcx 0xffff5
|
|
||||||
}
|
}
|
||||||
c.g.println('mov ${reg}, ${val}')
|
.r8 {
|
||||||
}
|
c.g.write8(0x41)
|
||||||
else {
|
c.g.write8(0xb8)
|
||||||
c.g.n_error('unhandled mov ${reg}, -1')
|
}
|
||||||
|
.r9 {
|
||||||
|
c.g.write8(0xb9)
|
||||||
|
}
|
||||||
|
.rdx, .edx {
|
||||||
|
c.g.write8(0xba)
|
||||||
|
}
|
||||||
|
.rsi {
|
||||||
|
// c.g.write8(0x48) // its 32bit!
|
||||||
|
c.g.write8(0xbe)
|
||||||
|
}
|
||||||
|
.r12 {
|
||||||
|
c.g.write8(0x41)
|
||||||
|
c.g.write8(0xbc) // r11 is 0xbb etc
|
||||||
|
}
|
||||||
|
.rbx {
|
||||||
|
c.g.write8(0xbb)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c.g.n_error('unhandled mov ${reg}')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
c.g.write32(val)
|
||||||
|
c.g.println('mov ${reg}, ${val}')
|
||||||
}
|
}
|
||||||
c.g.println('mov ${reg}, ${val}')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if val == 0 {
|
|
||||||
// Optimise to xor reg, reg when val is 0
|
|
||||||
match reg {
|
|
||||||
.eax, .rax {
|
|
||||||
c.g.write8(0x31)
|
|
||||||
c.g.write8(0xc0)
|
|
||||||
}
|
|
||||||
.edi, .rdi {
|
|
||||||
c.g.write8(0x31)
|
|
||||||
c.g.write8(0xff)
|
|
||||||
}
|
|
||||||
.rcx {
|
|
||||||
c.g.write8(0x48)
|
|
||||||
c.g.write8(0x31)
|
|
||||||
c.g.write8(0xc7)
|
|
||||||
}
|
|
||||||
.rdx {
|
|
||||||
c.g.write8(0x48)
|
|
||||||
c.g.write8(0x31)
|
|
||||||
c.g.write8(0xd2)
|
|
||||||
}
|
|
||||||
.edx {
|
|
||||||
c.g.write8(0x31)
|
|
||||||
c.g.write8(0xd2)
|
|
||||||
}
|
|
||||||
.rsi {
|
|
||||||
c.g.write8(0x48)
|
|
||||||
c.g.write8(0x31)
|
|
||||||
c.g.write8(0xf6)
|
|
||||||
}
|
|
||||||
.r12 {
|
|
||||||
c.g.write8(0x4d)
|
|
||||||
c.g.write8(0x31)
|
|
||||||
c.g.write8(0xe4)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c.g.n_error('unhandled mov ${reg}, ${reg}')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.g.println('xor ${reg}, ${reg}')
|
|
||||||
} else {
|
|
||||||
match reg {
|
|
||||||
.eax, .rax {
|
|
||||||
c.g.write8(0xb8)
|
|
||||||
}
|
|
||||||
.edi, .rdi {
|
|
||||||
c.g.write8(0xbf)
|
|
||||||
}
|
|
||||||
.rcx {
|
|
||||||
c.g.write8(0x48)
|
|
||||||
c.g.write8(0xc7)
|
|
||||||
c.g.write8(0xc1)
|
|
||||||
}
|
|
||||||
.r8 {
|
|
||||||
c.g.write8(0x41)
|
|
||||||
c.g.write8(0xb8)
|
|
||||||
}
|
|
||||||
.r9 {
|
|
||||||
c.g.write8(0xb9)
|
|
||||||
}
|
|
||||||
.rdx, .edx {
|
|
||||||
c.g.write8(0xba)
|
|
||||||
}
|
|
||||||
.rsi {
|
|
||||||
// c.g.write8(0x48) // its 32bit!
|
|
||||||
c.g.write8(0xbe)
|
|
||||||
}
|
|
||||||
.r12 {
|
|
||||||
c.g.write8(0x41)
|
|
||||||
c.g.write8(0xbc) // r11 is 0xbb etc
|
|
||||||
}
|
|
||||||
.rbx {
|
|
||||||
c.g.write8(0xbb)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c.g.n_error('unhandled mov ${reg}')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.g.write32(val)
|
|
||||||
c.g.println('mov ${reg}, ${val}')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2005,7 +2014,9 @@ fn (mut c Amd64) assign_struct_var(ident_var IdentVar, typ ast.Type, s int) {
|
|||||||
assert size == 0
|
assert size == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) assign_var(var IdentVar, typ ast.Type) {
|
fn (mut c Amd64) assign_var(var IdentVar, raw_type ast.Type) {
|
||||||
|
typ := c.g.unwrap(raw_type)
|
||||||
|
info := c.g.table.sym(typ).info
|
||||||
size := c.g.get_type_size(typ)
|
size := c.g.get_type_size(typ)
|
||||||
if typ.is_pure_float() {
|
if typ.is_pure_float() {
|
||||||
match var {
|
match var {
|
||||||
@ -2014,7 +2025,8 @@ fn (mut c Amd64) assign_var(var IdentVar, typ ast.Type) {
|
|||||||
// Amd64Register { c.g.mov_ssereg(var as Amd64Register, .xmm0) }
|
// Amd64Register { c.g.mov_ssereg(var as Amd64Register, .xmm0) }
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
} else if c.g.table.sym(typ).info is ast.Struct && !typ.is_any_kind_of_pointer() {
|
} else if info is ast.Struct && !typ.is_any_kind_of_pointer()
|
||||||
|
&& !raw_type.is_any_kind_of_pointer() {
|
||||||
c.assign_struct_var(var, typ, size)
|
c.assign_struct_var(var, typ, size)
|
||||||
} else if size in [1, 2, 4, 8] {
|
} else if size in [1, 2, 4, 8] {
|
||||||
match var {
|
match var {
|
||||||
@ -2023,7 +2035,7 @@ fn (mut c Amd64) assign_var(var IdentVar, typ ast.Type) {
|
|||||||
Register { c.mov_reg(var as Amd64Register, Amd64Register.rax) }
|
Register { c.mov_reg(var as Amd64Register, Amd64Register.rax) }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.g.n_error('error assigning type ${typ} with size ${size}')
|
c.g.n_error('error assigning type ${typ} with size ${size}: ${info}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2361,7 +2373,7 @@ fn (mut c Amd64) return_stmt(node ast.Return) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if node.exprs.len > 1 {
|
} else if node.exprs.len > 1 {
|
||||||
typ := c.g.return_type
|
typ := c.g.unwrap(c.g.return_type)
|
||||||
ts := c.g.table.sym(typ)
|
ts := c.g.table.sym(typ)
|
||||||
size := c.g.get_type_size(typ)
|
size := c.g.get_type_size(typ)
|
||||||
// construct a struct variable contains the return value
|
// construct a struct variable contains the return value
|
||||||
@ -3385,7 +3397,8 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LocalVar {
|
LocalVar {
|
||||||
size := c.g.get_type_size(var.typ)
|
typ := c.g.unwrap(var.typ)
|
||||||
|
size := c.g.get_type_size(typ)
|
||||||
|
|
||||||
// zero fill
|
// zero fill
|
||||||
mut left := if size >= 16 {
|
mut left := if size >= 16 {
|
||||||
@ -3414,12 +3427,12 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
|
|||||||
c.mov_int_to_var(var, 0, offset: size - left, typ: ast.i8_type_idx)
|
c.mov_int_to_var(var, 0, offset: size - left, typ: ast.i8_type_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
ts := c.g.table.sym(var.typ)
|
ts := c.g.table.sym(typ)
|
||||||
match ts.info {
|
match ts.info {
|
||||||
ast.Struct {
|
ast.Struct {
|
||||||
for i, f in ts.info.fields {
|
for i, f in ts.info.fields {
|
||||||
if f.has_default_expr && !init.init_fields.map(it.name).contains(f.name) {
|
if f.has_default_expr && !init.init_fields.map(it.name).contains(f.name) {
|
||||||
offset := c.g.structs[var.typ.idx()].offsets[i]
|
offset := c.g.structs[typ.idx()].offsets[i]
|
||||||
c.g.expr(f.default_expr)
|
c.g.expr(f.default_expr)
|
||||||
// TODO expr not on rax
|
// TODO expr not on rax
|
||||||
c.mov_reg_to_var(var, Amd64Register.rax, offset: offset, typ: f.typ)
|
c.mov_reg_to_var(var, Amd64Register.rax, offset: offset, typ: f.typ)
|
||||||
@ -3430,9 +3443,9 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
|
|||||||
}
|
}
|
||||||
for f in init.init_fields {
|
for f in init.init_fields {
|
||||||
field := ts.find_field(f.name) or {
|
field := ts.find_field(f.name) or {
|
||||||
c.g.n_error('Could not find field `${f.name}` on init')
|
c.g.n_error('Could not find field `${f.name}` on init (${ts.info})')
|
||||||
}
|
}
|
||||||
offset := c.g.structs[var.typ.idx()].offsets[field.i]
|
offset := c.g.structs[typ.idx()].offsets[field.i]
|
||||||
|
|
||||||
c.g.expr(f.expr)
|
c.g.expr(f.expr)
|
||||||
// TODO expr not on rax
|
// TODO expr not on rax
|
||||||
@ -3777,7 +3790,7 @@ fn (mut c Amd64) mov_ssereg_to_var(var Var, reg Amd64SSERegister, config VarConf
|
|||||||
LocalVar {
|
LocalVar {
|
||||||
offset := var.offset - config.offset
|
offset := var.offset - config.offset
|
||||||
is_far_var := offset > 0x80 || offset < -0x7f
|
is_far_var := offset > 0x80 || offset < -0x7f
|
||||||
typ := if config.typ == 0 { var.typ } else { config.typ }
|
typ := c.g.unwrap(if config.typ == 0 { var.typ } else { config.typ })
|
||||||
|
|
||||||
far_var_offset := if is_far_var { 0x40 } else { 0 }
|
far_var_offset := if is_far_var { 0x40 } else { 0 }
|
||||||
c.g.write8(if typ == ast.f32_type_idx { 0xf3 } else { 0xf2 })
|
c.g.write8(if typ == ast.f32_type_idx { 0xf3 } else { 0xf2 })
|
||||||
@ -3821,7 +3834,7 @@ fn (mut c Amd64) mov_var_to_ssereg(reg Amd64SSERegister, var Var, config VarConf
|
|||||||
LocalVar {
|
LocalVar {
|
||||||
offset := var.offset - config.offset
|
offset := var.offset - config.offset
|
||||||
is_far_var := offset > 0x80 || offset < -0x7f
|
is_far_var := offset > 0x80 || offset < -0x7f
|
||||||
typ := if config.typ == 0 { var.typ } else { config.typ }
|
typ := c.g.unwrap(if config.typ == 0 { var.typ } else { config.typ })
|
||||||
|
|
||||||
far_var_offset := if is_far_var { 0x40 } else { 0 }
|
far_var_offset := if is_far_var { 0x40 } else { 0 }
|
||||||
c.g.write8(if typ == ast.f32_type_idx { 0xf3 } else { 0xf2 })
|
c.g.write8(if typ == ast.f32_type_idx { 0xf3 } else { 0xf2 })
|
||||||
|
@ -320,6 +320,10 @@ pub fn (mut c Arm64) gen_arm64_exit(expr ast.Expr) {
|
|||||||
c.svc()
|
c.svc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Arm64) address_size() int {
|
||||||
|
return 8
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut c Arm64) gen_print(s string, fd int) {
|
fn (mut c Arm64) gen_print(s string, fd int) {
|
||||||
panic('Arm64.gen_print() is not implemented')
|
panic('Arm64.gen_print() is not implemented')
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||||||
} else if var.typ.is_pure_float() {
|
} else if var.typ.is_pure_float() {
|
||||||
g.code_gen.load_fp_var(node as ast.Ident)
|
g.code_gen.load_fp_var(node as ast.Ident)
|
||||||
} else {
|
} else {
|
||||||
ts := g.table.sym(var.typ)
|
ts := g.table.sym(g.unwrap(var.typ))
|
||||||
match ts.info {
|
match ts.info {
|
||||||
ast.Struct {
|
ast.Struct {
|
||||||
g.code_gen.lea_var_to_reg(g.code_gen.main_reg(), g.get_var_offset(node.name))
|
g.code_gen.lea_var_to_reg(g.code_gen.main_reg(), g.get_var_offset(node.name))
|
||||||
|
@ -66,6 +66,7 @@ mut:
|
|||||||
interface CodeGen {
|
interface CodeGen {
|
||||||
mut:
|
mut:
|
||||||
g &Gen
|
g &Gen
|
||||||
|
address_size() int
|
||||||
adr(r Arm64Register, delta int) // Note: Temporary!
|
adr(r Arm64Register, delta int) // Note: Temporary!
|
||||||
allocate_var(name string, size int, initial_val int) int
|
allocate_var(name string, size int, initial_val int) int
|
||||||
apicall(call ApiCall) // winapi calls
|
apicall(call ApiCall) // winapi calls
|
||||||
@ -237,10 +238,9 @@ fn (mut g Gen) get_var_from_ident(ident ast.Ident) IdentVar {
|
|||||||
match obj {
|
match obj {
|
||||||
ast.Var {
|
ast.Var {
|
||||||
offset := g.get_var_offset(obj.name)
|
offset := g.get_var_offset(obj.name)
|
||||||
typ := obj.typ
|
|
||||||
return LocalVar{
|
return LocalVar{
|
||||||
offset: offset
|
offset: offset
|
||||||
typ: typ
|
typ: obj.typ
|
||||||
name: obj.name
|
name: obj.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -609,17 +609,24 @@ fn (mut g Gen) get_var_offset(var_name string) int {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) get_field_offset(typ ast.Type, name string) int {
|
fn (mut g Gen) get_field_offset(in_type ast.Type, name string) int {
|
||||||
|
typ := g.unwrap(in_type)
|
||||||
ts := g.table.sym(typ)
|
ts := g.table.sym(typ)
|
||||||
field := ts.find_field(name) or { g.n_error('Could not find field `${name}` on init') }
|
field := ts.find_field(name) or { g.n_error('Could not find field `${name}` on init') }
|
||||||
return g.structs[typ.idx()].offsets[field.i]
|
return g.structs[typ.idx()].offsets[field.i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) unwrap(typ ast.Type) ast.Type {
|
||||||
|
ts := g.table.sym(typ)
|
||||||
|
return if ts.info is ast.Alias { g.unwrap(ts.info.parent_type) } else { typ }
|
||||||
|
}
|
||||||
|
|
||||||
// get type size, and calculate size and align and store them to the cache when the type is struct
|
// get type size, and calculate size and align and store them to the cache when the type is struct
|
||||||
fn (mut g Gen) get_type_size(typ ast.Type) int {
|
fn (mut g Gen) get_type_size(raw_type ast.Type) int {
|
||||||
// TODO type flags
|
// TODO type flags
|
||||||
if typ.is_any_kind_of_pointer() {
|
typ := g.unwrap(raw_type)
|
||||||
return 8
|
if raw_type.is_any_kind_of_pointer() || typ.is_any_kind_of_pointer() {
|
||||||
|
return g.code_gen.address_size()
|
||||||
}
|
}
|
||||||
if typ in ast.number_type_idxs {
|
if typ in ast.number_type_idxs {
|
||||||
return match typ {
|
return match typ {
|
||||||
@ -699,7 +706,7 @@ fn (mut g Gen) get_type_align(typ ast.Type) int {
|
|||||||
if g.is_register_type(typ) || typ.is_pure_float() {
|
if g.is_register_type(typ) || typ.is_pure_float() {
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
ts := g.table.sym(typ)
|
ts := g.table.sym(g.unwrap(typ))
|
||||||
if ts.align != -1 {
|
if ts.align != -1 {
|
||||||
return ts.align
|
return ts.align
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||||||
ast.Import {} // do nothing here
|
ast.Import {} // do nothing here
|
||||||
ast.StructDecl {}
|
ast.StructDecl {}
|
||||||
ast.EnumDecl {}
|
ast.EnumDecl {}
|
||||||
|
ast.TypeDecl {}
|
||||||
else {
|
else {
|
||||||
eprintln('native.stmt(): bad node: ' + node.type_name())
|
eprintln('native.stmt(): bad node: ' + node.type_name())
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,52 @@ fn struct_test() {
|
|||||||
assert e.a == 3
|
assert e.a == 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AliasedStruct = Mutable
|
||||||
|
type AliasedPointer = &Mutable
|
||||||
|
|
||||||
|
fn alias_test() {
|
||||||
|
mut a := AliasedStruct{1}
|
||||||
|
a.a = 2
|
||||||
|
assert a.a == 2
|
||||||
|
mut b := &a
|
||||||
|
b.a = 3
|
||||||
|
assert a.a == 3
|
||||||
|
|
||||||
|
c := AliasedPointer{2}
|
||||||
|
assert c.a == 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_size28() Size28 {
|
||||||
|
return Size28{1, 2, 3, 4, 5, 6, 7}
|
||||||
|
}
|
||||||
|
type AliasedSize28 = Size28
|
||||||
|
|
||||||
|
fn init_aliased() AliasedSize28 {
|
||||||
|
return AliasedSize28{1, 2, 3, 4, 5, 6, 7}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn return_test() {
|
||||||
|
a := init_size28()
|
||||||
|
assert a.a == 1
|
||||||
|
assert a.b == 2
|
||||||
|
assert a.c == 3
|
||||||
|
assert a.d == 4
|
||||||
|
assert a.e == 5
|
||||||
|
assert a.f == 6
|
||||||
|
assert a.g == 7
|
||||||
|
|
||||||
|
b := init_aliased()
|
||||||
|
assert b.a == 1
|
||||||
|
assert b.b == 2
|
||||||
|
assert b.c == 3
|
||||||
|
assert b.d == 4
|
||||||
|
assert b.e == 5
|
||||||
|
assert b.f == 6
|
||||||
|
assert b.g == 7
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
struct_test()
|
struct_test()
|
||||||
|
return_test()
|
||||||
|
alias_test()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user