JavaLookup: Make JavaLookup not to use JavaClass>>lookupMethodFor:
Instead, implement method lookup as defined in JVM spec in
JavaLookuo::JVM>>lookupMethodForSelector:directedTo:
--- a/JavaLookup.st Sun Mar 27 22:29:04 2016 +0100
+++ b/JavaLookup.st Mon Mar 28 00:09:52 2016 +0100
@@ -35,21 +35,28 @@
category:'Languages-Java-Interop'
!
-Lookup subclass:#J2J
+Lookup subclass:#JVM
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:JavaLookup
+!
+
+JavaLookup::JVM subclass:#J2S
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:JavaLookup
+!
+
+JavaLookup::JVM subclass:#J2J
instanceVariableNames:''
classVariableNames:'NoSuchMethodErrorSelector AbstractMethodErrorSelectors'
poolDictionaries:''
privateIn:JavaLookup
!
-Lookup subclass:#J2S
- instanceVariableNames:''
- classVariableNames:''
- poolDictionaries:''
- privateIn:JavaLookup
-!
-
-Lookup subclass:#S2J
+JavaLookup::JVM subclass:#S2J
instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
@@ -256,101 +263,44 @@
"Modified: / 22-03-2016 / 22:44:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
-!JavaLookup::J2J class methodsFor:'initialization'!
-initialize
- "Invoked at system start or when the class is dynamically loaded."
-
- "/ please change as required (and remove this comment)
+!JavaLookup::JVM methodsFor:'lookup'!
- NoSuchMethodErrorSelector := #(
- " 0" #'throwNoSuchMethodError'
- " 1" #'throwNoSuchMethodError_:'
- " 2" #'throwNoSuchMethodError_:_:'
- " 3" #'throwNoSuchMethodError_:_:_:'
- " 4" #'throwNoSuchMethodError_:_:_:_:'
- " 5" #'throwNoSuchMethodError_:_:_:_:_:'
- " 6" #'throwNoSuchMethodError_:_:_:_:_:_:'
- " 7" #'throwNoSuchMethodError_:_:_:_:_:_:_:'
- " 8" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:'
- " 9" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:'
- "10" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:'
- "11" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:'
- "12" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:_:'
- "13" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:'
- "14" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:_:'
- "15" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:_:_:'
- ).
+lookupMethodForSelector: selector directedTo: c
+ "This method performs standard Java lookup as required JVM 8 spec, 6.5 invokevirtual.
+ NOTE: This method only handles Java method, i.e., it never returns a Smalltak
+ (or other language's) extension method."
+
+ | m s |
+
+ "Let C be the class of objectref. The actual method to be invoked is selected by the
+ following lookup procedure:
- 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_:_:_:_:_:_:_:_:_:_:_:_:_:_:_:'
- ).
+ 1. If C contains a declaration for an instance method m that
+ overrides (§5.4.5) the resolved method, then m is the method
+ to be invoked.
+ 2. Otherwise, if C has a superclass, a search for a declaration
+ of an instance method that overrides the resolved method
+ is performed, starting with the direct superclass of C and
+ continuing with the direct superclass of that class, and so forth,
+ until an overriding method is found or no further superclasses
+ exist. If an overriding method is found, it is the method to be
+ invoked."
- "Modified: / 23-03-2016 / 09:41:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-! !
-
-!JavaLookup::J2J methodsFor:'lookup'!
-
-lookupMethodForSelector: selector directedTo: initialSearchClass
- "This method performs standard Java lookup as required JVM spec. See
- - JVM spec, 5.4.2.1 Method overriding
- - JVM spec, 6.4 invokevirtual
-
- This is hacky because of those stupid package-private methods. Sigh."
-
- | method superMethod |
-
- method := super lookupMethodForSelector: selector directedTo: initialSearchClass.
- method notNil ifTrue:[
- superMethod := super lookupMethodForSelector: selector directedTo: method mclass superclass.
- [ superMethod notNil ] whileTrue:[
- (method overrides: superMethod) ifFalse:[
- method := superMethod
+ m := super lookupMethodForSelector: selector directedTo: c.
+ m isJavaMethod ifTrue:[
+ m notNil ifTrue:[
+ [ (s := super lookupMethodForSelector: selector directedTo: m mclass superclass) notNil ] whileTrue:[
+ (m overrides: s) ifFalse:[
+ m := s
+ ].
].
- superMethod := super lookupMethodForSelector: selector directedTo: superMethod mclass superclass.
].
].
- ^ method
+ ^ m
"Created: / 05-07-2012 / 11:06:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 23-03-2016 / 09:44:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-lookupMethodForSelector:selector directedTo:initialSearchClass for:aReceiver withArguments:argArrayOrNil from:sendingContext ilc: ilcCache
- | method |
- method := self lookupMethodForSelector: selector directedTo: initialSearchClass.
- "/ No method found. Return a trampoline that will throw NoSuchMethodError or AbstractMethodError
- "/ (for INVOKEINTERFACE)
- 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)
- ].
- ].
- ilcCache notNil ifTrue:[
- ilcCache bindTo: method forClass: initialSearchClass.
- ].
- ^ 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 (comment): / 27-03-2016 / 23:45:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!JavaLookup::J2S methodsFor:'lookup'!
@@ -451,6 +401,80 @@
"Modified: / 24-02-2012 / 20:36:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!JavaLookup::J2J class methodsFor:'initialization'!
+
+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_:'
+ " 2" #'throwNoSuchMethodError_:_:'
+ " 3" #'throwNoSuchMethodError_:_:_:'
+ " 4" #'throwNoSuchMethodError_:_:_:_:'
+ " 5" #'throwNoSuchMethodError_:_:_:_:_:'
+ " 6" #'throwNoSuchMethodError_:_:_:_:_:_:'
+ " 7" #'throwNoSuchMethodError_:_:_:_:_:_:_:'
+ " 8" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:'
+ " 9" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:'
+ "10" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:'
+ "11" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:'
+ "12" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:_:'
+ "13" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:'
+ "14" #'throwNoSuchMethodError_:_:_:_:_:_:_:_:_:_:_:_:_:_:'
+ "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>"
+! !
+
+!JavaLookup::J2J methodsFor:'lookup'!
+
+lookupMethodForSelector:selector directedTo:initialSearchClass for:aReceiver withArguments:argArrayOrNil from:sendingContext ilc: ilcCache
+ | method |
+
+ method := self lookupMethodForSelector: selector directedTo: initialSearchClass.
+ "/ No method found. Return a trampoline that will throw NoSuchMethodError or AbstractMethodError
+ "/ (for INVOKEINTERFACE)
+ 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)
+ ].
+ ].
+ ilcCache notNil ifTrue:[
+ ilcCache bindTo: method forClass: initialSearchClass.
+ ].
+ ^ 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>"
+! !
+
!JavaLookup::S2J methodsFor:'lookup'!
lookupMethodForSelector: selector directedTo: initialSearchClass for: receiver withArguments: argArrayOrNil from: sendingContext ilc: ilc
@@ -479,7 +503,7 @@
].
] ifFalse:[
"/ Lookup instance method
- method := receiver class lookupMethodFor: selector.
+ method := self lookupMethodForSelector: selector directedTo: receiver class.
method notNil ifTrue:[ ^ method ].
].
@@ -543,7 +567,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: / 23-03-2016 / 19:37:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 27-03-2016 / 23:57:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
lookupMethodsForSelector: selector in: initialSearchClass static: static