JavaLookup: Make Smalltalk-to-Java lookup to handle 'perform:' of static methods
...i.e., when one does something like
system perform: #'initializeSystemClass()V'.
then JavaLookup now returns the static method `java.lang.System#initializeSystemClass()`.
Arbitrary check for this `perform:`d methods with Java selectors has been
nuked from JavaClass>>perform:onReceiver:from:ifNotFound:
--- a/JavaClass.st Wed Mar 23 10:07:43 2016 +0000
+++ b/JavaClass.st Wed Mar 23 19:45:10 2016 +0000
@@ -1749,27 +1749,14 @@
<resource: #skipInDebuggersWalkBack>
| lo method selector class args|
+
selector := aMessage selector.
args := aMessage arguments.
-
- (selector includes: $() ifTrue:[
- "Java selector, search static methods"
- method := methodDictionary at:selector ifAbsent:[nil].
- (method notNil and:[method isStatic]) ifTrue:[
- "/ Must ensure the class is initialized here!! See documentation
- "/ for INVOKESTATIC
- method javaClass classInit.
- "/ Now, fire the method
- ^ method valueWithReceiver:self arguments:args selector:selector search:self class
- ].
- ].
-
class := receiver class.
-
lo := class getLookupObject isNil ifTrue: [ JavaLookup instance ] ifFalse: [ class lookupObject ].
method := lo lookupMethodForSelector: selector
- directedTo: class
+ directedTo: class theNonMetaclass
for: receiver
withArguments: args
from: sender
@@ -1783,7 +1770,7 @@
"Created: / 19-09-2011 / 23:33:06 / Jan Kurs <kursjan@fit.cvut.cz>"
"Modified: / 10-04-2012 / 16:47:31 / kursjan"
- "Modified: / 21-03-2016 / 01:05:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (format): / 23-03-2016 / 19:38:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!JavaClass methodsFor:'java initialization'!
--- a/JavaLookup.st Wed Mar 23 10:07:43 2016 +0000
+++ b/JavaLookup.st Wed Mar 23 19:45:10 2016 +0000
@@ -458,8 +458,35 @@
As a courtesy to a Smalltalker, try to map smalltalk selectors to a java ones.
Returns a method or nil"
- | name candidates m |
+ | name candidates method |
+ "/ First, handle the simple case when Smalltalk 'performs' a Java selector,
+ "/ i.e., something like:
+ "/
+ "/ system perform: #'initializeSystemClass()V'.
+ "/
+ "/ we have to distinguish between static method lookup (when a message
+ "/ is sent to the class) and instance method lookup since static methods
+ "/ are not inherited!!
+ receiver isBehavior ifTrue:[
+ "/ Lookup static method
+ method := receiver methodDictionary at: selector ifAbsent:[ nil ].
+ method notNil ifTrue:[
+ "/ Must ensure the class is initialized here!! See documentation
+ "/ for INVOKESTATIC
+ method javaClass classInit.
+ ^ method
+ ].
+ ] ifFalse:[
+ "/ Lookup instance method
+ method := receiver class lookupMethodFor: selector.
+ method notNil ifTrue:[ ^ method ].
+ ].
+
+
+ "/ OK - assuming a Java object has been sent a smalltalk(ish) selector,
+ "/ try to map that selector to a Java selector...this is where the magic
+ "/ happens.
name := selector upTo: $:.
candidates := OrderedCollection new.
@@ -468,21 +495,21 @@
"/ If candidates contains only one method that is not Java method,
"/ then return this method. It's either a smalltalk extension or
"/ ambiguous method trampoline...
- (candidates size == 1 and:[ (m := candidates anElement) isJavaMethod not]) ifTrue:[
- ilc notNil ifTrue: [ ilc bindTo: m forClass: receiver class ].
- ^ m.
+ (candidates size == 1 and:[ (method := candidates anElement) isJavaMethod not]) ifTrue:[
+ ilc notNil ifTrue: [ ilc bindTo: method forClass: receiver class ].
+ ^ method.
].
- m := self
+ method := self
compileProxyWithSelector: selector
in: receiver class
candidates: candidates.
- ilc notNil ifTrue: [ ilc bindTo: m forClass: receiver class ].
+ ilc notNil ifTrue: [ ilc bindTo: method forClass: receiver class ].
"Install the proxy"
self
addSelector: selector
- withMethod: m
+ withMethod: method
toClass: receiver class.
- ^ m.
+ ^ method.
].
"Hmm, hmm, maybe a public field?"
(argArrayOrNil size < 2) ifTrue: [
@@ -492,17 +519,17 @@
static: initialSearchClass isMetaclass
onlyPublic: true.
field notNil ifTrue: [
- m := self
+ method := self
compileProxyWithSelector: selector
in: receiver class
accessing: field.
- ilc notNil ifTrue: [ ilc bindTo: m forClass: receiver class ].
+ ilc notNil ifTrue: [ ilc bindTo: method forClass: receiver class ].
"Install the proxy"
self
addSelector: selector
- withMethod: m
+ withMethod: method
toClass: receiver class.
- ^ m.
+ ^ method.
]
].
^ nil
@@ -516,7 +543,7 @@
"Modified (comment): / 02-01-2012 / 10:35:25 / kursjan <kursjan@fit.cvut.cz>"
"Modified: / 18-11-2012 / 18:17:28 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
"Modified: / 16-12-2012 / 13:59:55 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
- "Modified: / 19-03-2014 / 17:27:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 23-03-2016 / 19:37:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
lookupMethodsForSelector: selector in: initialSearchClass static: static
--- a/JavaLookupTests.st Wed Mar 23 10:07:43 2016 +0000
+++ b/JavaLookupTests.st Wed Mar 23 19:45:10 2016 +0000
@@ -99,7 +99,7 @@
setUp
| md |
- Smalltalk loadPackage: 'stx:libjava/experiments'.
+ Smalltalk loadPackage: 'stx:libjava/tests'.
self javaTestClasses do:[:each |
md := each methodDictionary.
md copy keysAndValuesDo:[:sel :m|