Skip to content

Commit 9611eb2

Browse files
committed
Fix #1984: Clone labels in ensure block carefully ...
* When cloning ensure regions, don't clone jump/branch targets that don't exist in the ensure region.
1 parent c795b8f commit 9611eb2

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,18 @@ public void emitBody(IRBuilder b, IRScope s) {
222222

223223
public void cloneIntoHostScope(IRBuilder b, IRScope s) {
224224
InlinerInfo ii = new InlinerInfo(null, s, CloneMode.ENSURE_BLOCK_CLONE);
225+
226+
// Clone required labels.
227+
// During normal cloning below, labels not found in the rename map
228+
// are not cloned.
229+
ii.renameLabel(start);
230+
for (Instr i: instrs) {
231+
if (i instanceof LabelInstr) {
232+
ii.renameLabel(((LabelInstr)i).label);
233+
}
234+
}
235+
236+
// Clone instructions now
225237
b.addInstr(s, new LabelInstr(ii.getRenamedLabel(start)));
226238
b.addInstr(s, new ExceptionRegionStartMarkerInstr(bodyRescuer));
227239
for (Instr i: instrs) {

core/src/main/java/org/jruby/ir/transformations/inlining/InlinerInfo.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,29 @@ public IRScope getNewLexicalParentForClosure() {
131131
return hostScope;
132132
}
133133

134+
// Unconditional renaming of labels -- used to initialize ensure region cloning
135+
public void renameLabel(Label l) {
136+
Label newLbl = getInlineHostScope().getNewLabel();
137+
this.lblRenameMap.put(l, newLbl);
138+
}
139+
134140
public Label getRenamedLabel(Label l) {
135141
// Special case -- is there a way to avoid this?
136142
if (Label.UNRESCUED_REGION_LABEL.equals(l)) return l;
137143

138144
Label newLbl = this.lblRenameMap.get(l);
139145
if (newLbl == null) {
140-
newLbl = cloneMode == CloneMode.NORMAL_CLONE ? l.clone() : getInlineHostScope().getNewLabel();
141-
this.lblRenameMap.put(l, newLbl);
146+
if (cloneMode == CloneMode.ENSURE_BLOCK_CLONE) {
147+
// In ensure-block-clone mode, no cloning of labels not already pre-renamed and initialized
148+
// FIXME: IRScope.java:prepareInstructionsForInterpretation/Compilation assumes that
149+
// multiple labels with the same name are identical java objects. So, reuse the object here.
150+
newLbl = l;
151+
} else if (cloneMode == CloneMode.NORMAL_CLONE) {
152+
newLbl = l.clone();
153+
} else {
154+
newLbl = getInlineHostScope().getNewLabel();
155+
}
156+
this.lblRenameMap.put(l, newLbl);
142157
}
143158
return newLbl;
144159
}

0 commit comments

Comments
 (0)