@Override public Object execute(VirtualFrame frame) { final int count = RubyArguments.getArgumentsCount(frame.getArguments()); final int effectiveIndex = count + negativeIndex; assert effectiveIndex < count; return RubyArguments.getArgument(frame.getArguments(), effectiveIndex); }
@Override public Object execute(VirtualFrame frame) { if (RubyArguments.getUserArgumentsCount(frame.getArguments()) < minimum) { defaultValueProfile.enter(); return defaultValue.execute(frame); } else { return RubyArguments.getUserArgument(frame.getArguments(), index); } }
@Override public Object execute(VirtualFrame frame) { final int argumentCount = RubyArguments.getArgumentsCount(frame); if (notEnoughArgumentsProfile.profile(argumentCount <= minArgumentCount)) { return null; } final Object lastArgument = RubyArguments.getArgument(frame, argumentCount - 1); if (lastArgumentIsHashProfile.profile(RubyGuards.isRubyHash(lastArgument))) { return lastArgument; } return tryConvertToHash(frame, argumentCount, lastArgument); }
@Override public Object execute(VirtualFrame frame) { final RubyArguments rubyArguments = frame.getArguments(RubyArguments.class); final Object[] arguments = rubyArguments.getArguments(); final RubyClass arrayClass = getContext().getCoreLibrary().getArrayClass(); if (arguments.length <= index) { return new RubyArray(arrayClass); } else if (index == 0) { return new RubyArray(arrayClass, new ObjectArrayStore(arguments)); } else { return new RubyArray( arrayClass, new ObjectArrayStore(Arrays.copyOfRange(arguments, index, arguments.length))); } }
private Object tryConvertToHash( VirtualFrame frame, final int argumentCount, final Object lastArgument) { if (respondsToToHashProfile.profile(respondToToHash(frame, lastArgument))) { final Object converted = callToHash(frame, lastArgument); if (convertedIsHashProfile.profile(RubyGuards.isRubyHash(converted))) { RubyArguments.setArgument(frame, argumentCount - 1, converted); return converted; } } return null; }
@Override public boolean doesRespondTo(VirtualFrame frame, RubyBasicObject receiverObject) { // TODO(CS): copy-and-paste of the above - needs to be factored out 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"); } } return !entry.isMethodMissing(); }
@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)); }