--- a/JavaResolver.st Wed Mar 23 19:45:10 2016 +0000
+++ b/JavaResolver.st Sun Mar 27 22:29:04 2016 +0100
@@ -20,6 +20,8 @@
"
"{ Package: 'stx:libjava' }"
+"{ NameSpace: Smalltalk }"
+
Object subclass:#JavaResolver
instanceVariableNames:'exceptionThrower'
classVariableNames:'uniqueInstance'
@@ -445,7 +447,7 @@
"Modified: / 04-08-2014 / 15:52:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
-!JavaResolver methodsFor:'field resolving helpers'!
+!JavaResolver methodsFor:'field resolving-helpers'!
checkPermissionsForField: aJavaField from: accessingJavaClass to: resolvedJavaClass
^ self
@@ -474,19 +476,41 @@
"Modified: / 01-12-2012 / 13:46:02 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
! !
-!JavaResolver methodsFor:'interface method resolving'!
+!JavaResolver methodsFor:'method resolving'!
resolveInterfaceMethodIdentifiedByRef: aJavaInterfaceMethodRef
- | result class |
+ | result class search selector |
self validateInterfaceMethodRef: aJavaInterfaceMethodRef.
- result := self
- lookupInterfaceMethodIfAlreadyResolved: aJavaInterfaceMethodRef.
- result notNil ifTrue: [ ^ result ].
class := aJavaInterfaceMethodRef classRef resolve: false.
- class isNil ifTrue: [ self error: 'should not happen - tell mh' ].
+ class isNil ifTrue: [
+ self error: 'should not happen - tell mh'
+ ].
+ "Array types responds to all method of class java.lang.Object"
+ class isJavaArrayClass ifTrue:[
+ class := JavaVM classForName:'java.lang.Object'.
+ ].
class isInterface ifFalse: [ self throwIncompatibleClassChangeError ].
- result := class
- lookupMethodByNameAndType: aJavaInterfaceMethodRef nameAndType.
+
+ search := class.
+ selector := aJavaInterfaceMethodRef nameAndType selector.
+ [ search notNil and:[result isNil] ] whileTrue:[
+ result := search compiledMethodAt: selector.
+ search := search superclass.
+ ].
+ result isNil ifTrue:[
+ | queue |
+
+ queue := OrderedCollection withAll: class allInterfaces.
+ [ result isNil and:[queue notEmpty ] ] whileTrue:[
+ search := queue removeFirst.
+ result := search compiledMethodAt: selector.
+ result isNil ifTrue:[
+ search interfaces do:[:interface |
+ (queue includes: interface) ifFalse:[ queue add: interface ].
+ ].
+ ].
+ ].
+ ].
result isNil ifTrue: [ self throwNoSuchMethodError ].
(self
checkPermissionsForMethod: result
@@ -515,51 +539,26 @@
loading constraints TiL1 = TiL2 for i = 0 to n (§5.3.4)."
"Modified: / 01-12-2012 / 13:46:09 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
- "Modified: / 09-11-2013 / 00:12:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-! !
-
-!JavaResolver methodsFor:'interface method resolving helpers'!
-
-lookupInterfaceMethodIfAlreadyResolved: aJavaInterfaceMethodRef
- ^ nil.
-
- "Created: / 13-04-2011 / 11:53:36 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+ "Modified: / 27-03-2016 / 22:18:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
-validateInterfaceMethodRef: aJavaInterfaceMethodRef
- aJavaInterfaceMethodRef isJavaRef ifFalse: [
- self error: 'I expected JavaRef instance as an argument'
- ].
- aJavaInterfaceMethodRef isJavaInterfaceMethodRef ifFalse: [
- self error: 'I expected JavaMethodRef instance as an argument'
- ].
-
- "Created: / 13-04-2011 / 11:53:34 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
- "Modified: / 01-12-2012 / 13:46:20 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-! !
-
-!JavaResolver methodsFor:'method resolving'!
-
resolveMethodIndentifiedByRef:aJavaMethodRef
- | result class |
+ | result class selector search |
self validateMethodRef:aJavaMethodRef.
- result := self lookupMethodIfAlreadyResolved:aJavaMethodRef.
- result notNil ifTrue:[
- ^ result
- ].
+
class := aJavaMethodRef classRef resolve:false.
class isNil ifTrue:[
self error:'should not happen - tell mh'
].
- "Array types responds to all method of class java.lang.Object"
+ "Array types responds to all method of class java.lang.Object"
class isJavaArrayClass ifTrue:[
class := JavaVM classForName:'java.lang.Object'.
].
"
To resolve an unresolved symbolic reference from D to a method in
a class C, the symbolic reference to C given by the method reference
- is first resolved (§5.4.3.1). Therefore, any exceptions that can be
+ is first resolved (5.4.3.1). Therefore, any exceptions that can be
thrown due to resolution of a class reference can be thrown as a result
of method resolution. If the reference to C can be successfully resolved,
exceptions relating to the resolution of the method reference itself
@@ -571,23 +570,41 @@
class isInterface ifTrue:[
self throwIncompatibleClassChangeError
].
- "Method resolution attempts to look up the referenced method in C and its
+ "Method resolution attempts to look up the referenced method in C and its
superclasses:
If C declares a method with the name and descriptor specified by the method
reference, method lookup succeeds.
Otherwise, if C has a superclass, step 2 of method lookup is recursively
- invoked on the direct superclass of C.
-
- Otherwise, method lookup attempts to locate the referenced method in any of
+ invoked on the direct superclass of C."
+ search := class.
+ selector := aJavaMethodRef nameAndType selector.
+ [ search notNil and:[result isNil] ] whileTrue:[
+ result := search compiledMethodAt: selector.
+ search := search superclass.
+ ].
+ "Otherwise, method lookup attempts to locate the referenced method in any of
the superinterfaces of the specified class C.
If any superinterface of C declares a method with the name and descriptor
- specified by the method reference, method lookup succeeds.
- Otherwise, method lookup fails.
+ specified by the method reference, method lookup succeeds."
+ result isNil ifTrue:[
+ | queue |
+
+ queue := OrderedCollection withAll: class allInterfaces.
+ [ result isNil and:[queue notEmpty ] ] whileTrue:[
+ search := queue removeFirst.
+ result := search compiledMethodAt: selector.
+ result isNil ifTrue:[
+ search interfaces do:[:interface |
+ (queue includes: interface) ifFalse:[ queue add: interface ].
+ ].
+ ].
+ ].
+ ].
+ "Otherwise, method lookup fails.
If method lookup fails, method resolution throws a NoSuchMethodError. If method
lookup succeeds and the method is abstract, but C is not abstract, method resolution
throws an AbstractMethodError. Otherwise, if the referenced method is not accessible
- (§5.4.4) to D, method resolution throws an IllegalAccessError."
- result := class lookupMethodByNameAndType:aJavaMethodRef nameAndType.
+ (§5.4.4) to D, method resolution throws an IllegalAccessError."
result isNil ifTrue:[
self throwNoSuchMethodError
].
@@ -609,10 +626,10 @@
"Created: / 11-04-2011 / 19:45:34 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
"Modified: / 14-04-2011 / 00:01:34 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
"Modified (format): / 01-12-2012 / 13:46:25 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
- "Modified: / 04-08-2014 / 15:55:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 27-03-2016 / 22:19:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
-!JavaResolver methodsFor:'method resolving helpers'!
+!JavaResolver methodsFor:'method resolving-helpers'!
checkPermissionsForMethod: aJavaMethod from: accessingJavaClass to: resolvedJavaClass
^ self
@@ -626,11 +643,16 @@
"Modified: / 01-12-2012 / 13:46:58 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!
-lookupMethodIfAlreadyResolved: aJavaMethodRef
- ^ nil.
+validateInterfaceMethodRef: aJavaInterfaceMethodRef
+ aJavaInterfaceMethodRef isJavaRef ifFalse: [
+ self error: 'I expected JavaRef instance as an argument'
+ ].
+ aJavaInterfaceMethodRef isJavaInterfaceMethodRef ifFalse: [
+ self error: 'I expected JavaMethodRef instance as an argument'
+ ].
- "Created: / 11-04-2011 / 19:50:38 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
- "Modified: / 13-04-2011 / 11:57:00 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+ "Created: / 13-04-2011 / 11:53:34 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+ "Modified: / 01-12-2012 / 13:46:20 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!
validateMethodRef: aJavaMethodRef