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

Commits on Nov 1, 2016

  1. Simplified the defining of encoding constants.

    This reverts a large part of 1f88220 and 3beeeb8. As it turns out, the iterators provided by jcodings are a good enough interface and other usability improvements have been made, obviating the need for this visitor pattern.
    nirvdrum committed Nov 1, 2016
    Copy the full SHA
    3a9d19f View commit details
  2. Copy the full SHA
    446632b View commit details
  3. [Truffle] No need to lazy load dummy encodings.

    We load all encodings eagerly and account for dummy encodings during bootstrap.
    nirvdrum committed Nov 1, 2016
    Copy the full SHA
    5ec7793 View commit details
51 changes: 5 additions & 46 deletions core/src/main/java/org/jruby/runtime/encoding/EncodingService.java
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ public final class EncodingService {
private final CaseInsensitiveBytesHash<Entry> aliases;

// for fast lookup: encoding entry => org.jruby.RubyEncoding
public final IRubyObject[] encodingList;
private final IRubyObject[] encodingList;
// for fast lookup: org.joni.encoding.Encoding => org.jruby.RubyEncoding
private RubyEncoding[] encodingIndex = new RubyEncoding[4];
// the runtime
@@ -176,73 +176,32 @@ public RubyEncoding getEncoding(Encoding enc) {
return encodingIndex[enc.getIndex()];
}

public interface EncodingDefinitionVisitor {
public void defineEncoding(Entry encodingEntry, byte[] name, int p, int end);

public void defineConstant(int encodingListIndex, String constName);
}

public interface EncodingAliasVisitor {
public void defineAlias(int encodingListIndex, String constName);

public void defineConstant(int encodingListIndex, String constName);
}

public void defineEncodings() {
defineEncodings(new EncodingDefinitionVisitor() {
@Override
public void defineEncoding(Entry encodingEntry, byte[] name, int p, int end) {
RubyEncoding encoding = RubyEncoding.newEncoding(runtime, name, p, end, encodingEntry.isDummy());
encodingList[encodingEntry.getIndex()] = encoding;
}

@Override
public void defineConstant(int encodingListIndex, String constName) {
defineEncodingConstant(runtime, (RubyEncoding) encodingList[encodingListIndex], constName);
}
});
}

public void defineEncodings(EncodingDefinitionVisitor visitor) {
HashEntryIterator hei = encodings.entryIterator();
while (hei.hasNext()) {
CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry> e =
((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)hei.next());
Entry ee = e.value;

visitor.defineEncoding(ee, e.bytes, e.p, e.end);
RubyEncoding encoding = RubyEncoding.newEncoding(runtime, e.bytes, e.p, e.end, ee.isDummy());
encodingList[ee.getIndex()] = encoding;

for (String constName : EncodingUtils.encodingNames(e.bytes, e.p, e.end)) {
visitor.defineConstant(ee.getIndex(), constName);
defineEncodingConstant(runtime, (RubyEncoding) encodingList[ee.getIndex()], constName);
}
}
}

public void defineAliases() {
defineAliases(new EncodingAliasVisitor() {
@Override
public void defineAlias(int encodingListIndex, String constName) { }

@Override
public void defineConstant(int encodingListIndex, String constName) {
defineEncodingConstant(runtime, (RubyEncoding) encodingList[encodingListIndex], constName);
}
});
}

public void defineAliases(EncodingAliasVisitor visitor) {
HashEntryIterator hei = aliases.entryIterator();
while (hei.hasNext()) {
CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry> e =
((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)hei.next());
Entry ee = e.value;

// The alias name should be exactly the one in the encodings DB.
visitor.defineAlias(ee.getIndex(), new String(e.bytes, e.p, e.end));

// The constant names must be treated by the the <code>encodingNames</code> helper.
for (String constName : EncodingUtils.encodingNames(e.bytes, e.p, e.end)) {
visitor.defineConstant(ee.getIndex(), constName);
defineEncodingConstant(runtime, (RubyEncoding) encodingList[ee.getIndex()], constName);
}
}
}
Original file line number Diff line number Diff line change
@@ -26,9 +26,7 @@
import org.jcodings.transcode.TranscoderDB;
import org.jcodings.util.CaseInsensitiveBytesHash;
import org.jcodings.util.Hash;
import org.jruby.Ruby;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.builtins.CoreClass;
@@ -59,48 +57,27 @@
public abstract class EncodingConverterNodes {

@NonStandard
@CoreMethod(names = "initialize_jruby", required = 2, optional = 1, visibility = Visibility.PRIVATE)
@CoreMethod(names = "initialize_jruby", required = 2, optional = 1, lowerFixnum = 3, visibility = Visibility.PRIVATE)
public abstract static class InitializeNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization
public DynamicObject initialize(DynamicObject self, Object source, Object destination, Object unusedOptions) {
@Specialization(guards = { "isRubyEncoding(source)", "isRubyEncoding(destination)" })
public DynamicObject initialize(DynamicObject self, DynamicObject source, DynamicObject destination, int options) {
// Adapted from RubyConverter - see attribution there

Ruby runtime = getContext().getJRubyRuntime();
Encoding[] encs = {null, null};
byte[][] encNames = {null, null};
int[] ecflags = {0};
IRubyObject[] ecopts = {runtime.getNil()};

final IRubyObject sourceAsJRubyObj = toJRuby(source);
final IRubyObject destinationAsJRubyObj = toJRuby(destination);

EncodingUtils.econvArgs(runtime.getCurrentContext(), new IRubyObject[]{sourceAsJRubyObj, destinationAsJRubyObj}, encNames, encs, ecflags, ecopts);

//
// This method should only be called after the Encoding::Converter instance has already been initialized
// by Rubinius. Rubinius will do the heavy lifting of parsing the options hash and setting the `@options`
// ivar to the resulting int for EConv flags. Since we don't pass the proper data structures to EncodingUtils,
// we must override the flags after its had a pass in order to correct the bad flags value.
ecflags[0] = rubiniusToJRubyFlags((int) self.get("@options", coreLibrary().getNilObject()));
// ivar to the resulting int for EConv flags.

EConv econv = EncodingUtils.econvOpenOpts(runtime.getCurrentContext(), encNames[0], encNames[1], ecflags[0], ecopts[0]);
Encoding sourceEncoding = Layouts.ENCODING.getEncoding(source);
Encoding destinationEncoding = Layouts.ENCODING.getEncoding(destination);
final byte[] sourceEncodingName = sourceEncoding.getName();
final byte[] destinationEncodingName = destinationEncoding.getName();

if (econv == null) {
throw new UnsupportedOperationException();
}
final EConv econv = TranscoderDB.open(sourceEncodingName, destinationEncodingName, rubiniusToJRubyFlags(options));

if (!EncodingUtils.DECORATOR_P(encNames[0], encNames[1])) {
if (encs[0] == null) {
encs[0] = EncodingDB.dummy(encNames[0]).getEncoding();
}
if (encs[1] == null) {
encs[1] = EncodingDB.dummy(encNames[1]).getEncoding();
}
}

econv.sourceEncoding = encs[0];
econv.destinationEncoding = encs[1];
econv.sourceEncoding = sourceEncoding;
econv.destinationEncoding = destinationEncoding;

Layouts.ENCODING_CONVERTER.setEconv(self, econv);

@@ -124,16 +101,6 @@ private int rubiniusToJRubyFlags(int flags) {
return flags;
}

private IRubyObject toJRuby(Object object) {
if (RubyGuards.isRubyString(object)) {
return getContext().getJRubyRuntime().newString(RopeOperations.toByteListCopy(StringOperations.rope((DynamicObject) object)));
} else if (RubyGuards.isRubyEncoding(object)) {
return getContext().getJRubyRuntime().getEncodingService().convertEncodingToRubyEncoding(Layouts.ENCODING.getEncoding((DynamicObject) object));
} else {
throw new UnsupportedOperationException();
}
}

}

@NonStandard