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: d038d9793c8c
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a5b4bbc6d3fb
Choose a head ref
  • 3 commits
  • 7 files changed
  • 1 contributor

Commits on Jul 7, 2015

  1. Copy the full SHA
    c1d4d28 View commit details
  2. Copy the full SHA
    bf0ccc2 View commit details
  3. [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
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
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
@@ -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;
}

}