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

Commits on Jul 16, 2015

  1. Copy the full SHA
    faac890 View commit details
  2. Copy the full SHA
    f73b4bd View commit details
  3. Copy the full SHA
    2f16b7e View commit details
Original file line number Diff line number Diff line change
@@ -161,6 +161,10 @@ public static boolean isRubyEncodingConverter(RubyBasicObject encodingConverter)
return encodingConverter instanceof RubyEncodingConverter;
}

public static boolean isRubyTime(RubyBasicObject time) {
return time instanceof RubyTime;
}

// Internal types

public static boolean isThreadLocal(Object value) {
@@ -190,5 +194,4 @@ public static boolean isNaN(double value) {
public static boolean isInfinity(double value) {
return Double.isInfinite(value);
}

}
149 changes: 108 additions & 41 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/EncodingNodes.java
Original file line number Diff line number Diff line change
@@ -19,19 +19,88 @@
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.util.CaseInsensitiveBytesHash;
import org.jcodings.util.Hash;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.coerce.ToStrNode;
import org.jruby.truffle.nodes.coerce.ToStrNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyEncoding;
import org.jruby.util.ByteList;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

@CoreClass(name = "Encoding")
public abstract class EncodingNodes {

// Both are mutated only in CoreLibrary.initializeEncodingConstants().
private static RubyBasicObject[] encodingList = new RubyBasicObject[EncodingDB.getEncodings().size()];
private static Map<String, RubyBasicObject> lookup = new HashMap<>();

@TruffleBoundary
public static synchronized RubyBasicObject getEncoding(Encoding encoding) {
return lookup.get(new String(encoding.getName(), StandardCharsets.UTF_8).toLowerCase(Locale.ENGLISH));
}

@TruffleBoundary
public static RubyBasicObject getEncoding(String name) {
return lookup.get(name.toLowerCase(Locale.ENGLISH));
}

public static RubyBasicObject getEncoding(int index) {
return encodingList[index];
}

@TruffleBoundary
public static void storeEncoding(int encodingListIndex, RubyBasicObject encoding) {
assert RubyGuards.isRubyEncoding(encoding);
encodingList[encodingListIndex] = encoding;
lookup.put(getName(encoding).toString().toLowerCase(Locale.ENGLISH), encoding);
}

@TruffleBoundary
public static void storeAlias(String aliasName, RubyBasicObject encoding) {
assert RubyGuards.isRubyEncoding(encoding);
lookup.put(aliasName.toLowerCase(Locale.ENGLISH), encoding);
}

public static RubyBasicObject newEncoding(RubyClass encodingClass, Encoding encoding, byte[] name, int p, int end, boolean dummy) {
return createRubyEncoding(encodingClass, encoding, new ByteList(name, p, end), dummy);
}

public static Encoding getEncoding(RubyBasicObject encoding) {
assert RubyGuards.isRubyEncoding(encoding);
return ((RubyEncoding) encoding).encoding;
}

public static ByteList getName(RubyBasicObject encoding) {
assert RubyGuards.isRubyEncoding(encoding);
return ((RubyEncoding) encoding).name;
}

public static boolean isDummy(RubyBasicObject encoding) {
assert RubyGuards.isRubyEncoding(encoding);
return ((RubyEncoding) encoding).dummy;
}

public static RubyBasicObject[] cloneEncodingList() {
final RubyBasicObject[] clone = new RubyBasicObject[encodingList.length];

System.arraycopy(encodingList, 0, clone, 0, encodingList.length);

return clone;
}

public static RubyBasicObject createRubyEncoding(RubyClass encodingClass, Encoding encoding, ByteList name, boolean dummy) {
return new RubyEncoding(encodingClass, encoding, name, dummy);
}

@CoreMethod(names = "ascii_compatible?")
public abstract static class AsciiCompatibleNode extends CoreMethodArrayArgumentsNode {

@@ -40,9 +109,9 @@ public AsciiCompatibleNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public Object isCompatible(RubyEncoding encoding) {
public Object isCompatible(RubyBasicObject encoding) {
CompilerDirectives.transferToInterpreter();
return encoding.getEncoding().isAsciiCompatible();
return getEncoding(encoding).isAsciiCompatible();
}
}

@@ -59,19 +128,19 @@ public Object isCompatibleStringString(RubyBasicObject first, RubyBasicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(StringNodes.getCodeRangeable(first), StringNodes.getCodeRangeable(second));

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
}

@TruffleBoundary
@Specialization
public Object isCompatibleEncodingEncoding(RubyEncoding first, RubyEncoding second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(first.getEncoding(), second.getEncoding());
@Specialization(guards = {"isRubyEncoding(first)", "isRubyEncoding(second)"})
public Object isCompatibleEncodingEncoding(RubyBasicObject first, RubyBasicObject second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(getEncoding(first), getEncoding(second));

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -83,7 +152,7 @@ public Object isCompatibleStringRegexp(RubyBasicObject first, RubyBasicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(StringNodes.getByteList(first).getEncoding(), RegexpNodes.getRegex(second).getEncoding());

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -95,7 +164,7 @@ public Object isCompatibleRegexpString(RubyBasicObject first, RubyBasicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(RegexpNodes.getRegex(first).getEncoding(), StringNodes.getByteList(second).getEncoding());

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -107,7 +176,7 @@ public Object isCompatibleRegexpRegexp(RubyBasicObject first, RubyBasicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(RegexpNodes.getRegex(first).getEncoding(), RegexpNodes.getRegex(second).getEncoding());

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -119,7 +188,7 @@ public Object isCompatibleRegexpSymbol(RubyBasicObject first, RubyBasicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(RegexpNodes.getRegex(first).getEncoding(), SymbolNodes.getByteList(second).getEncoding());

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -131,7 +200,7 @@ public Object isCompatibleSymbolRegexp(RubyBasicObject first, RubyBasicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(SymbolNodes.getByteList(first).getEncoding(), RegexpNodes.getRegex(second).getEncoding());

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -143,7 +212,7 @@ public Object isCompatibleStringSymbol(RubyBasicObject first, RubyBasicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(StringNodes.getCodeRangeable(first), SymbolNodes.getCodeRangeable(second));

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -155,19 +224,19 @@ public Object isCompatibleSymbolSymbol(RubyBasicObject first, RubyBasicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(SymbolNodes.getCodeRangeable(first), SymbolNodes.getCodeRangeable(second));

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
}

@TruffleBoundary
@Specialization(guards = "isRubyString(first)")
public Object isCompatibleStringEncoding(RubyBasicObject first, RubyEncoding second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(StringNodes.getByteList(first).getEncoding(), second.getEncoding());
@Specialization(guards = {"isRubyString(first)", "isRubyEncoding(second)"})
public Object isCompatibleStringEncoding(RubyBasicObject first, RubyBasicObject second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(StringNodes.getByteList(first).getEncoding(), getEncoding(second));

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
return getEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -185,32 +254,32 @@ public SetDefaultExternalNode(RubyContext context, SourceSection sourceSection)
super(context, sourceSection);
}

@Specialization
public RubyEncoding defaultExternal(RubyEncoding encoding) {
@Specialization(guards = "isRubyEncoding(encoding)")
public RubyBasicObject defaultExternalEncoding(RubyBasicObject encoding) {
CompilerDirectives.transferToInterpreter();

getContext().getRuntime().setDefaultExternalEncoding(encoding.getEncoding());
getContext().getRuntime().setDefaultExternalEncoding(getEncoding(encoding));

return encoding;
}

@Specialization(guards = "isRubyString(encodingString)")
public RubyEncoding defaultExternal(RubyBasicObject encodingString) {
public RubyBasicObject defaultExternal(RubyBasicObject encodingString) {
CompilerDirectives.transferToInterpreter();

final RubyEncoding rubyEncoding = RubyEncoding.getEncoding(encodingString.toString());
getContext().getRuntime().setDefaultExternalEncoding(rubyEncoding.getEncoding());
final RubyBasicObject rubyEncoding = getEncoding(encodingString.toString());
getContext().getRuntime().setDefaultExternalEncoding(getEncoding(rubyEncoding));

return rubyEncoding;
}

@Specialization(guards = "isNil(nil)")
public RubyEncoding defaultExternal(Object nil) {
public RubyBasicObject defaultExternal(Object nil) {
throw new RaiseException(getContext().getCoreLibrary().argumentError("default external can not be nil", this));
}

@Specialization(guards = { "!isRubyEncoding(encoding)", "!isRubyString(encoding)", "!isNil(encoding)" })
public RubyEncoding defaultExternal(VirtualFrame frame, Object encoding) {
public RubyBasicObject defaultExternal(VirtualFrame frame, Object encoding) {
if (toStrNode == null) {
CompilerDirectives.transferToInterpreter();
toStrNode = insert(ToStrNodeGen.create(getContext(), getSourceSection(), null));
@@ -231,11 +300,11 @@ public SetDefaultInternalNode(RubyContext context, SourceSection sourceSection)
super(context, sourceSection);
}

@Specialization
public RubyEncoding defaultInternal(RubyEncoding encoding) {
@Specialization(guards = "isRubyEncoding(encoding)")
public RubyBasicObject defaultInternal(RubyBasicObject encoding) {
CompilerDirectives.transferToInterpreter();

getContext().getRuntime().setDefaultInternalEncoding(encoding.getEncoding());
getContext().getRuntime().setDefaultInternalEncoding(getEncoding(encoding));

return encoding;
}
@@ -259,7 +328,7 @@ public RubyBasicObject defaultInternal(VirtualFrame frame, Object encoding) {
}

final RubyBasicObject encodingName = toStrNode.executeToStr(frame, encoding);
getContext().getRuntime().setDefaultInternalEncoding(RubyEncoding.getEncoding(encodingName.toString()).getEncoding());
getContext().getRuntime().setDefaultInternalEncoding(getEncoding(getEncoding(encodingName.toString())));

return encodingName;
}
@@ -277,7 +346,7 @@ public ListNode(RubyContext context, SourceSection sourceSection) {
public RubyBasicObject list() {
CompilerDirectives.transferToInterpreter();

final RubyEncoding[] encodings = RubyEncoding.cloneEncodingList();
final RubyBasicObject[] encodings = cloneEncodingList();

return createArray(encodings, encodings.length);
}
@@ -307,10 +376,8 @@ public DummyNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public boolean isDummy(RubyEncoding encoding) {
CompilerDirectives.transferToInterpreter();

return encoding.isDummy();
public boolean isDummy(RubyBasicObject encoding) {
return EncodingNodes.isDummy(encoding);
}
}

@@ -337,9 +404,9 @@ public EncodingMapNode(RubyContext context, SourceSection sourceSection) {
public Object encodingMap(VirtualFrame frame) {
Object ret = newLookupTableNode.call(frame, getContext().getCoreLibrary().getLookupTableClass(), "new", null);

final RubyEncoding[] encodings = RubyEncoding.cloneEncodingList();
final RubyBasicObject[] encodings = cloneEncodingList();
for (int i = 0; i < encodings.length; i++) {
final Object upcased = upcaseNode.call(frame, createString(encodings[i].getName()), "upcase", null);
final Object upcased = upcaseNode.call(frame, createString(getName(encodings[i])), "upcase", null);
final Object key = toSymNode.call(frame, upcased, "to_sym", null);
final Object value = newTupleNode.call(frame, getContext().getCoreLibrary().getTupleClass(), "create", null, nil(), i);

@@ -381,14 +448,14 @@ public Object encodingMap(VirtualFrame frame) {
}

@TruffleBoundary
public Object indexLookup(RubyEncoding[] encodings, Encoding encoding) {
public Object indexLookup(RubyBasicObject[] encodings, Encoding encoding) {
// TODO (nirvdrum 25-Mar-15): Build up this lookup table in RubyEncoding as we register encodings.
if (encoding == null) {
return nil();
}

for (int i = 0; i < encodings.length; i++) {
if (encodings[i].getEncoding() == encoding) {
if (getEncoding(encodings[i]) == encoding) {
return i;
}
}
@@ -406,8 +473,8 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {

@TruffleBoundary
@Specialization
public RubyBasicObject toS(RubyEncoding encoding) {
final ByteList name = encoding.getName().dup();
public RubyBasicObject toS(RubyBasicObject encoding) {
final ByteList name = getName(encoding).dup();
name.setEncoding(ASCIIEncoding.INSTANCE);
return createString(name);
}
Original file line number Diff line number Diff line change
@@ -25,7 +25,6 @@
import org.jcodings.Encoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyThread.Status;
import org.jruby.exceptions.MainExitException;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyGuards;
@@ -139,7 +138,7 @@ public RubyBasicObject backtick(VirtualFrame frame, RubyBasicObject command) {
}

// TODO (nirvdrum 10-Mar-15) This should be using the default external encoding, rather than hard-coded to UTF-8.
return createString(resultBuilder.toString(), RubyEncoding.getEncoding("UTF-8").getEncoding());
return createString(resultBuilder.toString(), EncodingNodes.getEncoding(EncodingNodes.getEncoding("UTF-8")));
}

}
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.NotProvided;
Loading