Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 8dab723df87e
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0961f2dcf483
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Oct 27, 2014

  1. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    nomadium Miguel Landaeta
    Copy the full SHA
    be557da View commit details
  2. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    nomadium Miguel Landaeta
    Copy the full SHA
    9d24f55 View commit details
  3. For methods and other scopes do not mandatorily not allow ACP to run …

    …on them
    
    in case they happen to have an END block in them.
    
    I opened up issue #2073: END blocks in exotic scopes do not capture outer variables
    enebo committed Oct 27, 2014

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0961f2d View commit details
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -2959,11 +2959,13 @@ public Operand buildPostExe(PostExeNode postExeNode, IRScope s) {
closureBuilder.addInstr(endClosure, new CopyInstr(endClosure.getCurrentModuleVariable(), new ScopeModule(0)));
closureBuilder.build(postExeNode.getBodyNode(), endClosure);

// Record to IRScope so JIT can pre-compile all potentially activated END blocks.
topLevel.recordEndBlock(endClosure);

// Add an instruction in 's' to record the end block in the 'topLevel' scope.
// SSS FIXME: IR support for end-blocks that access vars in non-toplevel-scopes
// might be broken currently. We could either fix it or consider dropping support
// for END blocks altogether or only support them in the toplevel. Not worth the pain.
s.recordEndBlock(endClosure);
addInstr(s, new RecordEndBlockInstr(topLevel, new WrappedIRClosure(s.getSelf(), endClosure)));
return manager.getNil();
}
25 changes: 9 additions & 16 deletions core/src/main/java/org/jruby/ir/IRScope.java
Original file line number Diff line number Diff line change
@@ -527,22 +527,15 @@ protected Instr[] prepareInstructions() {
}

private boolean isUnsafeScope() {
boolean unsafeScope = false;
if (flags.contains(HAS_END_BLOCKS) || this.isBeginEndBlock()) {
unsafeScope = true;
} else {
List beginBlocks = this.getBeginBlocks();
// Ex: BEGIN {a = 1}; p a
if (beginBlocks == null || beginBlocks.isEmpty()) {
// Ex: eval("BEGIN {a = 1}; p a")
// Here, the BEGIN is added to the outer script scope.
beginBlocks = this.getNearestTopLocalVariableScope().getBeginBlocks();
unsafeScope = beginBlocks != null && !beginBlocks.isEmpty();
} else {
unsafeScope = true;
}
}
return unsafeScope;
if (this.isBeginEndBlock()) return true; // this is a BEGIN block

List beginBlocks = getBeginBlocks();
if (beginBlocks != null && !beginBlocks.isEmpty()) return true; // this contains a BEGIN block

// Does topmost variable scope contain any BEGIN blocks (IRScriptBody or IREval)?
// Ex1: eval("BEGIN {a = 1}; p a") Ex2: BEGIN {a = 1}; p a
beginBlocks = getNearestTopLocalVariableScope().getBeginBlocks();
return beginBlocks != null && !beginBlocks.isEmpty();
}

public List<CompilerPass> getExecutedPasses() {
Original file line number Diff line number Diff line change
@@ -57,21 +57,7 @@ public Object execute(IRScope scope, Object... data) {
scopeHasLocalVarStores = bindingHasEscaped;
}

boolean requireFrame = bindingHasEscaped || scope.usesEval();

for (IRFlags flag : scope.getFlags()) {
switch (flag) {
case BINDING_HAS_ESCAPED:
case CAN_CAPTURE_CALLERS_BINDING:
case REQUIRES_FRAME:
case REQUIRES_VISIBILITY:
case USES_BACKREF_OR_LASTLINE:
case USES_EVAL:
case USES_ZSUPER:
requireFrame = true;
}
}

boolean requireFrame = doesItRequireFrame(scope, bindingHasEscaped);
boolean requireBinding = !scope.getFlags().contains(IRFlags.DYNSCOPE_ELIMINATED);

if (requireBinding || requireFrame) {
@@ -148,6 +134,25 @@ public Object execute(IRScope scope, Object... data) {
return null;
}

private boolean doesItRequireFrame(IRScope scope, boolean bindingHasEscaped) {
boolean requireFrame = bindingHasEscaped || scope.usesEval();

for (IRFlags flag : scope.getFlags()) {
switch (flag) {
case BINDING_HAS_ESCAPED:
case CAN_CAPTURE_CALLERS_BINDING:
case REQUIRES_FRAME:
case REQUIRES_VISIBILITY:
case USES_BACKREF_OR_LASTLINE:
case USES_EVAL:
case USES_ZSUPER:
requireFrame = true;
}
}

return requireFrame;
}

@Override
public boolean invalidate(IRScope scope) {
// Cannot add call protocol instructions after we've added them once.