-
-
Save headius/6b9742cea31910cd2875 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
it "properly expands (or not) child class's 'each'-yielded args" do | |
cls1 = Class.new(Hash) do | |
attr_accessor :k_v | |
def each | |
super do |k, v| | |
@k_v = [k, v] | |
yield k, v | |
end | |
end | |
end | |
cls2 = Class.new(Hash) do | |
attr_accessor :k_v | |
def each | |
super do |k, v| | |
@k_v = [k, v] | |
yield([k, v]) | |
end | |
end | |
end | |
obj1 = cls1.new | |
obj1['a'] = 'b' | |
obj1.map {|k, v| [k, v]}.should == [['a', 'b']] | |
obj1.k_v.should == ['a', 'b'] | |
obj2 = cls2.new | |
obj2['a'] = 'b' | |
obj2.map {|k, v| [k, v]}.should == [['a', 'b']] | |
obj2.k_v.should == ['a', 'b'] | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10-27T15:59:33.850-05:00: BasicCompilerPassListener: Starting Optimize Dynamic Scopes on scope CLOSURE each_CLOSURE_1[/Users/headius/projects/jruby/spec/ruby/core/hash/shared/each.rb:40] | |
2014-10-27T15:59:33.850-05:00: BasicCompilerPassListener: | |
Graph: | |
BB [1:CL1_LBL_2:-1]:>[2,6] | |
BB [2:CL1_LBL_3:-1]:>[3], <[1] | |
BB [3:_CLOSURE_START_0:-1]:>[4,6], <[2] | |
BB [4:_GLOBAL_ENSURE_BLOCK__0:-1]:>[6], <[3] | |
BB [6:CL1_LBL_4:-1]:<[1,3,4] | |
2014-10-27T15:59:33.850-05:00: BasicCompilerPassListener: | |
Instructions: | |
BB [1:CL1_LBL_2:-1] | |
BB [2:CL1_LBL_3:-1] | |
%self = recv_self | |
%t_k_2 = recv_pre_reqd_arg(0) | |
%t_v_3 = recv_pre_reqd_arg(1) | |
thread_poll | |
BB [3:_CLOSURE_START_0:-1] | |
line_num(41) | |
put_field(%self, @k_v) = Array:[%t_k_2, %t_v_3] | |
line_num(42) | |
%v_0 = yield(%block(0:0), UNWRAP(Array:[%t_k_2, %t_v_3])) | |
return(%v_0) | |
BB [4:_GLOBAL_ENSURE_BLOCK__0:-1] | |
%v_0 = recv_jruby_exc | |
%v_1 = runtime_helper(HANDLE_BREAK_AND_RETURNS_IN_LAMBDA, [%v_0]) | |
return(%v_1) | |
BB [6:CL1_LBL_4:-1] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/src/main/java/org/jruby/ir/instructions/CallBase.java b/core/src/main/java/org/jruby/ir/instructions/CallBase.java | |
index 3db6bc1..be1fc1e 100644 | |
--- a/core/src/main/java/org/jruby/ir/instructions/CallBase.java | |
+++ b/core/src/main/java/org/jruby/ir/instructions/CallBase.java | |
@@ -131,6 +131,10 @@ public abstract class CallBase extends Instr implements Specializeable, ClosureA | |
return closure != null; | |
} | |
+ public boolean hasLiteralClosure() { | |
+ return closure instanceof WrappedIRClosure; | |
+ } | |
+ | |
public boolean isAllConstants() { | |
for (Operand argument : arguments) { | |
if (!(argument instanceof ImmutableLiteral)) return false; | |
@@ -287,9 +291,8 @@ public abstract class CallBase extends Instr implements Specializeable, ClosureA | |
private boolean computeRequiresCallersBindingFlag() { | |
if (canBeEval()) return true; | |
- // Conservative -- assuming that the callee will save the closure | |
- // and use it at a later point. | |
- if (closure != null) return true; | |
+ // literal closures can be used to capture surrounding binding | |
+ if (hasLiteralClosure()) return true; | |
String mname = getMethodAddr().getName(); | |
if (MethodIndex.SCOPE_AWARE_METHODS.contains(mname)) { | |
@@ -345,9 +348,8 @@ public abstract class CallBase extends Instr implements Specializeable, ClosureA | |
private boolean computeRequiresCallersFrameFlag() { | |
if (canBeEval()) return true; | |
- // Conservative -- assuming that the callee will save the closure | |
- // and use it at a later point. | |
- if (closure != null) return true; | |
+ // literal closures can be used to capture surrounding binding | |
+ if (hasLiteralClosure()) return true; | |
if (procNew) return true; | |
diff --git a/core/src/main/java/org/jruby/ir/instructions/UnresolvedSuperInstr.java b/core/src/main/java/org/jruby/ir/instructions/UnresolvedSuperInstr.java | |
index d91e691..a5afc68 100644 | |
--- a/core/src/main/java/org/jruby/ir/instructions/UnresolvedSuperInstr.java | |
+++ b/core/src/main/java/org/jruby/ir/instructions/UnresolvedSuperInstr.java | |
@@ -1,5 +1,7 @@ | |
package org.jruby.ir.instructions; | |
+import org.jruby.ir.IRFlags; | |
+import org.jruby.ir.IRScope; | |
import org.jruby.ir.IRVisitor; | |
import org.jruby.ir.Operation; | |
import org.jruby.ir.operands.MethAddr; | |
@@ -25,6 +27,12 @@ public class UnresolvedSuperInstr extends CallInstr { | |
} | |
@Override | |
+ public boolean computeScopeFlags(IRScope scope) { | |
+ scope.getFlags().add(IRFlags.REQUIRES_FRAME); // for current class and method name | |
+ return true; | |
+ } | |
+ | |
+ @Override | |
public Instr clone(CloneInfo ii) { | |
return new UnresolvedSuperInstr(ii.getRenamedVariable(getResult()), getReceiver().cloneForInlining(ii), cloneCallArgs(ii), closure == null ? null : closure.cloneForInlining(ii)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment