Skip to content

Commit

Permalink
Capture shared variable iter state immediately
Browse files Browse the repository at this point in the history
If not captured immediately, contained objects will be dumped and
clear this state, breaking the variable count just acquired.
  • Loading branch information
headius committed May 28, 2024
1 parent 0259e72 commit 982fb2e
Showing 1 changed file with 33 additions and 39 deletions.
72 changes: 33 additions & 39 deletions core/src/main/java/org/jruby/runtime/marshal/NewMarshal.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,31 +212,29 @@ public void writeDirectly(ThreadContext context, RubyOutputStream out, IRubyObje

} else {

try {
var ivarAccessors = checkVariables(value, shouldMarshalEncoding);

if (doVariables) {
// object has instance vars and isn't a class, get a snapshot to be marshalled
// and output the ivar header here
var ivarAccessors = checkVariables(value, shouldMarshalEncoding);
int size = variableCount;
clearVariableState();

// write `I' instance var signet if class is NOT a direct subclass of Object
out.write(TYPE_IVAR);
dumpBaseObject(context, out, value, nativeClassIndex);
if (doVariables) {
// object has instance vars and isn't a class, get a snapshot to be marshalled
// and output the ivar header here

if (shouldMarshalEncoding) {
writeInt(out, variableCount + 1); // vars preceded by encoding
writeEncoding(context, out, ((MarshalEncoding) value).getMarshalEncoding());
} else {
writeInt(out, variableCount);
}
// write `I' instance var signet if class is NOT a direct subclass of Object
out.write(TYPE_IVAR);
dumpBaseObject(context, out, value, nativeClassIndex);

ivarAccessors.forEach(new VariableDumper(context, out, value));
if (shouldMarshalEncoding) {
writeInt(out, size + 1); // vars preceded by encoding
writeEncoding(context, out, ((MarshalEncoding) value).getMarshalEncoding());
} else {
// no variables, no encoding
dumpBaseObject(context, out, value, nativeClassIndex);
writeInt(out, size);
}
} finally {
clearVariableState();

ivarAccessors.forEach(new VariableDumper(context, out, value));
} else {
// no variables, no encoding
dumpBaseObject(context, out, value, nativeClassIndex);
}

}
Expand Down Expand Up @@ -458,21 +456,19 @@ private void userCommon(ThreadContext context, RubyOutputStream out, IRubyObject
RubyString marshaled = castToString(context, dumpResult);

if (marshaled.hasVariables()) {
try {
var ivarAccessors = countVariables(marshaled);
var ivarAccessors = countVariables(marshaled);
int size = variableCount;
clearVariableState();

if (variableCount > 0) {
out.write(TYPE_IVAR);
dumpUserdefBase(out, runtime, klass, marshaled);
if (size > 0) {
out.write(TYPE_IVAR);
dumpUserdefBase(out, runtime, klass, marshaled);

writeInt(out, variableCount);
writeInt(out, size);

ivarAccessors.forEach(new VariableDumper(context, out, marshaled));
} else {
dumpUserdefBase(out, runtime, klass, marshaled);
}
} finally {
clearVariableState();
ivarAccessors.forEach(new VariableDumper(context, out, marshaled));
} else {
dumpUserdefBase(out, runtime, klass, marshaled);
}
} else {
dumpUserdefBase(out, runtime, klass, marshaled);
Expand Down Expand Up @@ -506,15 +502,13 @@ public void dumpVariables(ThreadContext context, RubyOutputStream out, IRubyObje
}

public void dumpVariables(ThreadContext context, RubyOutputStream out, IRubyObject value, int extraSize) {
try {
Map<String, VariableAccessor> ivarAccessors = countVariables(value, extraSize);
Map<String, VariableAccessor> ivarAccessors = countVariables(value, extraSize);
int size = variableCount;
clearVariableState();

writeInt(out, variableCount);
writeInt(out, size);

ivarAccessors.forEach(new VariableDumper(context, out, value));
} finally {
clearVariableState();
}
ivarAccessors.forEach(new VariableDumper(context, out, value));
}

private Map<String, VariableAccessor> countVariables(IRubyObject value) {
Expand Down

0 comments on commit 982fb2e

Please sign in to comment.