96 {
97 Fragment copy_args_prologue;
101 const int num_params =
102 num_fixed_params + num_opt_pos_params + num_opt_named_params;
104
105
106
107
111 true, &fixed_params);
112
113
114
115 const int min_num_pos_args = num_fixed_params;
116
117 LocalVariable* count_var = nullptr;
118 LocalVariable* optional_count_var = nullptr;
119 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
121 copy_args_prologue +=
123
125 copy_args_prologue +=
LoadNativeField(Slot::ArgumentsDescriptor_count());
127
128 copy_args_prologue +=
LoadLocal(count_var);
129 copy_args_prologue +=
IntConstant(min_num_pos_args);
130 copy_args_prologue +=
SmiBinaryOp(Token::kSUB,
true);
132 }
133
134
135 intptr_t param = 0;
136 for (; param < num_fixed_params; ++param) {
137 const auto [location, representation] = fixed_params[param];
138
139 const auto lo_location =
140 location.IsPairLocation() ? location.AsPairLocation()->At(0) : location;
141
142 if (lo_location.IsMachineRegister()) {
143 continue;
144 }
145
146 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
147 copy_args_prologue +=
LoadLocal(optional_count_var);
148 } else {
150 }
151 const intptr_t stack_slot_offset = lo_location.ToStackSlotOffset();
153 stack_slot_offset,
155 representation);
156 copy_args_prologue +=
157 StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
158 copy_args_prologue +=
Drop();
159 }
160
161
162 if (num_opt_pos_params > 0) {
163 JoinEntryInstr* next_missing = nullptr;
164 for (intptr_t opt_param = 0; param < num_params; ++param, ++opt_param) {
165 TargetEntryInstr *supplied, *missing;
167 copy_args_prologue +=
LoadLocal(optional_count_var);
169 copy_args_prologue +=
BranchIfTrue(&supplied, &missing);
170
171 Fragment good(supplied);
173
174
179 good +=
StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
181
182 Fragment not_good(missing);
183 if (next_missing != nullptr) {
184 not_good +=
Goto(next_missing);
185 not_good.current = next_missing;
186 }
188 not_good +=
Constant(DefaultParameterValueAt(opt_param));
189 not_good +=
190 StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
192 not_good +=
Goto(next_missing);
193
194 copy_args_prologue.current = good.current;
195 }
196 copy_args_prologue +=
Goto(next_missing );
197 copy_args_prologue.current = next_missing;
198
199 } else if (num_opt_named_params > 0) {
200 const intptr_t first_name_offset =
203
204
205 int* opt_param_position =
Z->Alloc<
int>(num_opt_named_params);
206 SortOptionalNamedParametersInto(opt_param_position, num_fixed_params,
207 num_params);
208
209 LocalVariable* optional_count_vars_processed =
211 ASSERT(optional_count_vars_processed !=
nullptr);
213 copy_args_prologue +=
214 StoreLocalRaw(TokenPosition::kNoSource, optional_count_vars_processed);
215 copy_args_prologue +=
Drop();
216
217 for (intptr_t
i = 0; param < num_params; ++param, ++
i) {
221 copy_args_prologue +=
LoadLocal(optional_count_vars_processed);
222 copy_args_prologue +=
SmiBinaryOp(Token::kMUL,
true);
224
225
226
227
228
229
230 Fragment good;
231 {
232
234 {
235
238 (first_name_offset +
245 }
251
252
254 ParameterVariable(opt_param_position[
i]));
256
257
258 good +=
LoadLocal(optional_count_vars_processed);
262 optional_count_vars_processed);
264 }
265
267
268 if (required) {
269 copy_args_prologue += good;
270 } else {
271
273 copy_args_prologue +=
277 copy_args_prologue +=
LoadLocal(tuple_diff);
278 copy_args_prologue +=
SmiBinaryOp(Token::kADD,
true);
281
282
285 ASSERT(param_name.IsSymbol());
286 copy_args_prologue +=
Constant(param_name);
287
288
289
290
291 TargetEntryInstr *supplied, *missing;
293
294
296
297
298 good.Prepend(supplied);
300
301
302 Fragment not_good(missing);
304 DefaultParameterValueAt(opt_param_position[
i] - num_fixed_params));
305
306
308 ParameterVariable(opt_param_position[
i]));
311
312 copy_args_prologue.current =
join;
313 }
314
315 copy_args_prologue +=
Drop();
316 }
317 }
318
319 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
320 copy_args_prologue +=
Drop();
321 copy_args_prologue +=
Drop();
322 copy_args_prologue +=
Drop();
323 }
324
325 return copy_args_prologue;
326}
static intptr_t ComputeLocationsOfFixedParameters(Zone *zone, const Function &function, bool should_assign_stack_locations=false, compiler::ParameterInfoArray *parameter_info=nullptr)
StringPtr ParameterNameAt(intptr_t index) const
bool IsRequiredAt(intptr_t index) const
intptr_t NumOptionalNamedParameters() const
intptr_t NumOptionalPositionalParameters() const
intptr_t num_fixed_parameters() const
intptr_t NumParameters() const
static Object & ZoneHandle()
LocalVariable * expression_temp_var() const
static word position_offset()
static word name_offset()
static word named_entry_size()
static word first_named_entry_offset()
static word data_offset()
Fragment IntConstant(int64_t value)
Fragment SmiRelationalOp(Token::Kind kind)
Fragment LoadLocal(LocalVariable *variable)
Fragment LoadFpRelativeSlot(intptr_t offset, CompileType result_type, Representation representation=kTagged)
Fragment LoadArgDescriptor()
JoinEntryInstr * BuildJoinEntry()
Fragment StoreLocalRaw(TokenPosition position, LocalVariable *variable)
Fragment LoadNativeField(const Slot &native_field, InnerPointerAccess loads_inner_pointer, bool calls_initializer=false)
Fragment BranchIfTrue(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry, bool negate=false)
Fragment LoadIndexed(classid_t class_id, intptr_t index_scale=compiler::target::kWordSize, bool index_unboxed=false, AlignmentType alignment=kAlignedAccess)
LocalVariable * MakeTemporary(const char *suffix=nullptr)
const Function & function_
Fragment Constant(const Object &value)
const ParsedFunction * parsed_function_
Fragment SmiBinaryOp(Token::Kind op, bool is_truncating=false)
Fragment Goto(JoinEntryInstr *destination)
Fragment BranchIfStrictEqual(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry)
static constexpr intptr_t kWordSize
static constexpr intptr_t kCompressedWordSize
GrowableArray< std::pair< Location, Representation > > ParameterInfoArray
static CompileType ParameterType(LocalVariable *param, Representation representation=kTagged)
static SkString join(const CommandLineFlags::StringArray &)