Skip to content

Commit

Permalink
Fix #1984: Clone labels in ensure block carefully ...
Browse files Browse the repository at this point in the history
* When cloning ensure regions, don't clone jump/branch targets
  that don't exist in the ensure region.
  • Loading branch information
subbuss committed Sep 19, 2014
1 parent c795b8f commit 9611eb2
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
12 changes: 12 additions & 0 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Expand Up @@ -222,6 +222,18 @@ public void emitBody(IRBuilder b, IRScope s) {

public void cloneIntoHostScope(IRBuilder b, IRScope s) {
InlinerInfo ii = new InlinerInfo(null, s, CloneMode.ENSURE_BLOCK_CLONE);

// Clone required labels.
// During normal cloning below, labels not found in the rename map
// are not cloned.
ii.renameLabel(start);
for (Instr i: instrs) {
if (i instanceof LabelInstr) {
ii.renameLabel(((LabelInstr)i).label);
}
}

// Clone instructions now
b.addInstr(s, new LabelInstr(ii.getRenamedLabel(start)));
b.addInstr(s, new ExceptionRegionStartMarkerInstr(bodyRescuer));
for (Instr i: instrs) {
Expand Down
Expand Up @@ -131,14 +131,29 @@ public IRScope getNewLexicalParentForClosure() {
return hostScope;
}

// Unconditional renaming of labels -- used to initialize ensure region cloning
public void renameLabel(Label l) {
Label newLbl = getInlineHostScope().getNewLabel();
this.lblRenameMap.put(l, newLbl);
}

public Label getRenamedLabel(Label l) {
// Special case -- is there a way to avoid this?
if (Label.UNRESCUED_REGION_LABEL.equals(l)) return l;

Label newLbl = this.lblRenameMap.get(l);
if (newLbl == null) {
newLbl = cloneMode == CloneMode.NORMAL_CLONE ? l.clone() : getInlineHostScope().getNewLabel();
this.lblRenameMap.put(l, newLbl);
if (cloneMode == CloneMode.ENSURE_BLOCK_CLONE) {
// In ensure-block-clone mode, no cloning of labels not already pre-renamed and initialized
// FIXME: IRScope.java:prepareInstructionsForInterpretation/Compilation assumes that
// multiple labels with the same name are identical java objects. So, reuse the object here.
newLbl = l;
} else if (cloneMode == CloneMode.NORMAL_CLONE) {
newLbl = l.clone();
} else {
newLbl = getInlineHostScope().getNewLabel();
}
this.lblRenameMap.put(l, newLbl);
}
return newLbl;
}
Expand Down

0 comments on commit 9611eb2

Please sign in to comment.