71
71
import org .truffleruby .core .proc .ProcNodes .ProcNewNode ;
72
72
import org .truffleruby .core .proc .ProcOperations ;
73
73
import org .truffleruby .core .proc .RubyProc ;
74
+ import org .truffleruby .core .range .RubyIntOrLongRange ;
75
+ import org .truffleruby .core .range .RubyObjectRange ;
74
76
import org .truffleruby .core .rope .CodeRange ;
75
77
import org .truffleruby .core .rope .Rope ;
76
78
import org .truffleruby .core .rope .RopeNodes ;
125
127
import org .truffleruby .language .objects .AllocationTracing ;
126
128
import org .truffleruby .language .objects .CheckIVarNameNode ;
127
129
import org .truffleruby .language .objects .IsANode ;
128
- import org .truffleruby .language .objects .IsImmutableObjectNode ;
130
+ import org .truffleruby .language .objects .IsCopyableObjectNode ;
131
+ import org .truffleruby .language .objects .IsCopyableObjectNodeGen ;
129
132
import org .truffleruby .language .objects .LogicalClassNode ;
130
133
import org .truffleruby .language .objects .MetaClassNode ;
131
134
import org .truffleruby .language .objects .ShapeCachingGuards ;
@@ -522,7 +525,7 @@ protected RubyDynamicObject copyRubyDynamicObject(RubyDynamicObject self,
522
525
}
523
526
524
527
@ Specialization
525
- protected RubyClass copyRubyClass (RubyClass self ,
528
+ protected RubyDynamicObject copyRubyClass (RubyClass self ,
526
529
@ Cached CopyInstanceVariablesNode copyInstanceVariablesNode ) {
527
530
var newClass = new RubyClass (coreLibrary ().classClass , getLanguage (), getEncapsulatingSourceSection (),
528
531
null , null , false , null , self .superclass );
@@ -531,33 +534,40 @@ protected RubyClass copyRubyClass(RubyClass self,
531
534
}
532
535
533
536
@ Specialization
534
- protected RubyString copyImmutableString (ImmutableRubyString string ,
537
+ protected RubyDynamicObject copy (ImmutableRubyString string ,
535
538
@ Cached DispatchNode allocateStringNode ) {
536
539
return (RubyString ) allocateStringNode .call (coreLibrary ().stringClass , "__allocate__" );
537
540
}
541
+
542
+ @ Specialization
543
+ protected RubyDynamicObject copy (RubyIntOrLongRange range ,
544
+ @ Cached DispatchNode allocateRangeNode ) {
545
+ return (RubyObjectRange ) allocateRangeNode .call (coreLibrary ().rangeClass , "__allocate__" );
546
+ }
538
547
}
539
548
540
- @ Primitive (name = "object_clone" )
549
+ @ Primitive (name = "object_clone" ) // "clone"
541
550
@ NodeChild (value = "object" , type = RubyNode .class )
542
551
@ NodeChild (value = "freeze" , type = RubyBaseNodeWithExecute .class )
543
552
public abstract static class CloneNode extends PrimitiveNode {
544
553
545
- @ Child private SingletonClassNode singletonClassNode ;
554
+ @ Child IsCopyableObjectNode isCopyableObjectNode = IsCopyableObjectNodeGen .create ();
555
+ @ Child SingletonClassNode singletonClassNode ;
546
556
private final BranchProfile cantUnfreezeErrorProfile = BranchProfile .create ();
547
557
548
- @ Specialization (limit = "getRubyLibraryCacheLimit()" )
549
- protected RubyDynamicObject clone (RubyDynamicObject object , Object freeze ,
558
+ @ Specialization (guards = "isCopyableObjectNode.execute(object)" , limit = "getRubyLibraryCacheLimit()" )
559
+ protected RubyDynamicObject copyable (Object object , Object freeze ,
560
+ @ Cached MetaClassNode metaClassNode ,
550
561
@ Cached CopyNode copyNode ,
551
562
@ Cached DispatchNode initializeCloneNode ,
552
563
@ Cached ConditionProfile isSingletonProfile ,
553
- @ Cached ConditionProfile isRubyClass ,
554
564
@ Cached HashingNodes .ToHashByHashCode hashNode ,
555
565
@ CachedLibrary ("object" ) RubyLibrary rubyLibrary ,
556
566
@ CachedLibrary (limit = "getRubyLibraryCacheLimit()" ) RubyLibrary rubyLibraryFreeze ) {
557
567
final RubyDynamicObject newObject = copyNode .executeCopy (object );
558
568
559
569
// Copy the singleton class if any.
560
- final RubyClass selfMetaClass = object . getMetaClass ( );
570
+ final RubyClass selfMetaClass = metaClassNode . execute ( object );
561
571
if (isSingletonProfile .profile (selfMetaClass .isSingleton )) {
562
572
final RubyClass newObjectMetaClass = executeSingletonClass (newObject );
563
573
newObjectMetaClass .fields .initCopy (selfMetaClass );
@@ -581,58 +591,14 @@ protected RubyDynamicObject clone(RubyDynamicObject object, Object freeze,
581
591
return newObject ;
582
592
}
583
593
584
- @ Specialization
585
- protected boolean cloneBoolean (boolean object , Object freeze ) {
586
- if (forceNotFrozen (freeze )) {
587
- raiseCantUnfreezeError (object );
588
- }
589
- return object ;
590
- }
591
-
592
- @ Specialization
593
- protected int cloneInteger (int object , Object freeze ) {
594
- if (forceNotFrozen (freeze )) {
595
- raiseCantUnfreezeError (object );
596
- }
597
- return object ;
598
- }
599
-
600
- @ Specialization
601
- protected long cloneLong (long object , Object freeze ) {
594
+ @ Specialization (guards = "!isCopyableObjectNode.execute(object)" )
595
+ protected Object notCopyable (Object object , Object freeze ) {
602
596
if (forceNotFrozen (freeze )) {
603
597
raiseCantUnfreezeError (object );
604
598
}
605
599
return object ;
606
600
}
607
601
608
- @ Specialization
609
- protected double cloneFloat (double object , Object freeze ) {
610
- if (forceNotFrozen (freeze )) {
611
- raiseCantUnfreezeError (object );
612
- }
613
- return object ;
614
- }
615
-
616
- @ Specialization (guards = "!isImmutableRubyString(object)" )
617
- protected ImmutableRubyObject cloneImmutableObject (ImmutableRubyObject object , Object freeze ) {
618
- if (forceNotFrozen (freeze )) {
619
- raiseCantUnfreezeError (object );
620
- }
621
- return object ;
622
- }
623
-
624
- @ Specialization
625
- protected RubyDynamicObject cloneImmutableRubyString (ImmutableRubyString object , Object freeze ,
626
- @ CachedLibrary (limit = "getRubyLibraryCacheLimit()" ) RubyLibrary rubyLibraryFreeze ,
627
- @ Cached MakeStringNode makeStringNode ) {
628
- final RubyDynamicObject newObject = makeStringNode .fromRope (object .rope , object .encoding );
629
- if (!forceNotFrozen (freeze )) {
630
- rubyLibraryFreeze .freeze (newObject );
631
- }
632
-
633
- return newObject ;
634
- }
635
-
636
602
private RubyHash createFreezeBooleanHash (boolean freeze , HashingNodes .ToHashByHashCode hashNode ) {
637
603
final RubySymbol key = coreSymbols ().FREEZE ;
638
604
@@ -677,20 +643,19 @@ private RubyClass executeSingletonClass(RubyDynamicObject newObject) {
677
643
public abstract static class DupNode extends AlwaysInlinedMethodNode {
678
644
@ Specialization
679
645
protected Object dup (Frame callerFrame , Object self , Object [] rubyArgs , RootCallTarget target ,
680
- @ Cached IsImmutableObjectNode isImmutableObjectNode ,
681
- @ Cached ConditionProfile immutableProfile ,
646
+ @ Cached IsCopyableObjectNode isCopyableObjectNode ,
647
+ @ Cached ConditionProfile isCopyableProfile ,
682
648
@ Cached CopyNode copyNode ,
683
649
@ Cached DispatchNode initializeDupNode ) {
684
- if (immutableProfile
685
- .profile (!(self instanceof ImmutableRubyString ) && isImmutableObjectNode .execute (self ))) {
686
- return self ;
687
- }
650
+ if (isCopyableProfile .profile (isCopyableObjectNode .execute (self ))) {
651
+ final RubyDynamicObject copy = copyNode .executeCopy (self );
688
652
689
- final RubyDynamicObject newObject = copyNode . executeCopy ( self );
653
+ initializeDupNode . call ( copy , "initialize_dup" , self );
690
654
691
- initializeDupNode .call (newObject , "initialize_dup" , self );
692
-
693
- return newObject ;
655
+ return copy ;
656
+ } else {
657
+ return self ;
658
+ }
694
659
}
695
660
}
696
661
0 commit comments