@Override public Object executeDispatch( VirtualFrame frame, Object receiverObject, Object methodName, Object blockObject, Object argumentsObjects) { if (!guardName(methodName) || !(receiverObject instanceof RubySymbol)) { return next.executeDispatch(frame, receiverObject, methodName, blockObject, argumentsObjects); } // Check the class has not been modified try { unmodifiedAssumption.check(); } catch (InvalidAssumptionException e) { return resetAndDispatch( frame, receiverObject, methodName, (RubyProc) blockObject, argumentsObjects, "class modified"); } switch (getDispatchAction()) { case CALL_METHOD: { if (isIndirect()) { return indirectCallNode.call( frame, method.getCallTarget(), RubyArguments.pack( method, method.getDeclarationFrame(), receiverObject, (RubyProc) blockObject, (Object[]) argumentsObjects)); } else { return callNode.call( frame, RubyArguments.pack( method, method.getDeclarationFrame(), receiverObject, (RubyProc) blockObject, (Object[]) argumentsObjects)); } } case RESPOND_TO_METHOD: return true; case READ_CONSTANT: return value; default: throw new UnsupportedOperationException(); } }
@Override protected Object executeDispatch(VirtualFrame frame, LlvmFunction function, Object[] arguments) { /* * Llvm has a quite simple call lookup: just ask the function for the current call target, * and call it. */ return callNode.call(frame, function.getCallTarget(), arguments); }
@Specialization(contains = "doDirect") protected Object doIndirect( VirtualFrame frame, LLVMFunction function, Object[] arguments, // @Cached("create()") IndirectCallNode callNode) { return callNode.call(frame, context.getFunction(function), arguments); }
@Override public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) { final RubyMethod method = block.getMethod(); return callNode.call( frame, method.getCallTarget(), RubyArguments.pack( method.getDeclarationFrame(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope(), argumentsObjects)); }
@Override public Object execute(VirtualFrame frame) { CompilerDirectives.transferToInterpreter(); // TODO(CS): cast final DynamicObject module = (DynamicObject) definingModule.execute(frame); lexicalScope.setLiveModule(module); Layouts.MODULE.getFields(lexicalScope.getParent().getLiveModule()).addLexicalDependent(module); final InternalMethod definition = definitionMethod.executeMethod(frame).withDeclaringModule(module); return callModuleDefinitionNode.call( frame, definition.getCallTarget(), RubyArguments.pack( definition, null, null, module, null, DeclarationContext.MODULE, new Object[] {})); }
@Override public Object execute(VirtualFrame frame) { final DynamicObject module = (DynamicObject) definingModule.execute(frame); final InternalMethod definition = prepareLexicalScope(module, definitionMethod.executeMethod(frame)); return callModuleDefinitionNode.call( frame, definition.getCallTarget(), RubyArguments.pack( null, null, definition, DeclarationContext.MODULE, null, module, null, new Object[] {})); }
@Override public Object dispatch( VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) { MethodCacheEntry entry = lookupInCache(receiverObject.getLookupNode()); if (entry == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); final RubyBasicObject boxedCallingSelf = getContext().getCoreLibrary().box(RubyArguments.getSelf(frame.getArguments())); try { entry = new MethodCacheEntry(lookup(boxedCallingSelf, receiverObject, name), false); } catch (UseMethodMissingException e) { try { entry = new MethodCacheEntry( lookup(boxedCallingSelf, receiverObject, "method_missing"), true); } catch (UseMethodMissingException e2) { throw new RaiseException( getContext() .getCoreLibrary() .runtimeError(receiverObject.toString() + " didn't have a #method_missing")); } } if (entry.isMethodMissing()) { hasAnyMethodsMissing = true; } cache.put(receiverObject.getLookupNode(), entry); if (cache.size() > RubyContext.GENERAL_DISPATCH_SIZE_WARNING_THRESHOLD) { getContext() .getRuntime() .getWarnings() .warn( IRubyWarnings.ID.TRUFFLE, getEncapsulatingSourceSection().getSource().getName(), getEncapsulatingSourceSection().getStartLine(), "general call node cache has " + cache.size() + " entries"); } } final Object[] argumentsToUse; if (hasAnyMethodsMissing && entry.isMethodMissing()) { final Object[] modifiedArgumentsObjects = new Object[1 + argumentsObjects.length]; modifiedArgumentsObjects[0] = getContext().newSymbol(name); System.arraycopy(argumentsObjects, 0, modifiedArgumentsObjects, 1, argumentsObjects.length); argumentsToUse = modifiedArgumentsObjects; } else { argumentsToUse = argumentsObjects; } return callNode.call( frame, entry.getMethod().getCallTarget(), RubyArguments.pack( entry.getMethod().getDeclarationFrame(), receiverObject, blockObject, argumentsToUse)); }
@Override public Object executeWith(VirtualFrame frame, TruffleObject truffleObject, Object[] arguments) { final CallTarget ct = findCallTarget(truffleObject); return indirectCallNode.call( frame, ct, accessArguments.executeCreate(truffleObject, arguments)); }