invoke.inc

Переключить прокрутку окна
Загрузить этот исходный код

;
  ; Реализация среды исполнения языка программирования
  ; Объектно-ориентированный продвинутый векторный транслятор
  ;
  ; 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>