Skip to content

Commit fe1daf6

Browse files
committed
[GR-16067] Super call block arg fix.
PullRequest: truffleruby/863
2 parents f5bde7e + bb0de54 commit fe1daf6

File tree

6 files changed

+30
-19
lines changed

6 files changed

+30
-19
lines changed

spec/ruby/language/super_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,25 @@ def m(v)
102102
c2.new.m(:dump) { :value }.should == :value
103103
end
104104

105+
it "uses block argument given to method when used in a block" do
106+
c1 = Class.new do
107+
def m
108+
yield
109+
end
110+
end
111+
c2 = Class.new(c1) do
112+
def m(v)
113+
ary = []
114+
1.times do
115+
ary << super()
116+
end
117+
ary
118+
end
119+
end
120+
121+
c2.new.m(:dump) { :value }.should == [ :value ]
122+
end
123+
105124
it "calls the superclass method when in a block" do
106125
SuperSpecs::S6.new.here.should == :good
107126
end

src/main/java/org/truffleruby/builtins/CoreMethodNodeManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import org.truffleruby.language.arguments.MissingArgumentBehavior;
3535
import org.truffleruby.language.arguments.NotProvidedNode;
3636
import org.truffleruby.language.arguments.ProfileArgumentNodeGen;
37-
import org.truffleruby.language.arguments.ReadBlockNode;
37+
import org.truffleruby.language.arguments.ReadBlockFromCurrentFrameArgumentsNode;
3838
import org.truffleruby.language.arguments.ReadKeywordArgumentNode;
3939
import org.truffleruby.language.arguments.ReadPreArgumentNode;
4040
import org.truffleruby.language.arguments.ReadRemainingArgumentsNode;
@@ -254,7 +254,7 @@ public static RubyNode createCoreMethodNode(NodeFactory<? extends RubyNode> node
254254
}
255255

256256
if (method.needsBlock()) {
257-
argumentsNodes[i++] = new ReadBlockNode(NotProvided.INSTANCE);
257+
argumentsNodes[i++] = new ReadBlockFromCurrentFrameArgumentsNode(NotProvided.INSTANCE);
258258
}
259259

260260
if (!method.keywordAsOptional().isEmpty()) {

src/main/java/org/truffleruby/core/proc/ProcNodes.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
import org.truffleruby.language.NotProvided;
2525
import org.truffleruby.language.Visibility;
2626
import org.truffleruby.language.arguments.ArgumentDescriptorUtils;
27-
import org.truffleruby.language.arguments.ReadBlockNode;
28-
import org.truffleruby.language.arguments.RubyArguments;
2927
import org.truffleruby.language.control.RaiseException;
3028
import org.truffleruby.language.dispatch.CallDispatchHeadNode;
3129
import org.truffleruby.language.locals.FindDeclarationVariableNodes.FindAndReadDeclarationVariableNode;
@@ -38,7 +36,6 @@
3836
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
3937
import com.oracle.truffle.api.dsl.Cached;
4038
import com.oracle.truffle.api.dsl.Specialization;
41-
import com.oracle.truffle.api.frame.Frame;
4239
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
4340
import com.oracle.truffle.api.frame.MaterializedFrame;
4441
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -95,10 +92,6 @@ protected static void debug(String str) {
9592
System.err.println(str);
9693
}
9794

98-
protected static ReadBlockNode createReadBlock() {
99-
return new ReadBlockNode(null);
100-
}
101-
10295
@TruffleBoundary
10396
protected DynamicObject tryParentBlockForCExts() {
10497
/*

src/main/java/org/truffleruby/language/arguments/ReadBlockNode.java renamed to src/main/java/org/truffleruby/language/arguments/ReadBlockFromCurrentFrameArgumentsNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
import org.truffleruby.Layouts;
1717
import org.truffleruby.language.RubyNode;
1818

19-
public class ReadBlockNode extends RubyNode {
19+
public class ReadBlockFromCurrentFrameArgumentsNode extends RubyNode {
2020

2121
private final Object valueIfAbsent;
2222

2323
private final ConditionProfile nullProfile = ConditionProfile.createBinaryProfile();
2424

25-
public ReadBlockNode(Object valueIfAbsent) {
25+
public ReadBlockFromCurrentFrameArgumentsNode(Object valueIfAbsent) {
2626
this.valueIfAbsent = valueIfAbsent;
2727
}
2828

src/main/java/org/truffleruby/parser/LoadArgumentsTranslator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import org.truffleruby.language.arguments.MissingArgumentBehavior;
2626
import org.truffleruby.language.arguments.MissingKeywordArgumentNode;
2727
import org.truffleruby.language.arguments.ProfileArgumentNodeGen;
28-
import org.truffleruby.language.arguments.ReadBlockNode;
28+
import org.truffleruby.language.arguments.ReadBlockFromCurrentFrameArgumentsNode;
2929
import org.truffleruby.language.arguments.ReadKeywordArgumentNode;
3030
import org.truffleruby.language.arguments.ReadKeywordRestArgumentNode;
3131
import org.truffleruby.language.arguments.ReadOptionalArgumentNode;
@@ -343,14 +343,14 @@ public RubyNode visitRestArgNode(RestArgParseNode node) {
343343
}
344344

345345
public RubyNode saveMethodBlockArg() {
346-
final RubyNode readNode = new ReadBlockNode(context.getCoreLibrary().getNil());
346+
final RubyNode readNode = new ReadBlockFromCurrentFrameArgumentsNode(context.getCoreLibrary().getNil());
347347
final FrameSlot slot = methodBodyTranslator.getEnvironment().getFrameDescriptor().findOrAddFrameSlot(TranslatorEnvironment.METHOD_BLOCK_NAME);
348348
return new WriteLocalVariableNode(slot, readNode);
349349
}
350350

351351
@Override
352352
public RubyNode visitBlockArgNode(BlockArgParseNode node) {
353-
final RubyNode readNode = new ReadBlockNode(context.getCoreLibrary().getNil());
353+
final RubyNode readNode = new ReadBlockFromCurrentFrameArgumentsNode(context.getCoreLibrary().getNil());
354354
final FrameSlot slot = methodBodyTranslator.getEnvironment().getFrameDescriptor().findFrameSlot(node.getName());
355355
return new WriteLocalVariableNode(slot, readNode);
356356
}

src/main/java/org/truffleruby/parser/MethodTranslator.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.truffleruby.language.SourceIndexLength;
2828
import org.truffleruby.language.arguments.MissingArgumentBehavior;
2929
import org.truffleruby.language.arguments.ProfileArgumentNodeGen;
30-
import org.truffleruby.language.arguments.ReadBlockNode;
3130
import org.truffleruby.language.arguments.ReadPreArgumentNode;
3231
import org.truffleruby.language.arguments.ShouldDestructureNode;
3332
import org.truffleruby.language.control.AndNode;
@@ -319,7 +318,7 @@ public RubyNode visitSuperNode(SuperParseNode node) {
319318
final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, node.getIterNode(), node.getArgsNode(), environment.getNamedMethodName());
320319

321320
final RubyNode arguments = new ReadSuperArgumentsNode(argumentsAndBlock.getArguments(), argumentsAndBlock.isSplatted());
322-
final RubyNode block = executeOrInheritBlock(argumentsAndBlock.getBlock());
321+
final RubyNode block = executeOrInheritBlock(argumentsAndBlock.getBlock(), node);
323322

324323
RubyNode callNode = new SuperCallNode(arguments, block);
325324
callNode = wrapCallWithLiteralBlock(argumentsAndBlock, callNode);
@@ -354,19 +353,19 @@ public RubyNode visitZSuperNode(ZSuperParseNode node) {
354353
final RubyNode arguments = new ReadZSuperArgumentsNode(
355354
reloadTranslator.getRestParameterIndex(),
356355
reloadSequence.getSequence());
357-
final RubyNode block = executeOrInheritBlock(argumentsAndBlock.getBlock());
356+
final RubyNode block = executeOrInheritBlock(argumentsAndBlock.getBlock(), node);
358357

359358
RubyNode callNode = new SuperCallNode(arguments, block);
360359
callNode = wrapCallWithLiteralBlock(argumentsAndBlock, callNode);
361360

362361
return withSourceSection(sourceSection, callNode);
363362
}
364363

365-
private RubyNode executeOrInheritBlock(RubyNode blockNode) {
364+
private RubyNode executeOrInheritBlock(RubyNode blockNode, ParseNode callNode) {
366365
if (blockNode != null) {
367366
return blockNode;
368367
} else {
369-
return new ReadBlockNode(context.getCoreLibrary().getNil());
368+
return environment.findLocalVarOrNilNode(TranslatorEnvironment.METHOD_BLOCK_NAME, callNode.getPosition());
370369
}
371370
}
372371

0 commit comments

Comments
 (0)