mirror of
https://github.com/dschmenk/VM02.git
synced 2024-06-07 18:29:28 +00:00
886 lines
17 KiB
ArmAsm
886 lines
17 KiB
ArmAsm
|
;*
|
||
|
;* JAVA VIRTUAL MACHINE FRAME/STACK SUPPORT FOR 6502
|
||
|
;*
|
||
|
;*
|
||
|
;* FRAME BLOCKS ARE LINKED LIST OF PREDEFINED SIZES TO HOLD LOCAL VARIABLES AND A STACK
|
||
|
;* FOR EACH METHOD INVOCATION. A FRAME BLOCK CONTAINS AS MANY FRAMES AS WILL FIT. WHEN
|
||
|
;* SPANNING BLOCKS, THE FIRST FIELDS IN THE BLOCK IS THE PREVIOUS BLOCK AND STACK_PTR.
|
||
|
;* THE FRAME BLOCK IS ORGANIZED AS:
|
||
|
;* FRAME_PTR -> PREV HFRAME
|
||
|
;* FRAME 0
|
||
|
;* ...
|
||
|
;* FRAME N
|
||
|
;* IF PREV HFRAME IS 0, THEN FRAME LIST IS EMPTY, THREAD IS FINISHED.
|
||
|
;*
|
||
|
;* A METHOD FRAME IS ORGANIZED AS:
|
||
|
;* VAR_BASE -> PARAMETERS/LOCAL VARIABLES
|
||
|
;* (BP),Y -> LOCAL VARIABLE POINTERS
|
||
|
;* RETURN ADDRESS = HMETHOD, PC
|
||
|
;* STACK_BASE -> STACK
|
||
|
;* ...
|
||
|
;* (SP),Y-> TOP OF STACK
|
||
|
;*
|
||
|
;* IF NEW FRAME WON'T FIT IN CURRENT FRAME BLOCK, ALLOCATE A NEW ONE AND LINK TO PREVIOUS
|
||
|
;*
|
||
|
.INCLUDE "global.inc"
|
||
|
.INCLUDE "class.inc"
|
||
|
.INCLUDE "frame.inc"
|
||
|
.IMPORT CROUT,COUT,PRSTR,KBWAIT,PRHSTR,PRHSTRLN
|
||
|
.IMPORT HMEM_ALLOC,HMEM_ALLOC_FIXED,HMEM_FREE,HMEM_LOCK,HMEM_UNLOCK,HMEM_UNLOCK_CODE
|
||
|
.IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC
|
||
|
.IMPORT HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL
|
||
|
.IMPORT HCLASS_NAME,HCLASS_HNDL,HCLASS_ADD,HCLASS_INDEX,CLASS_STRING,CLASS_OF,CLASS_LOCK,CLASS_UNLOCK
|
||
|
.IMPORT CLASS_METHODPTR,CLASS_VIRTCODE,CLASS_LOCKMETHOD,CLASS_UNLOCKMETHOD
|
||
|
.IMPORT THREAD_PUSH_TLS,THREAD_POP_TLS,THREAD_LOCK,THREAD_UNLOCK,CURRENT_THREAD
|
||
|
.IMPORT HCODE_ACCESS,HCODE_UNACCESS,HCODE_LOCK,HCODE_UNLOCK,HCODE_ISBYTECODE
|
||
|
.IMPORT HCODE_GETLOCALS,HCODE_GETCLASS,HCODE_FLAGS,HCODE_GETHEXCEPT,HCODE_GETEXCEPTLEN
|
||
|
.IMPORT EXECBYTECODES,LOOKUPCLASSIDX
|
||
|
.IMPORT UNREF_OBJECT,SYSTHROW,THROW_INTERNALERR,CURRENTEXCEPTN
|
||
|
.EXPORT ASYNC_VIRTUAL,ASYNC_STATIC,INVOKE_VIRTUAL,INVOKE_SPECIAL,INVOKE_STATIC,EXIT_METHOD,CATCH_EXCEPTN
|
||
|
|
||
|
.CODE
|
||
|
;*
|
||
|
;* INVOKE AN ASYNCHRONOUS METHOD. JSR HERE.
|
||
|
;* ENTRY: AX = METHOD OFFSET
|
||
|
;* Y = CLASS INDEX
|
||
|
;*
|
||
|
ASYNC_VIRTUAL: STY LOCKCLASS
|
||
|
.IFDEF DEBUG
|
||
|
STA METHDOFST
|
||
|
STX METHDOFST+1
|
||
|
.ENDIF
|
||
|
JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD
|
||
|
STA METHODPTR
|
||
|
STX METHODPTR+1
|
||
|
LDY #METHODVINDEX+1 ; GET INDEX FOR VIRTUAL TABLE
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
STA TMP+1
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
STA TMP
|
||
|
TSX
|
||
|
TXA
|
||
|
CLC
|
||
|
ADC (METHODPTR),Y ; SKIP METHOD PARAM SIZE
|
||
|
TAX
|
||
|
LDA $0105,X ; GET ICLASS FROM *THIS* REF
|
||
|
AND #$7F
|
||
|
.IFDEF DEBUG_INVOKE
|
||
|
BNE :+
|
||
|
JMP NULL_THIS
|
||
|
:
|
||
|
.ELSE
|
||
|
BEQ NULL_THIS
|
||
|
.ENDIF
|
||
|
TAY
|
||
|
LDA TMP
|
||
|
LDX TMP+1
|
||
|
JSR CLASS_VIRTCODE
|
||
|
JMP ASYNC_METHOD
|
||
|
ASYNC_STATIC: STY LOCKCLASS
|
||
|
.IFDEF DEBUG
|
||
|
STA METHDOFST
|
||
|
STX METHDOFST+1
|
||
|
.ENDIF
|
||
|
JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD
|
||
|
STA METHODPTR
|
||
|
STX METHODPTR+1
|
||
|
LDY #METHODSTATICODE+1 ; GET STATIC CODE HANDLE
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
ASYNC_METHOD: STA HMETHODCODE
|
||
|
STX HMETHODCODE+1
|
||
|
.IFDEF DEBUG_INVOKE
|
||
|
PSTR "INVOKING ASYNC METHOD:"
|
||
|
LDY LOCKCLASS
|
||
|
JSR CLASS_STRING
|
||
|
JSR HMEM_PTR
|
||
|
JSR PRSTR
|
||
|
LDA #'.'
|
||
|
JSR COUT
|
||
|
LDY #METHODNAME+1
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
JSR HMEM_PTR
|
||
|
JSR PRSTR
|
||
|
LDY #METHODDESC+1
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
JSR HMEM_PTR
|
||
|
JSR PRSTR
|
||
|
JSR CROUT
|
||
|
; JSR KBWAIT
|
||
|
.ENDIF
|
||
|
LDA HMETHODCODE
|
||
|
LDX HMETHODCODE+1
|
||
|
JSR HCODE_ISBYTECODE ; CHECK FOR NATIVE METHOD
|
||
|
BEQ ASYNCBYTECODE
|
||
|
LDY LOCKCLASS
|
||
|
JSR CLASS_UNLOCKMETHOD ; UNLOCK METHOD STRUCTURE
|
||
|
LDA HMETHODCODE
|
||
|
LDX HMETHODCODE+1
|
||
|
JSR HMEM_PTR
|
||
|
STA NATIVECODEPTR ; CALL NATIVE METHOD
|
||
|
STX NATIVECODEPTR+1
|
||
|
CLC ; CLEAR CARRY
|
||
|
JMP (NATIVECODEPTR)
|
||
|
ASYNCBYTECODE: JSR SAVEPC_RELFRM ; SAVE EXECPC AND RELEASE FRAME
|
||
|
PLA ; SAVE RETURN ADDRESS
|
||
|
TAX ; IN TLS
|
||
|
PLA
|
||
|
JSR THREAD_PUSH_TLS
|
||
|
LDA HEXECFRAME
|
||
|
LDX HEXECFRAME+1
|
||
|
JSR THREAD_PUSH_TLS
|
||
|
LDA #$00 ; ZERO OUT CURRENT FRAME
|
||
|
STA HEXECFRAME
|
||
|
STA HEXECFRAME+1
|
||
|
JMP BUILD_FRAME
|
||
|
NULL_THIS: LDA #17 ; NULL *THIS* REF
|
||
|
JMP SYSTHROW
|
||
|
;*
|
||
|
;* INVOKE A METHOD. DON'T JSR HERE, JMP HERE.
|
||
|
;* ENTRY: AX = METHOD OFFSET
|
||
|
;* Y = CLASS INDEX
|
||
|
;*
|
||
|
INVOKE_VIRTUAL: STY LOCKCLASS
|
||
|
.IFDEF DEBUG
|
||
|
STA METHDOFST
|
||
|
STX METHDOFST+1
|
||
|
.ENDIF
|
||
|
JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD
|
||
|
STA METHODPTR
|
||
|
STX METHODPTR+1
|
||
|
LDY #METHODVINDEX+1 ; GET INDEX FOR VIRTUAL TABLE
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
STA TMP+1
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
STA TMP
|
||
|
TSX
|
||
|
TXA
|
||
|
CLC
|
||
|
ADC (METHODPTR),Y ; SKIP METHOD PARAM SIZE
|
||
|
TAX
|
||
|
LDA $0103,X ; GET ICLASS FROM *THIS* REF
|
||
|
AND #$7F
|
||
|
BEQ NULL_THIS
|
||
|
TAY
|
||
|
LDA TMP
|
||
|
LDX TMP+1
|
||
|
JSR CLASS_VIRTCODE
|
||
|
JMP INVOKE_METHOD
|
||
|
INVOKE_SPECIAL: STY LOCKCLASS
|
||
|
.IFDEF DEBUG
|
||
|
STA METHDOFST
|
||
|
STX METHDOFST+1
|
||
|
.ENDIF
|
||
|
JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD
|
||
|
STA METHODPTR
|
||
|
STX METHODPTR+1
|
||
|
LDY #METHODVINDEX+1 ; GET INDEX FOR VIRTUAL TABLE
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
LDY LOCKCLASS
|
||
|
JSR CLASS_VIRTCODE
|
||
|
JMP INVOKE_METHOD
|
||
|
INVOKE_STATIC: STY LOCKCLASS
|
||
|
.IFDEF DEBUG
|
||
|
STA METHDOFST
|
||
|
STX METHDOFST+1
|
||
|
.ENDIF
|
||
|
JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD
|
||
|
STA METHODPTR
|
||
|
STX METHODPTR+1
|
||
|
LDY #METHODSTATICODE+1 ; GET STATIC CODE HANDLE
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
;*
|
||
|
;* INVOKE METHOD
|
||
|
;* ENTRY: AX = CODE HANDLE
|
||
|
;*
|
||
|
INVOKE_METHOD: STA HMETHODCODE
|
||
|
STX HMETHODCODE+1
|
||
|
.IFDEF DEBUG_INVOKE
|
||
|
PSTR "INVOKING METHOD:"
|
||
|
LDY LOCKCLASS
|
||
|
JSR CLASS_STRING
|
||
|
JSR HMEM_PTR
|
||
|
JSR PRSTR
|
||
|
LDA #'.'
|
||
|
JSR COUT
|
||
|
LDY #METHODNAME+1
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
JSR HMEM_PTR
|
||
|
JSR PRSTR
|
||
|
LDY #METHODDESC+1
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
JSR HMEM_PTR
|
||
|
JSR PRSTR
|
||
|
JSR CROUT
|
||
|
; JSR KBWAIT
|
||
|
.ENDIF
|
||
|
LDA EXECPC ; INCREMENT EXECPC
|
||
|
CLC
|
||
|
ADC #$03
|
||
|
STA EXECPC
|
||
|
BCC :+
|
||
|
INC EXECPC+1
|
||
|
: LDA HMETHODCODE
|
||
|
LDX HMETHODCODE+1
|
||
|
JSR HCODE_ISBYTECODE ; CHECK FOR NATIVE METHOD
|
||
|
BEQ BUILD_FRAME
|
||
|
LDY LOCKCLASS
|
||
|
JSR CLASS_UNLOCKMETHOD ; UNLOCK METHOD STRUCTURE
|
||
|
LDA HMETHODCODE
|
||
|
LDX HMETHODCODE+1
|
||
|
JSR HMEM_PTR
|
||
|
STA NATIVECODEPTR ; CALL NATIVE METHOD
|
||
|
STX NATIVECODEPTR+1
|
||
|
CLC ; CLEAR CARRY
|
||
|
JSR :+
|
||
|
SEI ; MAKE A SANE ENVIRONMENT ON RETURN
|
||
|
BIT LCBNK2
|
||
|
BIT LCBNK2
|
||
|
CLI
|
||
|
JMP EXECBYTECODES ; RETURN TO EXECUTING BYTECODES
|
||
|
: JMP (NATIVECODEPTR)
|
||
|
;*
|
||
|
;* BUILD A NEW FRAME FOR METHOD INVOCATION
|
||
|
;* A NEW FRAME BLOCK WILL BE ALLOCATED IF THE CURRENT
|
||
|
;* BLOCK CAN'T FIT THE NEW FRAME
|
||
|
;* ENTRY: METHODPTR = POINTER TO METHOD BEING CALLED
|
||
|
;*
|
||
|
BUILD_FRAME:
|
||
|
.IFDEF DEBUG
|
||
|
LDA $0101 ; CHECK FOR STACK OVERFLOW
|
||
|
CMP #$69
|
||
|
BEQ :++
|
||
|
: PERR "STACK OVERFLOW IN METHOD INVOKE"
|
||
|
BRK
|
||
|
JMP THROW_INTERNALERR
|
||
|
: LDA $0100
|
||
|
CMP #$69
|
||
|
BNE :--
|
||
|
.ENDIF
|
||
|
JSR SAVEPC_RELFRM ; SAVE EXECPC AND RELEASE FRAME
|
||
|
LDA HMETHODCODE
|
||
|
LDX HMETHODCODE+1
|
||
|
JSR HCODE_ACCESS ; ACCESS THIS CODE BLOCK
|
||
|
JSR HCODE_GETCLASS
|
||
|
STA CALLCLASS
|
||
|
JSR HCODE_GETLOCALS ; GET LOCAL VAR COUNT & SIZE IN BYTES
|
||
|
STY FRMVARS ; (INCLUDES PARAMETERS)
|
||
|
CLC
|
||
|
ADC #FRAMEBASESZ
|
||
|
BCC :+
|
||
|
INX
|
||
|
: LDY #$00
|
||
|
JSR HMEM_ALLOC ; ALLOCATE NEW FRAME
|
||
|
STA HLINKFRAME
|
||
|
STX HLINKFRAME+1
|
||
|
JSR HMEM_LOCK
|
||
|
STA FRAMEPTR
|
||
|
STX FRAMEPTR+1
|
||
|
.IFDEF DEBUG
|
||
|
LDY #FRAMEMETHOD
|
||
|
LDA METHDOFST
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY
|
||
|
LDA METHDOFST+1
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY
|
||
|
.ELSE
|
||
|
LDY #FRAMEICLASS ; SAVE CLASS IN FRAME
|
||
|
.ENDIF
|
||
|
LDA CALLCLASS
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY ; LDY #FRAMELOCALCNT
|
||
|
LDA FRMVARS ; SAVE LOCAL VAR COUNT
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY ; LDY #FRAMEHCODE
|
||
|
LDA HMETHODCODE ; SAVE CODE HANDLE IN FRAME
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY
|
||
|
LDA HMETHODCODE+1
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY ; LDY #FRAMEPC
|
||
|
LDA #$00 ; SET PC TO ENTRYPOINT
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY ; LDY #FRAMEHPREV
|
||
|
LDA HEXECFRAME ; LINK TO PREVIOUS FRAME HANDLE
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY
|
||
|
LDA HEXECFRAME+1
|
||
|
STA (FRAMEPTR),Y
|
||
|
LDA HLINKFRAME
|
||
|
LDX HLINKFRAME+1
|
||
|
JSR SETUP_FRAME
|
||
|
LDY #METHODDESC+1
|
||
|
LDA (METHODPTR),Y ; GET POINTER TO DESC STRING
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
JSR HMEM_LOCK ; LOCK STRING IN PLACE
|
||
|
STA SCANPTR
|
||
|
STX SCANPTR+1
|
||
|
LDY #$01 ; SKIP SIZE BYTE
|
||
|
STY SCANPOS
|
||
|
DEY
|
||
|
STY VARCNT
|
||
|
TSX ; COPY PARAMETERS INTO NEW LOCALS
|
||
|
TXA
|
||
|
LDY #METHODPARAMS
|
||
|
CLC
|
||
|
ADC (METHODPTR),Y ; ADD PARAM BYTE COUNT
|
||
|
TAX
|
||
|
STX STACKPOPPED
|
||
|
LDY #METHODACCESS ; CHECK FOR STATIC METHOD, Y = 0
|
||
|
LDA (METHODPTR),Y
|
||
|
AND #$08
|
||
|
BNE SCANPARAMTYPES
|
||
|
TXA
|
||
|
CLC
|
||
|
ADC #$04
|
||
|
STA STACKPOPPED
|
||
|
TAX
|
||
|
BNE COPYREF ; COPY THIS REF PARAMETER
|
||
|
SCANPARAMTYPES: LDY SCANPOS ; SCAN PARAMETERS FOR REF TYPE
|
||
|
INY
|
||
|
LDA (SCANPTR),Y
|
||
|
CMP #')' ; END OF PARAM LIST
|
||
|
BNE SCANPTYPECHK
|
||
|
JMP ZEROLOCALTYPES
|
||
|
SCANPTYPECHK: CMP #'L' ; CHECK FOR REFERENCE
|
||
|
BEQ SCANTYPEREF
|
||
|
CMP #'[' ; CHECK FOR ARRAY
|
||
|
BEQ SCANTYPEARRAY
|
||
|
CMP #'J'
|
||
|
BEQ SCANLONG
|
||
|
STY SCANPOS ; PULL 32 BIT VALUE OFF STACK
|
||
|
LDY VARCNT
|
||
|
: LDA #$00 ; NON-REF TYPE
|
||
|
STA (BPT),Y
|
||
|
LDA $0100,X
|
||
|
DEX
|
||
|
STA (BP3),Y
|
||
|
LDA $0100,X
|
||
|
DEX
|
||
|
STA (BP2),Y
|
||
|
LDA $0100,X
|
||
|
DEX
|
||
|
STA (BP1),Y
|
||
|
LDA $0100,X
|
||
|
DEX
|
||
|
STA (BP0),Y
|
||
|
INC VARCNT
|
||
|
BNE SCANPARAMTYPES
|
||
|
SCANLONG: STY SCANPOS
|
||
|
LDY VARCNT
|
||
|
INY
|
||
|
LDA #$00
|
||
|
STA (BPT),Y ; ZERO OUT HIWORD TYPE
|
||
|
DEY
|
||
|
INC VARCNT ; ADD TWO TO VARCNT TO MATCH UP LOCALS
|
||
|
BNE :-
|
||
|
SCANTYPEARRAY: INY ; EAT ARRAY
|
||
|
LDA (SCANPTR),Y
|
||
|
CMP #'['
|
||
|
BEQ SCANTYPEARRAY
|
||
|
CMP #'L' ; FALL THRU FOR ARRAY OBJS
|
||
|
BNE INCREFCNT
|
||
|
SCANTYPEREF: INY
|
||
|
LDA (SCANPTR),Y
|
||
|
CMP #';' ; CHECK FOR END OF REFERENCE
|
||
|
BNE SCANTYPEREF
|
||
|
INCREFCNT: STY SCANPOS
|
||
|
COPYREF: LDY VARCNT
|
||
|
LDA #T_REF|$80 ; PULL REF VALUE OFF STACK
|
||
|
STA (BPT),Y
|
||
|
LDA $0100,X
|
||
|
DEX
|
||
|
STA (BP3),Y
|
||
|
LDA $0100,X
|
||
|
DEX
|
||
|
AND #$7F ; MASK OFF NOINC FLAG
|
||
|
STA (BP2),Y
|
||
|
LDA $0100,X
|
||
|
DEX
|
||
|
STA (BP1),Y
|
||
|
LDA $0100,X
|
||
|
DEX
|
||
|
STA (BP0),Y
|
||
|
LDA $0103,X ; CHECK NOINC FLAG
|
||
|
BMI SKIPREFINC
|
||
|
LDA (BP1),Y ; CHECK NULL REF
|
||
|
BEQ SKIPREFINC
|
||
|
STX STACKPOS
|
||
|
TAX
|
||
|
LDA (BP0),Y
|
||
|
JSR HMEM_REF_INC ; INCREMENT REF CNT
|
||
|
LDX STACKPOS
|
||
|
SKIPREFINC: INC VARCNT
|
||
|
JMP SCANPARAMTYPES
|
||
|
ZEROLOCALTYPES: LDX STACKPOPPED ; UPDATE STACK POINTER
|
||
|
TXS
|
||
|
LDY #FRAMESP ; SAVE SP FOR EXCEPTION
|
||
|
TXA
|
||
|
STA (FRAMEPTR),Y
|
||
|
LDY #FRAMELOCALCNT ; ZERO OUT REMAINING LOCALS
|
||
|
LDA (FRAMEPTR),Y
|
||
|
SEC
|
||
|
SBC VARCNT
|
||
|
BEQ EXECFRAME
|
||
|
TAX
|
||
|
LDA #$00
|
||
|
LDY VARCNT
|
||
|
ZEROLOCALSLP: STA (BPT),Y
|
||
|
INY
|
||
|
DEX
|
||
|
BNE ZEROLOCALSLP
|
||
|
EXECFRAME: LDY #METHODDESC+1
|
||
|
LDA (METHODPTR),Y ; UNLOCK DESC STRING
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
JSR HMEM_UNLOCK
|
||
|
JSR HCODE_UNACCESS ; DONE ACCESSING CODE PARAMTERS
|
||
|
LDY LOCKCLASS
|
||
|
JSR CLASS_UNLOCKMETHOD ; UNLOCK METHOD STRUCTURE
|
||
|
LDA HMETHODCODE
|
||
|
LDX HMETHODCODE+1
|
||
|
JSR HCODE_FLAGS
|
||
|
AND #$20 ; CHECK FOR SYNCHRONIZED METHODS
|
||
|
BNE :+
|
||
|
JMP EXECBYTECODES
|
||
|
: LDY #METHODACCESS ; CHECK FOR STATIC METHOD
|
||
|
LDA (METHODPTR),Y
|
||
|
AND #$08
|
||
|
BEQ :+
|
||
|
LDY CALLCLASS
|
||
|
JSR HCLASS_INDEX
|
||
|
BCC LOCKNLOAD ; SHOULD ALWAYS BE TAKEN
|
||
|
PERR "BAD SYNCH CLASS"
|
||
|
: LDA (BP1),Y ; Y = 0
|
||
|
TAX
|
||
|
LDA (BP0),Y
|
||
|
LOCKNLOAD: PHA
|
||
|
LDY #FRAMESYNCHOBJ ; SAVE HCLASS IN FRAME FOR SYNCHRONIZATION
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY
|
||
|
TXA
|
||
|
STA (FRAMEPTR),Y
|
||
|
PLA
|
||
|
JSR THREAD_LOCK ; LOCK OBJECT
|
||
|
JMP EXECBYTECODES
|
||
|
;*
|
||
|
;* SETUP FRAME POINTERS
|
||
|
;* ENTRY: AX = FRAME HANDLE
|
||
|
;*
|
||
|
SETUP_FRAME: STA HEXECFRAME ; SET NEW FRAME
|
||
|
STX HEXECFRAME+1
|
||
|
JSR HMEM_LOCK ; LOCK FRAME IN PLACE, RETURN POINTER
|
||
|
STA FRAMEPTR
|
||
|
STX FRAMEPTR+1
|
||
|
LDY #FRAMEHCODE+1 ; GET CODE SEGMENT
|
||
|
LDA (FRAMEPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (FRAMEPTR),Y
|
||
|
JSR HCODE_LOCK
|
||
|
STA EXECCODEBASE
|
||
|
STX EXECCODEBASE+1
|
||
|
LDY #FRAMEPC ; SET PC POINTER
|
||
|
CLC ; ADD EXECPC OFFSET
|
||
|
ADC (FRAMEPTR),Y
|
||
|
INY
|
||
|
STA EXECPC
|
||
|
TXA
|
||
|
ADC (FRAMEPTR),Y
|
||
|
STA EXECPC+1
|
||
|
LDY #FRAMEICLASS ; SET CLASS INDEX
|
||
|
LDA (FRAMEPTR),Y
|
||
|
STA IEXECCLASS
|
||
|
TAY
|
||
|
JSR CLASS_LOCK
|
||
|
CLC
|
||
|
ADC #(CLASSCONSTPL-CONSTPLRECSZ) ; INDEX IS 1 BASED
|
||
|
BCC :+
|
||
|
INX
|
||
|
: STA EXECCONSTPL
|
||
|
STX EXECCONSTPL+1
|
||
|
LDY #FRAMELOCALCNT
|
||
|
LDA (FRAMEPTR),Y ; SETUP BASE POINTERS
|
||
|
STA TMP
|
||
|
LDA FRAMEPTR
|
||
|
LDX FRAMEPTR+1
|
||
|
CLC
|
||
|
ADC #FRAMEBASESZ
|
||
|
BCC :+
|
||
|
INX
|
||
|
CLC
|
||
|
: STA BPT ; BASE POINTER - TYPE
|
||
|
STX BPT+1
|
||
|
ADC TMP
|
||
|
BCC :+
|
||
|
INX
|
||
|
CLC
|
||
|
: STA BP0 ; BASE POINTER - BYTE0
|
||
|
STX BP0+1
|
||
|
ADC TMP
|
||
|
BCC :+
|
||
|
INX
|
||
|
CLC
|
||
|
: STA BP1 ; BASE POINTER - BYTE1
|
||
|
STX BP1+1
|
||
|
ADC TMP
|
||
|
BCC :+
|
||
|
INX
|
||
|
CLC
|
||
|
: STA BP2 ; BASE POINTER - BYTE2
|
||
|
STX BP2+1
|
||
|
ADC TMP
|
||
|
BCC :+
|
||
|
INX
|
||
|
CLC
|
||
|
: STA BP3 ; BASE POINTER - BYTE3
|
||
|
STX BP3+1
|
||
|
: RTS
|
||
|
;*
|
||
|
;* SAVE EXECPC AND FALL INTO RELEASE_FRAME
|
||
|
;*
|
||
|
SAVEPC_RELFRM: LDX HEXECFRAME+1
|
||
|
BEQ :-
|
||
|
LDA HEXECFRAME
|
||
|
JSR HMEM_PTR
|
||
|
STA FRAMEPTR
|
||
|
STX FRAMEPTR+1
|
||
|
LDY #FRAMEPC
|
||
|
LDA EXECPC ; SAVE INSTRUCTION PTR IN CURRENT FRAME
|
||
|
SEC ; SAVE AS OFFSET FROM CODEPTR
|
||
|
SBC EXECCODEBASE
|
||
|
STA (FRAMEPTR),Y
|
||
|
INY
|
||
|
LDA EXECPC+1
|
||
|
SBC EXECCODEBASE+1
|
||
|
STA (FRAMEPTR),Y
|
||
|
;*
|
||
|
;* RELEASE CURRENT FRAME'S MEMORY RESOURCES
|
||
|
;*
|
||
|
RELEASE_FRAME: LDY #FRAMEHCODE+1 ; EXIT CODE BLOCK
|
||
|
LDA (FRAMEPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (FRAMEPTR),Y
|
||
|
JSR HCODE_UNLOCK
|
||
|
LDA HEXECFRAME ; UNLOCK CURRENT FRAME
|
||
|
LDX HEXECFRAME+1
|
||
|
JSR HMEM_UNLOCK
|
||
|
LDY IEXECCLASS
|
||
|
JMP CLASS_UNLOCK
|
||
|
;*
|
||
|
;* EXIT A METHOD, BREAK DOWN FRAME.
|
||
|
;* ENTRY: AX = REFERENCE NOT TO DELETE
|
||
|
;*
|
||
|
EXIT_METHOD: STA RETURN_REF
|
||
|
STX RETURN_REF+1
|
||
|
.IFDEF DEBUG_INVOKE
|
||
|
PERR "EXITING METHOD"
|
||
|
; JSR KBWAIT
|
||
|
.ENDIF
|
||
|
.IFDEF DEBUG
|
||
|
LDA $0101 ; CHECK FOR STACK OVERFLOW
|
||
|
CMP #$69
|
||
|
BEQ :++
|
||
|
: PERR "STACK OVERFLOW IN EXIT METHOD"
|
||
|
BRK
|
||
|
JMP THROW_INTERNALERR
|
||
|
: LDA $0100
|
||
|
CMP #$69
|
||
|
BNE :--
|
||
|
.ENDIF
|
||
|
LDA HEXECFRAME ; SET FRAME POINTER
|
||
|
LDX HEXECFRAME+1
|
||
|
JSR HMEM_PTR
|
||
|
STA FRAMEPTR
|
||
|
STX FRAMEPTR+1
|
||
|
LDY #FRAMELOCALCNT
|
||
|
LDA (FRAMEPTR),Y
|
||
|
TAY
|
||
|
BEQ CHECKSYNC
|
||
|
DEREFLOCALS: DEY
|
||
|
LDA (BPT),Y ; CHECK FOR LOCAL REF VAR
|
||
|
BPL NEXTLOCAL
|
||
|
LDA (BP1),Y
|
||
|
BEQ NEXTLOCAL ; CHECK FOR NULL REFERENCE
|
||
|
TAX
|
||
|
LDA (BP0),Y
|
||
|
CMP RETURN_REF
|
||
|
BNE UNREFLOCAL
|
||
|
CPX RETURN_REF+1
|
||
|
BNE UNREFLOCAL ; MATCHES RETURN REF, DON'T DELETE
|
||
|
STY VARCNT
|
||
|
JSR HMEM_REF_DEC ; JUST DEC REF COUNT
|
||
|
LDY VARCNT
|
||
|
JMP NEXTLOCAL
|
||
|
UNREFLOCAL: TYA
|
||
|
PHA
|
||
|
LDA RETURN_REF
|
||
|
PHA
|
||
|
LDA RETURN_REF+1
|
||
|
PHA
|
||
|
LDA (BP3),Y
|
||
|
PHA
|
||
|
LDA (BP2),Y
|
||
|
PHA
|
||
|
TXA
|
||
|
PHA
|
||
|
LDA (BP0),Y
|
||
|
PHA
|
||
|
JSR UNREF_OBJECT
|
||
|
PLA
|
||
|
STA RETURN_REF+1
|
||
|
PLA
|
||
|
STA RETURN_REF
|
||
|
PLA
|
||
|
TAY
|
||
|
NEXTLOCAL: CPY #$00
|
||
|
BNE DEREFLOCALS
|
||
|
LDA HEXECFRAME ; RE-SET FRAME POINTER
|
||
|
LDX HEXECFRAME+1
|
||
|
JSR HMEM_PTR
|
||
|
STA FRAMEPTR
|
||
|
STX FRAMEPTR+1
|
||
|
CHECKSYNC: LDY #FRAMEHCODE+1
|
||
|
LDA (FRAMEPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (FRAMEPTR),Y
|
||
|
JSR HCODE_FLAGS
|
||
|
AND #$20 ; CHECK FOR SYNCHRONIZED METHODS
|
||
|
BEQ UNLINKFRAME
|
||
|
LDY #FRAMESYNCHOBJ+1
|
||
|
LDA (FRAMEPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (FRAMEPTR),Y
|
||
|
JSR THREAD_UNLOCK ; UNLOCK OBJECT
|
||
|
UNLINKFRAME: LDY #FRAMELINKPREV ; GET PREVIOUS FRAME
|
||
|
LDA (FRAMEPTR),Y
|
||
|
INY
|
||
|
STA HLINKFRAME
|
||
|
LDA (FRAMEPTR),Y
|
||
|
STA HLINKFRAME+1
|
||
|
JSR RELEASE_FRAME ; RELEASE CURRENT FRAME
|
||
|
LDA HEXECFRAME
|
||
|
LDX HEXECFRAME+1
|
||
|
JSR HMEM_FREE ; FREE UP ITS MEMORY
|
||
|
LDA HLINKFRAME
|
||
|
LDX HLINKFRAME+1
|
||
|
BEQ ASYNC_EXIT
|
||
|
JSR SETUP_FRAME
|
||
|
.IFDEF DEBUG_INVOKE
|
||
|
PSTR "RETURNING TO METHOD:"
|
||
|
LDY #FRAMEICLASS ; GET METHOD CLASS
|
||
|
LDA (FRAMEPTR),Y
|
||
|
TAY
|
||
|
STY CALLCLASS
|
||
|
JSR CLASS_STRING
|
||
|
JSR PRHSTR
|
||
|
LDA #'.'
|
||
|
JSR COUT
|
||
|
LDY #FRAMEMETHOD+1
|
||
|
LDA (FRAMEPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (FRAMEPTR),Y
|
||
|
STA METHDOFST
|
||
|
STX METHDOFST+1
|
||
|
LDY CALLCLASS
|
||
|
JSR CLASS_LOCKMETHOD ; GET POINTER TO LOCKED METHOD
|
||
|
STA METHODPTR
|
||
|
STX METHODPTR+1
|
||
|
LDY #METHODNAME+1
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
JSR PRHSTR
|
||
|
LDY #METHODDESC+1
|
||
|
LDA (METHODPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (METHODPTR),Y
|
||
|
JSR PRHSTR
|
||
|
JSR CROUT
|
||
|
LDY CALLCLASS
|
||
|
JSR CLASS_UNLOCKMETHOD
|
||
|
; JSR KBWAIT
|
||
|
.ENDIF
|
||
|
LDA EXECFLAGS ; CHECK FOR EXCEPTION
|
||
|
BMI CATCH_EXCEPTN
|
||
|
JMP EXECBYTECODES
|
||
|
ASYNC_EXIT: JSR THREAD_POP_TLS ; RETURN FROM ASYNC METHOD
|
||
|
STA HEXECFRAME
|
||
|
STX HEXECFRAME+1
|
||
|
CPX #$00
|
||
|
BEQ :+
|
||
|
JSR SETUP_FRAME
|
||
|
:
|
||
|
.IFDEF DEBUG_INVOKE
|
||
|
PERR "ASYNC RETURN"
|
||
|
; JSR KBWAIT
|
||
|
.ENDIF
|
||
|
JSR THREAD_POP_TLS
|
||
|
PHA
|
||
|
TXA
|
||
|
PHA
|
||
|
ASL EXECFLAGS ; MOVE EXCEPTION FLAG INTO CARRY
|
||
|
RTS
|
||
|
;*
|
||
|
;* AN EXCEPTION IS IN PROGRESS - SEARCH FOR MATCHING CATCH CLAUSE
|
||
|
;*
|
||
|
CATCH_EXCEPTN:
|
||
|
.IFDEF DEBUG_EXCEPT
|
||
|
; .IMPORT THREAD_TRACE
|
||
|
; JSR THREAD_TRACE
|
||
|
PERR "CATCH EXCEPTION"
|
||
|
JSR KBWAIT
|
||
|
.ENDIF
|
||
|
PLA ; POP EXCEPTION
|
||
|
STA CURRENTEXCEPTN
|
||
|
PLA
|
||
|
STA CURRENTEXCEPTN+1
|
||
|
PLA
|
||
|
STA CURRENTEXCEPTN+2
|
||
|
PLA
|
||
|
STA CURRENTEXCEPTN+3
|
||
|
LDY #FRAMESP ; RESTORE SP TO CALLING DEPTH
|
||
|
LDA (FRAMEPTR),Y ; PUSH EXCEPTION BACK ON STACK
|
||
|
TAX
|
||
|
TXS
|
||
|
LDA CURRENTEXCEPTN+3
|
||
|
PHA
|
||
|
LDA CURRENTEXCEPTN+2
|
||
|
PHA
|
||
|
LDA CURRENTEXCEPTN+1
|
||
|
PHA
|
||
|
LDA CURRENTEXCEPTN
|
||
|
PHA
|
||
|
LDY #FRAMEPC+1 ; RECOVER PC POINTER
|
||
|
LDA (FRAMEPTR),Y
|
||
|
DEY
|
||
|
STA EXCEPTPC+1
|
||
|
LDA (FRAMEPTR),Y
|
||
|
STA EXCEPTPC
|
||
|
LDY #FRAMEHCODE+1 ; GET CODE SEGMENT
|
||
|
LDA (FRAMEPTR),Y
|
||
|
DEY
|
||
|
TAX
|
||
|
LDA (FRAMEPTR),Y
|
||
|
JSR HCODE_ACCESS ; ACCESS THIS CODE BLOCK
|
||
|
JSR HCODE_GETHEXCEPT
|
||
|
STA HEXCEPTTBL
|
||
|
STX HEXCEPTTBL+1
|
||
|
CPX #$00
|
||
|
BEQ NOTCAUGHT
|
||
|
JSR HMEM_LOCK
|
||
|
STA EXCEPTPTR
|
||
|
STX EXCEPTPTR+1
|
||
|
JSR HCODE_GETEXCEPTLEN
|
||
|
STX EXCEPTCNT+1
|
||
|
SEARCHEXCEPT: STA EXCEPTCNT
|
||
|
ORA EXCEPTCNT+1
|
||
|
BNE CHKRANGE
|
||
|
NOTCAUGHT: JSR HCODE_UNACCESS
|
||
|
LDA HEXCEPTTBL
|
||
|
LDX HEXCEPTTBL+1
|
||
|
BEQ :+
|
||
|
JSR HMEM_UNLOCK
|
||
|
: LDA RETURN_REF
|
||
|
LDX RETURN_REF+1
|
||
|
JMP EXIT_METHOD ; BACKTRACE FRAMES
|
||
|
CHKRANGE: LDY #$03 ; CHECK HANDLER END RANGE
|
||
|
LDA EXCEPTPC
|
||
|
CMP (EXCEPTPTR),Y
|
||
|
DEY
|
||
|
LDA EXCEPTPC+1
|
||
|
SBC (EXCEPTPTR),Y
|
||
|
BCS NEXTEXCEPT
|
||
|
DEY ; CHECK HANDLER START RANGE
|
||
|
LDA EXCEPTPC
|
||
|
CMP (EXCEPTPTR),Y
|
||
|
DEY
|
||
|
LDA EXCEPTPC+1
|
||
|
SBC (EXCEPTPTR),Y
|
||
|
BCC NEXTEXCEPT
|
||
|
LDY #$06 ; CHECK HANDLER EXCEPTION
|
||
|
LDA (EXCEPTPTR),Y
|
||
|
INY
|
||
|
TAX
|
||
|
LDA (EXCEPTPTR),Y
|
||
|
CMP #$00
|
||
|
BNE :+
|
||
|
CPX #$00
|
||
|
BEQ CAUGHTEXCEPT
|
||
|
: JSR LOOKUPCLASSIDX
|
||
|
LDA CURRENTEXCEPTN+2
|
||
|
AND #$7F
|
||
|
JSR CLASS_OF ; IS EXCEPTION A CLASS OF HANDLER
|
||
|
BCS NEXTEXCEPT
|
||
|
CAUGHTEXCEPT: LDY #$05 ; GET HANDLER PC
|
||
|
LDA (EXCEPTPTR),Y
|
||
|
DEY
|
||
|
CLC
|
||
|
ADC EXECCODEBASE ; SET PC PTR
|
||
|
STA EXECPC
|
||
|
LDA (EXCEPTPTR),Y
|
||
|
ADC EXECCODEBASE+1
|
||
|
STA EXECPC+1
|
||
|
JSR HCODE_UNACCESS
|
||
|
LDA HEXCEPTTBL
|
||
|
LDX HEXCEPTTBL+1
|
||
|
JSR HMEM_UNLOCK
|
||
|
ASL EXECFLAGS ; CLEAR EXCEPTION FLAG
|
||
|
JMP EXECBYTECODES ; EXECUTE HANDLER
|
||
|
NEXTEXCEPT: LDA EXCEPTPTR
|
||
|
CLC
|
||
|
ADC #$08
|
||
|
BCC :+
|
||
|
INC EXCEPTPTR+1
|
||
|
: STA EXCEPTPTR
|
||
|
LDA EXCEPTCNT
|
||
|
SEC
|
||
|
SBC #$01
|
||
|
BCS :+
|
||
|
DEC EXCEPTCNT+1
|
||
|
: JMP SEARCHEXCEPT
|
||
|
|
||
|
.DATA
|
||
|
|
||
|
HEXCEPTTBL:
|
||
|
HLINKFRAME: .RES 2
|
||
|
EXCEPTPC:
|
||
|
METHDOFST: .RES 2
|
||
|
|