12
12
import org .truffleruby .RubyContext ;
13
13
import org .truffleruby .RubyLanguage ;
14
14
import org .truffleruby .core .array .ArrayAppendOneNode ;
15
- import org .truffleruby .core .array .ArrayToObjectArrayNode ;
16
- import org .truffleruby .core .array .ArrayToObjectArrayNodeGen ;
17
15
import org .truffleruby .core .array .AssignableNode ;
16
+ import org .truffleruby .core .array .RubyArray ;
18
17
import org .truffleruby .core .cast .BooleanCastNode ;
19
18
import org .truffleruby .core .cast .BooleanCastNodeGen ;
20
19
import org .truffleruby .core .inlined .LambdaToProcNode ;
25
24
import org .truffleruby .language .RubyGuards ;
26
25
import org .truffleruby .language .RubyNode ;
27
26
import org .truffleruby .language .arguments .RubyArguments ;
27
+ import org .truffleruby .language .arguments .SplatToArgsNode ;
28
28
import org .truffleruby .language .literal .NilLiteralNode ;
29
29
import org .truffleruby .language .methods .BlockDefinitionNode ;
30
30
import org .truffleruby .language .methods .InternalMethod ;
@@ -58,11 +58,12 @@ public class RubyCallNode extends RubyContextSourceNode implements AssignableNod
58
58
private final boolean isAttrAssign ;
59
59
60
60
@ Child private DispatchNode dispatch ;
61
- @ Child private ArrayToObjectArrayNode toObjectArrayNode ;
62
61
@ Child private DefinedNode definedNode ;
63
62
64
63
private final ConditionProfile nilProfile ;
65
64
65
+ @ Child private SplatToArgsNode splatToArgs ;
66
+
66
67
public RubyCallNode (RubyCallNodeParameters parameters ) {
67
68
this .methodName = parameters .getMethodName ();
68
69
this .receiver = parameters .getReceiver ();
@@ -91,25 +92,18 @@ public Object execute(VirtualFrame frame) {
91
92
if (isSafeNavigation && nilProfile .profile (receiverObject == nil )) {
92
93
return nil ;
93
94
}
94
- if (!isSplatted ) {
95
- final Object [] rubyArgs = RubyArguments .allocate (arguments .length );
96
- RubyArguments .setSelf (rubyArgs , receiverObject );
97
-
98
- executeArguments (frame , rubyArgs );
99
-
100
- RubyArguments .setBlock (rubyArgs , executeBlock (frame ));
101
-
102
- return executeWithArgumentsEvaluated (frame , receiverObject , rubyArgs );
103
- } else {
104
- final Object [] executedArguments = executeArguments (frame );
95
+ Object [] rubyArgs = RubyArguments .allocate (arguments .length );
96
+ RubyArguments .setSelf (rubyArgs , receiverObject );
105
97
106
- final Object blockObject = executeBlock (frame );
98
+ executeArguments (frame , rubyArgs );
107
99
108
- // The expansion of the splat is done after executing the block, for m(*args, &args.pop)
109
- final Object [] argumentsObjects = splat (executedArguments );
100
+ RubyArguments .setBlock (rubyArgs , executeBlock (frame ));
110
101
111
- return executeWithArgumentsEvaluated (frame , receiverObject , blockObject , argumentsObjects );
102
+ // The expansion of the splat is done after executing the block, for m(*args, &args.pop)
103
+ if (isSplatted ) {
104
+ rubyArgs = splatArgs (receiverObject , rubyArgs );
112
105
}
106
+ return executeWithArgumentsEvaluated (frame , receiverObject , rubyArgs );
113
107
}
114
108
115
109
@ Override
@@ -121,24 +115,22 @@ public void assign(VirtualFrame frame, Object value) {
121
115
if (isSafeNavigation && nilProfile .profile (receiverObject == nil )) {
122
116
return ;
123
117
}
118
+ Object [] rubyArgs = RubyArguments .allocate (arguments .length );
119
+ RubyArguments .setSelf (rubyArgs , receiverObject );
124
120
125
- final Object [] executedArguments = executeArguments (frame );
121
+ executeArguments (frame , rubyArgs );
126
122
127
- final Object blockObject = executeBlock (frame );
123
+ RubyArguments . setBlock ( rubyArgs , executeBlock (frame ) );
128
124
129
- final Object [] argumentsObjects ;
130
125
if (isSplatted ) {
131
- // The expansion of the splat is done after executing the block, for m(*args, &args.pop)
132
- argumentsObjects = splat (executedArguments );
133
- assert argumentsObjects [argumentsObjects .length - 1 ] == nil ;
134
- argumentsObjects [argumentsObjects .length - 1 ] = value ;
135
- } else {
136
- assert executedArguments [arguments .length - 1 ] == nil ;
137
- executedArguments [arguments .length - 1 ] = value ;
138
- argumentsObjects = executedArguments ;
126
+ rubyArgs = splatArgs (receiverObject , rubyArgs );
139
127
}
140
128
141
- executeWithArgumentsEvaluated (frame , receiverObject , blockObject , argumentsObjects );
129
+ int argCount = RubyArguments .getArgumentsCount (rubyArgs );
130
+ assert RubyArguments .getArgument (rubyArgs , argCount - 1 ) == nil ;
131
+ RubyArguments .setArgument (rubyArgs , argCount - 1 , value );
132
+
133
+ executeWithArgumentsEvaluated (frame , receiverObject , rubyArgs );
142
134
}
143
135
144
136
public Object executeWithArgumentsEvaluated (VirtualFrame frame , Object receiverObject , Object [] rubyArgs ) {
@@ -175,31 +167,20 @@ private Object executeBlock(VirtualFrame frame) {
175
167
}
176
168
}
177
169
178
- @ ExplodeLoop
179
- private Object [] executeArguments (VirtualFrame frame ) {
180
- final Object [] argumentsObjects = new Object [arguments .length ];
181
-
182
- for (int i = 0 ; i < arguments .length ; i ++) {
183
- argumentsObjects [i ] = arguments [i ].execute (frame );
184
- }
185
-
186
- return argumentsObjects ;
187
- }
188
-
189
170
@ ExplodeLoop
190
171
private void executeArguments (VirtualFrame frame , Object [] rubyArgs ) {
191
172
for (int i = 0 ; i < arguments .length ; i ++) {
192
173
RubyArguments .setArgument (rubyArgs , i , arguments [i ].execute (frame ));
193
174
}
194
175
}
195
176
196
- private Object [] splat (Object [] arguments ) {
197
- if (toObjectArrayNode == null ) {
177
+ private Object [] splatArgs (Object receiverObject , Object [] rubyArgs ) {
178
+ if (splatToArgs == null ) {
198
179
CompilerDirectives .transferToInterpreterAndInvalidate ();
199
- toObjectArrayNode = insert (ArrayToObjectArrayNodeGen . create ());
180
+ splatToArgs = insert (new SplatToArgsNode ());
200
181
}
201
- // TODO(CS): what happens if it isn't an Array?
202
- return toObjectArrayNode . unsplat ( arguments );
182
+
183
+ return splatToArgs . execute ( receiverObject , rubyArgs , ( RubyArray ) RubyArguments . getArgument ( rubyArgs , 0 ) );
203
184
}
204
185
205
186
@ Override
0 commit comments