Skip to content

Instantly share code, notes, and snippets.

@headius

headius/aaa.rb Secret

Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/6b9742cea31910cd2875 to your computer and use it in GitHub Desktop.
Save headius/6b9742cea31910cd2875 to your computer and use it in GitHub Desktop.
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
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]
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