9
9
*/
10
10
package org .truffleruby .core .symbol ;
11
11
12
+ import org .truffleruby .RubyContext ;
12
13
import org .truffleruby .builtins .CoreMethod ;
13
14
import org .truffleruby .builtins .CoreMethodArrayArgumentsNode ;
14
15
import org .truffleruby .builtins .CoreModule ;
17
18
import org .truffleruby .core .CoreLibrary ;
18
19
import org .truffleruby .core .array .RubyArray ;
19
20
import org .truffleruby .core .klass .RubyClass ;
21
+ import org .truffleruby .core .module .RubyModule ;
20
22
import org .truffleruby .core .proc .ProcOperations ;
21
23
import org .truffleruby .core .proc .ProcType ;
22
24
import org .truffleruby .core .proc .RubyProc ;
46
48
import com .oracle .truffle .api .frame .VirtualFrame ;
47
49
import com .oracle .truffle .api .source .SourceSection ;
48
50
51
+ import java .util .Map ;
52
+
49
53
@ CoreModule (value = "Symbol" , isClass = true )
50
54
public abstract class SymbolNodes {
51
55
@@ -101,34 +105,39 @@ public abstract static class ToProcNode extends CoreMethodArrayArgumentsNode {
101
105
@ Child private ReadCallerFrameNode readCallerFrame = ReadCallerFrameNode .create ();
102
106
103
107
@ Specialization (
104
- guards = { "cachedSymbol == symbol " , "getDeclarationContext (frame) == cachedDeclarationContext " },
108
+ guards = { "symbol == cachedSymbol " , "getRefinements (frame) == cachedRefinements " },
105
109
limit = "getIdentityCacheLimit()" )
106
110
protected RubyProc toProcCached (VirtualFrame frame , RubySymbol symbol ,
107
111
@ Cached ("symbol" ) RubySymbol cachedSymbol ,
108
- @ Cached ("getDeclarationContext (frame)" ) DeclarationContext cachedDeclarationContext ,
109
- @ Cached ("getOrCreateProc(cachedDeclarationContext , symbol)" ) RubyProc cachedProc ) {
112
+ @ Cached ("getRefinements (frame)" ) Map < RubyModule , RubyModule []> cachedRefinements ,
113
+ @ Cached ("getOrCreateProc(cachedRefinements , symbol)" ) RubyProc cachedProc ) {
110
114
return cachedProc ;
111
115
}
112
116
113
117
@ Specialization
114
118
protected RubyProc toProcUncached (VirtualFrame frame , RubySymbol symbol ) {
115
- DeclarationContext declarationContext = getDeclarationContext (frame );
116
- return getOrCreateProc (declarationContext , symbol );
119
+ final Map < RubyModule , RubyModule []> refinements = getRefinements (frame );
120
+ return getOrCreateProc (refinements , symbol );
117
121
}
118
122
119
123
@ TruffleBoundary
120
- protected RubyProc getOrCreateProc (DeclarationContext declarationContext , RubySymbol symbol ) {
121
- declarationContext = declarationContext == null ? DeclarationContext . NONE : declarationContext ;
124
+ protected RubyProc getOrCreateProc (Map < RubyModule , RubyModule []> refinements , RubySymbol symbol ) {
125
+ // TODO (eregon, 23 Sep 2020): this should ideally cache on the refinements by comparing classes, and not by identity.
122
126
return ConcurrentOperations .getOrCompute (
123
127
symbol .getCachedProcs (),
124
- declarationContext ,
125
- key -> createProc (key , symbol ));
128
+ refinements ,
129
+ key -> createProc (getContext (), key , symbol ));
126
130
}
127
131
128
132
@ TruffleBoundary
129
- protected RubyProc createProc (DeclarationContext declarationContext , RubySymbol symbol ) {
130
- final InternalMethod method = getContext ().getCoreMethods ().SYMBOL_TO_PROC ;
133
+ protected static RubyProc createProc (RubyContext context , Map <RubyModule , RubyModule []> refinements ,
134
+ RubySymbol symbol ) {
135
+ final InternalMethod method = context .getCoreMethods ().SYMBOL_TO_PROC ;
131
136
final SourceSection sourceSection = CoreLibrary .UNAVAILABLE_SOURCE_SECTION ;
137
+ final DeclarationContext declarationContext = refinements .isEmpty ()
138
+ ? DeclarationContext .NONE
139
+ : new DeclarationContext (Visibility .PUBLIC , null , refinements );
140
+
132
141
final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo (
133
142
sourceSection ,
134
143
method .getLexicalScope (),
@@ -145,9 +154,9 @@ protected RubyProc createProc(DeclarationContext declarationContext, RubySymbol
145
154
// binding as this simplifies the logic elsewhere in the runtime.
146
155
final MaterializedFrame declarationFrame = Truffle
147
156
.getRuntime ()
148
- .createMaterializedFrame (args , coreLibrary ().emptyDescriptor );
157
+ .createMaterializedFrame (args , context . getCoreLibrary ().emptyDescriptor );
149
158
final RubyRootNode rootNode = new RubyRootNode (
150
- getContext () ,
159
+ context ,
151
160
sourceSection ,
152
161
new FrameDescriptor (nil ),
153
162
sharedMethodInfo ,
@@ -157,7 +166,7 @@ protected RubyProc createProc(DeclarationContext declarationContext, RubySymbol
157
166
final RootCallTarget callTarget = Truffle .getRuntime ().createCallTarget (rootNode );
158
167
159
168
return ProcOperations .createRubyProc (
160
- getContext () .getCoreLibrary ().procShape ,
169
+ context .getCoreLibrary ().procShape ,
161
170
ProcType .PROC ,
162
171
sharedMethodInfo ,
163
172
callTarget ,
@@ -173,12 +182,16 @@ protected InternalMethod getMethod(VirtualFrame frame) {
173
182
return RubyArguments .getMethod (frame );
174
183
}
175
184
176
- protected int getCacheLimit () {
177
- return getContext ().getOptions ().SYMBOL_TO_PROC_CACHE ;
185
+ protected Map <RubyModule , RubyModule []> getRefinements (VirtualFrame frame ) {
186
+ final MaterializedFrame callerFrame = readCallerFrame .execute (frame );
187
+ final DeclarationContext declarationContext = RubyArguments .tryGetDeclarationContext (callerFrame );
188
+ return declarationContext != null
189
+ ? declarationContext .getRefinements ()
190
+ : DeclarationContext .NONE .getRefinements ();
178
191
}
179
192
180
- protected DeclarationContext getDeclarationContext ( VirtualFrame frame ) {
181
- return RubyArguments . tryGetDeclarationContext ( readCallerFrame . execute ( frame )) ;
193
+ protected int getCacheLimit ( ) {
194
+ return getContext (). getOptions (). SYMBOL_TO_PROC_CACHE ;
182
195
}
183
196
184
197
}
0 commit comments