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

Commits on Jun 22, 2016

  1. Copy the full SHA
    a8e2a80 View commit details
  2. Copy the full SHA
    d5c6b40 View commit details
  3. [Truffle] Added some delegates to EncodingManager to limit direct acc…

    …ess to the JRuby runtime.
    nirvdrum committed Jun 22, 2016
    Copy the full SHA
    5ee58e6 View commit details
6 changes: 6 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import org.jruby.Ruby;
import org.jruby.truffle.builtins.PrimitiveManager;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.encoding.EncodingManager;
import org.jruby.truffle.core.exception.CoreExceptions;
import org.jruby.truffle.core.kernel.AtExitManager;
import org.jruby.truffle.core.kernel.TraceManager;
@@ -80,6 +81,7 @@ public class RubyContext extends ExecutionContext {
private final CoreStrings coreStrings = new CoreStrings(this);
private final FrozenStrings frozenStrings = new FrozenStrings(this);
private final CoreExceptions coreExceptions = new CoreExceptions(this);
private final EncodingManager encodingManager = new EncodingManager(this);

private final CompilerOptions compilerOptions = Truffle.getRuntime().createCompilerOptions();

@@ -351,4 +353,8 @@ public CoreExceptions getCoreExceptions() {
return coreExceptions;
}

public EncodingManager getEncodingManager() {
return encodingManager;
}

}
11 changes: 4 additions & 7 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -42,7 +42,6 @@
import org.jruby.truffle.core.bool.TrueClassNodesFactory;
import org.jruby.truffle.core.dir.DirNodesFactory;
import org.jruby.truffle.core.encoding.EncodingConverterNodesFactory;
import org.jruby.truffle.core.encoding.EncodingNodes;
import org.jruby.truffle.core.encoding.EncodingNodesFactory;
import org.jruby.truffle.core.exception.ExceptionNodesFactory;
import org.jruby.truffle.core.fiber.FiberNodesFactory;
@@ -1081,26 +1080,24 @@ public void initializeEncodingConstants() {
getContext().getJRubyRuntime().getEncodingService().defineEncodings(new EncodingService.EncodingDefinitionVisitor() {
@Override
public void defineEncoding(EncodingDB.Entry encodingEntry, byte[] name, int p, int end) {
DynamicObject re = EncodingNodes.newEncoding(getContext(), encodingClass, null, name, p, end, encodingEntry.isDummy());
EncodingNodes.storeEncoding(encodingEntry.getIndex(), re);
context.getEncodingManager().defineEncoding(encodingClass, encodingEntry, name, p, end);
}

@Override
public void defineConstant(int encodingListIndex, String constName) {
Layouts.MODULE.getFields(encodingClass).setConstant(context, node, constName, EncodingNodes.getEncoding(encodingListIndex));
Layouts.MODULE.getFields(encodingClass).setConstant(context, node, constName, context.getEncodingManager().getRubyEncoding(encodingListIndex));
}
});

getContext().getJRubyRuntime().getEncodingService().defineAliases(new EncodingService.EncodingAliasVisitor() {
@Override
public void defineAlias(int encodingListIndex, String constName) {
DynamicObject re = EncodingNodes.getEncoding(encodingListIndex);
EncodingNodes.storeAlias(constName, re);
context.getEncodingManager().defineAlias(encodingListIndex, constName);
}

@Override
public void defineConstant(int encodingListIndex, String constName) {
Layouts.MODULE.getFields(encodingClass).setConstant(context, node, constName, EncodingNodes.getEncoding(encodingListIndex));
Layouts.MODULE.getFields(encodingClass).setConstant(context, node, constName, context.getEncodingManager().getRubyEncoding(encodingListIndex));
}
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2014, 2016 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.core.encoding;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.object.DynamicObject;
import org.jcodings.Encoding;
import org.jcodings.EncodingDB;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.util.ByteList;

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

public class EncodingManager {

private final DynamicObject[] ENCODING_LIST_BY_ENCODING_LIST_INDEX = new DynamicObject[EncodingDB.getEncodings().size()];
private final DynamicObject[] ENCODING_LIST_BY_ENCODING_INDEX = new DynamicObject[EncodingDB.getEncodings().size()];
private final Map<String, DynamicObject> LOOKUP = new HashMap<>();

private final RubyContext context;

public EncodingManager(RubyContext context) {
this.context = context;
}

@TruffleBoundary
public static DynamicObject newRubyEncoding(RubyContext context, DynamicObject encodingClass, Encoding encoding, byte[] name, int p, int end, boolean dummy) {
// TODO (nirvdrum 21-Jun-16): We probably don't need to create a ByteList and two Ropes. Without any guarantees on the code range of the encoding name, however, we must be conservative.
final Rope rope = StringOperations.ropeFromByteList(new ByteList(name, p, end, USASCIIEncoding.INSTANCE, false));
final Rope cachedRope = context.getRopeTable().getRope(rope.getBytes(), rope.getEncoding(), rope.getCodeRange());
final DynamicObject string = context.getFrozenStrings().getFrozenString(cachedRope);

return Layouts.ENCODING.createEncoding(Layouts.CLASS.getInstanceFactory(encodingClass), encoding, string, dummy);
}

public DynamicObject[] getUnsafeEncodingList() {
return ENCODING_LIST_BY_ENCODING_LIST_INDEX;
}

public DynamicObject getRubyEncoding(Encoding encoding) {
DynamicObject rubyEncoding = ENCODING_LIST_BY_ENCODING_INDEX[encoding.getIndex()];

if (rubyEncoding == null) {
// Bounded by the number of encodings
CompilerDirectives.transferToInterpreterAndInvalidate();

rubyEncoding = LOOKUP.get(new String(encoding.getName(), StandardCharsets.UTF_8).toLowerCase(Locale.ENGLISH));
ENCODING_LIST_BY_ENCODING_INDEX[encoding.getIndex()] = rubyEncoding;
}

return rubyEncoding;
}

@TruffleBoundary
public DynamicObject getRubyEncoding(String name) {
return LOOKUP.get(name.toLowerCase(Locale.ENGLISH));
}

@TruffleBoundary
public DynamicObject getRubyEncoding(int encodingListIndex) {
return ENCODING_LIST_BY_ENCODING_LIST_INDEX[encodingListIndex];
}

@TruffleBoundary
public void defineEncoding(DynamicObject encodingClass, EncodingDB.Entry encodingEntry, byte[] name, int p, int end) {
final DynamicObject rubyEncoding = newRubyEncoding(context, encodingClass, null, name, p, end, encodingEntry.isDummy());

ENCODING_LIST_BY_ENCODING_LIST_INDEX[encodingEntry.getIndex()] = rubyEncoding;
LOOKUP.put(Layouts.ENCODING.getName(rubyEncoding).toString().toLowerCase(Locale.ENGLISH), rubyEncoding);
}

@TruffleBoundary
public void defineAlias(int encodingListIndex, String name) {
final DynamicObject rubyEncoding = getRubyEncoding(encodingListIndex);

LOOKUP.put(name.toLowerCase(Locale.ENGLISH), rubyEncoding);
}

@TruffleBoundary
public Charset charsetForEncoding(Encoding encoding) {
return context.getJRubyRuntime().getEncodingService().charsetForEncoding(encoding);
}

@TruffleBoundary
public Encoding getLocaleEncoding() {
return context.getJRubyRuntime().getEncodingService().getLocaleEncoding();
}

}
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@
import org.jcodings.Encoding;
import org.jcodings.EncodingDB;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jcodings.util.CaseInsensitiveBytesHash;
import org.jcodings.util.Hash;
@@ -46,67 +45,9 @@
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
import org.jruby.util.ByteList;

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

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

// Both are mutated only in CoreLibrary.initializeEncodingConstants().
private static final DynamicObject[] ENCODING_LIST = new DynamicObject[EncodingDB.getEncodings().size()];
private static final Map<String, DynamicObject> LOOKUP = new HashMap<>();

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

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

public static DynamicObject getEncoding(int index) {
return ENCODING_LIST[index];
}

@TruffleBoundary
public static void storeEncoding(int encodingListIndex, DynamicObject encoding) {
assert RubyGuards.isRubyEncoding(encoding);
ENCODING_LIST[encodingListIndex] = encoding;
LOOKUP.put(Layouts.ENCODING.getName(encoding).toString().toLowerCase(Locale.ENGLISH), encoding);
}

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

@TruffleBoundary
public static DynamicObject newEncoding(RubyContext context, DynamicObject encodingClass, Encoding encoding, byte[] name, int p, int end, boolean dummy) {
// TODO (nirvdrum 21-Jun-16): We probably don't need to create a ByteList and two Ropes. Without any guarantees on the code range of the encoding name, however, we must be conservative.
final Rope rope = StringOperations.ropeFromByteList(new ByteList(name, p, end, USASCIIEncoding.INSTANCE, false));
final Rope cachedRope = context.getRopeTable().getRope(rope.getBytes(), rope.getEncoding(), rope.getCodeRange());
final DynamicObject string = context.getFrozenStrings().getFrozenString(cachedRope);

return createRubyEncoding(encodingClass, encoding, string, dummy);
}

public static Object[] cloneEncodingList() {
final Object[] clone = new Object[ENCODING_LIST.length];

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

return clone;
}

public static DynamicObject createRubyEncoding(DynamicObject encodingClass, Encoding encoding, DynamicObject name, boolean dummy) {
return Layouts.ENCODING.createEncoding(Layouts.CLASS.getInstanceFactory(encodingClass), encoding, name, dummy);
}

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

@@ -157,7 +98,7 @@ public DynamicObject isCompatibleStringStringUncached(DynamicObject first, Dynam
final Encoding compatibleEncoding = compatibleEncodingForStrings(first, second);

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -171,7 +112,7 @@ public Object isCompatibleEncodingEncoding(DynamicObject first, DynamicObject se
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(firstEncoding, secondEncoding);

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -183,7 +124,7 @@ public Object isCompatibleStringRegexp(DynamicObject first, DynamicObject second
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(Layouts.STRING.getRope(first).getEncoding(), Layouts.REGEXP.getRegex(second).getEncoding());

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -195,7 +136,7 @@ public Object isCompatibleRegexpString(DynamicObject first, DynamicObject second
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(Layouts.REGEXP.getRegex(first).getEncoding(), Layouts.STRING.getRope(second).getEncoding());

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -207,7 +148,7 @@ public Object isCompatibleRegexpRegexp(DynamicObject first, DynamicObject second
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(Layouts.REGEXP.getRegex(first).getEncoding(), Layouts.REGEXP.getRegex(second).getEncoding());

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -219,7 +160,7 @@ public Object isCompatibleRegexpSymbol(DynamicObject first, DynamicObject second
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(Layouts.REGEXP.getRegex(first).getEncoding(), Layouts.SYMBOL.getRope(second).getEncoding());

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -231,7 +172,7 @@ public Object isCompatibleSymbolRegexp(DynamicObject first, DynamicObject second
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(Layouts.SYMBOL.getRope(first).getEncoding(), Layouts.REGEXP.getRegex(second).getEncoding());

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -243,7 +184,7 @@ public Object isCompatibleStringSymbol(DynamicObject first, DynamicObject second
final Encoding compatibleEncoding = compatibleEncodingForRopes(StringOperations.rope(first), Layouts.SYMBOL.getRope(second));

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -255,7 +196,7 @@ public Object isCompatibleSymbolSymbol(DynamicObject first, DynamicObject second
final Encoding compatibleEncoding = compatibleEncodingForRopes(Layouts.SYMBOL.getRope(first), Layouts.SYMBOL.getRope(second));

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -267,7 +208,7 @@ public Object isCompatibleStringEncoding(DynamicObject first, DynamicObject seco
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(Layouts.STRING.getRope(first).getEncoding(), EncodingOperations.getEncoding(second));

if (compatibleEncoding != null) {
return getEncoding(compatibleEncoding);
return getContext().getEncodingManager().getRubyEncoding(compatibleEncoding);
} else {
return nil();
}
@@ -348,7 +289,7 @@ public DynamicObject defaultExternalEncoding(DynamicObject encoding) {
@TruffleBoundary
@Specialization(guards = "isRubyString(encodingString)")
public DynamicObject defaultExternal(DynamicObject encodingString) {
final DynamicObject rubyEncoding = getEncoding(encodingString.toString());
final DynamicObject rubyEncoding = getContext().getEncodingManager().getRubyEncoding(encodingString.toString());
getContext().getJRubyRuntime().setDefaultExternalEncoding(EncodingOperations.getEncoding(rubyEncoding));

return rubyEncoding;
@@ -402,7 +343,7 @@ public DynamicObject defaultInternal(VirtualFrame frame, Object encoding) {
}

final DynamicObject encodingName = toStrNode.executeToStr(frame, encoding);
getContext().getJRubyRuntime().setDefaultInternalEncoding(EncodingOperations.getEncoding(getEncoding(encodingName.toString())));
getContext().getJRubyRuntime().setDefaultInternalEncoding(EncodingOperations.getEncoding(getContext().getEncodingManager().getRubyEncoding(encodingName.toString())));

return encodingName;
}
@@ -415,9 +356,12 @@ public abstract static class ListNode extends CoreMethodArrayArgumentsNode {
@TruffleBoundary
@Specialization
public DynamicObject list() {
final Object[] encodings = cloneEncodingList();
final DynamicObject[] encodings = getContext().getEncodingManager().getUnsafeEncodingList();
final Object[] arrayStore = new Object[encodings.length];

System.arraycopy(encodings, 0, arrayStore, 0, encodings.length);

return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), encodings, encodings.length);
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), arrayStore, arrayStore.length);
}
}

@@ -427,7 +371,7 @@ public abstract static class LocaleCharacterMapNode extends CoreMethodArrayArgum

@Specialization
public DynamicObject localeCharacterMap() {
final DynamicObject rubyEncoding = EncodingNodes.getEncoding(getContext().getJRubyRuntime().getEncodingService().getLocaleEncoding());
final DynamicObject rubyEncoding = getContext().getEncodingManager().getRubyEncoding(getContext().getEncodingManager().getLocaleEncoding());

return Layouts.ENCODING.getName(rubyEncoding);
}
@@ -482,7 +426,7 @@ public EncodingMapNode(RubyContext context, SourceSection sourceSection) {
public Object encodingMap(VirtualFrame frame) {
Object ret = newLookupTableNode.call(frame, coreLibrary().getLookupTableClass(), "new", null);

final DynamicObject[] encodings = ENCODING_LIST;
final DynamicObject[] encodings = getContext().getEncodingManager().getUnsafeEncodingList();
for (int i = 0; i < encodings.length; i++) {
final Object upcased = upcaseNode.call(frame, Layouts.ENCODING.getName(encodings[i]), "upcase", null);
final Object key = toSymNode.call(frame, upcased, "to_sym", null);
@@ -514,11 +458,11 @@ public Object encodingMap(VirtualFrame frame) {
final Object externalTuple = makeTuple(frame, newTupleNode, create7BitString("external", UTF8Encoding.INSTANCE), indexLookup(encodings, defaultExternalEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("EXTERNAL"), externalTuple);

final Encoding localeEncoding = getLocaleEncoding();
final Encoding localeEncoding = getContext().getEncodingManager().getLocaleEncoding();
final Object localeTuple = makeTuple(frame, newTupleNode, create7BitString("locale", UTF8Encoding.INSTANCE), indexLookup(encodings, localeEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("LOCALE"), localeTuple);

final Encoding filesystemEncoding = getLocaleEncoding();
final Encoding filesystemEncoding = getContext().getEncodingManager().getLocaleEncoding();
final Object filesystemTuple = makeTuple(frame, newTupleNode, create7BitString("filesystem", UTF8Encoding.INSTANCE), indexLookup(encodings, filesystemEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("FILESYSTEM"), filesystemTuple);

@@ -529,11 +473,6 @@ private Object makeTuple(VirtualFrame frame, CallDispatchHeadNode newTupleNode,
return newTupleNode.call(frame, coreLibrary().getTupleClass(), "create", null, values);
}

@TruffleBoundary
private Encoding getLocaleEncoding() {
return getContext().getJRubyRuntime().getEncodingService().getLocaleEncoding();
}

@TruffleBoundary
public Object indexLookup(DynamicObject[] encodings, Encoding encoding) {
// TODO (nirvdrum 25-Mar-15): Build up this lookup table in RubyEncoding as we register encodings.
@@ -580,12 +519,12 @@ public static abstract class EncodingGetObjectEncodingNode extends PrimitiveArra

@Specialization(guards = "isRubyString(string)")
public DynamicObject encodingGetObjectEncodingString(DynamicObject string) {
return EncodingNodes.getEncoding(Layouts.STRING.getRope(string).getEncoding());
return getContext().getEncodingManager().getRubyEncoding(Layouts.STRING.getRope(string).getEncoding());
}

@Specialization(guards = "isRubySymbol(symbol)")
public DynamicObject encodingGetObjectEncodingSymbol(DynamicObject symbol) {
return EncodingNodes.getEncoding(Layouts.SYMBOL.getRope(symbol).getEncoding());
return getContext().getEncodingManager().getRubyEncoding(Layouts.SYMBOL.getRope(symbol).getEncoding());
}

@Specialization(guards = "isRubyEncoding(encoding)")
@@ -595,7 +534,7 @@ public DynamicObject encodingGetObjectEncoding(DynamicObject encoding) {

@Specialization(guards = "isRubyRegexp(regexp)")
public DynamicObject encodingGetObjectEncodingRegexp(DynamicObject regexp) {
return EncodingNodes.getEncoding(Layouts.REGEXP.getSource(regexp).getEncoding());
return getContext().getEncodingManager().getRubyEncoding(Layouts.REGEXP.getSource(regexp).getEncoding());
}

@Specialization(guards = {"!isRubyString(object)", "!isRubySymbol(object)", "!isRubyEncoding(object)", "!isRubyRegexp(object)"})
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@
import org.jruby.truffle.Layouts;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.util.ByteList;

public abstract class EncodingOperations {

Original file line number Diff line number Diff line change
@@ -201,7 +201,7 @@ private DynamicObject spawnAndCaptureOutput(DynamicObject command, final Dynamic
}

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

}
@@ -653,7 +653,7 @@ private CodeLoader.DeferredCall doEvalX(DynamicObject rubySource,
// TODO (pitr 15-Oct-2015): fix this ugly hack, required for AS, copy-paste
final String space = new String(new char[Math.max(line - 1, 0)]).replace("\0", "\n");
// TODO CS 14-Apr-15 concat space + code as a rope, otherwise the string will be copied after the rope is converted
final Source source = Source.fromText(space + RopeOperations.decodeRope(getContext().getJRubyRuntime(), code), filename);
final Source source = Source.fromText(space + RopeOperations.decodeRope(getContext(), code), filename);

final MaterializedFrame frame = Layouts.BINDING.getFrame(binding);
final DeclarationContext declarationContext = RubyArguments.getDeclarationContext(frame);
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.rope.Rope;
@@ -59,9 +61,9 @@ private DynamicObject createRegexp(DynamicObject[] parts) {
final Rope source = Layouts.REGEXP.getSource(regexp);

if (!BodyTranslator.all7Bit(preprocessed.getByteList().bytes())) {
Layouts.REGEXP.setSource(regexp, RopeOperations.withEncodingVerySlow(source, getContext().getJRubyRuntime().getEncodingService().getAscii8bitEncoding()));
Layouts.REGEXP.setSource(regexp, RopeOperations.withEncodingVerySlow(source, ASCIIEncoding.INSTANCE));
} else {
Layouts.REGEXP.setSource(regexp, RopeOperations.withEncodingVerySlow(source, getContext().getJRubyRuntime().getEncodingService().getUSAsciiEncoding()));
Layouts.REGEXP.setSource(regexp, RopeOperations.withEncodingVerySlow(source, USASCIIEncoding.INSTANCE));
}
}

Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.Ruby;
import org.jruby.RubyEncoding;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
@@ -124,7 +123,7 @@ public static String decodeUTF8(byte[] bytes, int offset, int byteLength) {
}

@TruffleBoundary
public static String decodeRope(Ruby runtime, Rope value) {
public static String decodeRope(RubyContext context, Rope value) {
// TODO CS 9-May-16 having recursive problems with this, so flatten up front for now

value = flatten(value);
@@ -142,7 +141,7 @@ public static String decodeRope(Ruby runtime, Rope value) {
Charset charset = encodingToCharsetMap.get(encoding);

if (charset == null) {
charset = runtime.getEncodingService().charsetForEncoding(encoding);
charset = context.getEncodingManager().charsetForEncoding(encoding);
encodingToCharsetMap.put(encoding, charset);
}

@@ -594,7 +593,7 @@ public static Rope format(RubyContext context, Object... values) {
|| encoding == ASCIIEncoding.INSTANCE) {
valueRope = stringRope;
} else {
valueRope = StringOperations.encodeRope(decodeRope(context.getJRubyRuntime(), stringRope), UTF8Encoding.INSTANCE);
valueRope = StringOperations.encodeRope(decodeRope(context, stringRope), UTF8Encoding.INSTANCE);
}
} else if (value instanceof Integer) {
valueRope = new LazyIntRope((int) value);
Original file line number Diff line number Diff line change
@@ -831,7 +831,6 @@ public Object crypt(DynamicObject string, DynamicObject salt) {
final Rope value = rope(string);
final Rope other = rope(salt);

final Encoding ascii8bit = getContext().getJRubyRuntime().getEncodingService().getAscii8bitEncoding();
if (other.byteLength() < 2) {
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new RaiseException(coreExceptions().argumentError("salt too short (need >= 2 bytes)", this));
@@ -860,7 +859,7 @@ public Object crypt(DynamicObject string, DynamicObject salt) {
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection()));
}

final DynamicObject ret = createString(StringOperations.ropeFromByteList(new ByteList(cryptedString, 0, cryptedString.length - 1, ascii8bit, false)));
final DynamicObject ret = createString(StringOperations.ropeFromByteList(new ByteList(cryptedString, 0, cryptedString.length - 1, ASCIIEncoding.INSTANCE, false)));

taintResultNode.maybeTaint(string, ret);
taintResultNode.maybeTaint(salt, ret);
@@ -1138,7 +1137,7 @@ public abstract static class EncodingNode extends CoreMethodArrayArgumentsNode {

@Specialization
public DynamicObject encoding(DynamicObject string) {
return EncodingNodes.getEncoding(StringOperations.encoding(string));
return getContext().getEncodingManager().getRubyEncoding(StringOperations.encoding(string));
}

}
@@ -1159,7 +1158,7 @@ public ForceEncodingNode(RubyContext context, SourceSection sourceSection) {
public DynamicObject forceEncodingString(DynamicObject string, DynamicObject encodingName,
@Cached("createBinaryProfile()") ConditionProfile differentEncodingProfile,
@Cached("createBinaryProfile()") ConditionProfile mutableRopeProfile) {
final DynamicObject encoding = EncodingNodes.getEncoding(encodingName.toString());
final DynamicObject encoding = getContext().getEncodingManager().getRubyEncoding(encodingName.toString());
return forceEncodingEncoding(string, encoding, differentEncodingProfile, mutableRopeProfile);
}

Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ public static DynamicObject createString(RubyContext context, Rope rope) {
// Since ByteList.toString does not decode properly
@CompilerDirectives.TruffleBoundary
public static String getString(RubyContext context, DynamicObject string) {
return RopeOperations.decodeRope(context.getJRubyRuntime(), StringOperations.rope(string));
return RopeOperations.decodeRope(context, StringOperations.rope(string));
}

public static StringCodeRangeableWrapper getCodeRangeableReadWrite(final DynamicObject string) {
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ public abstract static class EncodingNode extends CoreMethodArrayArgumentsNode {

@Specialization
public DynamicObject encoding(DynamicObject symbol) {
return EncodingNodes.getEncoding(Layouts.SYMBOL.getRope(symbol).getEncoding());
return getContext().getEncodingManager().getRubyEncoding(Layouts.SYMBOL.getRope(symbol).getEncoding());
}

}
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ public String toString(DynamicObject object) {
CompilerAsserts.neverPartOfCompilation();

if (RubyGuards.isRubyString(object)) {
return RopeOperations.decodeRope(getContext().getJRubyRuntime(), StringOperations.rope(object));
return RopeOperations.decodeRope(getContext(), StringOperations.rope(object));
} else if (RubyGuards.isRubySymbol(object)) {
return Layouts.SYMBOL.getString(object);
} else if (RubyGuards.isRubyException(object)) {
Original file line number Diff line number Diff line change
@@ -1353,7 +1353,7 @@ public RubyNode visitDotNode(org.jruby.ast.DotNode node) {
@Override
public RubyNode visitEncodingNode(org.jruby.ast.EncodingNode node) {
SourceSection sourceSection = translate(node.getPosition());
final RubyNode ret = new ObjectLiteralNode(context, sourceSection, EncodingNodes.getEncoding(node.getEncoding()));
final RubyNode ret = new ObjectLiteralNode(context, sourceSection, context.getEncodingManager().getRubyEncoding(node.getEncoding()));
return addNewlineIfNeeded(node, ret);
}

Original file line number Diff line number Diff line change
@@ -143,7 +143,7 @@ public DynamicObject startStream(DynamicObject emitter, int encodingOrdinal) {
}

final Encoding encoding = YAMLEncoding.values()[encodingOrdinal].getEncoding();
final Charset charset = getContext().getJRubyRuntime().getEncodingService().charsetForEncoding(encoding);
final Charset charset = getContext().getEncodingManager().charsetForEncoding(encoding);

Layouts.PSYCH_EMITTER.setEmitter(emitter,
new Emitter(