Skip to content

Commit 1e85fce

Browse files
committed
[GR-20165] Fix Kernel#clone for special values.
PullRequest: truffleruby/1199
2 parents eb01e3e + 81812c4 commit 1e85fce

File tree

5 files changed

+74
-10
lines changed

5 files changed

+74
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Bug fixes:
5050
* Implement Numeric#clone method to return self.
5151
* Fixed `Symbol#to_proc` to create proc with nil `source_location` (#1663).
5252
* Make `GC.start` work with keyword arguments.
53+
* Fixed `Kernel#clone` for `nil`, `true`, `false`, `Integer`, and `Symbol`.
5354

5455
Compatibility:
5556

spec/tags/core/kernel/clone_tags.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/main/java/org/truffleruby/core/exception/CoreExceptions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ public DynamicObject argumentErrorInvalidBigDecimal(String string, Node currentN
225225
return argumentError(StringUtils.format("invalid value for BigDecimal(): \"%s\"", string), currentNode);
226226
}
227227

228+
public DynamicObject argumentErrorCantUnfreeze(Object self, Node currentNode) {
229+
String className = Layouts.MODULE.getFields(context.getCoreLibrary().getLogicalClass(self)).getName();
230+
return argumentError(StringUtils.format("can't unfreeze %s", className), currentNode);
231+
}
232+
228233
// FrozenError
229234

230235
@TruffleBoundary

src/main/java/org/truffleruby/core/kernel/KernelNodes.java

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ protected RubyNode coerceToBoolean(RubyNode freeze) {
459459
return BooleanCastWithDefaultNodeGen.create(true, freeze);
460460
}
461461

462-
@Specialization
462+
@Specialization(guards = { "!isNil(self)", "!isRubyBignum(self)", "!isRubySymbol(self)" })
463463
protected DynamicObject clone(VirtualFrame frame, DynamicObject self, boolean freeze,
464464
@Cached("createBinaryProfile()") ConditionProfile isSingletonProfile,
465465
@Cached("createBinaryProfile()") ConditionProfile freezeProfile,
@@ -494,6 +494,73 @@ protected DynamicObject clone(VirtualFrame frame, DynamicObject self, boolean fr
494494
return newObject;
495495
}
496496

497+
@Specialization
498+
protected Object cloneBoolean(boolean self, boolean freeze,
499+
@Cached("createBinaryProfile()") ConditionProfile freezeProfile) {
500+
if (freezeProfile.profile(!freeze)) {
501+
raiseCantUnfreezeError(self);
502+
}
503+
return self;
504+
}
505+
506+
@Specialization
507+
protected Object cloneInteger(int self, boolean freeze,
508+
@Cached("createBinaryProfile()") ConditionProfile freezeProfile) {
509+
if (freezeProfile.profile(!freeze)) {
510+
raiseCantUnfreezeError(self);
511+
}
512+
return self;
513+
}
514+
515+
@Specialization
516+
protected Object cloneLong(long self, boolean freeze,
517+
@Cached("createBinaryProfile()") ConditionProfile freezeProfile) {
518+
if (freezeProfile.profile(!freeze)) {
519+
raiseCantUnfreezeError(self);
520+
}
521+
return self;
522+
}
523+
524+
@Specialization
525+
protected Object cloneFloat(double self, boolean freeze,
526+
@Cached("createBinaryProfile()") ConditionProfile freezeProfile) {
527+
if (freezeProfile.profile(!freeze)) {
528+
raiseCantUnfreezeError(self);
529+
}
530+
return self;
531+
}
532+
533+
@Specialization(guards = "isNil(nil)")
534+
protected Object cloneNil(Object nil, boolean freeze,
535+
@Cached("createBinaryProfile()") ConditionProfile freezeProfile) {
536+
if (freezeProfile.profile(!freeze)) {
537+
raiseCantUnfreezeError(nil);
538+
}
539+
return nil;
540+
}
541+
542+
@Specialization(guards = "isRubyBignum(object)")
543+
protected Object cloneBignum(DynamicObject object, boolean freeze,
544+
@Cached("createBinaryProfile()") ConditionProfile freezeProfile) {
545+
if (freezeProfile.profile(!freeze)) {
546+
raiseCantUnfreezeError(object);
547+
}
548+
return object;
549+
}
550+
551+
@Specialization(guards = "isRubySymbol(symbol)")
552+
protected Object cloneSymbol(DynamicObject symbol, boolean freeze,
553+
@Cached("createBinaryProfile()") ConditionProfile freezeProfile) {
554+
if (freezeProfile.profile(!freeze)) {
555+
raiseCantUnfreezeError(symbol);
556+
}
557+
return symbol;
558+
}
559+
560+
private void raiseCantUnfreezeError(Object self) {
561+
throw new RaiseException(getContext(), coreExceptions().argumentErrorCantUnfreeze(self, this));
562+
}
563+
497564
private DynamicObject executeSingletonClass(DynamicObject newObject) {
498565
if (singletonClassNode == null) {
499566
CompilerDirectives.transferToInterpreterAndInvalidate();

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ def protected_singleton_methods
5151
[]
5252
end
5353
private :protected_singleton_methods
54-
55-
def clone
56-
raise TypeError, "can't clone #{self.class.name}"
57-
end
5854
end
5955

6056
class NilClass

0 commit comments

Comments
 (0)