Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6e3f361dc923
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ae4ad8b396a2
Choose a head ref
  • 2 commits
  • 16 files changed
  • 1 contributor

Commits on Feb 18, 2016

  1. Copy the full SHA
    be4de4e View commit details

Commits on Feb 19, 2016

  1. Copy the full SHA
    ae4ad8b View commit details
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@
import org.jruby.truffle.language.methods.SharedMethodInfo;
import org.jruby.truffle.language.objects.SelfNode;
import org.jruby.truffle.language.objects.SingletonClassNode;
import org.jruby.truffle.language.translator.Translator;

import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -232,7 +233,7 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
}

final RubyNode checkArity = CheckArityNode.create(context, sourceSection, arity);
RubyNode sequence = SequenceNode.sequence(context, sourceSection, checkArity, methodNode);
RubyNode sequence = Translator.sequence(context, sourceSection, Arrays.asList(checkArity, methodNode));

if (method.returnsEnumeratorIfNoBlock()) {
// TODO BF 3-18-2015 Handle multiple method names correctly
Original file line number Diff line number Diff line change
@@ -90,11 +90,13 @@
import org.jruby.truffle.language.objects.SingletonClassNode;
import org.jruby.truffle.language.objects.SingletonClassNodeGen;
import org.jruby.truffle.language.objects.WriteInstanceVariableNode;
import org.jruby.truffle.language.translator.Translator;
import org.jruby.truffle.language.translator.TranslatorDriver.ParserContext;
import org.jruby.truffle.language.yield.YieldDispatchHeadNode;
import org.jruby.util.IdUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -430,7 +432,7 @@ public DynamicObject generateAccessor(VirtualFrame frame, DynamicObject module,
ReadPreArgumentNode readArgument = new ReadPreArgumentNode(getContext(), sourceSection, 0, MissingArgumentBehaviour.RUNTIME_ERROR);
accessInstanceVariable = new WriteInstanceVariableNode(getContext(), sourceSection, ivar, self, readArgument);
}
final RubyNode sequence = SequenceNode.sequence(getContext(), sourceSection, checkArity, accessInstanceVariable);
final RubyNode sequence = Translator.sequence(getContext(), sourceSection, Arrays.asList(checkArity, accessInstanceVariable));
final RubyRootNode rootNode = new RubyRootNode(getContext(), sourceSection, null, sharedMethodInfo, sequence, false);
final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
final InternalMethod method = new InternalMethod(sharedMethodInfo, accessorName, module, visibility, callTarget);
Original file line number Diff line number Diff line change
@@ -38,6 +38,9 @@
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.methods.SharedMethodInfo;
import org.jruby.truffle.language.methods.SymbolProcNode;
import org.jruby.truffle.language.translator.Translator;

import java.util.Arrays;

@CoreClass(name = "Symbol")
public abstract class SymbolNodes {
@@ -147,9 +150,7 @@ protected DynamicObject createProc(VirtualFrame frame, DynamicObject symbol) {
sourceSection, null, Arity.AT_LEAST_ONE, Layouts.SYMBOL.getString(symbol),
true, ArgumentDescriptor.ANON_REST, false, false, false);

final RubyRootNode rootNode = new RubyRootNode(getContext(), sourceSection, new FrameDescriptor(nil()), sharedMethodInfo, SequenceNode.sequence(getContext(), sourceSection,
CheckArityNode.create(getContext(), sourceSection, Arity.AT_LEAST_ONE),
new SymbolProcNode(getContext(), sourceSection, Layouts.SYMBOL.getString(symbol))), false);
final RubyRootNode rootNode = new RubyRootNode(getContext(), sourceSection, new FrameDescriptor(nil()), sharedMethodInfo, Translator.sequence(getContext(), sourceSection, Arrays.asList(CheckArityNode.create(getContext(), sourceSection, Arity.AT_LEAST_ONE), new SymbolProcNode(getContext(), sourceSection, Layouts.SYMBOL.getString(symbol)))), false);

final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
final InternalMethod method = RubyArguments.getMethod(frame.getArguments());
Original file line number Diff line number Diff line change
@@ -51,7 +51,6 @@
import org.jruby.truffle.language.NotProvided;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.backtrace.BacktraceFormatter;
import org.jruby.truffle.language.backtrace.BacktraceInterleaver;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.loader.SourceLoader;
import org.jruby.truffle.language.methods.InternalMethod;
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@
*/
package org.jruby.truffle.language.control;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyNode;
Original file line number Diff line number Diff line change
@@ -16,152 +16,13 @@
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.literal.LiteralNode;
import org.jruby.truffle.language.literal.NilNode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* A sequence of statements to be executed in serial.
*/
@NodeInfo(cost = NodeCost.NONE)
public final class SequenceNode extends RubyNode {

@Children private final RubyNode[] body;

public static RubyNode sequenceNoFlatten(RubyContext context, SourceSection sourceSection, RubyNode... sequence) {
return new SequenceNode(context, sourceSection, sequence);
}

public static RubyNode sequenceNoFlatten(RubyContext context, SourceSection sourceSection, List<RubyNode> sequence) {
return sequenceNoFlatten(context, sourceSection, sequence.toArray(new RubyNode[sequence.size()]));
}

public static RubyNode sequence(RubyContext context, SourceSection sourceSection, RubyNode... sequence) {
return sequence(context, sourceSection, Arrays.asList(sequence));
}

public static RubyNode sequence(RubyContext context, SourceSection sourceSection, List<RubyNode> sequence) {
final List<RubyNode> flattened = flatten(context, sequence, true);

if (flattened.isEmpty()) {
return new NilNode(context, sourceSection);
} else if (flattened.size() == 1) {
return flattened.get(0);
} else {
final RubyNode[] flatSequence = flattened.toArray(new RubyNode[flattened.size()]);
return new SequenceNode(context, enclosing(sourceSection, flatSequence), flatSequence);
}
}

public static SourceSection enclosing(SourceSection base, SourceSection... sourceSections) {
if (base.getSource() == null) {
return base;
}

if (sourceSections.length == 0) {
return base;
}

int startLine = base.getStartLine();
int endLine = base.getEndLine();

for (SourceSection sourceSection : sourceSections) {
startLine = Math.min(startLine, sourceSection.getStartLine());

final int nodeEndLine;

if (sourceSection.getSource() == null) {
nodeEndLine = sourceSection.getStartLine();
} else {
nodeEndLine = sourceSection.getEndLine();
}

endLine = Math.max(endLine, nodeEndLine);
}

final int index = base.getSource().getLineStartOffset(startLine);

int length = 0;

for (int n = startLine; n <= endLine; n++) {
// + 1 because the line length doesn't include any newlines
length += base.getSource().getLineLength(n) + 1;
}

length = Math.min(length, base.getSource().getLength() - index);
length = Math.max(0, length);

return base.getSource().createSection(base.getIdentifier(), index, length);
}

public static SourceSection enclosing(SourceSection base, RubyNode[] sequence) {
if (base.getSource() == null) {
return base;
}

if (sequence.length == 0) {
return base;
}

int startLine = base.getStartLine();
int endLine = base.getEndLine();

for (RubyNode node : sequence) {
final SourceSection nodeSourceSection = node.getEncapsulatingSourceSection();

startLine = Math.min(startLine, nodeSourceSection.getStartLine());

final int nodeEndLine;

if (nodeSourceSection.getSource() == null) {
nodeEndLine = nodeSourceSection.getStartLine();
} else {
nodeEndLine = nodeSourceSection.getEndLine();
}

endLine = Math.max(endLine, nodeEndLine);
}

final int index = base.getSource().getLineStartOffset(startLine);

int length = 0;

for (int n = startLine; n <= endLine; n++) {
// + 1 because the line length doesn't include any newlines
length += base.getSource().getLineLength(n) + 1;
}

length = Math.min(length, base.getSource().getLength() - index);
length = Math.max(0, length);

return base.getSource().createSection(base.getIdentifier(), index, length);
}

private static List<RubyNode> flatten(RubyContext context, List<RubyNode> sequence, boolean allowTrailingNil) {
final List<RubyNode> flattened = new ArrayList<>();

for (int n = 0; n < sequence.size(); n++) {
final boolean lastNode = n == sequence.size() - 1;
final RubyNode node = sequence.get(n);

if (node instanceof NilNode || (node instanceof LiteralNode && ((LiteralNode) node).getObject() == context.getCoreLibrary().getNilObject())) {
if (allowTrailingNil && lastNode) {
flattened.add(node);
}
} else if (node instanceof SequenceNode) {
flattened.addAll(flatten(context, Arrays.asList(((SequenceNode) node).body), lastNode));
} else {
flattened.add(node);
}
}

return flattened;
}

protected SequenceNode(RubyContext context, SourceSection sourceSection, RubyNode... body) {
public SequenceNode(RubyContext context, SourceSection sourceSection, RubyNode... body) {
super(context, sourceSection);
this.body = body;
}
@@ -187,4 +48,5 @@ public void executeVoid(VirtualFrame frame) {
public RubyNode[] getSequence() {
return body;
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -38,11 +38,13 @@
import org.jruby.truffle.language.exceptions.TopLevelRaiseHandler;
import org.jruby.truffle.language.methods.DeclarationContext;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.translator.Translator;
import org.jruby.truffle.language.translator.TranslatorDriver;
import org.jruby.util.ByteList;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class CodeLoader {

@@ -129,10 +131,7 @@ public Object execute(final org.jruby.ast.RootNode rootNode) {
final SourceSection sourceSection = originalRootNode.getSourceSection();
final RubyNode wrappedBody =
new TopLevelRaiseHandler(context, sourceSection,
SequenceNode.sequence(context, sourceSection,
new SetTopLevelBindingNode(context, sourceSection),
new LoadRequiredLibrariesNode(context, sourceSection),
originalRootNode.getBody()));
Translator.sequence(context, sourceSection, Arrays.asList(new SetTopLevelBindingNode(context, sourceSection), new LoadRequiredLibrariesNode(context, sourceSection), originalRootNode.getBody())));

final RubyRootNode newRootNode = originalRootNode.withBody(wrappedBody);

Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@
import org.jruby.truffle.core.array.ArrayDropTailNodeGen;
import org.jruby.truffle.core.array.ArrayGetTailNodeGen;
import org.jruby.truffle.core.array.ArrayLiteralNode;
import org.jruby.truffle.core.array.ArrayNodes.PushOneNode;
import org.jruby.truffle.core.array.ArrayNodesFactory;
import org.jruby.truffle.core.array.PrimitiveArrayNodeFactory;
import org.jruby.truffle.core.cast.HashCastNodeGen;
@@ -98,7 +97,6 @@
import org.jruby.truffle.language.control.ReturnNode;
import org.jruby.truffle.language.control.SequenceNode;
import org.jruby.truffle.language.control.UnlessNode;
import org.jruby.truffle.language.control.WhenSplatNode;
import org.jruby.truffle.language.control.WhileNode;
import org.jruby.truffle.language.defined.DefinedNode;
import org.jruby.truffle.language.defined.DefinedWrapperNode;
@@ -375,10 +373,7 @@ public RubyNode visitAttrAssignNode(org.jruby.ast.AttrAssignNode node) {
boolean isAccessorOnSelf = (node.getReceiverNode() instanceof org.jruby.ast.SelfNode);
final RubyNode actualCall = translateCallNode(callNode, isAccessorOnSelf, false);

final RubyNode ret = SequenceNode.sequence(context, sourceSection,
writeValue,
actualCall,
new ReadLocalVariableNode(context, sourceSection, frameSlot));
final RubyNode ret = sequence(context, sourceSection, Arrays.asList(writeValue, actualCall, new ReadLocalVariableNode(context, sourceSection, frameSlot)));

return addNewlineIfNeeded(node, ret);
}
@@ -443,7 +438,8 @@ public RubyNode visitBlockNode(org.jruby.ast.BlockNode node) {
if (translatedChildren.size() == 1) {
ret = translatedChildren.get(0);
} else {
ret = SequenceNode.sequence(context, sourceSection, translatedChildren.toArray(new RubyNode[translatedChildren.size()]));
RubyNode[] sequence = translatedChildren.toArray(new RubyNode[translatedChildren.size()]);
ret = sequence(context, sourceSection, Arrays.asList(sequence));
}

return addNewlineIfNeeded(node, ret);
@@ -672,7 +668,7 @@ private RubyNode translateCallNode(org.jruby.ast.CallNode node, boolean ignoreVi

children.addAll(Arrays.asList(argumentsAndBlock.getArguments()));

RubyNode translated = new RubyCallNode(context, SequenceNode.enclosing(sourceSection, children.toArray(new RubyNode[children.size()])),
RubyNode translated = new RubyCallNode(context, enclosing(sourceSection, children.toArray(new RubyNode[children.size()])),
node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(),
privately || ignoreVisibility, isVCall, argumentsAndBlock.getArguments());

@@ -840,15 +836,10 @@ public RubyNode visitCaseNode(org.jruby.ast.CaseNode node) {
for (org.jruby.ast.Node expressionNode : expressions) {
final RubyNode rubyExpression = expressionNode.accept(this);

if (expressionNode instanceof org.jruby.ast.SplatNode) {
final SplatCastNode splatCastNode = (SplatCastNode) rubyExpression;
comparisons.add(new WhenSplatNode(context, sourceSection, NodeUtil.cloneNode(readTemp), splatCastNode));
} else if (expressionNode instanceof org.jruby.ast.ArgsCatNode) {
final ArrayConcatNode arrayConcatNode = (ArrayConcatNode) rubyExpression;
comparisons.add(new WhenSplatNode(context, sourceSection, NodeUtil.cloneNode(readTemp), arrayConcatNode));
} else if (expressionNode instanceof org.jruby.ast.ArgsPushNode) {
final PushOneNode pushOneNode = (PushOneNode) rubyExpression;
comparisons.add(new WhenSplatNode(context, sourceSection, NodeUtil.cloneNode(readTemp), pushOneNode));
if (expressionNode instanceof org.jruby.ast.SplatNode
|| expressionNode instanceof org.jruby.ast.ArgsCatNode
|| expressionNode instanceof org.jruby.ast.ArgsPushNode) {
comparisons.add(new RubyCallNode(context, sourceSection, "when_splat", new SelfNode(context, sourceSection), null, false, true, rubyExpression, NodeUtil.cloneNode(readTemp)));
} else {
comparisons.add(new RubyCallNode(context, sourceSection, "===", rubyExpression, null, false, true, NodeUtil.cloneNode(readTemp)));
}
@@ -877,7 +868,7 @@ public RubyNode visitCaseNode(org.jruby.ast.CaseNode node) {

// A top-level block assigns the temp then runs the if

ret = SequenceNode.sequence(context, sourceSection, assignTemp, ifNode);
ret = sequence(context, sourceSection, Arrays.asList(assignTemp, ifNode));
} else {
for (int n = node.getCases().size() - 1; n >= 0; n--) {
final org.jruby.ast.WhenNode when = (org.jruby.ast.WhenNode) node.getCases().get(n);
@@ -970,7 +961,7 @@ private ModuleBodyDefinitionNode compileClassNode(SourceSection sourceSection, S
}

if (environment.getFlipFlopStates().size() > 0) {
body = SequenceNode.sequence(context, sourceSection, initFlipFlopStates(sourceSection), body);
body = sequence(context, sourceSection, Arrays.asList(initFlipFlopStates(sourceSection), body));
}

final RubyRootNode rootNode = new RubyRootNode(context, sourceSection, environment.getFrameDescriptor(), environment.getSharedMethodInfo(), body, environment.needsDeclarationFrame());
@@ -1764,7 +1755,7 @@ public RubyNode visitIfNode(org.jruby.ast.IfNode node) {
final RubyNode elseBodyTranslated = elseBody.accept(this);
ret = new UnlessNode(context, sourceSection, condition, elseBodyTranslated);
} else {
ret = SequenceNode.sequence(context, sourceSection, condition, new NilNode(context, sourceSection));
ret = sequence(context, sourceSection, Arrays.asList(condition, new NilNode(context, sourceSection)));
}

return addNewlineIfNeeded(node, ret);
@@ -2184,7 +2175,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgnNode node) {
tempValues[n] = NodeUtil.cloneNode(readTemp);
}

final RubyNode blockNode = SequenceNode.sequence(context, sourceSection, sequence);
final RubyNode blockNode = sequence(context, sourceSection, Arrays.asList(sequence));

final ArrayLiteralNode.UninitialisedArrayLiteralNode arrayNode = new ArrayLiteralNode.UninitialisedArrayLiteralNode(context, sourceSection, tempValues);

@@ -2269,7 +2260,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgnNode node) {
smallerSequence.add(translateDummyAssignment(postArray.get(n), assignedValue));
}

final RubyNode smaller = SequenceNode.sequence(context, sourceSection, smallerSequence);
final RubyNode smaller = sequence(context, sourceSection, smallerSequence);

final List<RubyNode> atLeastAsLargeSequence = new ArrayList<>();

@@ -2279,7 +2270,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgnNode node) {
atLeastAsLargeSequence.add(translateDummyAssignment(postArray.get(n), assignedValue));
}

final RubyNode atLeastAsLarge = SequenceNode.sequence(context, sourceSection, atLeastAsLargeSequence);
final RubyNode atLeastAsLarge = sequence(context, sourceSection, atLeastAsLargeSequence);

final RubyNode assignPost =
new IfElseNode(context, sourceSection,
@@ -2290,7 +2281,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgnNode node) {
sequence.add(assignPost);
}

result = new ElidableResultNode(context, sourceSection, SequenceNode.sequence(context, sourceSection, sequence), environment.findLocalVarNode(tempRHSName, sourceSection));
result = new ElidableResultNode(context, sourceSection, sequence(context, sourceSection, sequence), environment.findLocalVarNode(tempRHSName, sourceSection));
} else if (node.getPre() == null
&& node.getPost() == null
&& node.getRest() instanceof org.jruby.ast.StarNode) {
@@ -2345,7 +2336,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgnNode node) {
assignmentResult = environment.findLocalVarNode(tempRHSName, sourceSection);
}

result = new ElidableResultNode(context, sourceSection, SequenceNode.sequence(context, sourceSection, sequence), assignmentResult);
result = new ElidableResultNode(context, sourceSection, sequence(context, sourceSection, sequence), assignmentResult);
} else if (node.getPre() == null
&& node.getPost() == null
&& node.getRest() != null
@@ -2409,7 +2400,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgnNode node) {
smallerSequence.add(translateDummyAssignment(postArray.get(n), assignedValue));
}

final RubyNode smaller = SequenceNode.sequence(context, sourceSection, smallerSequence);
final RubyNode smaller = sequence(context, sourceSection, smallerSequence);

final List<RubyNode> atLeastAsLargeSequence = new ArrayList<>();

@@ -2419,7 +2410,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgnNode node) {
atLeastAsLargeSequence.add(translateDummyAssignment(postArray.get(n), assignedValue));
}

final RubyNode atLeastAsLarge = SequenceNode.sequence(context, sourceSection, atLeastAsLargeSequence);
final RubyNode atLeastAsLarge = sequence(context, sourceSection, atLeastAsLargeSequence);

final RubyNode assignPost =
new IfElseNode(context, sourceSection,
@@ -2429,7 +2420,7 @@ public RubyNode visitMultipleAsgnNode(org.jruby.ast.MultipleAsgnNode node) {

sequence.add(assignPost);

result = new ElidableResultNode(context, sourceSection, SequenceNode.sequence(context, sourceSection, sequence), environment.findLocalVarNode(tempRHSName, sourceSection));
result = new ElidableResultNode(context, sourceSection, sequence(context, sourceSection, sequence), environment.findLocalVarNode(tempRHSName, sourceSection));
} else {
context.getJRubyRuntime().getWarnings().warn(IRubyWarnings.ID.TRUFFLE, source.getName(), node.getPosition().getLine(), node + " unknown form of multiple assignment");
result = nilNode(sourceSection);
@@ -2525,7 +2516,7 @@ public RubyNode visitOpAsgnNode(org.jruby.ast.OpAsgnNode node) {
RubyNode rhs = writeMethod.accept(this);

final RubyNode ret = new DefinedWrapperNode(context, sourceSection,
SequenceNode.sequence(context, sourceSection, writeReceiverToTemp.accept(this), new OrNode(context, sourceSection, lhs, rhs)),
sequence(context, sourceSection, Arrays.asList(writeReceiverToTemp.accept(this), new OrNode(context, sourceSection, lhs, rhs))),
"assignment");

return addNewlineIfNeeded(node, ret);
@@ -3090,7 +3081,7 @@ protected RubyNode initFlipFlopStates(SourceSection sourceSection) {
initNodes[n] = new InitFlipFlopSlotNode(context, sourceSection, environment.getFlipFlopStates().get(n));
}

return SequenceNode.sequence(context, sourceSection, initNodes);
return sequence(context, sourceSection, Arrays.asList(initNodes));
}

@Override
Original file line number Diff line number Diff line change
@@ -39,13 +39,13 @@
import org.jruby.truffle.language.arguments.RunBlockKWArgsHelperNode;
import org.jruby.truffle.language.control.IfElseNode;
import org.jruby.truffle.language.control.IfNode;
import org.jruby.truffle.language.control.SequenceNode;
import org.jruby.truffle.language.literal.NilNode;
import org.jruby.truffle.language.locals.ReadLocalVariableNode;
import org.jruby.truffle.language.locals.WriteLocalVariableNode;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
@@ -174,7 +174,7 @@ public RubyNode visitArgsNode(org.jruby.ast.ArgsNode node) {
}
}

final RubyNode notNilSmaller = SequenceNode.sequence(context, sourceSection, notNilSmallerSequence);
final RubyNode notNilSmaller = sequence(context, sourceSection, notNilSmallerSequence);

// The load to use when the there is no rest

@@ -190,7 +190,7 @@ public RubyNode visitArgsNode(org.jruby.ast.ArgsNode node) {
}
}

final RubyNode noRest = SequenceNode.sequence(context, sourceSection, noRestSequence);
final RubyNode noRest = sequence(context, sourceSection, noRestSequence);

// The load to use when the array is not nil and at least as large as the number of required arguments

@@ -212,7 +212,7 @@ public RubyNode visitArgsNode(org.jruby.ast.ArgsNode node) {
}
}

final RubyNode notNilAtLeastAsLarge = SequenceNode.sequence(context, sourceSection, notNilAtLeastAsLargeSequence);
final RubyNode notNilAtLeastAsLarge = sequence(context, sourceSection, notNilAtLeastAsLargeSequence);

if (useArray()) {
if (node.getPreCount() == 0 || node.hasRestArg()) {
@@ -247,7 +247,7 @@ public RubyNode visitArgsNode(org.jruby.ast.ArgsNode node) {
sequence.add(node.getBlock().accept(this));
}

return SequenceNode.sequence(context, sourceSection, sequence);
return sequence(context, sourceSection, sequence);
}

@Override
@@ -501,7 +501,7 @@ public RubyNode visitMultipleAsgnNode(MultipleAsgnNode node) {
}
}

final RubyNode notNilSmaller = SequenceNode.sequence(context, sourceSection, notNilSmallerSequence);
final RubyNode notNilSmaller = sequence(context, sourceSection, notNilSmallerSequence);

// The load to use when the array is not nil and at least as large as the number of required arguments

@@ -531,7 +531,7 @@ public RubyNode visitMultipleAsgnNode(MultipleAsgnNode node) {
}
}

final RubyNode notNilAtLeastAsLarge = SequenceNode.sequence(context, sourceSection, notNilAtLeastAsLargeSequence);
final RubyNode notNilAtLeastAsLarge = sequence(context, sourceSection, notNilAtLeastAsLargeSequence);

popArraySlot(arraySlot);

@@ -579,19 +579,17 @@ public RubyNode visitMultipleAsgnNode(MultipleAsgnNode node) {
nilSequence.add(childNodes.get(0).accept(this));
}

final RubyNode nil = SequenceNode.sequence(context, sourceSection, nilSequence);
final RubyNode nil = sequence(context, sourceSection, nilSequence);

return SequenceNode.sequence(context, sourceSection,
new WriteLocalVariableNode(context, sourceSection,
return sequence(context, sourceSection, Arrays.asList(new WriteLocalVariableNode(context, sourceSection,
SplatCastNodeGen.create(context, sourceSection, SplatCastNode.NilBehavior.ARRAY_WITH_NIL, true,
readArgument(sourceSection)), arraySlot),
new IfElseNode(context, sourceSection,
readArgument(sourceSection)), arraySlot), new IfElseNode(context, sourceSection,
new IsNilNode(context, sourceSection, new ReadLocalVariableNode(context, sourceSection, arraySlot)),
nil,
new IfElseNode(context, sourceSection,
new ArrayIsAtLeastAsLargeAsNode(context, sourceSection, new ReadLocalVariableNode(context, sourceSection, arraySlot), node.getPreCount() + node.getPostCount()),
notNilAtLeastAsLarge,
notNilSmaller)));
notNilSmaller))));
}

@Override
Original file line number Diff line number Diff line change
@@ -57,6 +57,7 @@
import org.jruby.truffle.language.supercall.ZSuperOutsideMethodNode;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;

public class MethodTranslator extends BodyTranslator {
@@ -106,9 +107,7 @@ public BlockDefinitionNode compileBlockNode(SourceSection sourceSection, String

final RubyNode shouldDestructure = new ShouldDestructureNode(context, sourceSection, new RespondToNode(context, sourceSection, readArrayNode, "to_ary"));

final RubyNode arrayWasNotNil = SequenceNode.sequence(context, sourceSection,
writeArrayNode,
new NotNode(context, sourceSection, new IsNilNode(context, sourceSection, new ReadLocalVariableNode(context, sourceSection, arraySlot))));
final RubyNode arrayWasNotNil = sequence(context, sourceSection, Arrays.asList(writeArrayNode, new NotNode(context, sourceSection, new IsNilNode(context, sourceSection, new ReadLocalVariableNode(context, sourceSection, arraySlot)))));

final RubyNode shouldDestructureAndArrayWasNotNil = new AndNode(context, sourceSection,
shouldDestructure,
@@ -122,9 +121,7 @@ public BlockDefinitionNode compileBlockNode(SourceSection sourceSection, String
preludeProc = loadArguments;
}

final RubyNode preludeLambda = SequenceNode.sequence(context, sourceSection,
CheckArityNode.create(context, sourceSection, arityForCheck),
NodeUtil.cloneNode(loadArguments));
final RubyNode preludeLambda = sequence(context, sourceSection, Arrays.asList(CheckArityNode.create(context, sourceSection, arityForCheck), NodeUtil.cloneNode(loadArguments)));

RubyNode body;

@@ -142,7 +139,7 @@ public BlockDefinitionNode compileBlockNode(SourceSection sourceSection, String
}

// Procs
final RubyNode bodyProc = new CatchForProcNode(context, SequenceNode.enclosing(sourceSection, body.getEncapsulatingSourceSection()), composeBody(preludeProc, NodeUtil.cloneNode(body)));
final RubyNode bodyProc = new CatchForProcNode(context, enclosing(sourceSection, body.getEncapsulatingSourceSection()), composeBody(preludeProc, NodeUtil.cloneNode(body)));

final RubyRootNode newRootNodeForProcs = new RubyRootNode(context, considerExtendingMethodToCoverEnd(bodyProc.getEncapsulatingSourceSection()), environment.getFrameDescriptor(), environment.getSharedMethodInfo(),
bodyProc, environment.needsDeclarationFrame());
@@ -194,12 +191,12 @@ private boolean shouldConsiderDestructuringArrayArg(Arity arity) {
}

private RubyNode composeBody(RubyNode prelude, RubyNode body) {
final SourceSection sourceSection = SequenceNode.enclosing(prelude.getSourceSection(), body.getSourceSection());
final SourceSection sourceSection = enclosing(prelude.getSourceSection(), body.getSourceSection());

body = SequenceNode.sequence(context, sourceSection, prelude, body);
body = sequence(context, sourceSection, Arrays.asList(prelude, body));

if (environment.getFlipFlopStates().size() > 0) {
body = SequenceNode.sequence(context, sourceSection, initFlipFlopStates(sourceSection), body);
body = sequence(context, sourceSection, Arrays.asList(initFlipFlopStates(sourceSection), body));
}

return body;
@@ -236,15 +233,13 @@ public RubyNode doCompileMethodBody(SourceSection sourceSection, String methodNa
// Use Rubinius.primitive seems to turn off arity checking. See Time.from_array for example.
prelude = loadArguments;
} else {
prelude = SequenceNode.sequence(context, sourceSection,
CheckArityNode.create(context, sourceSection, arity),
loadArguments);
prelude = sequence(context, sourceSection, Arrays.asList(CheckArityNode.create(context, sourceSection, arity), loadArguments));
}

body = SequenceNode.sequence(context, body.getSourceSection(), prelude, body);
body = sequence(context, body.getSourceSection(), Arrays.asList(prelude, body));

if (environment.getFlipFlopStates().size() > 0) {
body = SequenceNode.sequence(context, body.getSourceSection(), initFlipFlopStates(sourceSection), body);
body = sequence(context, body.getSourceSection(), Arrays.asList(initFlipFlopStates(sourceSection), body));
}

body = new CatchForMethodNode(context, body.getSourceSection(), body, environment.getReturnID());
Original file line number Diff line number Diff line change
@@ -77,7 +77,7 @@ public RubyNode visitArgsNode(org.jruby.ast.ArgsNode node) {
System.err.println("WARNING: kwargs in zsuper not yet implemented at " + sourceSection.getShortDescription());
}

return SequenceNode.sequenceNoFlatten(context, sourceSection, sequence);
return new SequenceNode(context, sourceSection, sequence.toArray(new RubyNode[sequence.size()]));
}

@Override
Original file line number Diff line number Diff line change
@@ -15,13 +15,17 @@
import org.jruby.lexer.yacc.InvalidSourcePosition;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.SequenceNode;
import org.jruby.truffle.language.literal.LiteralNode;
import org.jruby.truffle.language.literal.NilNode;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public abstract class Translator extends org.jruby.ast.visitor.AbstractNodeVisitor<RubyNode> {
@@ -41,6 +45,91 @@ public Translator(Node currentNode, RubyContext context, Source source) {
this.source = source;
}

public static RubyNode sequence(RubyContext context, SourceSection sourceSection, List<RubyNode> sequence) {
final List<RubyNode> flattened = flatten(context, sequence, true);

if (flattened.isEmpty()) {
return new NilNode(context, sourceSection);
} else if (flattened.size() == 1) {
return flattened.get(0);
} else {
final RubyNode[] flatSequence = flattened.toArray(new RubyNode[flattened.size()]);
return new SequenceNode(context, enclosing(sourceSection, flatSequence), flatSequence);
}
}

public static SourceSection enclosing(SourceSection base, SourceSection... sourceSections) {
if (base.getSource() == null) {
return base;
}

if (sourceSections.length == 0) {
return base;
}

int startLine = base.getStartLine();
int endLine = base.getEndLine();

for (SourceSection sourceSection : sourceSections) {
startLine = Math.min(startLine, sourceSection.getStartLine());

final int nodeEndLine;

if (sourceSection.getSource() == null) {
nodeEndLine = sourceSection.getStartLine();
} else {
nodeEndLine = sourceSection.getEndLine();
}

endLine = Math.max(endLine, nodeEndLine);
}

final int index = base.getSource().getLineStartOffset(startLine);

int length = 0;

for (int n = startLine; n <= endLine; n++) {
// + 1 because the line length doesn't include any newlines
length += base.getSource().getLineLength(n) + 1;
}

length = Math.min(length, base.getSource().getLength() - index);
length = Math.max(0, length);

return base.getSource().createSection(base.getIdentifier(), index, length);
}

public static SourceSection enclosing(SourceSection base, RubyNode[] sequence) {
final SourceSection[] sourceSections = new SourceSection[sequence.length];

for (int n = 0; n < sequence.length; n++) {
sourceSections[n] = sequence[n].getEncapsulatingSourceSection();
}

return enclosing(base, sourceSections);
}

private static List<RubyNode> flatten(RubyContext context, List<RubyNode> sequence, boolean allowTrailingNil) {
final List<RubyNode> flattened = new ArrayList<>();

for (int n = 0; n < sequence.size(); n++) {
final boolean lastNode = n == sequence.size() - 1;
final RubyNode node = sequence.get(n);

if (node instanceof NilNode || (node instanceof LiteralNode && ((LiteralNode) node).getObject() == context.getCoreLibrary().getNilObject())) {
if (allowTrailingNil && lastNode) {
flattened.add(node);
}
} else if (node instanceof SequenceNode) {
flattened.addAll(flatten(context, Arrays.asList(((SequenceNode) node).getSequence()), lastNode));
} else {
flattened.add(node);
}
}

return flattened;
}

protected SourceSection translate(org.jruby.lexer.yacc.ISourcePosition sourcePosition) {
return translate(source, sourcePosition, getIdentifier());
}
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TranslatorDriver {
@@ -175,13 +176,13 @@ private RubyRootNode parse(Node currentNode, RubyContext context, Source source,
}

sequence.add(truffleNode);
truffleNode = SequenceNode.sequence(context, sourceSection, sequence);
truffleNode = Translator.sequence(context, sourceSection, sequence);
}

// Load flip-flop states

if (environment.getFlipFlopStates().size() > 0) {
truffleNode = SequenceNode.sequence(context, truffleNode.getSourceSection(), translator.initFlipFlopStates(truffleNode.getSourceSection()), truffleNode);
truffleNode = Translator.sequence(context, truffleNode.getSourceSection(), Arrays.asList(translator.initFlipFlopStates(truffleNode.getSourceSection()), truffleNode));
}

// Catch next
6 changes: 6 additions & 0 deletions truffle/src/main/ruby/core/shims.rb
Original file line number Diff line number Diff line change
@@ -280,3 +280,9 @@ def self.add_rejected_kwargs_to_rest(rest, kwargs)
end
end
end

def when_splat(cases, expression)
cases.any? do |c|
c === expression
end
end