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: 09552e5ff9ce
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 745848c2eec9
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Jan 12, 2015

  1. Copy the full SHA
    6199447 View commit details
  2. Copy the full SHA
    745848c View commit details
Showing with 18 additions and 9 deletions.
  1. +18 −9 core/src/main/java/org/jruby/truffle/nodes/rubinius/RubiniusSingleBlockArgNode.java
Original file line number Diff line number Diff line change
@@ -12,12 +12,16 @@

import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;

public class RubiniusSingleBlockArgNode extends RubyNode {
private final ConditionProfile emptyArgsProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile singleArgProfile = ConditionProfile.createBinaryProfile();

public RubiniusSingleBlockArgNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}
@@ -30,21 +34,26 @@ public Object execute(VirtualFrame frame) {
* This is our implementation of Rubinius.single_block_arg.
*
* In Rubinius, this method inspects the values yielded to the block, regardless of whether the block
* captures the values, and returns the first yielded value.
* captures the values, and returns the first value in the list of values yielded to the block.
*
* NB: In our case the arguments have already been destructured by the time this node is encountered.
* Thus, we don't need to do the destructuring work that Rubinius would do and in the case that we receive
* multiple arguments we need to reverse the destructuring by collecting the values into an array.
*/

int userArgumentCount = RubyArguments.getUserArgumentsCount(frame.getArguments());

if (userArgumentCount == 1) {
return RubyArguments.getUserArgument(frame.getArguments(), 0);

} else if (userArgumentCount > 1) {
Object[] extractedArguments = RubyArguments.extractUserArguments(frame.getArguments());
if (emptyArgsProfile.profile(userArgumentCount == 0)) {
return getContext().getCoreLibrary().getNilObject();
} else {
if (singleArgProfile.profile(userArgumentCount == 1)) {
return RubyArguments.getUserArgument(frame.getArguments(), 0);

return RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(), extractedArguments);
} else {
Object[] extractedArguments = RubyArguments.extractUserArguments(frame.getArguments());

} else {
return getContext().getCoreLibrary().getNilObject();
return RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(), extractedArguments);
}
}
}
}