Skip to content

Commit 6534616

Browse files
authored
native: fix convert_int_to_string, add comments in the verbose (-v) mode (#23743)
1 parent 997ffdc commit 6534616

4 files changed

Lines changed: 51 additions & 35 deletions

File tree

‎vlib/v/gen/native/amd64.v‎

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ fn (op JumpOp) amd64() u16 {
457457
fn (mut c Amd64) cjmp(op JumpOp) i32 {
458458
c.g.write16(op.amd64())
459459
pos := c.g.pos()
460-
c.g.write32(placeholder)
460+
c.g.write32(placeholder) // will get replaced by the right address
461461
c.g.println('${op}')
462462
return i32(pos)
463463
}
@@ -466,7 +466,7 @@ fn (mut c Amd64) jmp(addr i32) i32 {
466466
c.g.write8(0xe9)
467467
pos := c.g.pos()
468468
c.g.write32(addr) // 0xffffff
469-
c.g.println('jmp')
469+
c.g.println('jmp ${int(pos + addr).hex2()}')
470470
// return the position of jump address for placeholder
471471
return i32(pos)
472472
}
@@ -603,7 +603,7 @@ fn (mut c Amd64) mov_store(regptr Amd64Register, reg Amd64Register, size Size) {
603603
}
604604
c.g.write8(if size == ._8 { i32(0x88) } else { i32(0x89) })
605605
c.g.write8(i32(reg) % 8 * 8 + i32(regptr) % 8)
606-
c.g.println('mov [${regptr}], ${reg}')
606+
c.g.println('mov [${regptr}], ${reg} ; size:${size}bits')
607607
}
608608

609609
fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
@@ -885,7 +885,7 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) {
885885
} else {
886886
c.g.write8((0xff - offset + 1) % 0x100)
887887
}
888-
c.g.println('${instruction} ${reg}, ${size_str} PTR [rbp-${int(offset).hex2()}]')
888+
c.g.println('${instruction} ${reg}, ${size_str} PTR [rbp-${int(offset).hex2()}] ; `${var.name}`')
889889
}
890890
GlobalVar {
891891
// TODO
@@ -1263,6 +1263,7 @@ pub fn (mut c Amd64) test_reg(r Amd64Register) {
12631263

12641264
// return length in .rax of string pointed by given register
12651265
pub fn (mut c Amd64) inline_strlen(r Amd64Register) {
1266+
c.g.println('; inline_strlen: (reg:${r}) {')
12661267
c.mov_reg(Amd64Register.rdi, r)
12671268
c.mov(Amd64Register.rcx, -1)
12681269
c.mov(Amd64Register.eax, 0)
@@ -1271,6 +1272,7 @@ pub fn (mut c Amd64) inline_strlen(r Amd64Register) {
12711272
c.dec(.rcx)
12721273
c.mov_reg(Amd64Register.rax, Amd64Register.rcx)
12731274
c.g.println('strlen rax, ${r}')
1275+
c.g.println('; inline_strlen }')
12741276
}
12751277

12761278
pub fn (mut c Amd64) get_dllcall_addr(import_addr i64) i64 {
@@ -1296,6 +1298,7 @@ pub fn (mut c Amd64) dllcall(symbol string) {
12961298
}
12971299

12981300
fn (mut c Amd64) gen_print(s string, fd i32) {
1301+
c.g.println('; print: (fd:${fd} s:\'${s}\') {')
12991302
if c.g.pref.os == .windows {
13001303
c.sub(.rsp, 0x38)
13011304
c.mov(Amd64Register.rcx, -10 - fd)
@@ -1317,9 +1320,11 @@ fn (mut c Amd64) gen_print(s string, fd i32) {
13171320
c.mov(Amd64Register.edx, i32(s.len)) // len
13181321
c.syscall()
13191322
}
1323+
c.g.println('; print }')
13201324
}
13211325

13221326
pub fn (mut c Amd64) gen_print_reg(r Register, n i32, fd i32) {
1327+
c.g.println('; print_reg: (reg:${r} fd:${fd} len:${n}) {')
13231328
str_reg := if c.g.pref.os == .windows { Amd64Register.rdx } else { Amd64Register.rsi }
13241329
len_reg := if c.g.pref.os == .windows { Amd64Register.r8 } else { Amd64Register.rdx }
13251330
c.mov_reg(str_reg, r)
@@ -1347,6 +1352,7 @@ pub fn (mut c Amd64) gen_print_reg(r Register, n i32, fd i32) {
13471352
c.mov(Amd64Register.edi, fd)
13481353
c.syscall()
13491354
}
1355+
c.g.println('; print_reg }')
13501356
}
13511357

13521358
pub fn (mut c Amd64) gen_exit(expr ast.Expr) {
@@ -1590,10 +1596,9 @@ fn (mut c Amd64) div_reg(a Amd64Register, b Amd64Register) {
15901596
c.g.write8(0xf8)
15911597
}
15921598
.rbx {
1593-
c.mov(Amd64Register.edx, 0)
15941599
c.g.write8(0x48)
15951600
c.g.write8(0xf7)
1596-
c.g.write8(0xfb) // idiv ebx
1601+
c.g.write8(0xfb)
15971602
}
15981603
.rdx {
15991604
c.g.write8(0x48)
@@ -1937,8 +1942,8 @@ pub fn (mut c Amd64) call_fn(node ast.CallExpr) {
19371942
}
19381943

19391944
fn (mut c Amd64) call_builtin(name Builtin) i64 {
1940-
call_addr := c.call(0)
1941-
c.g.println('call builtin `${name}`')
1945+
c.g.println('; call builtin `${name}`: (the 0 will get replaced)')
1946+
call_addr := c.call(0) // the 0 will get replaced by the right addr when the function will be generated
19421947
return call_addr
19431948
}
19441949

@@ -3478,6 +3483,13 @@ fn (mut c Amd64) convert_int_to_string(a Register, b Register) {
34783483
c.g.write8(0x30)
34793484
c.g.println("mov BYTE PTR [rdi], '0'")
34803485

3486+
// null terminate the string
3487+
c.inc(.rdi)
3488+
c.g.write8(0xc6)
3489+
c.g.write8(0x07)
3490+
c.g.write8(0x0)
3491+
c.g.println('mov BYTE PTR [rdi], `\0`')
3492+
34813493
end_label := c.g.labels.new_label()
34823494
end_jmp_addr := c.jmp(0)
34833495
c.g.labels.patches << LabelPatch{
@@ -3513,32 +3525,18 @@ fn (mut c Amd64) convert_int_to_string(a Register, b Register) {
35133525
c.g.labels.addrs[skip_minus_label] = c.g.pos()
35143526
c.g.println('; label ${skip_minus_label}')
35153527

3516-
c.mov_reg(Amd64Register.r12, Amd64Register.rdi) // copy the buffer position to r12
3528+
c.mov_reg(Amd64Register.r12, Amd64Register.rdi) // copy the buffer position (start of the number without `-`) to r12
35173529

35183530
loop_label := c.g.labels.new_label()
35193531
loop_start := c.g.pos()
35203532
c.g.println('; label ${loop_label}')
35213533

3522-
c.push(Amd64Register.rax)
3523-
3524-
c.mov(Amd64Register.rdx, 0)
3534+
c.mov(Amd64Register.rdx, 0) // upperhalf of the dividend
35253535
c.mov(Amd64Register.rbx, 10)
3526-
c.div_reg(.rax, .rbx)
3527-
c.add8(.rdx, '0'[0])
3536+
c.div_reg(.rax, .rbx) // rax will be the result of the division
3537+
c.add8(.rdx, i32(`0`)) // rdx is the remainder, add 48 to convert it into it's ascii representation
35283538

3529-
c.g.write8(0x66)
3530-
c.g.write8(0x89)
3531-
c.g.write8(0x17)
3532-
c.g.println('mov BYTE PTR [rdi], rdx')
3533-
3534-
// divide the integer in rax by 10 for next iteration
3535-
c.pop(.rax)
3536-
c.mov(Amd64Register.rbx, 10)
3537-
c.cdq()
3538-
c.g.write8(0x48)
3539-
c.g.write8(0xf7)
3540-
c.g.write8(0xfb)
3541-
c.g.println('idiv rbx')
3539+
c.mov_store(.rdi, .rdx, ._8)
35423540

35433541
// go to the next character
35443542
c.inc(.rdi)
@@ -3550,9 +3548,15 @@ fn (mut c Amd64) convert_int_to_string(a Register, b Register) {
35503548
id: loop_label
35513549
pos: loop_cjmp_addr
35523550
}
3553-
c.g.println('; jump to label ${skip_minus_label}')
3551+
c.g.println('; jump to label ${loop_label}')
35543552
c.g.labels.addrs[loop_label] = loop_start
35553553

3554+
// null terminate the string
3555+
c.g.write8(0xc6)
3556+
c.g.write8(0x07)
3557+
c.g.write8(0x0)
3558+
c.g.println('mov BYTE PTR [rdi], `\0`')
3559+
35563560
// after all was converted, reverse the string
35573561
reg := c.g.get_builtin_arg_reg(.reverse_string, 0) as Amd64Register
35583562
c.mov_reg(reg, Amd64Register.r12)
@@ -3569,8 +3573,6 @@ fn (mut c Amd64) reverse_string(r Register) {
35693573
c.mov_reg(Amd64Register.rdi, reg)
35703574
}
35713575

3572-
c.mov(Amd64Register.eax, 0)
3573-
35743576
c.g.write8(0x48)
35753577
c.g.write8(0x8d)
35763578
c.g.write8(0x48)
@@ -3579,9 +3581,9 @@ fn (mut c Amd64) reverse_string(r Register) {
35793581

35803582
c.mov_reg(Amd64Register.rsi, Amd64Register.rdi)
35813583

3582-
c.g.write8(0xf2)
3583-
c.g.write8(0xae)
3584-
c.g.println('repnz scas al, BYTE PTR es:[rdi]')
3584+
// search for null at end of string
3585+
c.mov(Amd64Register.eax, 0)
3586+
c.cld_repne_scasb()
35853587

35863588
c.sub8(.rdi, 0x2)
35873589
c.cmp_reg(.rdi, .rsi)

‎vlib/v/gen/native/gen.v‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -856,9 +856,11 @@ fn (mut g Gen) allocate_string(s string, opsize i32, typ RelocType) i32 {
856856
return str_pos
857857
}
858858

859+
// allocates a buffer variable: name, size of stored type (nb of bytes), nb of items
859860
fn (mut g Gen) allocate_array(name string, size i32, items i32) i32 {
860-
pos := g.code_gen.allocate_var(name, size, items)
861-
g.stack_var_pos += (size * items)
861+
g.println('; allocate array `${name}` item-size:${size} items:${items}:')
862+
pos := g.code_gen.allocate_var(name, size, items) // store the lenght of the array on the stack
863+
g.stack_var_pos += (size * items) // reserve space on the stack for the items
862864
return pos
863865
}
864866

@@ -945,6 +947,7 @@ fn (mut g Gen) eval_escape_codes(str string) string {
945947
}
946948

947949
fn (mut g Gen) gen_to_string(reg Register, typ ast.Type) {
950+
g.println('; to_string (reg:${reg}) {')
948951
if typ.is_int() {
949952
buffer := g.allocate_array('itoa-buffer', 1, 32) // 32 characters should be enough
950953
g.code_gen.lea_var_to_reg(g.get_builtin_arg_reg(.int_to_string, 1), buffer)
@@ -969,9 +972,11 @@ fn (mut g Gen) gen_to_string(reg Register, typ ast.Type) {
969972
} else {
970973
g.n_error('int-to-string conversion not implemented for type ${typ}')
971974
}
975+
g.println('; to_string }')
972976
}
973977

974978
fn (mut g Gen) gen_var_to_string(reg Register, expr ast.Expr, var Var, config VarConfig) {
979+
g.println('; var_to_string {')
975980
typ := g.get_type_from_var(var)
976981
if typ == ast.rune_type_idx {
977982
buffer := g.code_gen.allocate_var('rune-buffer', 8, 0)
@@ -990,6 +995,7 @@ fn (mut g Gen) gen_var_to_string(reg Register, expr ast.Expr, var Var, config Va
990995
} else {
991996
g.n_error('int-to-string conversion not implemented for type ${typ}')
992997
}
998+
g.println('; var_to_string }')
993999
}
9941000

9951001
fn (mut g Gen) is_used_by_main(node ast.FnDecl) bool {

‎vlib/v/gen/native/tests/print.vv‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ fn test_interpolated() {
104104
println('num: ${num}; bool: ${boool}')
105105
}
106106

107+
fn test_intermediate() {
108+
c := 0
109+
a := 'a'
110+
println(c)
111+
}
112+
107113
fn main() {
108114
test_stdout()
109115
test_stderr()
@@ -113,4 +119,5 @@ fn main() {
113119
test_exprs()
114120
test_sizeof()
115121
test_interpolated()
122+
test_intermediate()
116123
}

‎vlib/v/gen/native/tests/print.vv.out‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ false true
2121
sizeof: 4, 12
2222
this is an interpolated string
2323
num: 42; bool: true
24+
0

0 commit comments

Comments
 (0)