Context variableSubclass:#JavaContext
instanceVariableNames:'exArg byteCode constPool method monitor'
classVariableNames:''
poolDictionaries:''
category:'Java-Support'
!
!JavaContext methodsFor:'ST context mimicri'!
arg1Index
"the java stack contains the receiver in a non-static
method, as slot 0. Therefore, the first arg is found at slot2
if this is for a non-static method"
self method isStatic ifTrue:[
^ 1
].
^ 2
!
argAt:n
"return the i'th argument (1..nArgs)"
^ self at:(self arg1Index - 1 + n)
"Created: / 2.1.1998 / 17:54:13 / cg"
"Modified: / 2.1.1998 / 21:39:30 / cg"
!
argAt:n put:value
"change the i'th argument (1..nArgs)"
^ super argAt:(self arg1Index - 1 + n) put:value
"Created: / 2.1.1998 / 17:54:34 / cg"
"Modified: / 2.1.1998 / 21:35:19 / cg"
!
args
"return an array filled with the arguments of this context"
|n|
n := self numArgs.
n == 0 ifTrue:[
"/ little optimization here - avoid creating empty containers
^ #()
].
^ (Array new:n) replaceFrom:1 to:n with:self startingAt:(self arg1Index).
"Created: / 2.1.1998 / 17:54:57 / cg"
"Modified: / 2.1.1998 / 21:34:44 / cg"
!
argsAndVars
"return an array filled with the arguments and variables of this context"
|n|
n := self numArgs + self numVars.
n == 0 ifTrue:[
"/ little optimization here - avoid creating empty containers
^ #()
].
^ (Array new:n) replaceFrom:1 to:n with:self startingAt:(self arg1Index).
"Created: / 2.1.1998 / 17:55:14 / cg"
"Modified: / 13.1.1998 / 15:44:56 / cg"
!
lineNumber
|nr pc|
pc := self pc.
"/ 'ask line for pc:' print. pc printCR.
pc isNil ifTrue:[
nr := self lineNumberFromMethod.
nr notNil ifTrue:[
^ nr
].
" '-> 0 [a]' printCR. "
^0
].
nr := self method lineNumberForPC:pc.
nr isNil ifTrue:[
nr := self lineNumberFromMethod.
nr notNil ifTrue:[
^ nr
].
" '-> 0 [b]' printCR. "
^ 0
].
"/ '-> ' print. nr printCR.
^ nr.
"Created: / 1.5.1996 / 15:05:47 / cg"
"Modified: / 15.1.1998 / 15:25:29 / cg"
!
lineNumberFromMethod
|m|
m := self method.
m notNil ifTrue:[
^ m lineNumber
].
^ nil
"Created: / 4.1.1998 / 23:34:45 / cg"
"Modified: / 4.1.1998 / 23:35:55 / cg"
!
method
"the method may be found in the interpreter temps ..."
(method isKindOf:JavaMethod) ifTrue:[^ method].
^ super method
"Created: / 1.5.1996 / 15:03:43 / cg"
"Modified: / 16.10.1998 / 01:22:12 / cg"
!
methodHome
^ self
!
numArgs
"return the number of args.
Redefined since Java keeps the receiver of a non-static method
at local slot 1."
|n|
n := super numArgs.
self method isStatic ifFalse:[
n := n - 1
].
^ n
"Created: / 2.1.1998 / 22:21:24 / cg"
!
numTemps
"return the number of temporary variables of the Method.
Redefined since Java keeps the receiver of a non-static method
at local slot 1."
|n|
n := self size - super numVars - super numArgs.
^ n
"Created: / 13.1.1998 / 16:52:32 / cg"
"Modified: / 13.1.1998 / 17:23:27 / cg"
!
numVars
"return the number of locals.
Redefined since Java keeps the receiver of a non-static method
at local slot 0 and holds the args as locals."
|n|
n := super numVars.
^ n - self numArgs
"Created: / 13.1.1998 / 17:03:08 / cg"
"Modified: / 13.1.1998 / 17:25:16 / cg"
!
pc
lineNr isNil ifTrue:[^ nil].
^ super lineNumber
"Created: / 4.1.1998 / 23:33:48 / cg"
!
selector
"the selector can be extracted from the method.
the method may be found in the interpreter temps ..."
|s m|
selector isNil ifTrue:[
m := self method.
m notNil ifTrue:[
^ m name
]
].
^ super selector
"Modified: / 30.12.1997 / 17:22:06 / cg"
"Created: / 30.12.1997 / 17:23:47 / cg"
!
setPC:newPC
lineNr := newPC
"Created: / 5.1.1998 / 00:09:02 / cg"
!
temporaries
"return an array filled with the arguments and variables of this context"
|n nSkipped|
"/ the flas-numVars includes the receiver and args
nSkipped := super numVars "self numArgs + self numVars".
"/ but my context setup is args+numvars.
nSkipped := super numArgs + super numVars.
n := self size - nSkipped.
n == 0 ifTrue:[
"/ little optimization here - avaoid creating empty containers
^ #()
].
^ (Array new:n) replaceFrom:1 to:n with:self startingAt:nSkipped+1.
"Created: / 13.1.1998 / 15:44:12 / cg"
"Modified: / 13.1.1998 / 17:22:54 / cg"
!
vars
"return an array filled with the local variables of this context"
|nonVars mySize|
mySize := self numVars.
mySize == 0 ifTrue:[
"/ little optimization here - avaoid creating empty containers
^ #()
].
nonVars := (self arg1Index-1) + self numArgs.
^ (Array new:mySize) replaceFrom:1 to:mySize with:self startingAt:nonVars+1
"Created: / 13.1.1998 / 16:48:16 / cg"
! !
!JavaContext methodsFor:'exception handler support'!
exceptionArg:aJavaException
exArg := aJavaException
"Created: / 7.1.1998 / 21:36:56 / cg"
!
markForException
"set the exception handler flag in the receiver.
The JVM needs this to enter an exception handler instead of restarting
from the beginning (when the context is restarted).
- a highly internal mechanism and not for public use."
flags := flags bitOr:16r08000000.
"/ %{ /* NOCONTEXT */
"/ __INST(flags) = (OBJ)((INT)__INST(flags) | __MASKSMALLINT(__JAVA_EX_PEND));
"/ %}
"Modified: 13.12.1995 / 19:05:22 / cg"
! !
!JavaContext methodsFor:'printing & storing'!
receiverPrintString
"return a string describing the receiver of the context"
|receiverClass receiverClassName newString implementorClass|
"/ %{
"/ /*
"/ * special handling for (invalid) free objects.
"/ * these only appear if some primitiveCode does not correctly use SEND macros,
"/ * which may lead to sends to free objects. In normal operation, this 'cannot' happen.
"/ */
"/ if (__isNonNilObject(__INST(receiver)) && (__qClass(__INST(receiver))==nil)) {
"/ receiverClassName = __MKSTRING("FreeObject");
"/ }
"/ %}.
receiverClassName notNil ifTrue:[^ receiverClassName].
receiverClass := receiver class.
receiverClassName := receiverClass name.
(receiverClass == SmallInteger) ifTrue:[
newString := '(' , receiver printString , ') ' , receiverClassName
] ifFalse:[
newString := receiverClassName
].
"
kludge to avoid slow search for containing class
"
(selector ~~ #doIt and:[selector ~~ #doIt:]) ifTrue:[
implementorClass := self methodClass.
].
implementorClass notNil ifTrue: [
(implementorClass ~~ receiverClass) ifTrue: [
newString := newString , '>>>',
implementorClass name printString
]
] ifFalse:[
self searchClass ~~ receiverClass ifTrue:[
newString := newString , '>>>' , self searchClass name
].
"/ "
"/ kludge for doIt - these unbound methods are not
"/ found in the classes methodDictionary
"/ "
"/ (selector ~~ #doIt and:[selector ~~ #doIt:]) ifTrue:[
"/ newString := newString , '>>>**NONE**'
"/ ]
].
^ newString
! !
!JavaContext methodsFor:'queries'!
hasStackToShow
"private interface to the debugger.
Smalltalk contexts return false here - other language frames
(i.e. Java frames) may want to show the evaluation stack"
^ true
"Modified: / 13.5.1997 / 16:31:12 / cg"
"Created: / 7.5.1998 / 01:23:57 / cg"
!
isJavaContext
"return true, if this is a javaContext."
^ true
"Created: / 8.5.1998 / 21:23:47 / cg"
!
stackFrame
"private interface to the debugger."
^ (1 to:self size) collect:[:i | self at:i]
"Created: / 7.5.1998 / 01:26:19 / cg"
! !
!JavaContext class methodsFor:'documentation'!
version
^ '$Header: /home/jv/Projects/SmalltalkX/repositories/cvs/stx/libjava/JavaContext.st,v 1.26 1998/11/10 00:23:19 cg Exp $'
! !