Skip to content

Commit ff3dc4e

Browse files
committed
[GR-17457] Refactor nodes to later support DSL inlining
PullRequest: truffleruby/3858
2 parents 0f64063 + dbe6173 commit ff3dc4e

File tree

4 files changed

+62
-140
lines changed

4 files changed

+62
-140
lines changed

src/main/java/org/truffleruby/core/binding/BindingNodes.java

Lines changed: 29 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.truffleruby.annotations.Primitive;
3030
import org.truffleruby.annotations.Visibility;
3131
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
32+
import org.truffleruby.builtins.CoreMethodNode;
3233
import org.truffleruby.builtins.PrimitiveArrayArgumentsNode;
3334
import org.truffleruby.core.array.ArrayHelpers;
3435
import org.truffleruby.core.array.RubyArray;
@@ -44,8 +45,6 @@
4445
import org.truffleruby.language.locals.FindDeclarationVariableNodes.FindAndReadDeclarationVariableNode;
4546
import org.truffleruby.language.locals.FindDeclarationVariableNodes.FrameSlotAndDepth;
4647
import org.truffleruby.language.locals.FrameDescriptorNamesIterator;
47-
import org.truffleruby.language.locals.WriteFrameSlotNode;
48-
import org.truffleruby.language.locals.WriteFrameSlotNodeGen;
4948

5049
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5150
import com.oracle.truffle.api.Truffle;
@@ -60,6 +59,8 @@
6059
import com.oracle.truffle.api.frame.MaterializedFrame;
6160
import com.oracle.truffle.api.frame.VirtualFrame;
6261
import com.oracle.truffle.api.source.SourceSection;
62+
import org.truffleruby.language.locals.WriteFrameSlotNode;
63+
import org.truffleruby.language.locals.WriteFrameSlotNodeGen;
6364
import org.truffleruby.parser.ParentFrameDescriptor;
6465
import org.truffleruby.parser.TranslatorEnvironment;
6566

@@ -278,33 +279,29 @@ public RubyNode cloneUninitialized() {
278279

279280
}
280281

281-
@GenerateUncached
282-
@GenerateNodeFactory
283282
@CoreMethod(names = "local_variable_get", required = 1)
284283
@NodeChild(value = "bindingNode", type = RubyNode.class)
285284
@NodeChild(value = "nameNode", type = RubyBaseNodeWithExecute.class)
286285
@ImportStatic(BindingNodes.class)
287-
public abstract static class LocalVariableGetNode extends RubySourceNode {
286+
public abstract static class BindingLocalVariableGetNode extends CoreMethodNode {
288287

289-
@NeverDefault
290-
public static LocalVariableGetNode create() {
291-
return BindingNodesFactory.LocalVariableGetNodeFactory.create(null, null);
288+
@CreateCast("nameNode")
289+
protected RubyBaseNodeWithExecute coerceToString(RubyBaseNodeWithExecute name) {
290+
return NameToJavaStringNode.create(name);
292291
}
293292

294-
public static LocalVariableGetNode create(RubyNode bindingNode, RubyBaseNodeWithExecute nameNode) {
295-
return BindingNodesFactory.LocalVariableGetNodeFactory.create(bindingNode, nameNode);
293+
@Specialization
294+
protected Object localVariableGet(RubyBinding binding, String name,
295+
@Cached LocalVariableGetNode localVariableGetNode) {
296+
return localVariableGetNode.execute(binding, name);
296297
}
298+
}
297299

298-
public abstract Object execute(RubyBinding binding, String name);
299-
300-
abstract RubyNode getBindingNode();
301-
302-
abstract RubyBaseNodeWithExecute getNameNode();
300+
@GenerateUncached
301+
@ImportStatic(BindingNodes.class)
302+
public abstract static class LocalVariableGetNode extends RubyBaseNode {
303303

304-
@CreateCast("nameNode")
305-
protected RubyBaseNodeWithExecute coerceToString(RubyBaseNodeWithExecute name) {
306-
return NameToJavaStringNode.create(name);
307-
}
304+
public abstract Object execute(RubyBinding binding, String name);
308305

309306
@Specialization(guards = "!isHiddenVariable(name)")
310307
protected Object localVariableGet(RubyBinding binding, String name,
@@ -326,56 +323,33 @@ protected Object localVariableGetLastLine(RubyBinding binding, String name) {
326323
getContext(),
327324
coreExceptions().nameError("Bad local variable name", binding, name, this));
328325
}
329-
330-
protected int getCacheLimit() {
331-
return getLanguage().options.BINDING_LOCAL_VARIABLE_CACHE;
332-
}
333-
334-
private RubyBaseNodeWithExecute getNameNodeBeforeCasting() {
335-
return ((NameToJavaStringNode) getNameNode()).getValueNode();
336-
}
337-
338-
@Override
339-
public RubyNode cloneUninitialized() {
340-
return create(
341-
getBindingNode().cloneUninitialized(),
342-
getNameNodeBeforeCasting().cloneUninitialized()).copyFlags(this);
343-
}
344-
345326
}
346327

347328
@ReportPolymorphism
348-
@GenerateUncached
349-
@GenerateNodeFactory
350329
@CoreMethod(names = "local_variable_set", required = 2)
351330
@NodeChild(value = "bindingNode", type = RubyNode.class)
352331
@NodeChild(value = "nameNode", type = RubyBaseNodeWithExecute.class)
353332
@NodeChild(value = "valueNode", type = RubyNode.class)
354-
@ImportStatic({ BindingNodes.class, FindDeclarationVariableNodes.class })
355-
public abstract static class LocalVariableSetNode extends RubySourceNode {
333+
public abstract static class BindingLocalVariableSetNode extends CoreMethodNode {
356334

357-
@NeverDefault
358-
public static LocalVariableSetNode create() {
359-
return BindingNodesFactory.LocalVariableSetNodeFactory.create(null, null, null);
335+
@CreateCast("nameNode")
336+
protected RubyBaseNodeWithExecute coerceToString(RubyBaseNodeWithExecute name) {
337+
return NameToJavaStringNode.create(name);
360338
}
361339

362-
public static LocalVariableSetNode create(RubyNode bindingNode, RubyBaseNodeWithExecute nameNode,
363-
RubyNode valueNode) {
364-
return BindingNodesFactory.LocalVariableSetNodeFactory.create(bindingNode, nameNode, valueNode);
340+
@Specialization
341+
protected Object localVariableSet(RubyBinding binding, String name, Object value,
342+
@Cached LocalVariableSetNode localVariableSetNode) {
343+
return localVariableSetNode.execute(binding, name, value);
365344
}
345+
}
366346

367-
public abstract Object execute(RubyBinding binding, String name, Object value);
368-
369-
abstract RubyNode getBindingNode();
370-
371-
abstract RubyBaseNodeWithExecute getNameNode();
372347

373-
abstract RubyNode getValueNode();
348+
@GenerateUncached
349+
@ImportStatic({ BindingNodes.class, FindDeclarationVariableNodes.class })
350+
public abstract static class LocalVariableSetNode extends RubyBaseNode {
374351

375-
@CreateCast("nameNode")
376-
protected RubyBaseNodeWithExecute coerceToString(RubyBaseNodeWithExecute name) {
377-
return NameToJavaStringNode.create(name);
378-
}
352+
public abstract Object execute(RubyBinding binding, String name, Object value);
379353

380354
@Specialization(
381355
guards = {
@@ -449,19 +423,6 @@ protected WriteFrameSlotNode createWriteNode(int frameSlot) {
449423
protected int getCacheLimit() {
450424
return getLanguage().options.BINDING_LOCAL_VARIABLE_CACHE;
451425
}
452-
453-
private RubyBaseNodeWithExecute getNameNodeBeforeCasting() {
454-
return ((NameToJavaStringNode) getNameNode()).getValueNode();
455-
}
456-
457-
@Override
458-
public RubyNode cloneUninitialized() {
459-
return create(
460-
getBindingNode().cloneUninitialized(),
461-
getNameNodeBeforeCasting().cloneUninitialized(),
462-
getValueNode().cloneUninitialized()).copyFlags(this);
463-
}
464-
465426
}
466427

467428
@Primitive(name = "local_variable_names")

src/main/java/org/truffleruby/core/string/StringNodes.java

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
import com.oracle.truffle.api.dsl.Bind;
7676
import com.oracle.truffle.api.dsl.Cached.Exclusive;
7777
import com.oracle.truffle.api.dsl.Cached.Shared;
78-
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
78+
import com.oracle.truffle.api.dsl.GenerateUncached;
7979
import com.oracle.truffle.api.dsl.NeverDefault;
8080
import com.oracle.truffle.api.nodes.Node;
8181
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
@@ -145,10 +145,10 @@
145145
import org.truffleruby.interop.ToJavaStringNode;
146146
import org.truffleruby.language.Nil;
147147
import org.truffleruby.language.NotProvided;
148+
import org.truffleruby.language.RubyBaseNode;
148149
import org.truffleruby.language.RubyBaseNodeWithExecute;
149150
import org.truffleruby.language.RubyGuards;
150151
import org.truffleruby.language.RubyNode;
151-
import org.truffleruby.language.RubySourceNode;
152152
import org.truffleruby.annotations.Visibility;
153153
import org.truffleruby.language.arguments.ReadCallerVariablesNode;
154154
import org.truffleruby.language.control.DeferredRaiseException;
@@ -167,7 +167,6 @@
167167
import com.oracle.truffle.api.dsl.Cached;
168168
import com.oracle.truffle.api.dsl.CreateCast;
169169
import com.oracle.truffle.api.dsl.Fallback;
170-
import com.oracle.truffle.api.dsl.GenerateUncached;
171170
import com.oracle.truffle.api.dsl.ImportStatic;
172171
import com.oracle.truffle.api.dsl.NodeChild;
173172
import com.oracle.truffle.api.dsl.ReportPolymorphism;
@@ -182,25 +181,22 @@
182181
@CoreModule(value = "String", isClass = true)
183182
public abstract class StringNodes {
184183

185-
@GenerateUncached
186-
@GenerateNodeFactory
187184
@CoreMethod(names = { "__allocate__", "__layout_allocate__" }, constructor = true, visibility = Visibility.PRIVATE)
188185
@NodeChild(value = "rubyClassNode", type = RubyNode.class)
189-
public abstract static class AllocateNode extends RubySourceNode {
186+
public abstract static class StringAllocateNode extends CoreMethodNode {
190187

191-
@NeverDefault
192-
public static AllocateNode create() {
193-
return StringNodesFactory.AllocateNodeFactory.create(null);
188+
@Specialization
189+
protected RubyString allocate(RubyClass rubyClass,
190+
@Cached AllocateNode allocateNode) {
191+
return allocateNode.execute(rubyClass);
194192
}
193+
}
195194

196-
public static AllocateNode create(RubyNode rubyClassNode) {
197-
return StringNodesFactory.AllocateNodeFactory.create(rubyClassNode);
198-
}
195+
@GenerateUncached
196+
public abstract static class AllocateNode extends RubyBaseNode {
199197

200198
public abstract RubyString execute(RubyClass rubyClass);
201199

202-
abstract RubyNode getRubyClassNode();
203-
204200
@Specialization
205201
protected RubyString allocate(RubyClass rubyClass) {
206202
final RubyString string = new RubyString(
@@ -212,12 +208,6 @@ protected RubyString allocate(RubyClass rubyClass) {
212208
AllocationTracing.trace(string, this);
213209
return string;
214210
}
215-
216-
@Override
217-
public RubyNode cloneUninitialized() {
218-
return create(getRubyClassNode().cloneUninitialized()).copyFlags(this);
219-
}
220-
221211
}
222212

223213
@CoreMethod(names = "encoding")

src/main/java/org/truffleruby/interop/InteropNodes.java

Lines changed: 19 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.truffleruby.core.symbol.RubySymbol;
4848
import org.truffleruby.language.Nil;
4949
import org.truffleruby.language.NotProvided;
50+
import org.truffleruby.language.RubyBaseNode;
5051
import org.truffleruby.language.RubyGuards;
5152
import org.truffleruby.language.RubyNode;
5253
import org.truffleruby.language.RubySourceNode;
@@ -92,15 +93,6 @@ public static Object execute(Object receiver, Object[] args, InteropLibrary rece
9293
}
9394
}
9495

95-
public static Object invoke(InteropLibrary receivers, Object receiver, String member, Object[] args,
96-
TranslateInteropExceptionNode translateInteropExceptionNode) {
97-
try {
98-
return receivers.invokeMember(receiver, member, args);
99-
} catch (InteropException e) {
100-
throw translateInteropExceptionNode.executeInInvokeMember(e, receiver, args);
101-
}
102-
}
103-
10496
public static Object readMember(InteropLibrary interop, Object receiver, String name,
10597
TranslateInteropExceptionNode translateInteropException) {
10698
try {
@@ -1192,35 +1184,14 @@ protected double as(Object receiver,
11921184
// endregion
11931185

11941186
// region Null
1195-
@GenerateUncached
1196-
@GenerateNodeFactory
11971187
@CoreMethod(names = "null?", onSingleton = true, required = 1)
1198-
@NodeChild(value = "argumentNodes", type = RubyNode[].class)
1199-
public abstract static class IsNullNode extends RubySourceNode {
1200-
1201-
public static IsNullNode create() {
1202-
return InteropNodesFactory.IsNullNodeFactory.create(null);
1203-
}
1204-
1205-
public static IsNullNode create(RubyNode[] argumentNodes) {
1206-
return InteropNodesFactory.IsNullNodeFactory.create(argumentNodes);
1207-
}
1208-
1209-
abstract Object execute(Object receiver);
1210-
1211-
abstract RubyNode[] getArgumentNodes();
1188+
public abstract static class IsNullNode extends CoreMethodArrayArgumentsNode {
12121189

12131190
@Specialization(limit = "getInteropCacheLimit()")
12141191
protected boolean isNull(Object receiver,
12151192
@CachedLibrary("receiver") InteropLibrary receivers) {
12161193
return receivers.isNull(receiver);
12171194
}
1218-
1219-
@Override
1220-
public RubyNode cloneUninitialized() {
1221-
return create(cloneUninitialized(getArgumentNodes())).copyFlags(this);
1222-
}
1223-
12241195
}
12251196
// endregion
12261197

@@ -1468,25 +1439,30 @@ protected Nil remove(Object receiver, Object identifier,
14681439
}
14691440
}
14701441

1471-
@GenerateUncached
1472-
@GenerateNodeFactory
14731442
@CoreMethod(names = "invoke_member", onSingleton = true, required = 2, rest = true)
1474-
@NodeChild(value = "argumentNodes", type = RubyNode[].class)
1475-
public abstract static class InvokeMemberNode extends RubySourceNode {
1443+
public abstract static class InteropInvokeMemberNode extends CoreMethodArrayArgumentsNode {
14761444

1477-
@NeverDefault
1478-
public static InvokeMemberNode create() {
1479-
return InteropNodesFactory.InvokeMemberNodeFactory.create(null);
1445+
@Specialization
1446+
protected Object invokeMember(Object receiver, Object identifier, Object[] args,
1447+
@Cached InvokeMemberNode invokeMemberNode) {
1448+
return invokeMemberNode.execute(receiver, identifier, args);
14801449
}
1450+
}
1451+
1452+
@GenerateUncached
1453+
public abstract static class InvokeMemberNode extends RubyBaseNode {
14811454

1482-
public static InvokeMemberNode create(RubyNode[] argumentNodes) {
1483-
return InteropNodesFactory.InvokeMemberNodeFactory.create(argumentNodes);
1455+
private static Object invoke(InteropLibrary receivers, Object receiver, String member, Object[] args,
1456+
TranslateInteropExceptionNode translateInteropExceptionNode) {
1457+
try {
1458+
return receivers.invokeMember(receiver, member, args);
1459+
} catch (InteropException e) {
1460+
throw translateInteropExceptionNode.executeInInvokeMember(e, receiver, args);
1461+
}
14841462
}
14851463

14861464
public abstract Object execute(Object receiver, Object identifier, Object[] args);
14871465

1488-
abstract RubyNode[] getArgumentNodes();
1489-
14901466
@Specialization(limit = "getInteropCacheLimit()")
14911467
protected Object invokeCached(Object receiver, Object identifier, Object[] args,
14921468
@Cached ToJavaStringNode toJavaStringNode,
@@ -1497,14 +1473,9 @@ protected Object invokeCached(Object receiver, Object identifier, Object[] args,
14971473
final Object foreign = invoke(receivers, receiver, name, args, translateInteropException);
14981474
return foreignToRubyNode.executeConvert(foreign);
14991475
}
1500-
1501-
@Override
1502-
public RubyNode cloneUninitialized() {
1503-
return create(cloneUninitialized(getArgumentNodes())).copyFlags(this);
1504-
}
1505-
15061476
}
15071477

1478+
15081479
@CoreMethod(names = "member_readable?", onSingleton = true, required = 2)
15091480
public abstract static class IsMemberReadableNode extends CoreMethodArrayArgumentsNode {
15101481
@Specialization(limit = "getInteropCacheLimit()")

src/main/java/org/truffleruby/language/methods/CallForeignMethodNode.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.truffleruby.core.cast.ToSymbolNode;
2727
import org.truffleruby.core.numeric.RubyBignum;
2828
import org.truffleruby.core.proc.RubyProc;
29-
import org.truffleruby.interop.InteropNodes.InvokeMemberNode;
29+
import org.truffleruby.interop.InteropNodes;
3030
import org.truffleruby.interop.InteropNodes.ReadMemberNode;
3131
import org.truffleruby.interop.InteropNodes.WriteMemberWithoutConversionNode;
3232
import org.truffleruby.interop.TranslateInteropExceptionNode;
@@ -132,7 +132,7 @@ public abstract static class InvokeOrReadMemberNode extends RubyBaseNode {
132132
@Specialization(guards = "args.length == 0", limit = "getInteropCacheLimit()")
133133
protected static Object readOrInvoke(Object receiver, String name, Object[] args,
134134
@Cached ToSymbolNode toSymbolNode,
135-
@Cached @Shared InvokeMemberNode invokeNode,
135+
@Cached @Shared InteropNodes.InvokeMemberNode invokeNode,
136136
@Cached ReadMemberNode readNode,
137137
@Cached InlinedConditionProfile invocable,
138138
@CachedLibrary("receiver") InteropLibrary receivers,
@@ -146,7 +146,7 @@ protected static Object readOrInvoke(Object receiver, String name, Object[] args
146146

147147
@Specialization(guards = "args.length != 0")
148148
protected Object invoke(Object receiver, String name, Object[] args,
149-
@Cached @Shared InvokeMemberNode invokeNode) {
149+
@Cached @Shared InteropNodes.InvokeMemberNode invokeNode) {
150150
return invokeNode.execute(receiver, name, args);
151151
}
152152
}
@@ -237,7 +237,7 @@ protected Object callDouble(Object receiver, String name, Object[] args,
237237
limit = "getInteropCacheLimit()")
238238
protected Object call(Object receiver, String name, Object[] args,
239239
@CachedLibrary("receiver") InteropLibrary receivers,
240-
@Cached InvokeMemberNode invokeNode) {
240+
@Cached InteropNodes.InvokeMemberNode invokeNode) {
241241
return invokeNode.execute(receiver, name, args);
242242
}
243243
}

0 commit comments

Comments
 (0)