Skip to content

Commit 90244ee

Browse files
committed
Update the STable of delegates in P6Opaque.change_type.
This fixes a bug where cloning a P6Opaque resulted in an object of the wrong type if the opaque had a delegate and was then change_type-d without needing to introduce a new delegate. Thus obj.st != obj.delegate.st. Since P6OpaqueBaseInstance.clone simply clones the delegate if one is present, this resulted in an object of the wrong type under these conditions.
1 parent a141179 commit 90244ee

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

src/vm/jvm/runtime/org/perl6/nqp/sixmodel/reprs/P6Opaque.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -658,14 +658,15 @@ public void change_type(ThreadContext tc, SixModelObject obj, SixModelObject new
658658
// If there's a different number of attributes, need to set up delegate.
659659
// Note the condition below works because we don't make an entry in the
660660
// class handles list for a type with no attributes.
661+
P6OpaqueBaseInstance instance = (P6OpaqueBaseInstance)obj;
661662
if (ourREPRData.classHandles.length != targetREPRData.classHandles.length) {
662663
// Create delegate.
663664
SixModelObject delegate = newType.st.REPR.allocate(tc, newType.st);
664665

665666
// Find original object.
666667
SixModelObject orig;
667-
if (((P6OpaqueBaseInstance)obj).delegate != null)
668-
orig = ((P6OpaqueBaseInstance)obj).delegate;
668+
if (instance.delegate != null)
669+
orig = instance.delegate;
669670
else
670671
orig = obj;
671672

@@ -679,7 +680,13 @@ public void change_type(ThreadContext tc, SixModelObject obj, SixModelObject new
679680
catch (IllegalAccessException e) { throw new RuntimeException(e); }
680681

681682
// Install.
682-
((P6OpaqueBaseInstance)obj).delegate = delegate;
683+
instance.delegate = delegate;
684+
}
685+
// If we don't have to create a new delegate, but there's a delegate
686+
// in place already, the delegate needs a new STable as well.
687+
// Otherwise, methods introduced in the new type won't be available.
688+
else if(instance.delegate != null) {
689+
instance.delegate.st = newType.st;
683690
}
684691

685692
// Switch STable over to the new type.

0 commit comments

Comments
 (0)