Skip to content

Commit

Permalink
Showing 25 changed files with 166 additions and 119 deletions.
17 changes: 4 additions & 13 deletions core/src/main/java/org/jruby/RubyArgsFile.java
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@
import java.io.IOException;
import static org.jruby.RubyEnumerator.enumeratorize;

import org.jruby.anno.FrameField;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.RaiseException;
import jnr.posix.FileStat;
@@ -239,6 +240,7 @@ public static IRubyObject external_encoding(ThreadContext context, IRubyObject r
return ((RubyIO) getData(context, recv, "no stream to set encoding").currentFile).external_encoding(context);
}

// MRI: argf_getline
private static IRubyObject argf_getline(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
ArgsFileData data = ArgsFileData.getDataFrom(recv);

@@ -269,21 +271,10 @@ private static IRubyObject argf_getline(ThreadContext context, IRubyObject recv,
/** Read a line.
*
*/
@JRubyMethod(name = "gets", optional = 1)
@JRubyMethod(name = "gets", optional = 1, writes = FrameField.LASTLINE)
public static IRubyObject gets(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
ArgsFileData data = ArgsFileData.getDataFrom(recv);

if (!data.next_argv(context)) return context.runtime.getNil();

IRubyObject line;
if (!(data.currentFile instanceof RubyIO)) {
line = data.currentFile.callMethod(context, "gets", args);
} else {
line = argf_getline(context, recv, args);
}

IRubyObject line = argf_getline(context, recv, args);
context.setLastLine(line);
context.runtime.getGlobalVariables().set("$_", line);

return line;
}
10 changes: 0 additions & 10 deletions core/src/main/java/org/jruby/RubyGlobal.java
Original file line number Diff line number Diff line change
@@ -286,19 +286,9 @@ private static Channel prepareStdioChannel(Ruby runtime, STDIO stdio, Object str
} else {
switch (stdio) {
case IN:
stream = ShellLauncher.unwrapFilterInputStream((InputStream)stream);
if (stream instanceof FileInputStream) {
return ((FileInputStream)stream).getChannel();
}

return Channels.newChannel((InputStream)stream);
case OUT:
case ERR:
stream = ShellLauncher.unwrapFilterOutputStream((OutputStream)stream);
if (stream instanceof FileOutputStream) {
return ((FileOutputStream)stream).getChannel();
}

return Channels.newChannel((OutputStream)stream);
default: throw new RuntimeException("invalid stdio: " + stdio);
}
8 changes: 7 additions & 1 deletion core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -318,9 +318,15 @@ public static IRubyObject getc(ThreadContext context, IRubyObject recv) {
return defin.callMethod(context, "getc");
}

// MRI: rb_f_gets
@JRubyMethod(optional = 1, module = true, visibility = PRIVATE)
public static IRubyObject gets(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
return RubyArgsFile.gets(context, context.runtime.getArgsFile(), args);
Ruby runtime = context.runtime;

if (recv == runtime.getArgsFile()) {
return RubyArgsFile.gets(context, runtime.getArgsFile(), args);
}
return runtime.getArgsFile().callMethod(context, "gets", args);
}

@JRubyMethod(optional = 1, module = true, visibility = PRIVATE)
5 changes: 1 addition & 4 deletions core/src/main/java/org/jruby/ext/ffi/AbstractMemory.java
Original file line number Diff line number Diff line change
@@ -194,10 +194,7 @@ public boolean equals(Object obj) {
public IRubyObject op_equal(ThreadContext context, IRubyObject obj) {
return context.runtime.newBoolean(this.equals(obj));
}
@Override
public final boolean eql(IRubyObject other) {
return this.equals(other);
}

/**
* Calculates the hash code for this <tt>MemoryPointer</tt>
*
21 changes: 10 additions & 11 deletions core/src/main/java/org/jruby/util/io/OpenFile.java
Original file line number Diff line number Diff line change
@@ -1398,18 +1398,17 @@ boolean waitReadable(ThreadContext context, ChannelFD fd) {
}
}

// kinda-hacky way to see if there's more data to read from a seekable channel
/*
Seekable channels (usually FileChannel) are treated as ready always. There are
three kinds we typically see:
1. files, which always select(2) as ready
2. stdio, which we can't select and can't check .size for available data
3. subprocess stdio, which we can't select and can't check .size either
In all three cases, without native fd logic, we can't do anything to determine
if the stream is ready, so we just assume it is and hope for the best.
*/
if (fd.chSeek != null) {
FileChannel fdSeek = fd.chSeek;
try {
// not a real file, can't get size...we'll have to just read and block
if (fdSeek.size() < 0) return true;

// if current position is less than file size, read should not block
return fdSeek.position() < fdSeek.size();
} catch (IOException ioe) {
throw context.runtime.newIOErrorFromException(ioe);
}
return true;
}
} finally {
if (locked) unlock();
2 changes: 2 additions & 0 deletions lib/pom.rb
Original file line number Diff line number Diff line change
@@ -70,6 +70,8 @@ def to_pathname
jar "org.jruby:jruby-core:#{version}", :scope => 'test'

repository( :url => 'http://rubygems-proxy.torquebox.org/releases',
:id => 'tb-rubygems-releases' )
repository( :url => 'https://otto.takari.io/content/repositories/rubygems/maven/releases',
:id => 'rubygems-releases' )

plugin( :clean,
6 changes: 5 additions & 1 deletion lib/pom.xml
Original file line number Diff line number Diff line change
@@ -164,9 +164,13 @@
</dependencies>
<repositories>
<repository>
<id>rubygems-releases</id>
<id>tb-rubygems-releases</id>
<url>http://rubygems-proxy.torquebox.org/releases</url>
</repository>
<repository>
<id>rubygems-releases</id>
<url>https://otto.takari.io/content/repositories/rubygems/maven/releases</url>
</repository>
</repositories>
<build>
<resources>
9 changes: 9 additions & 0 deletions spec/ffi/pointer_spec.rb
Original file line number Diff line number Diff line change
@@ -138,6 +138,15 @@ def to_ptr
expect(FFI::MemoryPointer.new(:int, 1).type_size).to eq(FFI.type_size(:int))
end
end

it "is not eql? for purposes of hash lookup (GH-2995)" do
a = FFI::Pointer.new(0)
b = FFI::Pointer.new(0)

expect(a == b).to eq true
expect(a.eql? b).to eq false
expect(Hash[a,true][b]).to eq nil
end
end

describe "AutoPointer" do
8 changes: 8 additions & 0 deletions spec/ruby/language/break_spec.rb
Original file line number Diff line number Diff line change
@@ -16,6 +16,14 @@
@program.break_value
ScratchPad.recorded.should == [:a, :aa, :b, :break, :d]
end

describe "yielded inside a while" do
it "breaks out of the block" do
value = @program.break_in_block_in_while
ScratchPad.recorded.should == [:aa, :break]
value.should == :value
end
end
end

describe "The break statement in a captured block" do
19 changes: 19 additions & 0 deletions spec/ruby/language/fixtures/break.rb
Original file line number Diff line number Diff line change
@@ -109,6 +109,25 @@ def break_in_yielding_method
def method(v)
yield v
end

def invoke_yield_in_while
looping = true
while looping
note :aa
yield
note :bb
looping = false
end
note :should_not_reach_here
end

def break_in_block_in_while
invoke_yield_in_while do
note :break
break :value
note :c
end
end
end

class Lambda < Driver
3 changes: 2 additions & 1 deletion spec/truffle/tags/core/process/setrlimit_tags.txt
Original file line number Diff line number Diff line change
@@ -34,4 +34,5 @@ fails:Process.setrlimit when passed a String coerces 'RTPRIO' into RLIMIT_RTPRIO
fails:Process.setrlimit when passed a String coerces 'SIGPENDING' into RLIMIT_SIGPENDING
fails:Process.setrlimit when passed a String coerces 'MSGQUEUE' into RLIMIT_MSGQUEUE
fails:Process.setrlimit when passed a String coerces 'NICE' into RLIMIT_NICE

fails:Process.setrlimit when passed a Symbol coerces :RTTIME into RLIMIT_RTTIME
fails:Process.setrlimit when passed a String coerces 'RTTIME' into RLIMIT_RTTIME
2 changes: 1 addition & 1 deletion test/check_versions.sh
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ check maven/jruby-jars/lib/jruby-stdlib-$jar_version.jar 8
check maven/jruby-complete/target/jruby-complete-$jar_version.jar 27
check maven/jruby/target/jruby-$jar_version.jar 9
check maven/jruby-dist/target/jruby-dist-$jar_version-bin.tar.gz 45 jruby-$jar_version
check maven/jruby-dist/target/jruby-dist-$jar_version-bin200.tar.gz 17 jruby-$jar_version
check maven/jruby-dist/target/jruby-dist-$jar_version-bin200.tar.gz 19 jruby-$jar_version
check maven/jruby-dist/target/jruby-dist-$jar_version-src.zip 14 jruby-$jar_version
check maven/jruby-dist/target/jruby-dist-$jar_version-bin.zip 45 jruby-$jar_version
check core/target/jruby-core-$jar_version.jar 9
7 changes: 2 additions & 5 deletions test/pom.rb
Original file line number Diff line number Diff line change
@@ -38,12 +38,9 @@ def truffle_spec_config(spec_type, generate_report)
id 'org.jruby:jruby-tests'

repository( 'http://rubygems-proxy.torquebox.org/releases',
:id => 'tb-rubygems-releases' )
repository( :url => 'https://otto.takari.io/content/repositories/rubygems/maven/releases',
:id => 'rubygems-releases' )
repository( 'http://rubygems-proxy.torquebox.org/prereleases',
:id => 'rubygems-prereleases' ) do
releases 'false'
snapshots 'true'
end

plugin_repository( 'https://oss.sonatype.org/content/repositories/snapshots/',
:id => 'sonatype' ) do
Original file line number Diff line number Diff line change
@@ -14,23 +14,23 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.BreakException;
import org.jruby.truffle.translator.TranslatorEnvironment.BlockID;
import org.jruby.truffle.translator.TranslatorEnvironment.BreakID;

public class BreakNode extends RubyNode {

private final BlockID blockID;
private final BreakID breakID;

@Child private RubyNode child;

public BreakNode(RubyContext context, SourceSection sourceSection, BlockID blockID, RubyNode child) {
public BreakNode(RubyContext context, SourceSection sourceSection, BreakID breakID, RubyNode child) {
super(context, sourceSection);
this.blockID = blockID;
this.breakID = breakID;
this.child = child;
}

@Override
public Object execute(VirtualFrame frame) {
throw new BreakException(blockID, child.execute(frame));
throw new BreakException(breakID, child.execute(frame));
}

}
Original file line number Diff line number Diff line change
@@ -102,17 +102,23 @@ private void addCoreMethod(MethodDetails methodDetails) {
if (method.onSingleton()) {
System.err.println("WARNING: Either onSingleton or isModuleFunction for " + methodDetails.getIndicativeName());
}
if (method.constructor()) {
System.err.println("WARNING: Either constructor or isModuleFunction for " + methodDetails.getIndicativeName());
}
if (!module.isOnlyAModule()) {
System.err.println("WARNING: Using isModuleFunction on a Class for " + methodDetails.getIndicativeName());
}
}
if (method.onSingleton() && method.constructor()) {
System.err.println("WARNING: Either onSingleton or isModuleFunction for " + methodDetails.getIndicativeName());
}

final RubyRootNode rootNode = makeGenericMethod(context, methodDetails);

if (method.isModuleFunction()) {
addMethod(module, rootNode, names, Visibility.PRIVATE);
addMethod(getSingletonClass(module), rootNode, names, Visibility.PUBLIC);
} else if (method.onSingleton()) {
} else if (method.onSingleton() || method.constructor()) {
addMethod(getSingletonClass(module), rootNode, names, visibility);
} else {
addMethod(module, rootNode, names, visibility);
Original file line number Diff line number Diff line change
@@ -34,18 +34,14 @@ public InitializeNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public RubyBasicObject initialize(RubyException exception, UndefinedPlaceholder message) {
CompilerDirectives.transferToInterpreter();

exception.initialize(nil());
return nil();
return exception;
}

@Specialization
@Specialization(guards = "!isUndefinedPlaceholder(message)")
public RubyBasicObject initialize(RubyException exception, Object message) {
CompilerDirectives.transferToInterpreter();

exception.initialize(message);
return nil();
return exception;
}

}
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.translator.TranslatorEnvironment.BlockID;
import org.jruby.truffle.translator.TranslatorEnvironment.BreakID;

/**
* Create a RubyProc to pass as a block to the called method.
@@ -37,11 +37,11 @@ public class BlockDefinitionNode extends RubyNode {
private final CallTarget callTargetForMethods;

private final boolean requiresDeclarationFrame;
private final BlockID blockID;
private final BreakID breakID;

public BlockDefinitionNode(RubyContext context, SourceSection sourceSection, SharedMethodInfo sharedMethodInfo,
boolean requiresDeclarationFrame, CallTarget callTargetForBlocks,
CallTarget callTargetForProcs, CallTarget callTargetForMethods, BlockID blockID) {
CallTarget callTargetForProcs, CallTarget callTargetForMethods, BreakID breakID) {
super(context, sourceSection);
this.sharedMethodInfo = sharedMethodInfo;

@@ -50,11 +50,11 @@ public BlockDefinitionNode(RubyContext context, SourceSection sourceSection, Sha
this.callTargetForMethods = callTargetForMethods;

this.requiresDeclarationFrame = requiresDeclarationFrame;
this.blockID = blockID;
this.breakID = breakID;
}

public BlockID getBlockID() {
return blockID;
public BreakID getBreakID() {
return breakID;
}

@Override
Original file line number Diff line number Diff line change
@@ -16,24 +16,25 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.BreakException;
import org.jruby.truffle.translator.TranslatorEnvironment.BlockID;
import org.jruby.truffle.translator.TranslatorEnvironment.BreakID;

/**
* Catch a {@code break} jump in a block at the top level and handle it as a return.
* Catch a {@code break} from a call with a block containing a break
* or inside a while/until loop.
*/
public class CatchBreakFromCallNode extends RubyNode {
public class CatchBreakNode extends RubyNode {

@Child private RubyNode body;

private final BlockID blockID;
private final BreakID breakID;

private final BranchProfile breakProfile = BranchProfile.create();
private final ConditionProfile matchingBreakProfile = ConditionProfile.createCountingProfile();

public CatchBreakFromCallNode(RubyContext context, SourceSection sourceSection, RubyNode body, BlockID blockID) {
public CatchBreakNode(RubyContext context, SourceSection sourceSection, RubyNode body, BreakID breakID) {
super(context, sourceSection);
this.body = body;
this.blockID = blockID;
this.breakID = breakID;
}

@Override
@@ -43,7 +44,7 @@ public Object execute(VirtualFrame frame) {
} catch (BreakException e) {
breakProfile.enter();

if (matchingBreakProfile.profile(e.getBlockID() == blockID)) {
if (matchingBreakProfile.profile(e.getBreakID() == breakID)) {
return e.getResult();
} else {
throw e;
Original file line number Diff line number Diff line change
@@ -197,7 +197,7 @@ public boolean setAutorelease(RubyBasicObject pointer, boolean autorelease) {

}

@RubiniusPrimitive(name = "pointer_set_at_offset", lowerFixnumParameters = {0, 2})
@RubiniusPrimitive(name = "pointer_set_at_offset", lowerFixnumParameters = {0, 1})
@ImportStatic(RubiniusTypes.class)
public static abstract class PointerSetAtOffsetPrimitiveNode extends RubiniusPrimitiveNode {

@@ -206,11 +206,17 @@ public PointerSetAtOffsetPrimitiveNode(RubyContext context, SourceSection source
}

@Specialization(guards = "type == TYPE_INT")
public int setAtOffset(RubyBasicObject pointer, int offset, int type, int value) {
public int setAtOffsetInt(RubyBasicObject pointer, int offset, int type, int value) {
getPointer(pointer).putInt(offset, value);
return value;
}

@Specialization(guards = "type == TYPE_LONG")
public long setAtOffsetLong(RubyBasicObject pointer, int offset, int type, long value) {
getPointer(pointer).putLong(offset, value);
return value;
}

}

@RubiniusPrimitive(name = "pointer_read_pointer")
Original file line number Diff line number Diff line change
@@ -10,23 +10,23 @@
package org.jruby.truffle.runtime.control;

import com.oracle.truffle.api.nodes.ControlFlowException;
import org.jruby.truffle.translator.TranslatorEnvironment.BlockID;
import org.jruby.truffle.translator.TranslatorEnvironment.BreakID;

/**
* Controls a break from a control structure or method.
*/
public final class BreakException extends ControlFlowException {

private final BlockID blockID;
private final BreakID breakID;
private final Object result;

public BreakException(BlockID blockID, Object result) {
this.blockID = blockID;
public BreakException(BreakID breakID, Object result) {
this.breakID = breakID;
this.result = result;
}

public BlockID getBlockID() {
return blockID;
public BreakID getBreakID() {
return breakID;
}

public Object getResult() {
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;

import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
@@ -77,6 +78,7 @@
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.truffle.translator.TranslatorEnvironment.BreakID;
import org.jruby.util.ByteList;
import org.jruby.util.KeyValuePair;
import org.jruby.util.StringSupport;
@@ -367,12 +369,7 @@ public RubyNode visitBlockNode(org.jruby.ast.BlockNode node) {

@Override
public RubyNode visitBreakNode(org.jruby.ast.BreakNode node) {
if (!(environment.isBlock() || translatingWhile)) {
// TODO(CS 10-Jan-15): must raise a proper exception rather, but not sure if it should be a JRuby exception or a Truffle one
System.err.printf("%s:%d: Invalid break%n", node.getPosition().getFile(), node.getPosition().getLine() + 1);
System.err.printf("%s: compile error (SyntaxError)%n", node.getPosition().getFile());
System.exit(1);
}
assert environment.isBlock() || translatingWhile : "The parser did not see an invalid break";

final SourceSection sourceSection = translate(node.getPosition());

@@ -390,7 +387,7 @@ public RubyNode visitBreakNode(org.jruby.ast.BreakNode node) {
resultNode = node.getValueNode().accept(this);
}

return new BreakNode(context, sourceSection, environment.getBlockID(), resultNode);
return new BreakNode(context, sourceSection, environment.getBreakID(), resultNode);
}

@Override
@@ -616,7 +613,7 @@ public RubyNode visitCallNodeExtraArgument(CallNode node, RubyNode extraArgument

if (argumentsAndBlock.getBlock() instanceof BlockDefinitionNode) { // if we have a literal block, break breaks out of this call site
BlockDefinitionNode blockDef = (BlockDefinitionNode) argumentsAndBlock.getBlock();
translated = new CatchBreakFromCallNode(context, sourceSection, translated, blockDef.getBlockID());
translated = new CatchBreakNode(context, sourceSection, translated, blockDef.getBreakID());
}

// return instrumenter.instrumentAsCall(translated, node.getName());
@@ -685,6 +682,18 @@ protected ArgumentsAndBlockTranslation translateArgumentsAndBlock(SourceSection
arguments.add(argsNode);
}

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

for (org.jruby.ast.Node argument : arguments) {
argumentsTranslated.add(argument.accept(this));
}

if (extraArgument != null) {
argumentsTranslated.add(extraArgument);
}

final RubyNode[] argumentsTranslatedArray = argumentsTranslated.toArray(new RubyNode[argumentsTranslated.size()]);

if (iterNode instanceof org.jruby.ast.BlockPassNode) {
blockPassNode = ((org.jruby.ast.BlockPassNode) iterNode).getBodyNode();
}
@@ -705,18 +714,6 @@ protected ArgumentsAndBlockTranslation translateArgumentsAndBlock(SourceSection
blockTranslated = null;
}

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

for (org.jruby.ast.Node argument : arguments) {
argumentsTranslated.add(argument.accept(this));
}

if (extraArgument != null) {
argumentsTranslated.add(extraArgument);
}

final RubyNode[] argumentsTranslatedArray = argumentsTranslated.toArray(new RubyNode[argumentsTranslated.size()]);

return new ArgumentsAndBlockTranslation(blockTranslated, argumentsTranslatedArray, isSplatted);
}

@@ -1060,7 +1057,12 @@ public RubyNode visitDVarNode(org.jruby.ast.DVarNode node) {
}

e.declareVar(node.getName());
readNode = e.findLocalVarNode(node.getName(), translate(node.getPosition()));

// Searching for a local variable must start at the base environment, even though we may have determined
// the variable should be declared in a parent frame descriptor. This is so the search can determine
// whether to return a ReadLocalVariableNode or a ReadDeclarationVariableNode and potentially record the
// fact that a declaration frame is needed.
readNode = environment.findLocalVarNode(node.getName(), translate(node.getPosition()));
}

return readNode;
@@ -1712,7 +1714,7 @@ public RubyNode visitIterNode(org.jruby.ast.IterNode node) {

final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(
context, environment, environment.getParseEnvironment(), environment.getReturnID(), hasOwnScope, false,
sharedMethodInfo, environment.getNamedMethodName(), true, environment.getParseEnvironment().allocateBlockID());
sharedMethodInfo, environment.getNamedMethodName(), true, environment.getParseEnvironment().allocateBreakID());
final MethodTranslator methodCompiler = new MethodTranslator(currentNode, context, this, newEnvironment, true, source, argsNode);
methodCompiler.translatingForStatement = translatingForStatement;

@@ -2726,8 +2728,12 @@ private RubyNode visitWhileNode(org.jruby.ast.WhileNode node, boolean conditionI
}

final RubyNode body;
final BreakID whileBreakID = environment.getParseEnvironment().allocateBreakID();

final boolean oldTranslatingWhile = translatingWhile;
translatingWhile = true;
BreakID oldBreakID = environment.getBreakID();
environment.setBreakIDForWhile(whileBreakID);
try {
if (node.getBodyNode().isNil()) {
body = new DefinedWrapperNode(context, sourceSection,
@@ -2737,6 +2743,7 @@ private RubyNode visitWhileNode(org.jruby.ast.WhileNode node, boolean conditionI
body = node.getBodyNode().accept(this);
}
} finally {
environment.setBreakIDForWhile(oldBreakID);
translatingWhile = oldTranslatingWhile;
}

@@ -2748,7 +2755,7 @@ private RubyNode visitWhileNode(org.jruby.ast.WhileNode node, boolean conditionI
loop = WhileNode.createDoWhile(context, sourceSection, condition, body);
}

return new CatchBreakFromCallNode(context, sourceSection, loop, environment.getBlockID());
return new CatchBreakNode(context, sourceSection, loop, whileBreakID);
}

@Override
@@ -2842,7 +2849,7 @@ public RubyNode visitLambdaNode(org.jruby.ast.LambdaNode node) {

final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(
context, environment, environment.getParseEnvironment(), environment.getReturnID(), false, false,
sharedMethodInfo, sharedMethodInfo.getName(), true, environment.getParseEnvironment().allocateBlockID());
sharedMethodInfo, sharedMethodInfo.getName(), true, environment.getParseEnvironment().allocateBreakID());
final MethodTranslator methodCompiler = new MethodTranslator(currentNode, context, this, newEnvironment, false, source, argsNode);

final RubyNode definitionNode = methodCompiler.compileFunctionNode(translate(node.getPosition()), sharedMethodInfo.getName(), node.getBodyNode(), sharedMethodInfo);
Original file line number Diff line number Diff line change
@@ -243,7 +243,7 @@ public RubyNode compileFunctionNode(SourceSection sourceSection, String methodNa
final CallTarget callTargetAsMethod = Truffle.getRuntime().createCallTarget(newRootNodeWithCatchReturn);

return new BlockDefinitionNode(context, sourceSection, environment.getSharedMethodInfo(),
environment.needsDeclarationFrame(), callTargetAsBlock, callTargetAsProc, callTargetAsMethod, environment.getBlockID());
environment.needsDeclarationFrame(), callTargetAsBlock, callTargetAsProc, callTargetAsMethod, environment.getBreakID());
} else {
return new MethodDefinitionNode(context, sourceSection, methodName, environment.getSharedMethodInfo(),
environment.needsDeclarationFrame(), Truffle.getRuntime().createCallTarget(rootNode));
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@

import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.translator.TranslatorEnvironment.BlockID;
import org.jruby.truffle.translator.TranslatorEnvironment.BreakID;

/**
* Translator environment, unique per parse/translation.
@@ -48,8 +48,8 @@ public long allocateReturnID() {
return allocated;
}

public BlockID allocateBlockID() {
return new BlockID();
public BreakID allocateBreakID() {
return new BreakID();
}

}
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@

public class TranslatorEnvironment {

public static class BlockID {
public static class BreakID {
};

private final RubyContext context;
@@ -38,7 +38,7 @@ public static class BlockID {

private final long returnID;
private final boolean isBlock;
private final BlockID blockID;
private BreakID breakID;

private final boolean ownScopeForAssignments;
private final boolean neverAssignInParentScope;
@@ -56,7 +56,7 @@ public static class BlockID {

public TranslatorEnvironment(RubyContext context, TranslatorEnvironment parent, ParseEnvironment parseEnvironment,
long returnID, boolean ownScopeForAssignments, boolean neverAssignInParentScope,
SharedMethodInfo sharedMethodInfo, String namedMethodName, boolean isBlock, BlockID blockID,
SharedMethodInfo sharedMethodInfo, String namedMethodName, boolean isBlock, BreakID breakID,
FrameDescriptor frameDescriptor) {
this.context = context;
this.parent = parent;
@@ -67,15 +67,14 @@ public TranslatorEnvironment(RubyContext context, TranslatorEnvironment parent,
this.neverAssignInParentScope = neverAssignInParentScope;
this.sharedMethodInfo = sharedMethodInfo;
this.namedMethodName = namedMethodName;
assert isBlock == (blockID != null);
this.isBlock = isBlock;
this.blockID = blockID;
this.breakID = breakID;
}

public TranslatorEnvironment(RubyContext context, TranslatorEnvironment parent, ParseEnvironment parseEnvironment,
long returnID, boolean ownScopeForAssignments, boolean neverAssignInParentScope,
SharedMethodInfo methodIdentifier, String namedMethodName, boolean isBlock, BlockID blockID) {
this(context, parent, parseEnvironment, returnID, ownScopeForAssignments, neverAssignInParentScope, methodIdentifier, namedMethodName, isBlock, blockID,
SharedMethodInfo methodIdentifier, String namedMethodName, boolean isBlock, BreakID breakID) {
this(context, parent, parseEnvironment, returnID, ownScopeForAssignments, neverAssignInParentScope, methodIdentifier, namedMethodName, isBlock, breakID,
new FrameDescriptor(context.getCoreLibrary().getNilObject()));
}

@@ -221,7 +220,12 @@ public boolean isBlock() {
return isBlock;
}

public BlockID getBlockID() {
return blockID;
public BreakID getBreakID() {
return breakID;
}

public void setBreakIDForWhile(BreakID breakID) {
this.breakID = breakID;
}

}
6 changes: 5 additions & 1 deletion truffle/src/main/ruby/core/shims.rb
Original file line number Diff line number Diff line change
@@ -227,7 +227,11 @@ def locations
end

def to_s
message.to_s
if message.nil?
self.class.to_s
else
message.to_s
end
end

end

0 comments on commit 33768a5

Please sign in to comment.