Skip to content

Commit 272e69f

Browse files
committed
Add Primitive.string_binary_append and start using it
1 parent befb4af commit 272e69f

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

src/main/java/org/truffleruby/core/string/StringNodes.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4247,6 +4247,8 @@ private Object bytesToInum(AbstractTruffleString tstring, RubyEncoding encoding,
42474247
}
42484248
}
42494249

4250+
/** The semantics of this primitive are such that the original string's byte[] should be extended without
4251+
* negotiating the encoding. */
42504252
@Primitive(name = "string_byte_append")
42514253
public abstract static class StringByteAppendPrimitiveNode extends PrimitiveArrayArgumentsNode {
42524254
@Specialization(guards = "libOther.isRubyString(other)", limit = "1")
@@ -4255,8 +4257,7 @@ protected RubyString stringByteAppend(RubyString string, Object other,
42554257
@Cached RubyStringLibrary libOther,
42564258
@Cached TruffleString.ConcatNode concatNode,
42574259
@Cached TruffleString.ForceEncodingNode forceEncodingNode) {
4258-
// The semantics of this primitive are such that the original string's byte[] should be extended without
4259-
// negotiating the encoding.
4260+
42604261
var leftEncoding = libString.getEncoding(string);
42614262
var left = string.tstring;
42624263
var right = forceEncodingNode.execute(libOther.getTString(other), libOther.getTEncoding(other),
@@ -4266,6 +4267,28 @@ protected RubyString stringByteAppend(RubyString string, Object other,
42664267
}
42674268
}
42684269

4270+
/** The semantics of this primitive are such that the LHS string must be BINARY and then the result is BINARY as
4271+
* well, and the RHS bytes are just appended to the LHS bytes, without encoding negotiation (which could cause the
4272+
* LHS encoding to change). */
4273+
@Primitive(name = "string_binary_append")
4274+
public abstract static class StringBinaryAppendNode extends PrimitiveArrayArgumentsNode {
4275+
@Specialization(guards = "libOther.isRubyString(other)", limit = "1")
4276+
protected RubyString stringBinaryAppend(RubyString string, Object other,
4277+
@Cached RubyStringLibrary libString,
4278+
@Cached RubyStringLibrary libOther,
4279+
@Cached TruffleString.ConcatNode concatNode,
4280+
@Cached TruffleString.ForceEncodingNode forceEncodingNode) {
4281+
if (libString.getEncoding(string) != Encodings.BINARY) {
4282+
throw CompilerDirectives.shouldNotReachHere("LHS String must be BINARY");
4283+
}
4284+
var left = string.tstring;
4285+
var right = forceEncodingNode.execute(libOther.getTString(other), libOther.getTEncoding(other),
4286+
Encodings.BINARY.tencoding);
4287+
string.setTString(concatNode.execute(left, right, Encodings.BINARY.tencoding, true), Encodings.BINARY);
4288+
return string;
4289+
}
4290+
}
4291+
42694292
@Primitive(name = "string_substring", lowerFixnum = { 1, 2 })
42704293
@ImportStatic(StringGuards.class)
42714294
public abstract static class StringSubstringPrimitiveNode extends PrimitiveArrayArgumentsNode {

src/main/ruby/truffleruby/core/marshal.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,30 +158,31 @@ def __custom_marshal__(ms)
158158
end
159159

160160
ivars = Primitive.object_ivars(self)
161-
out << 'I'.b
161+
Primitive.string_binary_append out, 'I'
162162

163163
cls = Primitive.object_class self
164164
if Primitive.module_anonymous?(cls)
165165
raise TypeError, "can't dump anonymous class #{cls}"
166166
end
167167
name = Primitive.module_name cls
168-
out << Truffle::Type.binary_string("u#{ms.serialize(name.to_sym)}")
168+
Primitive.string_binary_append out, "u#{ms.serialize(name.to_sym)}"
169169

170170
str = _dump
171-
out << ms.serialize_integer(str.bytesize) + str.b
171+
Primitive.string_binary_append out, ms.serialize_integer(str.bytesize)
172+
Primitive.string_binary_append out, str
172173

173174
count = ivars.size + extra_values.size
174-
out << ms.serialize_integer(count)
175+
Primitive.string_binary_append out, ms.serialize_integer(count)
175176

176177
ivars.each do |ivar|
177178
val = Primitive.object_ivar_get self, ivar
178-
out << ms.serialize(ivar)
179-
out << ms.serialize(val)
179+
Primitive.string_binary_append out, ms.serialize(ivar)
180+
Primitive.string_binary_append out, ms.serialize(val)
180181
end
181182

182183
extra_values.each_pair do |key, value|
183-
out << ms.serialize(key)
184-
out << ms.serialize(value)
184+
Primitive.string_binary_append out, ms.serialize(key)
185+
Primitive.string_binary_append out, ms.serialize(value)
185186
end
186187

187188
out

0 commit comments

Comments
 (0)