JavaLookup.st
changeset 3555 47da2d42a016
parent 3554 1e2d0859a20c
child 3602 e35b48285df7
--- a/JavaLookup.st	Mon Mar 28 00:09:52 2016 +0100
+++ b/JavaLookup.st	Tue Mar 29 20:50:42 2016 +0100
@@ -51,7 +51,7 @@
 
 JavaLookup::JVM subclass:#J2J
 	instanceVariableNames:''
-	classVariableNames:'NoSuchMethodErrorSelector AbstractMethodErrorSelectors'
+	classVariableNames:'NoSuchMethodErrorSelector'
 	poolDictionaries:''
 	privateIn:JavaLookup
 !
@@ -263,7 +263,6 @@
     "Modified: / 22-03-2016 / 22:44:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
-
 !JavaLookup::JVM methodsFor:'lookup'!
 
 lookupMethodForSelector: selector directedTo: c
@@ -297,10 +296,49 @@
             ].
         ].
     ].
+    "3. Otherwise, if there is exactly one maximally-specific method
+        (§5.4.3.3) in the superinterfaces of C that matches the resolved
+        method's name and descriptor and is not abstract , then it is
+        the method to be invoked.
+    "
+    m isNil ifTrue:[ 
+        | class interfaces superinterfaces interfaceMethod |
+
+        class := c.
+        interfaces := Set new.
+        "/ Collect interfaces from all superclasses. 
+        "/ We cannot use JavaClass>>allInterfaces as it also
+        "/ returns superinterfaces of interfaces, flattened."
+        [ class notNil ] whileTrue:[ 
+            interfaces addAll: c interfaces.
+            class := class superclass.
+        ].
+        [ interfaces notEmpty ] whileTrue:[
+            interfaces do:[ :interface|
+                | interfaceMethod superinterfaces |
+
+                interfaceMethod := interface compiledMethodAt: selector.
+                "/ We must also test whether found is a JavaMethod. It could
+                "/ be a Smalltalk extension in the interface - such methods
+                "/ are not handled here (no such thing in JVM spec)
+                (interfaceMethod notNil and: [interfaceMethod isJavaMethod]) ifTrue:[
+                    m := interfaceMethod.
+                    "/ To terminate the loop
+                    interfaces := superinterfaces := #().
+                ] ifFalse:[
+                    superinterfaces isNil ifTrue:[ 
+                        superinterfaces := Set new.
+                    ].
+                    superinterfaces addAll: interface interfaces.
+                ].
+                interfaces := superinterfaces.
+            ]
+        ]
+    ].
     ^ m
 
     "Created: / 05-07-2012 / 11:06:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (comment): / 27-03-2016 / 23:45:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-03-2016 / 20:42:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaLookup::J2S methodsFor:'lookup'!
@@ -406,8 +444,6 @@
 initialize
     "Invoked at system start or when the class is dynamically loaded."
 
-    "/ please change as required (and remove this comment)
-
     NoSuchMethodErrorSelector := #(
             " 0" #'throwNoSuchMethodError'
             " 1" #'throwNoSuchMethodError_:'
@@ -427,26 +463,7 @@
             "15" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:_:_:'
     ).
 
-    AbstractMethodErrorSelectors := #(
-            " 0" #'throwAbstractMethodError'
-            " 1" #'throwAbstractMethodError_:'
-            " 2" #'throwAbstractMethodError_:_:'
-            " 3" #'throwAbstractMethodError_:_:_:'
-            " 4" #'throwAbstractMethodError_:_:_:_:'
-            " 5" #'throwAbstractMethodError_:_:_:_:_:'
-            " 6" #'throwAbstractMethodError_:_:_:_:_:_:'
-            " 7" #'throwAbstractMethodError_:_:_:_:_:_:_:'
-            " 8" #'throwAbstractMethodError_:_:_:_:_:_:_:_:'
-            " 9" #'throwAbstractMethodError_:_:_:_:_:_:_:_:_:'
-            "10" #'throwAbstractMethodError_:_:_:_:_:_:_:_:_:_:'
-            "11" #'throwAbstractMethodError_:_:_:_:_:_:_:_:_:_:_:'
-            "12" #'throwAbstractMethodError_:_:_:_:_:_:_:_:_:_:_:_:'
-            "13" #'throwAbstractMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:'
-            "14" #'throwAbstractMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:_:'
-            "15" #'throwAbstractMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:_:_:'
-    ).
-
-    "Modified: / 23-03-2016 / 09:41:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 29-03-2016 / 21:07:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaLookup::J2J methodsFor:'lookup'!
@@ -455,15 +472,9 @@
     | method |
 
     method := self lookupMethodForSelector: selector directedTo: initialSearchClass.
-    "/ No method found. Return a trampoline that will throw NoSuchMethodError or AbstractMethodError
-    "/ (for INVOKEINTERFACE)
+    "/ No method found. Return a trampoline that will throw NoSuchMethodError
     method isNil ifTrue:[ 
-        "/ This is a hacky check whether the failing instruction is INVOKEINTERFACE or not
-        (sendingContext method byteCode at: sendingContext pc - 1) == 185 ifTrue:[ 
-            method := JavaVM class >> (AbstractMethodErrorSelectors at: argArrayOrNil size + 1)
-        ] ifFalse:[ 
-            method := JavaVM class >> (NoSuchMethodErrorSelector at: argArrayOrNil size + 1)
-        ].
+        method := JavaVM class >> (NoSuchMethodErrorSelector at: argArrayOrNil size + 1)
     ].
     ilcCache notNil ifTrue:[
         ilcCache bindTo: method forClass: initialSearchClass.
@@ -471,8 +482,7 @@
     ^ method.
 
     "Created: / 22-03-2016 / 22:43:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 23-03-2016 / 09:57:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (format): / 28-03-2016 / 00:00:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-03-2016 / 20:45:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaLookup::S2J methodsFor:'lookup'!