12
12
import static org .jruby .RubyArray .newArray ;
13
13
import static org .jruby .runtime .Helpers .arrayOf ;
14
14
15
- public abstract class IRBlockBody extends ContextAwareBlockBody {
15
+ public abstract class AbstractIRBlockBody extends ContextAwareBlockBody {
16
16
protected final String fileName ;
17
17
protected final int lineNumber ;
18
18
protected final IRClosure closure ;
19
19
ThreadLocal <EvalType > evalType ;
20
20
21
- public IRBlockBody (IRScope closure , Signature signature ) {
21
+ public AbstractIRBlockBody (IRScope closure , Signature signature ) {
22
22
// ThreadLocal not set by default to avoid having many thread-local values initialized
23
23
// servers such as Tomcat tend to do thread-local checks when un-deploying apps,
24
24
// for JRuby leads to 100s of SEVERE warnings for a mid-size (booted) Rails app
25
25
this (closure , signature , new ThreadLocal ());
26
26
}
27
27
28
- /* internal */ IRBlockBody (IRScope closure , Signature signature , ThreadLocal evalType ) {
28
+ /* internal */ AbstractIRBlockBody (IRScope closure , Signature signature , ThreadLocal evalType ) {
29
29
super (closure .getStaticScope (), signature );
30
30
this .closure = (IRClosure ) closure ;
31
31
this .fileName = closure .getFileName ();
32
32
this .lineNumber = closure .getLineNumber ();
33
33
this .evalType = evalType ;
34
34
}
35
35
36
+ @ Override
36
37
public final EvalType getEvalType () {
37
38
final EvalType type = this .evalType .get ();
38
39
return type == null ? EvalType .NONE : type ;
39
40
}
40
41
42
+ @ Override
41
43
public void setEvalType (final EvalType type ) {
42
44
if (type == null || type == EvalType .NONE ) {
43
45
this .evalType .remove ();
@@ -46,6 +48,7 @@ public void setEvalType(final EvalType type) {
46
48
}
47
49
}
48
50
51
+ @ Override
49
52
public IRubyObject yield (ThreadContext context , Block block , IRubyObject value , IRubyObject self , Block blockArg ) {
50
53
if (canInvokeDirect ()) {
51
54
return invokeYieldDirect (context , block , arrayOf (value ), blockArg , self );
@@ -54,6 +57,7 @@ public IRubyObject yield(ThreadContext context, Block block, IRubyObject value,
54
57
}
55
58
}
56
59
60
+ @ Override
57
61
public IRubyObject yield (ThreadContext context , Block block , IRubyObject [] args , IRubyObject self , Block blockArg ) {
58
62
if (canInvokeDirect ()) {
59
63
return invokeYieldDirect (context , block , args , blockArg , self );
@@ -87,52 +91,46 @@ public IRubyObject call(ThreadContext context, Block block, IRubyObject[] args,
87
91
88
92
@ Override
89
93
public IRubyObject yieldSpecific (ThreadContext context , Block block ) {
90
- return invokeSpecific (context , block , Block .NULL_BLOCK , null );
94
+ return invokeYieldSpecific (context , block , Block .NULL_BLOCK , null );
91
95
}
92
96
93
97
@ Override
94
98
public IRubyObject yieldSpecific (ThreadContext context , Block block , IRubyObject arg0 ) {
95
- return invokeSpecific (context , block , arg0 , Block .NULL_BLOCK , null );
99
+ return invokeYieldSpecific (context , block , arg0 , Block .NULL_BLOCK , null );
96
100
}
97
101
98
102
@ Override
99
103
public IRubyObject yieldSpecific (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 ) {
100
- return invokeSpecific (context , block , arg0 , arg1 , Block .NULL_BLOCK , null );
104
+ return invokeYieldSpecific (context , block , arg0 , arg1 , Block .NULL_BLOCK , null );
101
105
}
102
106
103
107
@ Override
104
108
public IRubyObject yieldSpecific (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , IRubyObject arg2 ) {
105
- return invokeSpecific (context , block , arg0 , arg1 , arg2 , Block .NULL_BLOCK , null );
109
+ return invokeYieldSpecific (context , block , arg0 , arg1 , arg2 , Block .NULL_BLOCK , null );
106
110
}
107
111
108
- protected abstract boolean canInvokeDirect ();
112
+ protected boolean canInvokeDirect () {
113
+ return false ;
114
+ }
109
115
110
- /**
111
- * This is the only method that *must* be implemented in blocks, and represents the bulk of logic.
112
- *
113
- * Other forms empty into this one and can be overridden to optimize specific paths.
114
- *
115
- * @param context
116
- * @param block
117
- * @param args
118
- * @param blockArg
119
- * @param self
120
- * @return
121
- */
122
- protected abstract IRubyObject invoke (ThreadContext context , Block block , IRubyObject [] args , Block blockArg , IRubyObject self );
116
+ protected IRubyObject invoke (ThreadContext context , Block block , IRubyObject [] args , Block blockArg , IRubyObject self ) {
117
+ throw new UnsupportedOperationException ("invoke not implemented" );
118
+ }
123
119
124
- protected abstract IRubyObject invokeCallDirect (ThreadContext context , Block block , IRubyObject [] args , Block blockArg , IRubyObject self );
120
+ protected IRubyObject invokeCallDirect (ThreadContext context , Block block , IRubyObject [] args , Block blockArg , IRubyObject self ) {
121
+ throw new UnsupportedOperationException ("invokeCallDirect not implemented" );
122
+ }
125
123
126
- protected abstract IRubyObject invokeYieldDirect (ThreadContext context , Block block , IRubyObject [] args , Block blockArg , IRubyObject self );
124
+ protected IRubyObject invokeYieldDirect (ThreadContext context , Block block , IRubyObject [] args , Block blockArg , IRubyObject self ) {
125
+ throw new UnsupportedOperationException ("invokeYieldDirect not implemented" );
126
+ }
127
127
128
128
IRubyObject invokeYield (ThreadContext context , Block block , IRubyObject value , Block blockArg , IRubyObject self ) {
129
129
if (block .isLambda ()) return invokeLambda (context , block , value , blockArg , self );
130
130
131
131
int blockArity = signature .arityValue ();
132
132
133
- if (value == null ) { // no args case from BlockBody.yieldSpecific
134
- return invoke (context , block , IRubyObject .NULL_ARRAY , blockArg , self );
135
- } else if (!signature .hasKwargs () && blockArity >= -1 && blockArity <= 1 ) {
133
+ if (!signature .hasKwargs () && blockArity >= -1 && blockArity <= 1 ) {
136
134
return invoke (context , block , arrayOf (value ), blockArg , self );
137
135
} else {
138
136
return invoke (context , block , toAry (context , value ), blockArg , self );
@@ -141,9 +139,7 @@ IRubyObject invokeYield(ThreadContext context, Block block, IRubyObject value, B
141
139
142
140
IRubyObject invokeLambda (ThreadContext context , Block block , IRubyObject value , Block blockArg , IRubyObject self ) {
143
141
// Lambda does not splat arrays even if a rest arg is present when it wants a single parameter filled.
144
- if (value == null ) { // no args case from BlockBody.yieldSpecific
145
- return invokeLambda (context , block , IRubyObject .NULL_ARRAY , blockArg , self );
146
- } else if (signature .required () == 1 || signature .arityValue () == -1 ) {
142
+ if (signature .required () == 1 || signature .arityValue () == -1 ) {
147
143
return invokeLambda (context , block , arrayOf (value ), blockArg , self );
148
144
} else {
149
145
return invokeLambda (context , block , toAry (context , value ), blockArg , self );
@@ -156,7 +152,7 @@ IRubyObject invokeLambda(ThreadContext context, Block block, IRubyObject[] args,
156
152
return invoke (context , block , args , blockArg , self );
157
153
}
158
154
159
- IRubyObject invokeSpecific (ThreadContext context , Block block , Block blockArg , IRubyObject self ) {
155
+ IRubyObject invokeYieldSpecific (ThreadContext context , Block block , Block blockArg , IRubyObject self ) {
160
156
if (canInvokeDirect ()) {
161
157
return invokeYieldDirect (context , block , null , blockArg , self );
162
158
} else {
@@ -166,8 +162,8 @@ IRubyObject invokeSpecific(ThreadContext context, Block block, Block blockArg, I
166
162
}
167
163
}
168
164
169
- IRubyObject invokeSpecific (ThreadContext context , Block block , IRubyObject arg0 , Block blockArg , IRubyObject self ) {
170
- if (canInvokeDirect ()) return invokeSpecificDirect (context , block , arg0 , blockArg , self );
165
+ IRubyObject invokeYieldSpecific (ThreadContext context , Block block , IRubyObject arg0 , Block blockArg , IRubyObject self ) {
166
+ if (canInvokeDirect ()) return invokeYieldSpecificDirect (context , block , arg0 , blockArg , self );
171
167
172
168
if (arg0 instanceof RubyArray ) {
173
169
// Unwrap the array arg
@@ -182,7 +178,7 @@ IRubyObject invokeSpecific(ThreadContext context, Block block, IRubyObject arg0,
182
178
return invokeYield (context , block , arg0 , blockArg , self );
183
179
}
184
180
185
- IRubyObject invokeSpecificDirect (ThreadContext context , Block block , IRubyObject arg0 , Block blockArg , IRubyObject self ) {
181
+ IRubyObject invokeYieldSpecificDirect (ThreadContext context , Block block , IRubyObject arg0 , Block blockArg , IRubyObject self ) {
186
182
IRubyObject [] args ;
187
183
if (arg0 instanceof RubyArray ) {
188
184
// Unwrap the array arg
@@ -193,37 +189,55 @@ IRubyObject invokeSpecificDirect(ThreadContext context, Block block, IRubyObject
193
189
return invokeYieldDirect (context , block , args , blockArg , self );
194
190
}
195
191
196
- IRubyObject invokeSpecific (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , Block blockArg , IRubyObject self ) {
197
- if (canInvokeDirect ()) return invokeSpecificDirect (context , block , arg0 , arg1 , blockArg , self );
192
+ IRubyObject invokeYieldSpecific (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , Block blockArg , IRubyObject self ) {
193
+ if (canInvokeDirect ()) return invokeYieldSpecificDirect (context , block , arg0 , arg1 , blockArg , self );
194
+
195
+ IRubyObject [] args = boxArgs (context , block , arg0 , arg1 );
196
+
197
+ return invoke (context , block , args , blockArg , self );
198
+ }
199
+
200
+ private IRubyObject [] boxArgs (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 ) {
201
+ IRubyObject [] args ;
198
202
199
203
switch (signature .arityValue ()) {
200
204
case 0 :
201
- return invoke (context , block , IRubyObject .NULL_ARRAY , blockArg , self );
205
+ args = IRubyObject .NULL_ARRAY ;
206
+ break ;
202
207
case 1 :
203
- return invoke (context , block , arrayOf (newArray (context .runtime , arg0 , arg1 )), blockArg , self );
208
+ args = arrayOf (newArray (context .runtime , arg0 , arg1 ));
209
+ break ;
204
210
default :
205
- IRubyObject [] args = arrayOf (arg0 , arg1 );
211
+ args = arrayOf (arg0 , arg1 );
206
212
if (block .isLambda ()) signature .checkArity (context .runtime , args );
207
- return invoke (context , block , args , blockArg , self );
208
213
}
214
+ return args ;
209
215
}
210
216
211
- IRubyObject invokeSpecific (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , IRubyObject arg2 , Block blockArg , IRubyObject self ) {
212
- if ( canInvokeDirect ()) return invokeSpecificDirect ( context , block , arg0 , arg1 , arg2 , blockArg , self ) ;
217
+ private IRubyObject [] boxArgs (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , IRubyObject arg2 ) {
218
+ IRubyObject [] args ;
213
219
214
220
switch (signature .arityValue ()) {
215
221
case 0 :
216
- return invoke (context , block , IRubyObject .NULL_ARRAY , blockArg , self );
222
+ args = IRubyObject .NULL_ARRAY ;
223
+ break ;
217
224
case 1 :
218
- return invoke (context , block , arrayOf (newArray (context .runtime , arg0 , arg1 , arg2 )), blockArg , self );
225
+ args = arrayOf (newArray (context .runtime , arg0 , arg1 , arg2 ));
226
+ break ;
219
227
default :
220
- IRubyObject [] args = arrayOf (arg0 , arg1 , arg2 );
228
+ args = arrayOf (arg0 , arg1 , arg2 );
221
229
if (block .isLambda ()) signature .checkArity (context .runtime , args );
222
- return invoke (context , block , args , blockArg , self );
223
230
}
231
+ return args ;
232
+ }
233
+
234
+ IRubyObject invokeYieldSpecific (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , IRubyObject arg2 , Block blockArg , IRubyObject self ) {
235
+ if (canInvokeDirect ()) return invokeYieldSpecificDirect (context , block , arg0 , arg1 , arg2 , blockArg , self );
236
+
237
+ return invoke (context , block , boxArgs (context , block , arg0 , arg1 , arg2 ), blockArg , self );
224
238
}
225
239
226
- IRubyObject invokeSpecificDirect (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , Block blockArg , IRubyObject self ) {
240
+ IRubyObject invokeYieldSpecificDirect (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , Block blockArg , IRubyObject self ) {
227
241
switch (signature .arityValue ()) {
228
242
case 0 :
229
243
return invokeYieldDirect (context , block , arrayOf (arg0 , arg1 ), blockArg , self );
@@ -234,7 +248,7 @@ IRubyObject invokeSpecificDirect(ThreadContext context, Block block, IRubyObject
234
248
}
235
249
}
236
250
237
- IRubyObject invokeSpecificDirect (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , IRubyObject arg2 , Block blockArg , IRubyObject self ) {
251
+ IRubyObject invokeYieldSpecificDirect (ThreadContext context , Block block , IRubyObject arg0 , IRubyObject arg1 , IRubyObject arg2 , Block blockArg , IRubyObject self ) {
238
252
switch (signature .arityValue ()) {
239
253
case 0 :
240
254
return invokeYieldDirect (context , block , arrayOf (arg0 , arg1 , arg2 ), blockArg , self );
0 commit comments