13
13
import org .truffleruby .RubyLanguage ;
14
14
import org .truffleruby .core .array .ArrayToObjectArrayNode ;
15
15
import org .truffleruby .core .array .ArrayToObjectArrayNodeGen ;
16
- import org .truffleruby .core .array .ArrayUtils ;
17
16
import org .truffleruby .core .array .AssignableNode ;
18
17
import org .truffleruby .core .cast .BooleanCastNode ;
19
18
import org .truffleruby .core .cast .BooleanCastNodeGen ;
22
21
import org .truffleruby .language .RubyBaseNode ;
23
22
import org .truffleruby .language .RubyContextSourceNode ;
24
23
import org .truffleruby .language .RubyNode ;
24
+ import org .truffleruby .language .literal .NilLiteralNode ;
25
25
import org .truffleruby .language .methods .BlockDefinitionNode ;
26
26
import org .truffleruby .language .methods .InternalMethod ;
27
27
@@ -88,7 +88,7 @@ public Object execute(VirtualFrame frame) {
88
88
return nil ;
89
89
}
90
90
91
- final Object [] executedArguments = executeArguments (frame , arguments . length );
91
+ final Object [] executedArguments = executeArguments (frame );
92
92
93
93
final Object blockObject = executeBlock (frame );
94
94
@@ -99,27 +99,28 @@ public Object execute(VirtualFrame frame) {
99
99
}
100
100
101
101
@ Override
102
- public void assign (VirtualFrame frame , Object extraArgument ) {
102
+ public void assign (VirtualFrame frame , Object value ) {
103
+ assert getLastArgumentNode () instanceof NilLiteralNode &&
104
+ ((NilLiteralNode ) getLastArgumentNode ()).isImplicit () : getLastArgumentNode ();
105
+
103
106
final Object receiverObject = receiver .execute (frame );
104
107
if (isSafeNavigation && nilProfile .profile (receiverObject == nil )) {
105
108
return ;
106
109
}
107
110
108
- final Object [] argumentsObjects ;
109
- final Object blockObject ;
110
- if (isSplatted ) {
111
- final Object [] executedArguments = executeArguments (frame , arguments .length );
111
+ final Object [] executedArguments = executeArguments (frame );
112
112
113
- blockObject = executeBlock (frame );
113
+ final Object blockObject = executeBlock (frame );
114
114
115
+ final Object [] argumentsObjects ;
116
+ if (isSplatted ) {
115
117
// The expansion of the splat is done after executing the block, for m(*args, &args.pop)
116
- argumentsObjects = ArrayUtils .append (splat (executedArguments ), extraArgument );
118
+ argumentsObjects = splat (executedArguments );
119
+ assert argumentsObjects [argumentsObjects .length - 1 ] == nil ;
120
+ argumentsObjects [argumentsObjects .length - 1 ] = value ;
117
121
} else {
118
- final Object [] executedArguments = executeArguments (frame , arguments .length + 1 );
119
- executedArguments [arguments .length ] = extraArgument ;
120
-
121
- blockObject = executeBlock (frame );
122
-
122
+ assert executedArguments [arguments .length - 1 ] == nil ;
123
+ executedArguments [arguments .length - 1 ] = value ;
123
124
argumentsObjects = executedArguments ;
124
125
}
125
126
@@ -152,8 +153,8 @@ private Object executeBlock(VirtualFrame frame) {
152
153
}
153
154
154
155
@ ExplodeLoop
155
- private Object [] executeArguments (VirtualFrame frame , int size ) {
156
- final Object [] argumentsObjects = new Object [size ];
156
+ private Object [] executeArguments (VirtualFrame frame ) {
157
+ final Object [] argumentsObjects = new Object [arguments . length ];
157
158
158
159
for (int i = 0 ; i < arguments .length ; i ++) {
159
160
argumentsObjects [i ] = arguments [i ].execute (frame );
@@ -193,6 +194,10 @@ public boolean hasLiteralBlock() {
193
194
return hasLiteralBlock ;
194
195
}
195
196
197
+ private RubyNode getLastArgumentNode () {
198
+ return arguments [arguments .length - 1 ];
199
+ }
200
+
196
201
@ Override
197
202
public AssignableNode toAssignableNode () {
198
203
return this ;
0 commit comments