Skip to content

Commit 5af77b6

Browse files
committed
Enable the creation of dummy encodings from C extensions.
1 parent 4c1f3cb commit 5af77b6

File tree

6 files changed

+62
-2
lines changed

6 files changed

+62
-2
lines changed

lib/truffle/truffle/cext.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,11 @@ def rb_enc_to_index(enc)
733733
Truffle.invoke_primitive :encoding_get_encoding_index, enc
734734
end
735735

736+
def rb_define_dummy_encoding(name)
737+
enc, idx = Truffle::EncodingOperations.dummy_encoding(name)
738+
idx
739+
end
740+
736741
def rb_str_new_frozen(value)
737742
if value.frozen?
738743
value
@@ -899,7 +904,7 @@ def rb_str_encode(str, to, ecflags, ecopts)
899904
end
900905

901906
def rb_str_conv_enc_opts(str, from, to, ecflags, ecopts)
902-
if (to.ascii_compatible? && str.ascii_only?) || to == Encoding::ASCII_8BIT
907+
if (to.ascii_compatible? && str.ascii_only?) || to == Encoding::ASCII_8BIT || to.dummy?
903908
if str.encoding != to
904909
str = str.dup
905910
str.force_encoding(to)

src/main/c/cext/ruby.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3099,7 +3099,7 @@ int rb_enc_replicate(const char *name, rb_encoding *encoding) {
30993099
}
31003100

31013101
int rb_define_dummy_encoding(const char *name) {
3102-
rb_tr_error("rb_define_dummy_encoding not implemented");
3102+
return polyglot_as_i32(RUBY_CEXT_INVOKE_NO_WRAP("rb_define_dummy_encoding", rb_str_new_cstr(name)));
31033103
}
31043104

31053105
#undef rb_enc_str_new_cstr

src/main/java/org/truffleruby/core/CoreLibrary.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,7 @@ public DynamicObject getWarningModule() {
14241424
"/core/truffle/boot.rb",
14251425
"/core/truffle/debug.rb",
14261426
"/core/truffle/warnings.rb",
1427+
"/core/truffle/encoding_operations.rb",
14271428
"/core/truffle/exception_operations.rb",
14281429
"/core/truffle/hash_operations.rb",
14291430
"/core/truffle/numeric_operations.rb",

src/main/java/org/truffleruby/core/encoding/EncodingManager.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,18 @@ public DynamicObject defineAlias(Encoding encoding, String name) {
260260
return rubyEncoding;
261261
}
262262

263+
@TruffleBoundary
264+
public synchronized DynamicObject dummyEncoding(String name) {
265+
if (getRubyEncoding(name) != null) {
266+
return null;
267+
}
268+
269+
EncodingDB.dummy(name);
270+
byte[] nameBytes = name.getBytes();
271+
final Entry entry = EncodingDB.getEncodings().get(nameBytes);
272+
return defineEncoding(entry, nameBytes, 0, nameBytes.length);
273+
}
274+
263275
@TruffleBoundary
264276
public synchronized DynamicObject replicateEncoding(Encoding encoding, String name) {
265277
if (getRubyEncoding(name) != null) {

src/main/java/org/truffleruby/core/encoding/EncodingNodes.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,29 @@ private DynamicObject replicate(String name, Encoding encoding) {
676676

677677
}
678678

679+
@Primitive(name = "dummy_encoding", needsSelf = false)
680+
public static abstract class DummyEncodingeNode extends PrimitiveArrayArgumentsNode {
681+
682+
@Specialization(guards = "isRubyString(nameObject)")
683+
public DynamicObject dummyEncoding(DynamicObject nameObject) {
684+
final String name = StringOperations.getString(nameObject);
685+
686+
final DynamicObject newEncoding = dummy(name);
687+
if (newEncoding == null) {
688+
throw new RaiseException(getContext(), coreExceptions().argumentErrorEncodingAlreadyRegistered(name, this));
689+
}
690+
691+
final int index = Layouts.ENCODING.getEncoding(newEncoding).getIndex();
692+
return createArray(new Object[]{ newEncoding, index }, 2);
693+
}
694+
695+
@TruffleBoundary
696+
private DynamicObject dummy(String name) {
697+
return getContext().getEncodingManager().dummyEncoding(name);
698+
}
699+
700+
}
701+
679702
@Primitive(name = "encoding_get_encoding_by_index", needsSelf = false, lowerFixnum = 1)
680703
public static abstract class GetEncodingObjectByIndexNode extends PrimitiveArrayArgumentsNode {
681704

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. This
4+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
5+
# redistribute it and/or modify it under the terms of the:
6+
#
7+
# Eclipse Public License version 1.0, or
8+
# GNU General Public License version 2, or
9+
# GNU Lesser General Public License version 2.1.
10+
11+
module Truffle
12+
module EncodingOperations
13+
def self.dummy_encoding(name)
14+
new_encoding, index = Truffle.invoke_primitive :dummy_encoding, name
15+
::Encoding::EncodingMap[name.upcase.to_sym] = [nil, index]
16+
[new_encoding, index]
17+
end
18+
end
19+
end

0 commit comments

Comments
 (0)