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: 0ddeeeb8bc72
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bc7833214aad
Choose a head ref

Commits on May 22, 2015

  1. This is a fix for bug ID 2964. The URL to see the write up is here:

    #2964
    
    On windows the mvn -Ptest fails due to incorrect substitution of '/' and '\'.
    
     See the write up for more details.
    
     Cris Shupp
     Greg Bowman
    cngshow committed May 22, 2015
    Copy the full SHA
    6556c49 View commit details

Commits on Jul 7, 2015

  1. Copy the full SHA
    3bbaba8 View commit details
  2. Add spec for Module#prepend

    * When a module is prepended after and affects subclasses.
    eregon committed Jul 7, 2015
    Copy the full SHA
    096125d View commit details
  3. Copy the full SHA
    b61eeb1 View commit details
  4. [Truffle] Always create a PrependMarker.

    * Needed unless we have a linked list outside the RubyModule instance.
    eregon committed Jul 7, 2015
    Copy the full SHA
    c8f9ee8 View commit details
  5. Copy the full SHA
    1809625 View commit details
  6. Tag out new spec

    enebo committed Jul 7, 2015
    Copy the full SHA
    d038d97 View commit details
  7. Copy the full SHA
    c1d4d28 View commit details
  8. Copy the full SHA
    bf0ccc2 View commit details
  9. [Truffle] Added a constant-rewriting hack to support 3rd party code r…

    …elying on JRuby internals that JRuby+Truffle doesn't support.
    nirvdrum committed Jul 7, 2015
    2
    Copy the full SHA
    a5b4bbc View commit details
  10. Copy the full SHA
    5e4d2f8 View commit details
  11. Use our older open3 on Windows until we have spawn.

    This isn't really a fix for #3075 but it mitigates the issue for
    now and popen3 will at least be no *worse* than it was under 1.7.
    Remaining work for this will require getting spawn to work on
    Windows.
    
    Fixes #3075.
    headius committed Jul 7, 2015
    Copy the full SHA
    f417f92 View commit details
  12. Merge pull request #2973 from gpbowman-git/master

    This is a fix for bug ID 2964.  The URL to see the write up is here:
    headius committed Jul 7, 2015
    Copy the full SHA
    61ba53c View commit details

Commits on Jul 8, 2015

  1. Copy the full SHA
    1875515 View commit details
  2. [Truffle] Partial fix for zsuper calls in blocks.

    This fixes one very specific case of #3106: zsuper bug with blocks.
    nirvdrum committed Jul 8, 2015
    Copy the full SHA
    5f1babf View commit details
  3. Copy the full SHA
    3af7fe1 View commit details
  4. Copy the full SHA
    3dbb634 View commit details
  5. Copy the full SHA
    15f6d49 View commit details
  6. Copy the full SHA
    c4524a1 View commit details
  7. Copy the full SHA
    492fd74 View commit details
  8. Copy the full SHA
    84e8e8e View commit details
  9. Copy the full SHA
    8847061 View commit details
  10. Copy the full SHA
    fad35ba View commit details
  11. Copy the full SHA
    bc78332 View commit details
Showing with 936 additions and 75 deletions.
  1. +1 −0 core/src/main/java/org/jruby/runtime/ArgumentDescriptor.java
  2. +12 −1 core/src/main/java/org/jruby/runtime/ArgumentType.java
  3. +1 −1 core/src/main/java/org/jruby/runtime/Helpers.java
  4. +1 −1 core/src/main/java/org/jruby/util/JRubyFile.java
  5. +5 −4 core/src/test/java/org/jruby/test/TestKernel.java
  6. +731 −0 lib/ruby/stdlib/jruby/open3_windows.rb
  7. +8 −1 lib/ruby/stdlib/open3.rb
  8. +6 −0 spec/regression/GH-3086_anon_args_in_to_proc_parameters_spec.rb
  9. +17 −1 spec/ruby/core/module/prepend_spec.rb
  10. +1 −0 spec/tags/ruby/core/module/prepend_spec.txt
  11. +0 −5 spec/truffle/tags/core/string/modulo_tags.txt
  12. +0 −5 test/jruby/test_array.rb
  13. +2 −2 test/jruby/test_kernel.rb
  14. +1 −1 tool/truffle-findbugs.sh
  15. +8 −4 truffle/pom.rb
  16. +10 −6 truffle/pom.xml
  17. +4 −2 truffle/src/main/java/org/jruby/truffle/nodes/constants/ReadConstantNode.java
  18. +4 −4 truffle/src/main/java/org/jruby/truffle/nodes/core/TrufflePrimitiveNodes.java
  19. +14 −10 truffle/src/main/java/org/jruby/truffle/nodes/supercall/GeneralSuperReCallNode.java
  20. +23 −1 truffle/src/main/java/org/jruby/truffle/pack/nodes/write/WritePaddedBytesNode.java
  21. +7 −1 truffle/src/main/java/org/jruby/truffle/pack/parser/FormatDirective.java
  22. +2 −2 truffle/src/main/java/org/jruby/truffle/pack/parser/FormatParser.java
  23. +9 −2 truffle/src/main/java/org/jruby/truffle/pack/parser/FormatTokenizer.java
  24. +35 −0 truffle/src/main/java/org/jruby/truffle/runtime/ConstantReplacer.java
  25. +25 −19 truffle/src/main/java/org/jruby/truffle/runtime/core/RubyModule.java
  26. +1 −1 truffle/src/main/ruby/core/config.rb
  27. +5 −0 truffle/src/main/ruby/core/shims.rb
  28. +3 −1 truffle/src/test/java/org/jruby/truffle/tck/RubyTckTest.java
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ public class ArgumentDescriptor {
public static final ArgumentDescriptor[] EMPTY_ARRAY = new ArgumentDescriptor[0];

public ArgumentDescriptor(ArgumentType type, String name) {
assert name != null || type.anonymous : "null argument name given for non-anonymous argument type";
this.type = type;
this.name = name;
}
13 changes: 12 additions & 1 deletion core/src/main/java/org/jruby/runtime/ArgumentType.java
Original file line number Diff line number Diff line change
@@ -52,7 +52,18 @@ public String renderPrefixForm(String name) {
}

public RubyArray toArrayForm(Ruby runtime, String name) {
return anonymous ? runtime.newArray(runtime.newSymbol(symbolicName)) : runtime.newArray(runtime.newSymbol(symbolicName), runtime.newSymbol(name));
// we check for null name here as a precaution, since it will certainly blow up newSymbol (#3086)
return anonymous || name == null ? runtime.newArray(runtime.newSymbol(symbolicName)) : runtime.newArray(runtime.newSymbol(symbolicName), runtime.newSymbol(name));
}

public ArgumentType anonymousForm() {
switch (this) {
case opt: return anonopt;
case req: return anonreq;
case rest: return anonrest;
case keyrest: return anonkeyrest;
}
return this;
}

public final String symbolicName;
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/runtime/Helpers.java
Original file line number Diff line number Diff line change
@@ -2393,7 +2393,7 @@ public static ArgumentDescriptor[] parameterListToArgumentDescriptors(String[] p
if (param.length() > 1) {
parms[i] = new ArgumentDescriptor(type, param.substring(1));
} else {
parms[i] = new ArgumentDescriptor(type);
parms[i] = new ArgumentDescriptor(type.anonymousForm());
}
}

2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/util/JRubyFile.java
Original file line number Diff line number Diff line change
@@ -120,7 +120,7 @@ private static FileResource createResource(Ruby runtime, String cwd, String path

public static String normalizeSeps(String path) {
if (Platform.IS_WINDOWS) {
return path.replace(File.separatorChar, '/');
return path.replace('/', File.separatorChar);
} else {
return path;
}
9 changes: 5 additions & 4 deletions core/src/test/java/org/jruby/test/TestKernel.java
Original file line number Diff line number Diff line change
@@ -31,8 +31,7 @@
***** END LICENSE BLOCK *****/
package org.jruby.test;

import java.util.ArrayList;

import java.io.File;
import org.jruby.Ruby;
import org.jruby.RubyException;
import org.jruby.RubyFixnum;
@@ -61,15 +60,17 @@ public void testLoad() throws Exception {
assertEquals("load did not load the same file several times", "1", eval("load '../test/loadTest.rb'"));
}


public void testRequire() throws Exception {
char s = File.separatorChar;
//reset the $loadTestvar
eval("$loadTest = nil");
assertEquals("failed to load the file test/loadTest", "0", eval("require '../test/loadTest'"));
assertEquals("incorrectly reloaded the file test/loadTest", "", eval("require '../test/loadTest'"));

assertEquals("incorrect value for $\" variable", "true", eval("print $\"[-1].end_with?('test/loadTest.rb')"));
assertEquals("incorrect value for $\" variable", "true", eval("print $\"[-1].end_with?('test" + s + "loadTest.rb')"));
}


public void testPrintf() throws Exception {
assertEquals("hello", eval("printf(\"%s\", \"hello\")"));
assertEquals("", eval("printf(\"%s\", nil)"));
731 changes: 731 additions & 0 deletions lib/ruby/stdlib/jruby/open3_windows.rb

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion lib/ruby/stdlib/open3.rb
Original file line number Diff line number Diff line change
@@ -27,7 +27,14 @@
# - Open3.pipeline : run a pipeline and wait for its completion
#

module Open3
# Because spawn does not yet work on Windows, we fall back on the older open3 there.
real_open3 = true
if defined?(org) && org.jruby.platform.Platform::IS_WINDOWS
require 'jruby/open3_windows'
real_open3 = false
end

real_open3 && module Open3

# Open stdin, stdout, and stderr streams and start external executable.
# In addition, a thread to wait for the started process is created.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
describe 'A method with anonymous required arguments' do
it 'can to_proc and produce parameters without error' do
# anonymous required args built wrong, caused NPE (#3086)
method(:`).to_proc.parameters.should == [[:req]]
end
end
18 changes: 17 additions & 1 deletion spec/ruby/core/module/prepend_spec.rb
Original file line number Diff line number Diff line change
@@ -117,8 +117,12 @@ def self.prepend_features(mod)
m1 = Module.new { def calc(x) x end }
m2 = Module.new { prepend(m1) }
c1 = Class.new { prepend(m2) }
c2 = Class.new { prepend(m2.dup) }
m2dup = m2.dup
m2dup.ancestors.should == [m2dup,m1,m2]
c2 = Class.new { prepend(m2dup) }
c1.ancestors[0,3].should == [m1,m2,c1]
c1.new.should be_kind_of(m1)
c2.ancestors[0,4].should == [m2dup,m1,m2,c2]
c2.new.should be_kind_of(m1)
end

@@ -127,6 +131,18 @@ def self.prepend_features(mod)
Class.new { prepend(m) }.ancestors.should_not include(m)
end

it "adds the module in the subclass chains" do
parent = Class.new { def chain; [:parent]; end }
child = Class.new(parent) { def chain; super << :child; end }
mod = Module.new { def chain; super << :mod; end }
parent.prepend mod
parent.ancestors[0,2].should == [mod, parent]
child.ancestors[0,3].should == [child, mod, parent]

parent.new.chain.should == [:parent, :mod]
child.new.chain.should == [:parent, :mod, :child]
end

it "inserts a later prepended module into the chain" do
m1 = Module.new { def chain; super << :m1; end }
m2 = Module.new { def chain; super << :m2; end }
1 change: 1 addition & 0 deletions spec/tags/ruby/core/module/prepend_spec.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Module#prepend keeps the module in the chain when dupping an intermediate module
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/string/modulo_tags.txt
Original file line number Diff line number Diff line change
@@ -67,19 +67,14 @@ fails:String#% behaves as if calling Kernel#Integer for %o argument, if it does
fails:String#% tries to convert the passed argument to an Array using #to_ary
fails:String#% behaves as if calling Kernel#Float for %e arguments, when the passed argument does not respond to #to_ary
fails:String#% behaves as if calling Kernel#Float for %e arguments, when the passed argument is hexadecimal string
fails:String#% doesn't taint the result for %e when argument is tainted
fails:String#% behaves as if calling Kernel#Float for %E arguments, when the passed argument does not respond to #to_ary
fails:String#% behaves as if calling Kernel#Float for %E arguments, when the passed argument is hexadecimal string
fails:String#% doesn't taint the result for %E when argument is tainted
fails:String#% behaves as if calling Kernel#Float for %f arguments, when the passed argument does not respond to #to_ary
fails:String#% behaves as if calling Kernel#Float for %f arguments, when the passed argument is hexadecimal string
fails:String#% doesn't taint the result for %f when argument is tainted
fails:String#% behaves as if calling Kernel#Float for %g arguments, when the passed argument does not respond to #to_ary
fails:String#% behaves as if calling Kernel#Float for %g arguments, when the passed argument is hexadecimal string
fails:String#% doesn't taint the result for %g when argument is tainted
fails:String#% behaves as if calling Kernel#Float for %G arguments, when the passed argument does not respond to #to_ary
fails:String#% behaves as if calling Kernel#Float for %G arguments, when the passed argument is hexadecimal string
fails:String#% doesn't taint the result for %G when argument is tainted
fails:String#% when format string contains %{} sections replaces %{} sections with values from passed-in hash
fails:String#% when format string contains %{} sections raises KeyError if key is missing from passed-in hash
fails:String#% when format string contains %{} sections should raise ArgumentError if no hash given
5 changes: 0 additions & 5 deletions test/jruby/test_array.rb
Original file line number Diff line number Diff line change
@@ -24,11 +24,6 @@ def test_uniq_with_block_after_slice
assert_equal [1], [1, 1, 1][1,2].uniq! { |x| x }
end

def test_uniq_with_block_after_slice
assert_equal [1], [1, 1, 1][1,2].uniq { |x| x }
assert_equal [1], [1, 1, 1][1,2].uniq! { |x| x }
end

# JRUBY-4157
def test_shared_ary_slice
assert_equal [4,5,6], [1,2,3,4,5,6].slice(1,5).slice!(2,3)
4 changes: 2 additions & 2 deletions test/jruby/test_kernel.rb
Original file line number Diff line number Diff line change
@@ -106,11 +106,11 @@ def test_Float
# binding
# block_given?
class CheckBlockGiven; def self.go() block_given? end; end
def test_iterator?
def test_block_given?
assert !(Kernel.block_given?)
assert(CheckBlockGiven.go { true })
assert(!CheckBlockGiven.go)
assert(!CheckBlockGiven.go(&Proc.new))
assert(CheckBlockGiven.go(&Proc.new{}))
end

# callcc
2 changes: 1 addition & 1 deletion tool/truffle-findbugs.sh
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ else
ui_options=""
fi

mvn package || exit $?
./mvnw package || exit $?

version=3.0.0
shasum=30bdcee2c909a0eef61a4f60f4489cd2f5a4d21c
12 changes: 8 additions & 4 deletions truffle/pom.rb
Original file line number Diff line number Diff line change
@@ -15,10 +15,10 @@
repository( :url => 'http://lafo.ssw.uni-linz.ac.at/nexus/content/repositories/snapshots/',
:id => 'truffle' )

truffle_version = '0.8-cf1503da2456b46677cbf0ed286614d660126a1b-SNAPSHOT'
jar 'com.oracle:truffle:' + truffle_version
jar 'com.oracle:truffle-dsl-processor:' + truffle_version, :scope => 'provided'
jar 'com.oracle:truffle-tck:' + truffle_version, :scope => 'test'
truffle_version = '4858c5e074e9005075e89cf5b1c2347ee73a5d31-SNAPSHOT'
jar 'com.oracle.truffle:truffle:' + truffle_version
jar 'com.oracle.truffle:truffle-dsl-processor:' + truffle_version, :scope => 'provided'
jar 'com.oracle.truffle:truffle-tck:' + truffle_version, :scope => 'test'
jar 'junit:junit', :scope => 'test'

plugin( :compiler,
@@ -33,6 +33,10 @@
execute_goals( 'compile',
:id => 'default-compile',
:phase => 'compile',
'annotationProcessors' => [
'com.oracle.truffle.dsl.processor.TruffleProcessor',
'com.oracle.truffle.dsl.processor.LanguageRegistrationProcessor'
],
'generatedSourcesDirectory' => 'target/generated-sources',
'compilerArgs' => [ '-XDignore.symbol.file=true',
'-J-Duser.language=en',
16 changes: 10 additions & 6 deletions truffle/pom.xml
Original file line number Diff line number Diff line change
@@ -29,20 +29,20 @@ DO NOT MODIFIY - GENERATED CODE
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<groupId>com.oracle.truffle</groupId>
<artifactId>truffle</artifactId>
<version>0.8-cf1503da2456b46677cbf0ed286614d660126a1b-SNAPSHOT</version>
<version>4858c5e074e9005075e89cf5b1c2347ee73a5d31-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<groupId>com.oracle.truffle</groupId>
<artifactId>truffle-dsl-processor</artifactId>
<version>0.8-cf1503da2456b46677cbf0ed286614d660126a1b-SNAPSHOT</version>
<version>4858c5e074e9005075e89cf5b1c2347ee73a5d31-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<groupId>com.oracle.truffle</groupId>
<artifactId>truffle-tck</artifactId>
<version>0.8-cf1503da2456b46677cbf0ed286614d660126a1b-SNAPSHOT</version>
<version>4858c5e074e9005075e89cf5b1c2347ee73a5d31-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -78,6 +78,10 @@ DO NOT MODIFIY - GENERATED CODE
<goal>compile</goal>
</goals>
<configuration>
<annotationProcessors>
<annotationProcessor>com.oracle.truffle.dsl.processor.TruffleProcessor</annotationProcessor>
<annotationProcessor>com.oracle.truffle.dsl.processor.LanguageRegistrationProcessor</annotationProcessor>
</annotationProcessors>
<generatedSourcesDirectory>target/generated-sources</generatedSourcesDirectory>
<compilerArgs>
<compilerArg>-XDignore.symbol.file=true</compilerArg>
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.literal.LiteralNode;
import org.jruby.truffle.runtime.ConstantReplacer;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.RubyConstant;
import org.jruby.truffle.runtime.RubyContext;
@@ -26,9 +27,10 @@ public class ReadConstantNode extends RubyNode {

public ReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, LexicalScope lexicalScope) {
super(context, sourceSection);
this.name = name;

this.name = ConstantReplacer.replacementName(sourceSection, name);
this.getConstantNode =
GetConstantNodeGen.create(context, sourceSection, receiver, new LiteralNode(context, sourceSection, name),
GetConstantNodeGen.create(context, sourceSection, receiver, new LiteralNode(context, sourceSection, this.name),
LookupConstantNodeGen.create(context, sourceSection, lexicalScope, null, null));
}

Original file line number Diff line number Diff line change
@@ -433,16 +433,16 @@ public RubyBasicObject debugPrint(RubyString string) {

}

@CoreMethod(names = "home_directory", onSingleton = true)
public abstract static class HomeDirectoryNode extends CoreMethodNode {
@CoreMethod(names = "jruby_home_directory", onSingleton = true)
public abstract static class JRubyHomeDirectoryNode extends CoreMethodNode {

public HomeDirectoryNode(RubyContext context, SourceSection sourceSection) {
public JRubyHomeDirectoryNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@TruffleBoundary
@Specialization
public RubyBasicObject homeDirectory() {
public RubyBasicObject jrubyHomeDirectory() {
return createString(getContext().getRuntime().getJRubyHome());
}

Original file line number Diff line number Diff line change
@@ -64,17 +64,21 @@ public final Object execute(VirtualFrame frame) {
originalArguments = frame.getArguments();
}

// Reload the arguments
Object[] superArguments = new Object[reloadNodes.length];
for (int n = 0; n < superArguments.length; n++) {
superArguments[n] = reloadNodes[n].execute(frame);
}
Object[] superArguments = RubyArguments.extractUserArguments(originalArguments);

if (isSplatted) {
CompilerDirectives.transferToInterpreter();
assert superArguments.length == 1;
assert RubyGuards.isRubyArray(superArguments[0]);
superArguments = ArrayNodes.slowToArray(((RubyBasicObject) superArguments[0]));
if (!inBlock) {
// Reload the arguments
superArguments = new Object[reloadNodes.length];
for (int n = 0; n < superArguments.length; n++) {
superArguments[n] = reloadNodes[n].execute(frame);
}

if (isSplatted) {
CompilerDirectives.transferToInterpreter();
assert superArguments.length == 1;
assert RubyGuards.isRubyArray(superArguments[0]);
superArguments = ArrayNodes.slowToArray(((RubyBasicObject) superArguments[0]));
}
}

// Execute or inherit the block
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jruby.truffle.pack.nodes.PackNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.util.ByteList;
@@ -25,15 +26,36 @@
})
public abstract class WritePaddedBytesNode extends PackNode {

private final ConditionProfile leftJustifiedProfile = ConditionProfile.createBinaryProfile();
private final int padding;
private final boolean leftJustified;

public WritePaddedBytesNode(RubyContext context, int padding) {
public WritePaddedBytesNode(RubyContext context, int padding, boolean leftJustified) {
super(context);
this.padding = padding;
this.leftJustified = leftJustified;
}

@Specialization
public Object write(VirtualFrame frame, ByteList bytes) {
if (leftJustifiedProfile.profile(leftJustified)) {
return writeLeftJustified(frame, bytes);
} else {
return writeRightJustified(frame, bytes);
}
}

private Object writeLeftJustified(VirtualFrame frame, ByteList bytes) {
writeBytes(frame, bytes);

for (int n = 0; n < padding - bytes.length(); n++) {
writeByte(frame, (byte) ' ');
}

return null;
}

private Object writeRightJustified(VirtualFrame frame, ByteList bytes) {
for (int n = 0; n < padding - bytes.length(); n++) {
writeByte(frame, (byte) ' ');
}
Original file line number Diff line number Diff line change
@@ -20,12 +20,14 @@ public class FormatDirective {

private final int spacePadding;
private final int zeroPadding;
private final boolean leftJustified;
private final int precision;
private final char type;

public FormatDirective(int spacePadding, int zeroPadding, int precision, char type) {
public FormatDirective(int spacePadding, int zeroPadding, boolean leftJustified, int precision, char type) {
this.spacePadding = spacePadding;
this.zeroPadding = zeroPadding;
this.leftJustified = leftJustified;
this.precision = precision;
this.type = type;
}
@@ -38,6 +40,10 @@ public int getZeroPadding() {
return zeroPadding;
}

public boolean getLeftJustified() {
return leftJustified;
}

public int getPrecision() {
return precision;
}
Original file line number Diff line number Diff line change
@@ -83,8 +83,8 @@ public PackNode parse(FormatTokenizer tokenizer) {
node = WriteBytesNodeGen.create(context, ReadStringNodeGen.create(
context, true, "to_s", false, new ByteList(), new SourceNode()));
} else {
node = WritePaddedBytesNodeGen.create(context, directive.getSpacePadding(), ReadStringNodeGen.create(
context, true, "to_s", false, new ByteList(), new SourceNode()));
node = WritePaddedBytesNodeGen.create(context, directive.getSpacePadding(), directive.getLeftJustified(),
ReadStringNodeGen.create(context, true, "to_s", false, new ByteList(), new SourceNode()));
}
break;
case 'd':
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
*/
public class FormatTokenizer {

private static final String TYPE_CHARS = "%sdiuxXfgGeE";
private static final String TYPE_CHARS = "%-sdiuxXfgGeE";

private final ByteList format;
private int position;
@@ -66,6 +66,13 @@ public Object next() {

position++;

boolean leftJustified = false;

if (format.charAt(position) == '-') {
leftJustified = true;
position++;
}

int spacePadding;
int zeroPadding;

@@ -111,7 +118,7 @@ public Object next() {

position++;

return new FormatDirective(spacePadding, zeroPadding, precision, type);
return new FormatDirective(spacePadding, zeroPadding, leftJustified, precision, type);
}

private int readInt() {
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/

package org.jruby.truffle.runtime;

import com.oracle.truffle.api.source.SourceSection;

/**
* Some 3rd party code make assumptions about the JRuby runtime based upon the values in some constants. Where the
* JRuby+Truffle runtime diverges from the behavior of JRuby, we may need to replace the value of these constants
* in order to lead the code down a different branch.
*/
public class ConstantReplacer {

public static String replacementName(SourceSection sourceSection, String name) {
// The thread_safe gem checks if JRUBY_VERSION is defined and then uses RUBY_VERSION as
// a fallback. We rename the constant being looked for to one that doesn't exist so the defined?
// lookup fails.
if (sourceSection.getSource().getName().endsWith("thread_safe.rb")) {
if (name.equals("JRUBY_VERSION") || name.equals("RUBY_VERSION")) {
return name + "_NONEXISTENT";
}
}

return name;
}

}
Original file line number Diff line number Diff line change
@@ -89,6 +89,19 @@ public void insertAfter(RubyModule module) {

}

public static void debugModuleChain(RubyModule module) {
ModuleChain chain = module;
while (chain != null) {
System.err.print(chain.getClass());
if (!(chain instanceof PrependMarker)) {
RubyModule real = chain.getActualModule();
System.err.print(" " + real.getName());
}
System.err.println();
chain = chain.getParentModule();
}
}

/**
* The slot within a module definition method frame where we store the implicit state that is
* the current visibility for new methods.
@@ -98,8 +111,7 @@ public void insertAfter(RubyModule module) {
// The context is stored here - objects can obtain it via their class (which is a module)
private final RubyContext context;

/** Either {@code this} or a {@link PrependMarker} */
@CompilationFinal protected ModuleChain start = this;
protected final ModuleChain start = new PrependMarker(this);
@CompilationFinal protected ModuleChain parentModule;

private final RubyModule lexicalParent;
@@ -178,8 +190,8 @@ public void initCopy(RubyModule from) {
this.constants.putAll(from.constants);
this.classVariables.putAll(from.classVariables);

if (from.start instanceof PrependMarker) {
this.parentModule = from.start;
if (from.start.getParentModule() != from) {
this.parentModule = from.start.getParentModule();
} else {
this.parentModule = from.parentModule;
}
@@ -272,21 +284,15 @@ public void prepend(Node currentNode, RubyModule module) {
throw new RaiseException(getContext().getCoreLibrary().argumentError("cyclic prepend detected", currentNode));
}

if (start == this) {
// Create an PrependMarker pointing to an empty module or class
// serving as an indirection to the first prepended module
start = new PrependMarker(this);
}

Stack<RubyModule> modulesToPrepend = new Stack<>();
modulesToPrepend.push(module);
for (RubyModule includedModule : module.prependedAndIncludedModules()) {
modulesToPrepend.push(includedModule);
}

for (RubyModule mod : modulesToPrepend) {
start.insertAfter(mod);
mod.addDependent(this);
ModuleChain mod = module.start;
ModuleChain cur = start;
while (mod != null && !(mod instanceof RubyClass)) {
if (!(mod instanceof PrependMarker)) {
cur.insertAfter(mod.getActualModule());
mod.getActualModule().addDependent(this);
cur = cur.getParentModule();
}
mod = mod.getParentModule();
}

newVersion();
2 changes: 1 addition & 1 deletion truffle/src/main/ruby/core/config.rb
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ module RbConfig
'exeext' => '',
'EXEEXT' => 'rubytruffle',
'host_os' => Truffle::Primitive.host_os,
'libdir' => "#{Truffle::Primitive.home_directory}/lib/ruby/truffle",
'libdir' => "#{Truffle::Primitive.jruby_home_directory}/lib/ruby/truffle",
'ruby_install_name' => 'rubytruffle',
'RUBY_INSTALL_NAME' => 'rubytruffle',
'ruby_version' => '2.2.0',
5 changes: 5 additions & 0 deletions truffle/src/main/ruby/core/shims.rb
Original file line number Diff line number Diff line change
@@ -222,3 +222,8 @@ def to_s
end

end

# Hack to let code run that try to invoke RubyGems directly. We don't yet support RubyGems, but in most cases where
# this call would be made, we've already set up the $LOAD_PATH so the call would no-op anyway.
def gem(*args)
end
4 changes: 3 additions & 1 deletion truffle/src/test/java/org/jruby/truffle/tck/RubyTckTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. This
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
@@ -17,6 +17,7 @@
import static org.junit.Assert.*;

public class RubyTckTest extends TruffleTCK {

@Test
public void checkVM() {
TruffleVM vm = TruffleVM.newVM().build();
@@ -88,4 +89,5 @@ public void testMaxOrMinValue() throws Exception {
public void testMaxOrMinValue2() throws Exception {
super.testMaxOrMinValue2();
}

}