@ExplodeLoop @Override public final Object execute(VirtualFrame frame) { final Object self = RubyArguments.getSelf(frame.getArguments()); // Execute the arguments final Object[] argumentsObjects = new Object[arguments.length]; CompilerAsserts.compilationConstant(arguments.length); for (int i = 0; i < arguments.length; i++) { argumentsObjects[i] = arguments[i].execute(frame); } // Execute the block RubyProc blockObject; if (block != null) { final Object blockTempObject = block.execute(frame); if (blockTempObject instanceof RubyNilClass) { blockObject = null; } else { blockObject = (RubyProc) blockTempObject; } } else { blockObject = null; } // Check we have a method and the module is unmodified if (!guard(frame, self)) { CompilerDirectives.transferToInterpreterAndInvalidate(); lookup(frame); } // Call the method if (isSplatted) { // TODO(CS): need something better to splat the arguments array notDesignedForCompilation(); final RubyArray argumentsArray = (RubyArray) argumentsObjects[0]; return callNode.call( frame, RubyArguments.pack( superMethod, superMethod.getDeclarationFrame(), self, blockObject, argumentsArray.slowToArray())); } else { return callNode.call( frame, RubyArguments.pack( superMethod, superMethod.getDeclarationFrame(), self, blockObject, argumentsObjects)); } }
@Specialization(guards = "guardName") public Object dispatch( VirtualFrame frame, RubyNilClass methodReceiverObject, LexicalScope lexicalScope, RubySymbol receiverObject, Object methodName, Object blockObject, Object argumentsObjects, Dispatch.DispatchAction dispatchAction) { CompilerAsserts.compilationConstant(dispatchAction); // Check the class has not been modified try { unmodifiedAssumption.check(); } catch (InvalidAssumptionException e) { return resetAndDispatch( frame, methodReceiverObject, lexicalScope, receiverObject, methodName, CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false), argumentsObjects, dispatchAction, "class modified"); } if (dispatchAction == Dispatch.DispatchAction.CALL_METHOD) { return callNode.call( frame, RubyArguments.pack( method, method.getDeclarationFrame(), receiverObject, CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false), CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true))); } else if (dispatchAction == Dispatch.DispatchAction.RESPOND_TO_METHOD) { return true; } else if (dispatchAction == Dispatch.DispatchAction.READ_CONSTANT) { return value; } else { throw new UnsupportedOperationException(); } }