subject.inc

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

;
 ;  Исходный код среды исполнения ПВТ-ОО.
 ;
 ;  Этот исходный код является частью проекта ПВТ-ОО.
 ;
 ;  Copyright © 2021 Малик Разработчик
 ;
 ;  Это свободная программа: вы можете перераспространять её и/или
 ;  изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
 ;  в каком она была опубликована Фондом свободного программного обеспечения;
 ;  либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
 ;
 ;  Эта программа распространяется в надежде, что она может быть полезна,
 ;  но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
 ;  или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
 ;  общественной лицензии GNU.
 ;
 ;  Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
 ;  вместе с этой программой. Если это не так, см.
 ;  <http://www.gnu.org/licenses/>.
;

; <fold subject macroinstructions>
    macro rdehp gpr64* {
                mov     gpr64, qword[rbx+context$ehp]
    }

    macro rdtsp gpr64 {
        if(gpr64 eq)
                    mov     rsi, qword[rbx+context$tsp]
        else
                    mov     gpr64, qword[rbx+context$tsp]
        end if
    }

    macro rdtbp gpr64 {
        if(gpr64 eq)
                    mov     rdi, qword[rbx+context$tbp]
        else
                    mov     gpr64, qword[rbx+context$tbp]
        end if
    }

    macro wrehp gpr64* {
                mov     qword[rbx+context$ehp], gpr64
    }

    macro wrtsp gpr64 {
        if(gpr64 eq)
                    mov     qword[rbx+context$tsp], rsi
        else
                    mov     qword[rbx+context$tsp], gpr64
        end if
    }

    macro wrtbp gpr64 {
        if(gpr64 eq)
                    mov     qword[rbx+context$tbp], rdi
        else
                    mov     qword[rbx+context$tbp], gpr64
        end if
    }

    macro throw exceptionType* {
                lea     rax, [avt.lang.#exceptionType#$create$avt.lang.Throwable$long$]
                jmp     subj$throwexception
    }
; </fold>

; <fold subject implementation>
    if(used subj$throwexception) ; <fold >
        proc subj$throwexception ; (createMethodPointer in rax)
                    add     qword[rbx+context$guardEnd], -$0c00
                    rdtsp
                    mov     rcx, [rbx+context$irp]
                    mov     rdi, [rbx+context$suppressedInstancePointer]
                    test    rdi, rdi
                    jz      @F
                    lock inc qword[rdi+avt.lang.Object$fldRefCountFromOthers]
            @@:     lea     rsp, [rsp-$30]
                    lea     rsi, [rsi-$03]
                    mov     qword[rsp+$28], $00
                    mov     qword[rsp+$20], rcx
                    mov     qword[rsp+$18], $00
                    mov     qword[rsp+$10], rdi
                    mov     qword[rsp+$08], $00
                    mov     qword[rsp+$00], rcx
                    mov     word[rsi], TAG_LONG or (TAG_OBJECT shl 8)
                    wrtsp
                    call    rax
                    mov     rcx, [rsp]
                    rdtsp
                    lea     rsp, [rsp+$10]
                    lea     rsi, [rsi+$01]
                    wrtsp
                    add     qword[rbx+context$guardEnd], $0c00
                    jmp     qword[rbx+context$ehp]
        end_proc
    end if ; </fold>

    if(used subj$stackrealize) ; <fold >
        subj stackrealize ; (bytes in ecx): tsp in rsi [unmodified: rax, rdi]
                    neg     ecx
                    movsxd  rcx, ecx
                    lea     rdx, [rsp+rcx*1]
                    cmp     rdx, [rbx+context$guardEnd]
                    jl      .L.000
                    cmp     rdx, [rbx+context$tagsPointer]
                    jng     .L.001
            .L.000: throw   StackOverflowError
            .L.001: sar     rcx, $04
                    rdtsp
                    mov     rsp, rdx
                    lea     rsi, [rsi+rcx*1]
                    wrtsp
        end_subj
    end if ; </fold>

    if(used subj$stackdeallocate) ; <fold >
        subj stackdeallocate ; (newRSP in rcx): newRSP in rcx, newTSP in rsi [unmodified: rax]
                    rdtsp
                    mov     rdi, rsp
                    jmp     .L.003
            .L.000: mov     dl, [rsi]
                    cmp     dl, TAG_OBJECT
                    je      .L.001
                    cmp     dl, TAG_SUPPRESS
                    jne     .L.002
                    mov     rdx, [rdi+$08]
                    mov     qword[rbx+context$suppressedInstructionPointer], rdx
                    mov     rdx, [rdi+$00]
                    xchg    qword[rbx+context$suppressedInstancePointer], rdx
                    test    rdx, rdx
                    jz      .L.002
                    lock dec qword[rdx+avt.lang.Object$fldRefCountFromOthers]
                    jmp     .L.002
            .L.001: mov     rdx, [rdi]
                    test    rdx, rdx
                    jz      .L.002
                    lock dec qword[rdx+avt.lang.Object$fldRefCountFromOthers]
            .L.002: mov     byte[rsi], TAG_EMPTY
                    lea     rsi, [rsi+$01]
                    lea     rdi, [rdi+$10]
            .L.003: cmp     rdi, rcx
                    jl      .L.000
        end_subj
    end if ; </fold>

    if(used subj$stackelements) ; <fold >
        subj stackelements ; (tsp in rsi): stackElements in rax
                    mov     eax, [rsi]
                    cmp     eax, TAG_LONG8
                    je      .L.004
                    cmp     eax, TAG_DOUBLE8
                    je      .L.004
                    cmp     ax, TAG_INT8
                    je      .L.002
                    cmp     ax, TAG_FLOAT8
                    je      .L.002
                    cmp     ax, TAG_LONG4
                    je      .L.002
                    cmp     ax, TAG_DOUBLE4
                    je      .L.002
                    mov     eax, $01
                    jmp     .L.RET
            .L.002: mov     eax, $02
                    jmp     .L.RET
            .L.004: mov     eax, $04
            .L.RET:
        end_subj
    end if ; </fold>
; </fold>