;
; Реализация среды исполнения языка программирования
; Объектно-ориентированный продвинутый векторный транслятор
;
; Copyright © 2021, 2024 Малик Разработчик
;
; Это свободная программа: вы можете перераспространять ее и/или изменять
; ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
; в каком она была опубликована Фондом свободного программного обеспечения;
; либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
;
; Эта программа распространяется в надежде, что она будет полезной,
; но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
; или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
; общественной лицензии GNU.
;
; Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
; вместе с этой программой. Если это не так, см.
; <https://www.gnu.org/licenses/>.
;
; <fold инструкции вызова методов>
; <fold приватные макросы — должны использоваться только этим текстом исходного кода>
macro _chknull_l tagOffset* {
local .L.0000
mov r00q, [rsp+(tagOffset)*$10]
test r00q, r00q
jnz .L.0000
_throw NullPointerException
.L.0000:
}
macro _chknull_t tagOffset* {
local .L.0000
test qword [rsp+(tagOffset)*$10], -$01
jnz .L.0000
_throw NullPointerException
.L.0000:
}
macro _virtual virtualMethodIndex* {
add r00q, [r00+avt.lang.Object$fldClassOffset]
mov r01d, [r00+avt.lang.Class$fldVirtualsOffset]
lea r00q, [r00+r01*1+$00]
add r00q, [r00+(virtualMethodIndex)*8]
}
macro _service serviceMethodIndex*, serviceFullName* {
__push $03
add r00q, [r00+avt.lang.Object$fldClassOffset]
lea r01q, [serviceFullName]
mov r02d, (serviceMethodIndex)*$20
incrcoth r00q
incrcoth r01q
mov qword [rsp+$28], $00
mov qword [rsp+$20], r00q
mov qword [rsp+$18], $00
mov qword [rsp+$10], r01q
mov qword [rsp+$08], $00
mov qword [rsp+$00], r02q
__sttag_y $01, (TAG_OBJECT shl 8)+(TAG_OBJECT shl 0)
call avt.lang.Class$getServiceMethodEntryPoint$avt.lang.Class$int$
}
; </fold>
; <fold вызов методов и блоков финализации>
macro invfin labelFinally* {
xor r01q, r01q
call labelFinally
}
macro invstat methodFullName* {
call methodFullName
}
macro invspec methodFullName* {
_chknull_t methodFullName#.arg.tags-1
call methodFullName
}
macro invvirt methodFullName* {
local .dummy
label .dummy at methodFullName
_chknull_l methodFullName#.arg.tags-1
_virtual methodFullName#.idx.virt
call r00q
}
macro invserv serviceFullName*, methodArguName* {
local .dummy
label .dummy at serviceFullName#$#methodArguName
_chknull_l serviceFullName#$#methodArguName#.arg.tags-1
_service serviceFullName#$#methodArguName#.idx.serv, serviceFullName
call r00q
}
; </fold>
; <fold уничтожение возвращённого результата>
macro releaser {
tstdecrcoth qsc0
}
macro releasee {
ffree esc0
fincstp
}
macro released { }
macro released2 { }
macro released4 { }
macro released8 { }
macro releasef { }
macro releasef2 { }
macro releasef4 { }
macro releasef8 { }
macro releaseb2 { }
macro releaseb4 { }
macro releaseb8 { }
macro releases2 { }
macro releases4 { }
macro releases8 { }
macro releasei { }
macro releasei2 { }
macro releasei4 { }
macro releasei8 { }
macro releasel { }
macro releasel2 { }
macro releasel4 { }
macro releasel8 { }
; </fold>
; <fold создание новых инстанций>
macro newa_c classFullName*, capacity* {
if((capacity) < 0)
mov r00d, capacity
newa classFullName
else
__push $02
lea r01q, [classFullName]
incrcoth r01q
mov qword [rsp+$18], $00
mov qword [rsp+$10], r01q
mov qword [rsp+$08], $00
mov qword [rsp+$00], capacity
__sttag_x $01, TAG_OBJECT
call avt.lang.Class$allocateArray$int$
end if
}
macro newa classFullName* {
__push $02
lea r01q, [classFullName]
incrcoth r01q
mov qword [rsp+$18], $00
mov qword [rsp+$10], r01q
mov qword [rsp+$08], $00
mov qword [rsp+$00], r00q
__sttag_x $01, TAG_OBJECT
call avt.lang.Class$allocateArray$int$
}
macro newam classFullName* {
__push $02
lea r01q, [classFullName]
incrcoth r01q
mov qword [rsp+$18], $00
mov qword [rsp+$10], r01q
mov qword [rsp+$08], $00
mov qword [rsp+$00], r00q
__sttag_y $00, (TAG_OBJECT shl 8)+(TAG_OBJECT shl 0)
call avt.lang.Class$allocateArray$int.01d$
}
macro newi classFullName* {
__push $01
lea r00q, [classFullName]
incrcoth r00q
mov qword [rsp+$08], $00
mov qword [rsp+$00], r00q
__sttag_x $00, TAG_OBJECT
call avt.lang.Class$allocateInstance$
}
; </fold>
; <fold вход, выход>
macro menter dataElements* {
local .L.0000
mov r00q, [rbx+ctxt$ehb]
lea r01q, [.L.IEHB]
lea rsp, [rsp-.loc.data-$18]
lea rsi, [rsi-.loc.tags-$02]
mov word [rsi+.loc.tags+$00], TAG_SF_METHOD
mov qword [rsp+.loc.data+$10], r00q
mov qword [rsp+.loc.data+$08], rdi
mov qword [rsp+.loc.data+$00], rbp
mov qword [rbx+ctxt$ehb], r01q
lea rdi, [rsi+.loc.tags+$00]
lea rbp, [rsp+.loc.data+$00]
lea r02q, [rsp-(dataElements)*$10]
cmp r02q, [rbx+ctxt$grd]
jge .L.0000
lea rsi, [rsi+.loc.tags+$00]
lea rsp, [rsp+.loc.data+$00]
_throw StackOverflowError
.L.0000:
}
macro mleave {
local .L.0000
local .L.0001
local .L.0002
local .L.0003
lea r01q, [rsp+$00]
lea r08q, [rbp+.arg.data+$20]
.L.0000: movzx r02d, word [rsi+$00]
cmp r02b, TAG_OBJECT
je .L.0001
cmp r02w, TAG_SF_METHOD
jne .L.0002
; TAG_SF_METHOD
mov rbp, [r01+$00]
mov rdi, [r01+$08]
mov r02q, [r01+$10]
mov qword [rbx+ctxt$ehb], r02q
__cltag_y $00
lea rsi, [rsi+$02]
lea rsp, [r01+$18]
lea r01q, [r01+$20]
jmp .L.0003
.L.0001: ; TAG_OBJECT
mov r02q, [r01+$00]
tstdecrcoth r02q
.L.0002: ; ==========
__cltag_x $00
lea rsi, [rsi+$01]
lea r01q, [r01+$10]
.L.0003: cmp r01q, r08q
jl .L.0000
if(.arg.data > 0)
ret .arg.data
else
ret
end if
separator_c
.L.IEHB:
}
; </fold>
; <fold блок инициализации класса>
macro citrlock classFullName* {
__push $01
lea r00q, [classFullName]
incrcoth r00q
mov qword [rsp+$08], $00
mov qword [rsp+$00], r00q
__sttag_x $00, TAG_OBJECT
call avt.lang.Class$clinitTryLock$
}
macro ciunlock classFullName* {
__push $01
lea r00q, [classFullName]
incrcoth r00q
mov qword [rsp+$08], $00
mov qword [rsp+$00], r00q
__sttag_x $00, TAG_OBJECT
call avt.lang.Class$clinitUnlock$
}
; </fold>
; <fold блок синхронизации>
macro monenter {
invspec avt.lang.Object$lock$
}
macro monleave {
invspec avt.lang.Object$unlock$
}
; </fold>
; <fold блок финализации>
macro finenter {
push r01q
lea rsi, [rsi-$01]
}
macro finleave {
lea rsi, [rsi+$01]
pop r01q
ret
}
; </fold>
; <fold переход в методы реализации сервисов>
macro jmpspec methodFullName* {
local .L.0000
local .L.0001
.L.0000: jmp methodFullName
.L.0001: nopvar $20-(.L.0001-.L.0000)
}
macro jmpvirt methodFullName* {
local .L.0000
local .L.0001
.L.0000: mov r00q, [rsp+methodFullName#.arg.data-$08]
_virtual methodFullName#.idx.virt
jmp r00q
.L.0001: nopvar $20-(.L.0001-.L.0000)
}
; </fold>
; </fold>