Skip to content

Commit 04897a1

Browse files
committed
Copy Data type's var table manager with new realClass
In order to allow Data types to specialize their fields completely, we introduced a copy constructor for VariableTableManager that duplicates the Data type's VTM into the new subclass. But because that duplicate still used the same realClass, variable accessors would frequently return to the original Data type's VTM rather than use the duplicate. This patch fixes the duplication process to also reset the realClass to the new Data type subclass, keeping all future usages and updates at the correct level. Without this, new instance variables discovered on subtypes would add an accessor on the subtype, but then proceed to allocate the variable table based on the size of the table in the old VTM from the Data supertype.
1 parent 0c09944 commit 04897a1

File tree

2 files changed

+10
-9
lines changed

2 files changed

+10
-9
lines changed

core/src/main/java/org/jruby/RubyClass.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ public static RubyClass newClass(ThreadContext context, RubyClass superClass, St
550550
baseName(name);
551551
clazz.makeMetaClass(context, superClass.getMetaClass());
552552
if (setParent) clazz.setParent(parent);
553-
clazz.copyVariableTableManager(context, superClass);
553+
clazz.copyVariableTableManagerForData(context, superClass);
554554
parent.setConstant(context, name, clazz, file, line);
555555
superClass.invokeInherited(context, superClass, clazz);
556556
return clazz;
@@ -1073,7 +1073,7 @@ private RubyClass initializeCommon(ThreadContext context, RubyClass superClazz,
10731073
allocator = superClazz.allocator;
10741074
makeMetaClass(context, superClazz.getMetaClass());
10751075
superClazz.addSubclass(this);
1076-
copyVariableTableManager(context, superClazz);
1076+
copyVariableTableManagerForData(context, superClazz);
10771077

10781078
marshal = superClazz.marshal;
10791079

@@ -1083,11 +1083,11 @@ private RubyClass initializeCommon(ThreadContext context, RubyClass superClazz,
10831083
return this;
10841084
}
10851085

1086-
private void copyVariableTableManager(ThreadContext context, RubyClass superClazz) {
1086+
private void copyVariableTableManagerForData(ThreadContext context, RubyClass superClazz) {
10871087
VariableTableManager variableTableManager = superClazz.getVariableTableManager();
10881088
if (variableTableManager.getRealClass().superClass() == context.runtime.getData()) {
10891089
// duplicate data's variable table in subclasses
1090-
this.variableTableManager = variableTableManager.duplicate();
1090+
this.variableTableManager = variableTableManager.duplicateForData(this);
10911091
}
10921092
}
10931093

core/src/main/java/org/jruby/runtime/ivars/VariableTableManager.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,14 @@ public VariableTableManager(RubyClass realClass) {
107107
}
108108

109109
/**
110-
* Copy constructor with deep cloning.
110+
* Copy constructor with deep cloning for subclasses of Data types. The new realClass will be the
111+
* subclass rather than the original Data type.
111112
*
112113
* @param original VariableTableManager to copy
113114
*/
114-
VariableTableManager(VariableTableManager original) {
115+
VariableTableManager(VariableTableManager original, RubyClass realClass) {
115116
synchronized (original) {
116-
this.realClass = original.realClass;
117+
this.realClass = realClass;
117118
this.variableAccessors = copyVariableAccessors(original.variableAccessors);
118119
this.variableNames = original.variableNames.clone();
119120
this.hasObjectID = original.hasObjectID;
@@ -544,8 +545,8 @@ public Object clearVariable(RubyBasicObject object, String name) {
544545
}
545546
}
546547

547-
public VariableTableManager duplicate() {
548-
return new VariableTableManager(this);
548+
public VariableTableManager duplicateForData(RubyClass newRealClass) {
549+
return new VariableTableManager(this, newRealClass);
549550
}
550551

551552
/**

0 commit comments

Comments
 (0)