9
9
*/
10
10
package org .truffleruby .language .methods ;
11
11
12
+ import com .oracle .truffle .api .dsl .Cached ;
13
+ import com .oracle .truffle .api .dsl .Specialization ;
12
14
import org .truffleruby .core .kernel .TruffleKernelNodes .GetSpecialVariableStorage ;
13
15
import org .truffleruby .core .proc .ProcOperations ;
14
16
import org .truffleruby .core .proc .ProcCallTargets ;
20
22
import org .truffleruby .language .control .BreakID ;
21
23
import org .truffleruby .language .control .FrameOnStackMarker ;
22
24
23
- import com .oracle .truffle .api .CompilerDirectives ;
24
25
import com .oracle .truffle .api .frame .VirtualFrame ;
25
26
import org .truffleruby .parser .BodyTranslator ;
26
27
27
28
/** Create a Ruby Proc to pass as a block to the called method. The literal block is represented as call targets and a
28
29
* SharedMethodInfo. This is executed at the call site just before dispatch. */
29
- public final class BlockDefinitionNode extends RubyContextSourceNode {
30
+ public abstract class BlockDefinitionNode extends RubyContextSourceNode {
30
31
31
32
private final ProcType type ;
32
33
private final SharedMethodInfo sharedMethodInfo ;
33
34
private final ProcCallTargets callTargets ;
34
35
private final BreakID breakID ;
35
36
private final int frameOnStackMarkerSlot ;
36
37
37
- @ Child private GetSpecialVariableStorage readSpecialVariableStorageNode ;
38
- @ Child private WithoutVisibilityNode withoutVisibilityNode ;
39
-
40
38
public BlockDefinitionNode (
41
39
ProcType type ,
42
40
SharedMethodInfo sharedMethodInfo ,
@@ -50,15 +48,18 @@ public BlockDefinitionNode(
50
48
this .breakID = breakID ;
51
49
52
50
this .frameOnStackMarkerSlot = frameOnStackMarkerSlot ;
53
- readSpecialVariableStorageNode = GetSpecialVariableStorage .create ();
54
51
}
55
52
56
53
public BreakID getBreakID () {
57
54
return breakID ;
58
55
}
59
56
60
- @ Override
61
- public RubyProc execute (VirtualFrame frame ) {
57
+ public abstract RubyProc execute (VirtualFrame virtualFrame );
58
+
59
+ @ Specialization
60
+ RubyProc doBlockDefinition (VirtualFrame frame ,
61
+ @ Cached GetSpecialVariableStorage readSpecialVariableStorageNode ,
62
+ @ Cached WithoutVisibilityNode withoutVisibilityNode ) {
62
63
final FrameOnStackMarker frameOnStackMarker ;
63
64
if (frameOnStackMarkerSlot != BodyTranslator .NO_FRAME_ON_STACK_MARKER ) {
64
65
frameOnStackMarker = (FrameOnStackMarker ) frame .getObject (frameOnStackMarkerSlot );
@@ -74,23 +75,16 @@ public RubyProc execute(VirtualFrame frame) {
74
75
sharedMethodInfo ,
75
76
callTargets ,
76
77
frame .materialize (),
77
- readSpecialVariableStorageNode .executeCached (frame ),
78
+ readSpecialVariableStorageNode .execute (frame , this ),
78
79
RubyArguments .getMethod (frame ),
79
80
frameOnStackMarker ,
80
- executeWithoutVisibility (RubyArguments .getDeclarationContext (frame )));
81
+ withoutVisibilityNode . executeWithoutVisibility (this , RubyArguments .getDeclarationContext (frame )));
81
82
}
82
83
83
- private DeclarationContext executeWithoutVisibility (DeclarationContext ctxIn ) {
84
- if (withoutVisibilityNode == null ) {
85
- CompilerDirectives .transferToInterpreterAndInvalidate ();
86
- withoutVisibilityNode = insert (WithoutVisibilityNodeGen .create ());
87
- }
88
- return withoutVisibilityNode .executeWithoutVisibility (ctxIn );
89
- }
90
84
91
85
@ Override
92
86
public RubyNode cloneUninitialized () {
93
- var copy = new BlockDefinitionNode (type , sharedMethodInfo , callTargets , breakID , frameOnStackMarkerSlot );
87
+ var copy = BlockDefinitionNodeGen . create (type , sharedMethodInfo , callTargets , breakID , frameOnStackMarkerSlot );
94
88
return copy .copyFlags (this );
95
89
}
96
90
0 commit comments