by _mental_ » Sun Dec 09, 2018 9:39 am
It's some sort of non-tirivial problem with JIT. The sample works correctly without it.
Spoiler: Source code
Code: Select all
class BugTestEvent : StaticEventHandler
{
override void NewGame()
{
Class<actor> cls=GetThatClass();
cls.getclassname();
}
Class<actor> GetThatClass()
{return 'Clip';}
}
Spoiler: Assembly
Code: Select all
=======================================================
Function: BugTestEvent.NewGame
=======================================================
L0:
push rbx
push rbp
sub rsp, 216
lea rcx, [rsp+80] ; lea callReturns, [&stackalloc]
mov rax, 4316211488 ; mov tmpPtr0, 4316211488
mov edx, dword [rax] ; mov tmpDword0, dword [tmpPtr0]
add edx, 1 ; add tmpDword0, 1
mov dword [rax], edx ; mov dword [tmpPtr0], tmpDword0
lea rbx, [rsp+16] ; lea vmframe, [&vmstack]
mov rax, [rsi] ; mov regA0, [args]
xor edx, edx ; xor regD0, regD0
xor rdx, rdx ; xor regA1, regA1
; line 7: 50000101 CALL_K
mov rdi, 4374345728 ; mov tmpPtr0, 4374345728
mov [rbx+32], rax ; mov [vmframe+32], regA0
lea rax, [rbx+48] ; lea tmpPtr3, [vmframe+48]
mov [rcx], rax ; mov [callReturns], tmpPtr3
mov byte [rcx+8], 3 ; mov byte [callReturns+8], 3
lea rsi, [rbx+32] ; lea tmpPtr4, [vmframe+32]
mov rbp, [rdi+80] ; mov tmpPtr5, [tmpPtr0+80]
mov edx, 1
mov r8d, 1
call rbp ; BugTestEvent.GetThatClass
mov rdx, [rbx+48] ; mov regA1, [vmframe+48]
; line 8: 11000100 LW
test rdx, rdx ; test regA1, regA1
je L2 ; je L2
mov eax, dword [rdx+56] ; mov regD0, dword [regA1+56] <-- crash!
; line -1: 54808000 RET
mov eax, 0 ; mov tmpDword0, 0
jmp L1
L2:
mov qword [rsp], rdx ; [Save] regA1
mov rdi, 4374345392
mov rsi, 4428707436
mov edx, 1
call 4303722016
L1:
add rsp, 216
pop rbp
pop rbx
ret
=======================================================
Function: BugTestEvent.GetThatClass
=======================================================
L0:
mov rax, 4316211488 ; mov tmpPtr0, 4316211488
mov edx, dword [rax] ; mov tmpDword0, dword [tmpPtr0]
add edx, 1 ; add tmpDword0, 1
mov dword [rax], edx ; mov dword [tmpPtr0], tmpDword0
mov rax, [rsi] ; mov regA0, [args]
; line 11: 54800700 RET
mov edx, 0 ; mov tmpDword0, 0
cmp edx, r8d ; cmp tmpDword0, numret
jge L2 ; jge L2
mov rax, [rcx] ; mov tmpPtr0, [ret]
mov qword [rax], 105553169906048 ; mov qword [tmpPtr0], 105553169906048
add edx, 1 ; add tmpDword0, 1
mov eax, edx ; [Move] tmpDword0
jmp L1
L2:
mov eax, r8d ; [Move] numret
L1:
ret
In the assembly above the place marked with
crash! contains bogus (truncated?) value in RDX.
It's some sort of non-tirivial problem with JIT. The sample works correctly without it.
[spoiler=Source code][code]class BugTestEvent : StaticEventHandler
{
override void NewGame()
{
Class<actor> cls=GetThatClass();
cls.getclassname();
}
Class<actor> GetThatClass()
{return 'Clip';}
}[/code][/spoiler][spoiler=Assembly][code]=======================================================
Function: BugTestEvent.NewGame
=======================================================
L0:
push rbx
push rbp
sub rsp, 216
lea rcx, [rsp+80] ; lea callReturns, [&stackalloc]
mov rax, 4316211488 ; mov tmpPtr0, 4316211488
mov edx, dword [rax] ; mov tmpDword0, dword [tmpPtr0]
add edx, 1 ; add tmpDword0, 1
mov dword [rax], edx ; mov dword [tmpPtr0], tmpDword0
lea rbx, [rsp+16] ; lea vmframe, [&vmstack]
mov rax, [rsi] ; mov regA0, [args]
xor edx, edx ; xor regD0, regD0
xor rdx, rdx ; xor regA1, regA1
; line 7: 50000101 CALL_K
mov rdi, 4374345728 ; mov tmpPtr0, 4374345728
mov [rbx+32], rax ; mov [vmframe+32], regA0
lea rax, [rbx+48] ; lea tmpPtr3, [vmframe+48]
mov [rcx], rax ; mov [callReturns], tmpPtr3
mov byte [rcx+8], 3 ; mov byte [callReturns+8], 3
lea rsi, [rbx+32] ; lea tmpPtr4, [vmframe+32]
mov rbp, [rdi+80] ; mov tmpPtr5, [tmpPtr0+80]
mov edx, 1
mov r8d, 1
call rbp ; BugTestEvent.GetThatClass
mov rdx, [rbx+48] ; mov regA1, [vmframe+48]
; line 8: 11000100 LW
test rdx, rdx ; test regA1, regA1
je L2 ; je L2
mov eax, dword [rdx+56] ; mov regD0, dword [regA1+56] <-- crash!
; line -1: 54808000 RET
mov eax, 0 ; mov tmpDword0, 0
jmp L1
L2:
mov qword [rsp], rdx ; [Save] regA1
mov rdi, 4374345392
mov rsi, 4428707436
mov edx, 1
call 4303722016
L1:
add rsp, 216
pop rbp
pop rbx
ret
=======================================================
Function: BugTestEvent.GetThatClass
=======================================================
L0:
mov rax, 4316211488 ; mov tmpPtr0, 4316211488
mov edx, dword [rax] ; mov tmpDword0, dword [tmpPtr0]
add edx, 1 ; add tmpDword0, 1
mov dword [rax], edx ; mov dword [tmpPtr0], tmpDword0
mov rax, [rsi] ; mov regA0, [args]
; line 11: 54800700 RET
mov edx, 0 ; mov tmpDword0, 0
cmp edx, r8d ; cmp tmpDword0, numret
jge L2 ; jge L2
mov rax, [rcx] ; mov tmpPtr0, [ret]
mov qword [rax], 105553169906048 ; mov qword [tmpPtr0], 105553169906048
add edx, 1 ; add tmpDword0, 1
mov eax, edx ; [Move] tmpDword0
jmp L1
L2:
mov eax, r8d ; [Move] numret
L1:
ret[/code][/spoiler]
In the assembly above the place marked with [b]crash![/b] contains bogus (truncated?) value in RDX.