Skip to content

Commit 8899356

Browse files
committed
Clone instructions properly before rebuilding interpreter context.
* This fixes failing tests on this branch.
1 parent ce466f2 commit 8899356

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

core/src/main/java/org/jruby/ir/IRScope.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public abstract class IRScope implements ParseResult {
142142

143143
// What state is this scope in?
144144
enum ScopeState {
145-
INIT, INSTRS_CLONED, CFG_BUILT
145+
INIT, INTERPED, INSTRS_CLONED, CFG_BUILT
146146
};
147147

148148
private ScopeState state = ScopeState.INIT;
@@ -455,6 +455,13 @@ public CFG buildCFG() {
455455
return getCFG();
456456
}
457457

458+
// If the scope has already been interpreted once,
459+
// the scope can be on the call stack right now.
460+
// So, clone instructions before building the CFG.
461+
if (this.state == ScopeState.INTERPED) {
462+
this.cloneInstrs();
463+
}
464+
458465
CFG newCFG = new CFG(this);
459466
newCFG.build(getInstrs());
460467
// Clear out instruction list after CFG has been built.
@@ -637,7 +644,7 @@ public InterpreterContext prepareForInterpretation() {
637644
}
638645

639646
protected void cloneInstrs() {
640-
if (this.state == ScopeState.INIT) {
647+
if (getCFG() == null) {
641648
// Clone instrs before modifying them
642649
SimpleCloneInfo cloneInfo = new SimpleCloneInfo(this, false);
643650
List<Instr> newInstrList = new ArrayList<Instr>(this.instrList.size());
@@ -647,20 +654,22 @@ protected void cloneInstrs() {
647654
this.instrList = newInstrList;
648655
this.state = ScopeState.INSTRS_CLONED;
649656
}
657+
for (IRClosure cl: getClosures()) {
658+
cl.cloneInstrs();
659+
}
650660
}
651661

652662
/** Run any necessary passes to get the IR ready for interpretation */
653663
public synchronized InterpreterContext prepareForInterpretation(boolean rebuild) {
654-
if (interpreterContext != null) {
664+
if (interpreterContext == null) {
665+
this.state = ScopeState.INTERPED;
666+
} else {
655667
if (!rebuild || getCFG() != null) {
656668
return interpreterContext; // Already prepared/rebuilt
657669
}
658670

659671
// If rebuilding, clone instrs before building cfg, running passes, etc.
660672
this.cloneInstrs();
661-
for (IRClosure cl: getClosures()) {
662-
cl.cloneInstrs();
663-
}
664673

665674
// Build CFG, run passes, etc.
666675
initScope(false);

0 commit comments

Comments
 (0)