@@ -299,11 +299,13 @@ public final Object dispatch(Frame frame, Object receiver, String methodName, Ob
299
299
}
300
300
301
301
private Object callMethodMissing (Frame frame , Object receiver , String methodName , Object [] rubyArgs ) {
302
+ // profiles through lazy node creation
302
303
final RubySymbol symbolName = nameToSymbol (methodName );
304
+
303
305
final Object [] newArgs = RubyArguments .repack (rubyArgs , receiver , 0 , 1 );
304
306
305
307
RubyArguments .setArgument (newArgs , 0 , symbolName );
306
- final Object result = callMethodMissingNode ( frame , receiver , newArgs );
308
+ final Object result = getMethodMissingNode (). dispatch ( frame , receiver , "method_missing" , newArgs );
307
309
308
310
if (result == MISSING ) {
309
311
methodMissingMissing .enter ();
@@ -319,24 +321,30 @@ private Object callMethodMissing(Frame frame, Object receiver, String methodName
319
321
}
320
322
321
323
protected Object callForeign (Object receiver , String methodName , Object [] rubyArgs ) {
324
+ // profiles through lazy node creation
325
+ final CallForeignMethodNode callForeignMethodNode = getCallForeignMethodNode ();
326
+
327
+ final Object block = RubyArguments .getBlock (rubyArgs );
328
+ final Object [] arguments = RubyArguments .getPositionalArguments (rubyArgs , false );
329
+ return callForeignMethodNode .execute (receiver , methodName , block , arguments );
330
+ }
331
+
332
+ protected CallForeignMethodNode getCallForeignMethodNode () {
322
333
if (callForeign == null ) {
323
334
CompilerDirectives .transferToInterpreterAndInvalidate ();
324
335
callForeign = insert (CallForeignMethodNode .create ());
325
336
}
326
-
327
- final Object block = RubyArguments .getBlock (rubyArgs );
328
- final Object [] arguments = RubyArguments .getPositionalArguments (rubyArgs , false );
329
- return callForeign .execute (receiver , methodName , block , arguments );
337
+ return callForeign ;
330
338
}
331
339
332
- protected Object callMethodMissingNode ( Frame frame , Object receiver , Object [] rubyArgs ) {
340
+ protected DispatchNode getMethodMissingNode ( ) {
333
341
if (callMethodMissing == null ) {
334
342
CompilerDirectives .transferToInterpreterAndInvalidate ();
335
343
// #method_missing ignores refinements on CRuby: https://bugs.ruby-lang.org/issues/13129
336
344
callMethodMissing = insert (
337
345
DispatchNode .create (DispatchConfiguration .PRIVATE_RETURN_MISSING_IGNORE_REFINEMENTS ));
338
346
}
339
- return callMethodMissing . dispatch ( frame , receiver , "method_missing" , rubyArgs ) ;
347
+ return callMethodMissing ;
340
348
}
341
349
342
350
protected RubySymbol nameToSymbol (String methodName ) {
@@ -394,16 +402,13 @@ protected Uncached(DispatchConfiguration config) {
394
402
}
395
403
396
404
@ Override
397
- protected Object callForeign (Object receiver , String methodName , Object [] rubyArgs ) {
398
- final Object block = RubyArguments .getBlock (rubyArgs );
399
- final Object [] arguments = RubyArguments .getPositionalArguments (rubyArgs , false );
400
- return CallForeignMethodNode .getUncached ().execute (receiver , methodName , block , arguments );
405
+ protected CallForeignMethodNode getCallForeignMethodNode () {
406
+ return CallForeignMethodNode .getUncached ();
401
407
}
402
408
403
409
@ Override
404
- protected Object callMethodMissingNode (Frame frame , Object receiver , Object [] rubyArgs ) {
405
- return DispatchNode .getUncached (DispatchConfiguration .PRIVATE_RETURN_MISSING_IGNORE_REFINEMENTS )
406
- .dispatch (frame , receiver , "method_missing" , rubyArgs );
410
+ protected DispatchNode getMethodMissingNode () {
411
+ return DispatchNode .getUncached (DispatchConfiguration .PRIVATE_RETURN_MISSING_IGNORE_REFINEMENTS );
407
412
}
408
413
409
414
@ Override
0 commit comments