|
24 | 24 | import org.truffleruby.language.NotProvided;
|
25 | 25 | import org.truffleruby.language.Visibility;
|
26 | 26 | import org.truffleruby.language.arguments.ArgumentDescriptorUtils;
|
| 27 | +import org.truffleruby.language.arguments.ReadBlockNode; |
27 | 28 | import org.truffleruby.language.arguments.RubyArguments;
|
28 | 29 | import org.truffleruby.language.control.RaiseException;
|
29 | 30 | import org.truffleruby.language.dispatch.CallDispatchHeadNode;
|
| 31 | +import org.truffleruby.language.locals.FindDeclarationVariableNodes.FindAndReadDeclarationVariableNode; |
30 | 32 | import org.truffleruby.language.objects.AllocateObjectNode;
|
31 | 33 | import org.truffleruby.language.yield.CallBlockNode;
|
32 | 34 | import org.truffleruby.parser.ArgumentDescriptor;
|
| 35 | +import org.truffleruby.parser.TranslatorEnvironment; |
33 | 36 |
|
34 | 37 | import com.oracle.truffle.api.CompilerDirectives;
|
35 | 38 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
| 39 | +import com.oracle.truffle.api.dsl.Cached; |
36 | 40 | import com.oracle.truffle.api.dsl.Specialization;
|
37 | 41 | import com.oracle.truffle.api.frame.Frame;
|
38 | 42 | import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
|
@@ -68,32 +72,42 @@ public abstract DynamicObject executeProcNew(
|
68 | 72 | Object block);
|
69 | 73 |
|
70 | 74 | @Specialization
|
71 |
| - public DynamicObject proc(VirtualFrame frame, DynamicObject procClass, Object[] args, NotProvided block) { |
72 |
| - final Frame parentFrame = getContext().getCallStack().getCallerFrameIgnoringSend() |
73 |
| - .getFrame(FrameAccess.READ_ONLY); |
| 75 | + public DynamicObject proc(VirtualFrame frame, DynamicObject procClass, Object[] args, NotProvided block, |
| 76 | + @Cached("create(nil())") FindAndReadDeclarationVariableNode readNode) { |
| 77 | + final MaterializedFrame parentFrame = getContext().getCallStack().getCallerFrameIgnoringSend() |
| 78 | + .getFrame(FrameAccess.MATERIALIZE).materialize(); |
74 | 79 |
|
75 |
| - DynamicObject parentBlock = RubyArguments.getBlock(parentFrame); |
| 80 | + DynamicObject parentBlock = (DynamicObject) readNode.execute(parentFrame, TranslatorEnvironment.TEMP_PREFIX + "__unnamed_block_arg__"); |
76 | 81 |
|
77 |
| - if (parentBlock == null) { |
| 82 | + if (parentBlock == nil()) { |
78 | 83 | parentBlock = tryParentBlockForCExts();
|
79 | 84 | }
|
80 | 85 |
|
81 |
| - if (parentBlock == null) { |
| 86 | + if (parentBlock == nil()) { |
82 | 87 | throw new RaiseException(getContext(), coreExceptions().argumentErrorProcWithoutBlock(this));
|
83 | 88 | }
|
84 | 89 |
|
85 | 90 | return executeProcNew(frame, procClass, args, parentBlock);
|
86 | 91 | }
|
87 | 92 |
|
88 | 93 | @TruffleBoundary
|
89 |
| - private static DynamicObject tryParentBlockForCExts() { |
| 94 | + protected static void debug(String str) { |
| 95 | + System.err.println(str); |
| 96 | + } |
| 97 | + |
| 98 | + protected static ReadBlockNode createReadBlock() { |
| 99 | + return new ReadBlockNode(null); |
| 100 | + } |
| 101 | + |
| 102 | + @TruffleBoundary |
| 103 | + protected DynamicObject tryParentBlockForCExts() { |
90 | 104 | /*
|
91 | 105 | * TODO CS 11-Mar-17 to pass the remaining cext proc specs we need to determine here if Proc.new has been
|
92 | 106 | * called from a cext from rb_funcall, and then reach down the stack to the Ruby method that originally
|
93 | 107 | * went into C and get the block from there.
|
94 | 108 | */
|
95 | 109 |
|
96 |
| - return null; |
| 110 | + return nil(); |
97 | 111 | }
|
98 | 112 |
|
99 | 113 | @Specialization(guards = { "procClass == getProcClass()", "block.getShape() == getProcShape()" })
|
|
0 commit comments