24
24
package com .oracle .truffle .espresso .runtime .dispatch .staticobject ;
25
25
26
26
import com .oracle .truffle .api .dsl .Cached ;
27
+ import com .oracle .truffle .api .dsl .Cached .Exclusive ;
27
28
import com .oracle .truffle .api .dsl .GenerateUncached ;
28
29
import com .oracle .truffle .api .dsl .Specialization ;
29
30
import com .oracle .truffle .api .interop .ArityException ;
30
31
import com .oracle .truffle .api .interop .UnsupportedTypeException ;
31
32
import com .oracle .truffle .api .profiles .InlinedBranchProfile ;
32
- import com .oracle .truffle .espresso .EspressoLanguage ;
33
33
import com .oracle .truffle .espresso .impl .Klass ;
34
34
import com .oracle .truffle .espresso .impl .Method ;
35
- import com .oracle .truffle .espresso .meta .Meta ;
36
35
import com .oracle .truffle .espresso .nodes .EspressoNode ;
37
36
import com .oracle .truffle .espresso .nodes .interop .CandidateMethodWithArgs ;
38
37
import com .oracle .truffle .espresso .nodes .interop .InvokeEspressoNode ;
@@ -73,21 +72,14 @@ public abstract static class Virtual extends InteropLookupAndInvoke {
73
72
@ Specialization
74
73
public Object doVirtual (StaticObject receiver , Klass klass , Object [] arguments , String member ,
75
74
@ Cached LookupVirtualMethodNode lookup ,
76
- @ Cached OverLoadedMethodSelectorNode selector ,
77
- @ Cached ToEspressoNode .DynamicToEspresso toEspresso ,
78
- @ Cached InvokeEspressoNode invoke ,
79
- @ Cached InlinedBranchProfile single ,
80
- @ Cached InlinedBranchProfile nonVarargs ,
81
- @ Cached InlinedBranchProfile varargs ,
82
- @ Cached InlinedBranchProfile multiple ,
75
+ @ Cached SelectAndInvokeNode selectAndInvoke ,
83
76
@ Cached InlinedBranchProfile error ,
84
77
@ Cached InlinedBranchProfile exception )
85
78
throws ArityException , UnsupportedTypeException {
86
79
assert receiver != null ;
87
80
Method [] candidates = lookup .execute (klass , member , arguments .length );
88
81
if (candidates != null ) {
89
- return selectAndInvoke (receiver , arguments , candidates , this , selector , toEspresso , invoke ,
90
- single , nonVarargs , varargs , multiple , error , exception );
82
+ return selectAndInvoke (selectAndInvoke , exception , receiver , arguments , candidates );
91
83
}
92
84
error .enter (this );
93
85
throw ArityException .create (arguments .length + 1 , -1 , arguments .length );
@@ -99,81 +91,91 @@ public abstract static class NonVirtual extends InteropLookupAndInvoke {
99
91
@ Specialization
100
92
public Object doNonVirtual (StaticObject receiver , Klass klass , Object [] arguments , String member ,
101
93
@ Cached LookupDeclaredMethod lookup ,
102
- @ Cached OverLoadedMethodSelectorNode selector ,
103
- @ Cached ToEspressoNode .DynamicToEspresso toEspresso ,
104
- @ Cached InvokeEspressoNode invoke ,
105
- @ Cached InlinedBranchProfile single ,
106
- @ Cached InlinedBranchProfile nonVarargs ,
107
- @ Cached InlinedBranchProfile varargs ,
108
- @ Cached InlinedBranchProfile multiple ,
94
+ @ Cached SelectAndInvokeNode selectAndInvoke ,
109
95
@ Cached InlinedBranchProfile error ,
110
96
@ Cached InlinedBranchProfile exception )
111
97
throws ArityException , UnsupportedTypeException {
112
98
boolean isStatic = receiver == null ;
113
99
Method [] candidates = lookup .execute (klass , member , true , isStatic , arguments .length );
114
100
if (candidates != null ) {
115
- return selectAndInvoke (receiver , arguments , candidates , this , selector , toEspresso , invoke ,
116
- single , nonVarargs , varargs , multiple , error , exception );
101
+ return selectAndInvoke (selectAndInvoke , exception , receiver , arguments , candidates );
117
102
}
118
103
error .enter (this );
119
104
throw ArityException .create (arguments .length + 1 , -1 , arguments .length );
120
105
}
121
106
}
122
107
123
- private static Object selectAndInvoke (StaticObject receiver , Object [] arguments , Method [] candidates ,
124
- InteropLookupAndInvoke node ,
125
- OverLoadedMethodSelectorNode selector ,
126
- ToEspressoNode .DynamicToEspresso toEspresso ,
127
- InvokeEspressoNode invoke ,
128
- InlinedBranchProfile single ,
129
- InlinedBranchProfile nonVarargs ,
130
- InlinedBranchProfile varargs ,
131
- InlinedBranchProfile multiple ,
132
- InlinedBranchProfile error ,
133
- InlinedBranchProfile exception )
134
- throws ArityException , UnsupportedTypeException {
135
- assert candidates .length > 0 ;
108
+ Object selectAndInvoke (SelectAndInvokeNode selectAndInvoke , InlinedBranchProfile exception ,
109
+ StaticObject receiver , Object [] args , Method [] candidates ) throws UnsupportedTypeException , ArityException {
136
110
try {
137
- if (candidates .length == 1 ) {
138
- single .enter (node );
139
- // common case with no overloads
140
- Method m = candidates [0 ];
141
- assert m .isPublic ();
142
- if (!m .isVarargs ()) {
143
- nonVarargs .enter (node );
144
- assert m .getParameterCount () == arguments .length ;
145
- return invoke .execute (m , receiver , arguments );
146
- } else {
147
- varargs .enter (node );
148
- CandidateMethodWithArgs matched = MethodArgsUtils .matchCandidate (m , arguments , m .resolveParameterKlasses (), toEspresso );
149
- if (matched != null ) {
150
- matched = MethodArgsUtils .ensureVarArgsArrayCreated (matched );
151
- if (matched != null ) {
152
- return invoke .execute (matched .getMethod (), receiver , matched .getConvertedArgs (), true );
153
- }
154
- }
155
- error .enter (node );
156
- throw UnsupportedTypeException .create (arguments );
157
- }
111
+ return selectAndInvoke .execute (receiver , args , candidates );
112
+ } catch (EspressoException e ) {
113
+ exception .enter (this );
114
+ throw InteropUtils .unwrapExceptionBoundary (getLanguage (), e , getMeta ());
115
+ }
116
+ }
117
+
118
+ @ GenerateUncached
119
+ abstract static class SelectAndInvokeNode extends EspressoNode {
120
+ public abstract Object execute (StaticObject receiver , Object [] args , Method [] candidates ) throws ArityException , UnsupportedTypeException ;
121
+
122
+ @ Specialization (guards = {"isSingleNonVarargs(candidates)" })
123
+ Object doSingleNonVarargs (StaticObject receiver , Object [] args , Method [] candidates ,
124
+ @ Cached @ Exclusive InvokeEspressoNode invoke )
125
+ throws ArityException , UnsupportedTypeException {
126
+ assert candidates .length == 1 ;
127
+ Method m = candidates [0 ];
128
+ assert m .getParameterCount () == args .length ;
129
+ assert m .isPublic ();
130
+ return invoke .execute (m , receiver , args );
131
+ }
132
+
133
+ @ Specialization (guards = {"isSingleVarargs(candidates)" })
134
+ Object doSingleVarargs (StaticObject receiver , Object [] args , Method [] candidates ,
135
+ @ Cached @ Exclusive InvokeEspressoNode invoke ,
136
+ @ Cached ToEspressoNode .DynamicToEspresso toEspresso ,
137
+ @ Cached InlinedBranchProfile error )
138
+ throws ArityException , UnsupportedTypeException {
139
+ assert candidates .length == 1 ;
140
+ Method m = candidates [0 ];
141
+ assert m .isPublic ();
142
+ CandidateMethodWithArgs matched = MethodArgsUtils .matchCandidate (m , args , m .resolveParameterKlasses (), toEspresso );
143
+ if (matched != null ) {
144
+ matched = MethodArgsUtils .ensureVarArgsArrayCreated (matched );
145
+ assert matched != null ;
146
+ return invoke .execute (matched .getMethod (), receiver , matched .getConvertedArgs (), true );
147
+ }
148
+ error .enter (this );
149
+ throw UnsupportedTypeException .create (args );
150
+ }
151
+
152
+ @ Specialization (guards = {"isMulti(candidates)" })
153
+ Object doMulti (StaticObject receiver , Object [] args , Method [] candidates ,
154
+ @ Cached OverLoadedMethodSelectorNode selector ,
155
+ @ Cached @ Exclusive InvokeEspressoNode invoke ,
156
+ @ Cached InlinedBranchProfile error )
157
+ throws ArityException , UnsupportedTypeException {
158
+ CandidateMethodWithArgs typeMatched = selector .execute (candidates , args );
159
+ if (typeMatched != null ) {
160
+ // single match found!
161
+ return invoke .execute (typeMatched .getMethod (), receiver , typeMatched .getConvertedArgs (), true );
158
162
} else {
159
- multiple .enter (node );
160
- // multiple overloaded methods found
161
- // find method with type matches
162
- CandidateMethodWithArgs typeMatched = selector .execute (candidates , arguments );
163
- if (typeMatched != null ) {
164
- // single match found!
165
- return invoke .execute (typeMatched .getMethod (), receiver , typeMatched .getConvertedArgs (), true );
166
- } else {
167
- // unable to select exactly one best candidate for the input args!
168
- error .enter (node );
169
- throw UnsupportedTypeException .create (arguments );
170
- }
163
+ // unable to select exactly one best candidate for the input args!
164
+ error .enter (this );
165
+ throw UnsupportedTypeException .create (args );
171
166
}
172
- } catch (EspressoException e ) {
173
- exception .enter (node );
174
- Meta meta = e .getGuestException ().getKlass ().getMeta ();
175
- EspressoLanguage language = meta .getLanguage ();
176
- throw InteropUtils .unwrapExceptionBoundary (language , e , meta );
167
+ }
168
+
169
+ static boolean isSingleNonVarargs (Method [] candidates ) {
170
+ return candidates .length == 1 && !candidates [0 ].isVarargs ();
171
+ }
172
+
173
+ static boolean isSingleVarargs (Method [] candidates ) {
174
+ return candidates .length == 1 && candidates [0 ].isVarargs ();
175
+ }
176
+
177
+ static boolean isMulti (Method [] candidates ) {
178
+ return candidates .length > 1 ;
177
179
}
178
180
}
179
181
}
0 commit comments