Skip to content

Commit a2c8ba1

Browse files
committed
[GR-29207] Refactor and always split Numeric#step
PullRequest: truffleruby/2417
2 parents 81ad76e + 2deed53 commit a2c8ba1

File tree

12 files changed

+216
-250
lines changed

12 files changed

+216
-250
lines changed

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,6 @@ public RubyNode createCoreMethodNode(NodeFactory<? extends RubyBaseNode> nodeFac
358358
}
359359

360360
if (method.needsBlock()) {
361-
/* The way we write specializations for getting a block or not is that we use NotProvided like a missing
362-
* argument. The block coming into the method is actually always Nil or RubyProc, so here we check which and
363-
* convert Nil to NotProvided. */
364361
argumentsNodes[i++] = new ReadBlockFromCurrentFrameArgumentsNode();
365362
}
366363

src/main/java/org/truffleruby/core/array/ArrayDupNode.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.oracle.truffle.api.dsl.Cached;
1818
import com.oracle.truffle.api.dsl.ImportStatic;
1919
import com.oracle.truffle.api.dsl.Specialization;
20-
import com.oracle.truffle.api.frame.VirtualFrame;
2120
import com.oracle.truffle.api.library.CachedLibrary;
2221
import com.oracle.truffle.api.nodes.ExplodeLoop;
2322
import org.truffleruby.language.objects.AllocationTracing;
@@ -26,7 +25,7 @@
2625
@ImportStatic(ArrayGuards.class)
2726
public abstract class ArrayDupNode extends RubyContextNode {
2827

29-
public abstract RubyArray executeDup(VirtualFrame frame, RubyArray array);
28+
public abstract RubyArray executeDup(RubyArray array);
3029

3130
@Specialization(
3231
guards = {

src/main/java/org/truffleruby/core/cast/SplatCastNode.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.oracle.truffle.api.dsl.Cached;
2525
import com.oracle.truffle.api.dsl.NodeChild;
2626
import com.oracle.truffle.api.dsl.Specialization;
27-
import com.oracle.truffle.api.frame.VirtualFrame;
2827

2928
import static org.truffleruby.language.dispatch.DispatchConfiguration.PRIVATE_RETURN_MISSING;
3029

@@ -59,7 +58,7 @@ public void doNotCopy() {
5958
public abstract RubyNode getChild();
6059

6160
@Specialization
62-
protected Object splatNil(VirtualFrame frame, Nil nil) {
61+
protected Object splatNil(Nil nil) {
6362
switch (nilBehavior) {
6463
case EMPTY_ARRAY:
6564
return createEmptyArray();
@@ -68,7 +67,7 @@ protected Object splatNil(VirtualFrame frame, Nil nil) {
6867
return createArray(new Object[]{ nil });
6968

7069
case CONVERT:
71-
return callToA(frame, nil);
70+
return callToA(nil);
7271

7372
case NIL:
7473
return nil;
@@ -79,18 +78,18 @@ protected Object splatNil(VirtualFrame frame, Nil nil) {
7978
}
8079

8180
@Specialization
82-
protected RubyArray splat(VirtualFrame frame, RubyArray array) {
81+
protected RubyArray splat(RubyArray array) {
8382
// TODO(cs): is it necessary to dup here in all cases?
8483
// It is needed at least for [*ary] (parsed as just a SplatParseNode) and b = *ary.
8584
if (copy) {
86-
return executeDup(frame, array);
85+
return executeDup(array);
8786
} else {
8887
return array;
8988
}
9089
}
9190

9291
@Specialization(guards = { "!isNil(object)", "!isRubyArray(object)" })
93-
protected RubyArray splat(VirtualFrame frame, Object object,
92+
protected RubyArray splat(Object object,
9493
@Cached DispatchNode toArrayNode) {
9594
final Object array = toArrayNode.call(
9695
coreLibrary().truffleTypeModule,
@@ -102,27 +101,27 @@ protected RubyArray splat(VirtualFrame frame, Object object,
102101
return createArray(new Object[]{ object });
103102
} else {
104103
if (copy) {
105-
return executeDup(frame, (RubyArray) array);
104+
return executeDup((RubyArray) array);
106105
} else {
107106
return (RubyArray) array;
108107
}
109108
}
110109
}
111110

112-
private Object callToA(VirtualFrame frame, Object nil) {
111+
private Object callToA(Object nil) {
113112
if (toA == null) {
114113
CompilerDirectives.transferToInterpreterAndInvalidate();
115114
toA = insert(DispatchNode.create(PRIVATE_RETURN_MISSING));
116115
}
117116
return toA.call(nil, "to_a");
118117
}
119118

120-
private RubyArray executeDup(VirtualFrame frame, RubyArray array) {
119+
private RubyArray executeDup(RubyArray array) {
121120
if (dup == null) {
122121
CompilerDirectives.transferToInterpreterAndInvalidate();
123122
dup = insert(ArrayDupNodeGen.create());
124123
}
125-
return dup.executeDup(frame, array);
124+
return dup.executeDup(array);
126125
}
127126

128127
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. This
3+
* code is released under a tri EPL/GPL/LGPL license. You can use it,
4+
* redistribute it and/or modify it under the terms of the:
5+
*
6+
* Eclipse Public License version 2.0, or
7+
* GNU General Public License version 2, or
8+
* GNU Lesser General Public License version 2.1.
9+
*/
10+
package org.truffleruby.core.cast;
11+
12+
import org.truffleruby.core.method.RubyMethod;
13+
import org.truffleruby.core.method.RubyUnboundMethod;
14+
import org.truffleruby.core.proc.RubyProc;
15+
import org.truffleruby.language.RubyBaseNode;
16+
17+
import com.oracle.truffle.api.RootCallTarget;
18+
import com.oracle.truffle.api.dsl.Specialization;
19+
20+
public abstract class ToCallTargetNode extends RubyBaseNode {
21+
22+
public static ToCallTargetNode create() {
23+
return ToCallTargetNodeGen.create();
24+
}
25+
26+
public abstract RootCallTarget execute(Object executable);
27+
28+
@Specialization
29+
protected RootCallTarget boundMethod(RubyMethod method) {
30+
return method.method.getCallTarget();
31+
}
32+
33+
@Specialization
34+
protected RootCallTarget unboundMethod(RubyUnboundMethod method) {
35+
return method.method.getCallTarget();
36+
}
37+
38+
@Specialization
39+
protected RootCallTarget proc(RubyProc proc) {
40+
return proc.callTarget;
41+
}
42+
43+
}

src/main/java/org/truffleruby/debug/TruffleDebugNodes.java

Lines changed: 18 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.truffleruby.core.array.library.ArrayStoreLibrary;
4646
import org.truffleruby.core.binding.BindingNodes;
4747
import org.truffleruby.core.binding.RubyBinding;
48+
import org.truffleruby.core.cast.ToCallTargetNode;
4849
import org.truffleruby.core.hash.RubyHash;
4950
import org.truffleruby.core.method.RubyMethod;
5051
import org.truffleruby.core.method.RubyUnboundMethod;
@@ -59,8 +60,6 @@
5960
import org.truffleruby.interop.ToJavaStringNode;
6061
import org.truffleruby.language.ImmutableRubyObject;
6162
import org.truffleruby.core.string.ImmutableRubyString;
62-
import org.truffleruby.language.Nil;
63-
import org.truffleruby.language.NotProvided;
6463
import org.truffleruby.language.RubyDynamicObject;
6564
import org.truffleruby.language.RubyRootNode;
6665
import org.truffleruby.language.arguments.RubyArguments;
@@ -196,50 +195,17 @@ protected Object printBacktrace() {
196195

197196
}
198197

199-
@CoreMethod(
200-
names = "ast",
201-
onSingleton = true,
202-
optional = 1,
203-
needsBlock = true,
204-
argumentNames = { "method_or_proc", "block" })
198+
@CoreMethod(names = "ast", onSingleton = true, required = 1)
205199
public abstract static class ASTNode extends CoreMethodArrayArgumentsNode {
206-
207-
@TruffleBoundary
208-
@Specialization
209-
protected Object astMethod(RubyMethod method, Nil block) {
210-
ast(method.method);
211-
return nil;
212-
}
213-
214-
@TruffleBoundary
215-
@Specialization
216-
protected Object astUnboundMethod(RubyUnboundMethod method, Nil block) {
217-
ast(method.method);
218-
return nil;
219-
}
220-
221200
@TruffleBoundary
222201
@Specialization
223-
protected Object astProc(RubyProc proc, Nil block) {
224-
ast(proc.callTarget);
202+
protected Object ast(Object executable,
203+
@Cached ToCallTargetNode toCallTargetNode) {
204+
final RootCallTarget callTarget = toCallTargetNode.execute(executable);
205+
ast(callTarget.getRootNode());
225206
return nil;
226207
}
227208

228-
@TruffleBoundary
229-
@Specialization
230-
protected Object astBlock(NotProvided proc, RubyProc block) {
231-
ast(block.callTarget);
232-
return nil;
233-
}
234-
235-
private Object ast(InternalMethod method) {
236-
return ast(method.getCallTarget());
237-
}
238-
239-
private Object ast(RootCallTarget rootCallTarget) {
240-
return ast(rootCallTarget.getRootNode());
241-
}
242-
243209
private Object ast(Node node) {
244210
if (node == null) {
245211
return nil;
@@ -255,53 +221,29 @@ private Object ast(Node node) {
255221

256222
return createArray(array.toArray());
257223
}
258-
259224
}
260225

261-
@CoreMethod(
262-
names = "print_ast",
263-
onSingleton = true,
264-
optional = 1,
265-
needsBlock = true,
266-
argumentNames = { "method_or_proc", "block" })
226+
@CoreMethod(names = "print_ast", onSingleton = true, required = 1)
267227
public abstract static class PrintASTNode extends CoreMethodArrayArgumentsNode {
268-
269-
@TruffleBoundary
270-
@Specialization
271-
protected Object astMethod(RubyMethod method, Nil block) {
272-
printAst(method.method);
273-
return nil;
274-
}
275-
276-
@TruffleBoundary
277-
@Specialization
278-
protected Object astUnboundMethod(RubyUnboundMethod method, Nil block) {
279-
printAst(method.method);
280-
return nil;
281-
}
282-
283228
@TruffleBoundary
284229
@Specialization
285-
protected Object astProc(RubyProc proc, Nil block) {
286-
printAst(proc.callTarget);
230+
protected Object printAST(Object executable,
231+
@Cached ToCallTargetNode toCallTargetNode) {
232+
final RootCallTarget callTarget = toCallTargetNode.execute(executable);
233+
NodeUtil.printCompactTree(System.err, callTarget.getRootNode());
287234
return nil;
288235
}
236+
}
289237

238+
@CoreMethod(names = "ast_size", onSingleton = true, required = 1)
239+
public abstract static class ASTSizeNode extends CoreMethodArrayArgumentsNode {
290240
@TruffleBoundary
291241
@Specialization
292-
protected Object astBlock(NotProvided proc, RubyProc block) {
293-
printAst(block.callTarget);
294-
return nil;
295-
}
296-
297-
public static void printAst(InternalMethod method) {
298-
NodeUtil.printCompactTree(System.err, method.getCallTarget().getRootNode());
242+
protected int astSize(Object executable,
243+
@Cached ToCallTargetNode toCallTargetNode) {
244+
final RootCallTarget callTarget = toCallTargetNode.execute(executable);
245+
return NodeUtil.countNodes(callTarget.getRootNode());
299246
}
300-
301-
private void printAst(RootCallTarget callTarget) {
302-
NodeUtil.printCompactTree(System.err, callTarget.getRootNode());
303-
}
304-
305247
}
306248

307249
@CoreMethod(names = "shape", onSingleton = true, required = 1)

src/main/java/org/truffleruby/extra/TruffleGraalNodes.java

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
*/
1010
package org.truffleruby.extra;
1111

12+
import com.oracle.truffle.api.dsl.Cached;
1213
import com.oracle.truffle.api.library.CachedLibrary;
1314
import org.truffleruby.builtins.CoreMethod;
1415
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
1516
import org.truffleruby.builtins.CoreModule;
1617
import org.truffleruby.builtins.Primitive;
1718
import org.truffleruby.builtins.PrimitiveNode;
18-
import org.truffleruby.core.method.RubyMethod;
19-
import org.truffleruby.core.method.RubyUnboundMethod;
19+
import org.truffleruby.core.cast.ToCallTargetNode;
2020
import org.truffleruby.core.proc.ProcCallTargets;
2121
import org.truffleruby.core.proc.ProcType;
2222
import org.truffleruby.core.proc.RubyProc;
@@ -43,69 +43,33 @@
4343
@CoreModule("Truffle::Graal")
4444
public abstract class TruffleGraalNodes {
4545

46-
@CoreMethod(names = "always_split", onSingleton = true, required = 1, argumentNames = "method_or_proc")
46+
@CoreMethod(names = "always_split", onSingleton = true, required = 1)
4747
public abstract static class AlwaysSplitNode extends CoreMethodArrayArgumentsNode {
48-
49-
@TruffleBoundary
50-
@Specialization
51-
protected RubyMethod splitMethod(RubyMethod rubyMethod) {
52-
if (getContext().getOptions().ALWAYS_SPLIT_HONOR) {
53-
RubyRootNode rootNode = (RubyRootNode) rubyMethod.method.getCallTarget().getRootNode();
54-
rootNode.setSplit(Split.ALWAYS);
55-
}
56-
return rubyMethod;
57-
}
58-
5948
@TruffleBoundary
6049
@Specialization
61-
protected RubyUnboundMethod splitUnboundMethod(RubyUnboundMethod rubyMethod) {
50+
protected Object alwaysSplit(Object executable,
51+
@Cached ToCallTargetNode toCallTargetNode) {
52+
final RootCallTarget callTarget = toCallTargetNode.execute(executable);
6253
if (getContext().getOptions().ALWAYS_SPLIT_HONOR) {
63-
RubyRootNode rootNode = (RubyRootNode) rubyMethod.method.getCallTarget().getRootNode();
54+
RubyRootNode rootNode = (RubyRootNode) callTarget.getRootNode();
6455
rootNode.setSplit(Split.ALWAYS);
6556
}
66-
return rubyMethod;
67-
}
68-
69-
@TruffleBoundary
70-
@Specialization
71-
protected RubyProc splitProc(RubyProc rubyProc) {
72-
if (getContext().getOptions().ALWAYS_SPLIT_HONOR) {
73-
((RubyRootNode) rubyProc.callTarget.getRootNode()).setSplit(Split.ALWAYS);
74-
}
75-
return rubyProc;
57+
return executable;
7658
}
7759
}
7860

79-
@CoreMethod(names = "never_split", onSingleton = true, required = 1, argumentNames = "method_or_proc")
61+
@CoreMethod(names = "never_split", onSingleton = true, required = 1)
8062
public abstract static class NeverSplitNode extends CoreMethodArrayArgumentsNode {
81-
82-
@TruffleBoundary
83-
@Specialization
84-
protected RubyMethod neverSplitMethod(RubyMethod rubyMethod) {
85-
if (getContext().getOptions().NEVER_SPLIT_HONOR) {
86-
RubyRootNode rootNode = (RubyRootNode) rubyMethod.method.getCallTarget().getRootNode();
87-
rootNode.setSplit(Split.NEVER);
88-
}
89-
return rubyMethod;
90-
}
91-
9263
@TruffleBoundary
9364
@Specialization
94-
protected RubyUnboundMethod neverSplitUnboundMethod(RubyUnboundMethod rubyMethod) {
65+
protected Object neverSplit(Object executable,
66+
@Cached ToCallTargetNode toCallTargetNode) {
67+
final RootCallTarget callTarget = toCallTargetNode.execute(executable);
9568
if (getContext().getOptions().NEVER_SPLIT_HONOR) {
96-
RubyRootNode rootNode = (RubyRootNode) rubyMethod.method.getCallTarget().getRootNode();
69+
RubyRootNode rootNode = (RubyRootNode) callTarget.getRootNode();
9770
rootNode.setSplit(Split.NEVER);
9871
}
99-
return rubyMethod;
100-
}
101-
102-
@TruffleBoundary
103-
@Specialization
104-
protected RubyProc neverSplitProc(RubyProc rubyProc) {
105-
if (getContext().getOptions().NEVER_SPLIT_HONOR) {
106-
((RubyRootNode) rubyProc.callTarget.getRootNode()).setSplit(Split.NEVER);
107-
}
108-
return rubyProc;
72+
return executable;
10973
}
11074
}
11175

0 commit comments

Comments
 (0)