JavaLookup: Make Smalltalk-to-Java lookup to handle 'perform:' of static methods
authorJan Vrany <jan.vrany@fit.cvut.cz>
Wed, 23 Mar 2016 19:45:10 +0000
changeset 3552 9c3f3089d912
parent 3551 f8304e321df7
child 3553 5329fb7027e8
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:
JavaClass.st
JavaLookup.st
JavaLookupTests.st
--- 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|