Skip to content

Commit

Permalink
Merge branch 'master' into truffle-head
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed May 29, 2015
2 parents e26c54f + 18e602d commit 33768a5
Show file tree
Hide file tree
Showing 25 changed files with 166 additions and 119 deletions.
17 changes: 4 additions & 13 deletions core/src/main/java/org/jruby/RubyArgsFile.java
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}
Expand Down
10 changes: 0 additions & 10 deletions core/src/main/java/org/jruby/RubyGlobal.java
Expand Up @@ -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);
}
Expand Down
8 changes: 7 additions & 1 deletion core/src/main/java/org/jruby/RubyKernel.java
Expand Up @@ -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)
Expand Down
5 changes: 1 addition & 4 deletions core/src/main/java/org/jruby/ext/ffi/AbstractMemory.java
Expand Up @@ -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>
*
Expand Down
21 changes: 10 additions & 11 deletions core/src/main/java/org/jruby/util/io/OpenFile.java
Expand Up @@ -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();
Expand Down
2 changes: 2 additions & 0 deletions lib/pom.rb
Expand Up @@ -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,
Expand Down
6 changes: 5 additions & 1 deletion lib/pom.xml
Expand Up @@ -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>
Expand Down
9 changes: 9 additions & 0 deletions spec/ffi/pointer_spec.rb
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions spec/ruby/language/break_spec.rb
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions spec/ruby/language/fixtures/break.rb
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion spec/truffle/tags/core/process/setrlimit_tags.txt
Expand Up @@ -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
Expand Up @@ -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
Expand Down
7 changes: 2 additions & 5 deletions test/pom.rb
Expand Up @@ -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
Expand Down
Expand Up @@ -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));
}

}
Expand Up @@ -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);
Expand Down
Expand Up @@ -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;
}

}
Expand Down
Expand Up @@ -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.
Expand All @@ -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;

Expand All @@ -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
Expand Down
Expand Up @@ -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
Expand All @@ -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;
Expand Down

0 comments on commit 33768a5

Please sign in to comment.