@ExplodeLoop @Override public RubyArray executeArray(VirtualFrame frame) { CompilerDirectives.transferToInterpreter(); final Object[] executedValues = new Object[values.length]; for (int n = 0; n < values.length; n++) { executedValues[n] = values[n].execute(frame); } final RubyArray array = RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(), executedValues); final Object store = array.getStore(); if (store == null) { replace(new EmptyArrayLiteralNode(getContext(), getSourceSection(), values)); } if (store instanceof int[]) { replace(new IntegerFixnumArrayLiteralNode(getContext(), getSourceSection(), values)); } else if (store instanceof long[]) { replace(new LongFixnumArrayLiteralNode(getContext(), getSourceSection(), values)); } else if (store instanceof double[]) { replace(new FloatArrayLiteralNode(getContext(), getSourceSection(), values)); } else { replace(new ObjectArrayLiteralNode(getContext(), getSourceSection(), values)); } return array; }
public int readFixnum(RubyBasicObject object, boolean condition) throws UnexpectedResultException { if (isSet(object)) { return CompilerDirectives.unsafeGetInt(object, offset, condition, this); } else { throw new UnexpectedResultException(NilPlaceholder.INSTANCE); } }
@Override public Object execute(VirtualFrame frame) { if (CompilerDirectives.injectBranchProbability( getBranchProbability(), condition.executeBoolean(frame))) { if (CompilerDirectives.inInterpreter()) { thenCount++; } thenProfile.enter(); return thenBody.execute(frame); } else { if (CompilerDirectives.inInterpreter()) { elseCount++; } elseProfile.enter(); return elseBody.execute(frame); } }
@Specialization public Object methodMissing(RubyBasicObject self, Object[] args, RubyProc block) { notDesignedForCompilation(); CompilerDirectives.transferToInterpreter(); final RubySymbol name = (RubySymbol) args[0]; final Object[] sentArgs = Arrays.copyOfRange(args, 1, args.length); return methodMissing(self, name, sentArgs, block); }
@Specialization public Object methodMissing( RubyBasicObject self, Object[] args, @SuppressWarnings("unused") UndefinedPlaceholder block) { notDesignedForCompilation(); CompilerDirectives.transferToInterpreter(); final RubySymbol name = (RubySymbol) args[0]; final Object[] sentArgs = Arrays.copyOfRange(args, 1, args.length); return methodMissing(self, name, sentArgs, 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 execute(VirtualFrame frame) { while (true) { try { final Object result = tryPart.execute(frame); elsePart.executeVoid(frame); return result; } catch (ControlFlowException exception) { controlFlowProfile.enter(); throw exception; } catch (RuntimeException exception) { CompilerDirectives.transferToInterpreter(); try { return handleException(frame, exception); } catch (RetryException e) { continue; } } } }
public void writeFixnum(RubyBasicObject object, int value) { CompilerDirectives.unsafePutInt(object, offset, value, null); markAsSet(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)); }