Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
dart_tools_api.h
Go to the documentation of this file.
1// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_INCLUDE_DART_TOOLS_API_H_
6#define RUNTIME_INCLUDE_DART_TOOLS_API_H_
7
8#include "dart_api.h" /* NOLINT */
9
10/** \mainpage Dart Tools Embedding API Reference
11 *
12 * This reference describes the Dart embedding API for tools. Tools include
13 * a debugger, service protocol, and timeline.
14 *
15 * NOTE: The APIs described in this file are unstable and subject to change.
16 *
17 * This reference is generated from the header include/dart_tools_api.h.
18 */
19
20/*
21 * ========
22 * Debugger
23 * ========
24 */
25
26/**
27 * ILLEGAL_ISOLATE_ID is a number guaranteed never to be associated with a
28 * valid isolate.
29 */
30#define ILLEGAL_ISOLATE_ID ILLEGAL_PORT
31
32/**
33 * ILLEGAL_ISOLATE_GROUP_ID is a number guaranteed never to be associated with a
34 * valid isolate group.
35 */
36#define ILLEGAL_ISOLATE_GROUP_ID 0
37
38/*
39 * =======
40 * Service
41 * =======
42 */
43
44/**
45 * A service request callback function.
46 *
47 * These callbacks, registered by the embedder, are called when the VM receives
48 * a service request it can't handle and the service request command name
49 * matches one of the embedder registered handlers.
50 *
51 * The return value of the callback indicates whether the response
52 * should be used as a regular result or an error result.
53 * Specifically, if the callback returns true, a regular JSON-RPC
54 * response is built in the following way:
55 *
56 * {
57 * "jsonrpc": "2.0",
58 * "result": <json_object>,
59 * "id": <some sequence id>,
60 * }
61 *
62 * If the callback returns false, a JSON-RPC error is built like this:
63 *
64 * {
65 * "jsonrpc": "2.0",
66 * "error": <json_object>,
67 * "id": <some sequence id>,
68 * }
69 *
70 * \param method The rpc method name.
71 * \param param_keys Service requests can have key-value pair parameters. The
72 * keys and values are flattened and stored in arrays.
73 * \param param_values The values associated with the keys.
74 * \param num_params The length of the param_keys and param_values arrays.
75 * \param user_data The user_data pointer registered with this handler.
76 * \param result A C string containing a valid JSON object. The returned
77 * pointer will be freed by the VM by calling free.
78 *
79 * \return True if the result is a regular JSON-RPC response, false if the
80 * result is a JSON-RPC error.
81 */
82typedef bool (*Dart_ServiceRequestCallback)(const char* method,
83 const char** param_keys,
84 const char** param_values,
85 intptr_t num_params,
86 void* user_data,
87 const char** json_object);
88
89/**
90 * Register a Dart_ServiceRequestCallback to be called to handle
91 * requests for the named rpc on a specific isolate. The callback will
92 * be invoked with the current isolate set to the request target.
93 *
94 * \param method The name of the method that this callback is responsible for.
95 * \param callback The callback to invoke.
96 * \param user_data The user data passed to the callback.
97 *
98 * NOTE: If multiple callbacks with the same name are registered, only
99 * the last callback registered will be remembered.
100 */
102 const char* method,
104 void* user_data);
105
106/**
107 * Register a Dart_ServiceRequestCallback to be called to handle
108 * requests for the named rpc. The callback will be invoked without a
109 * current isolate.
110 *
111 * \param method The name of the command that this callback is responsible for.
112 * \param callback The callback to invoke.
113 * \param user_data The user data passed to the callback.
114 *
115 * NOTE: If multiple callbacks with the same name are registered, only
116 * the last callback registered will be remembered.
117 */
119 const char* method,
121 void* user_data);
122
123/**
124 * Embedder information which can be requested by the VM for internal or
125 * reporting purposes.
126 *
127 * The pointers in this structure are not going to be cached or freed by the VM.
128 */
129
130#define DART_EMBEDDER_INFORMATION_CURRENT_VERSION (0x00000001)
131
132typedef struct {
133 int32_t version;
134 const char* name; // [optional] The name of the embedder
135 int64_t current_rss; // [optional] the current RSS of the embedder
136 int64_t max_rss; // [optional] the maximum RSS of the embedder
138
139/**
140 * Callback provided by the embedder that is used by the VM to request
141 * information.
142 *
143 * \return Returns a pointer to a Dart_EmbedderInformation structure.
144 * The embedder keeps the ownership of the structure and any field in it.
145 * The embedder must ensure that the structure will remain valid until the
146 * next invocation of the callback.
147 */
150
151/**
152 * Register a Dart_ServiceRequestCallback to be called to handle
153 * requests for the named rpc. The callback will be invoked without a
154 * current isolate.
155 *
156 * \param method The name of the command that this callback is responsible for.
157 * \param callback The callback to invoke.
158 * \param user_data The user data passed to the callback.
159 *
160 * NOTE: If multiple callbacks are registered, only the last callback registered
161 * will be remembered.
162 */
165
166/**
167 * Invoke a vm-service method and wait for its result.
168 *
169 * \param request_json The utf8-encoded json-rpc request.
170 * \param request_json_length The length of the json-rpc request.
171 *
172 * \param response_json The returned utf8-encoded json response, must be
173 * free()ed by caller.
174 * \param response_json_length The length of the returned json response.
175 * \param error An optional error, must be free()ed by caller.
176 *
177 * \return Whether the call was successfully performed.
178 *
179 * NOTE: This method does not need a current isolate and must not have the
180 * vm-isolate being the current isolate. It must be called after
181 * Dart_Initialize() and before Dart_Cleanup().
182 */
183DART_EXPORT bool Dart_InvokeVMServiceMethod(uint8_t* request_json,
184 intptr_t request_json_length,
185 uint8_t** response_json,
186 intptr_t* response_json_length,
187 char** error);
188
189/*
190 * ========
191 * Event Streams
192 * ========
193 */
194
195/**
196 * A callback invoked when the VM service gets a request to listen to
197 * some stream.
198 *
199 * \return Returns true iff the embedder supports the named stream id.
200 */
201typedef bool (*Dart_ServiceStreamListenCallback)(const char* stream_id);
202
203/**
204 * A callback invoked when the VM service gets a request to cancel
205 * some stream.
206 */
207typedef void (*Dart_ServiceStreamCancelCallback)(const char* stream_id);
208
209/**
210 * Adds VM service stream callbacks.
211 *
212 * \param listen_callback A function pointer to a listen callback function.
213 * A listen callback function should not be already set when this function
214 * is called. A NULL value removes the existing listen callback function
215 * if any.
216 *
217 * \param cancel_callback A function pointer to a cancel callback function.
218 * A cancel callback function should not be already set when this function
219 * is called. A NULL value removes the existing cancel callback function
220 * if any.
221 *
222 * \return Success if the callbacks were added. Otherwise, returns an
223 * error handle.
224 */
226 Dart_ServiceStreamListenCallback listen_callback,
227 Dart_ServiceStreamCancelCallback cancel_callback);
228
229/**
230 * Sends a data event to clients of the VM Service.
231 *
232 * A data event is used to pass an array of bytes to subscribed VM
233 * Service clients. For example, in the standalone embedder, this is
234 * function used to provide WriteEvents on the Stdout and Stderr
235 * streams.
236 *
237 * If the embedder passes in a stream id for which no client is
238 * subscribed, then the event is ignored.
239 *
240 * \param stream_id The id of the stream on which to post the event.
241 *
242 * \param event_kind A string identifying what kind of event this is.
243 * For example, 'WriteEvent'.
244 *
245 * \param bytes A pointer to an array of bytes.
246 *
247 * \param bytes_length The length of the byte array.
248 *
249 * \return NULL if the arguments are well formed. Otherwise, returns an
250 * error string. The caller is responsible for freeing the error message.
251 */
252DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
253 const char* event_kind,
254 const uint8_t* bytes,
255 intptr_t bytes_length);
256
257/*
258 * ========
259 * Reload support
260 * ========
261 *
262 * These functions are used to implement reloading in the Dart VM.
263 * This is an experimental feature, so embedders should be prepared
264 * for these functions to change.
265 */
266
267/**
268 * A callback which determines whether the file at some url has been
269 * modified since some time. If the file cannot be found, true should
270 * be returned.
271 */
272typedef bool (*Dart_FileModifiedCallback)(const char* url, int64_t since);
273
275 Dart_FileModifiedCallback file_modified_callback);
276
277/**
278 * Returns true if isolate is currently reloading.
279 */
281
282/*
283 * ========
284 * Timeline
285 * ========
286 */
287
288/**
289 * Enable tracking of specified timeline category. This is operational
290 * only when systrace timeline functionality is turned on.
291 *
292 * \param categories A comma separated list of categories that need to
293 * be enabled, the categories are
294 * "all" : All categories
295 * "API" - Execution of Dart C API functions
296 * "Compiler" - Execution of Dart JIT compiler
297 * "CompilerVerbose" - More detailed Execution of Dart JIT compiler
298 * "Dart" - Execution of Dart code
299 * "Debugger" - Execution of Dart debugger
300 * "Embedder" - Execution of Dart embedder code
301 * "GC" - Execution of Dart Garbage Collector
302 * "Isolate" - Dart Isolate lifecycle execution
303 * "VM" - Execution in Dart VM runtime code
304 * "" - None
305 *
306 * When "all" is specified all the categories are enabled.
307 * When a comma separated list of categories is specified, the categories
308 * that are specified will be enabled and the rest will be disabled.
309 * When "" is specified all the categories are disabled.
310 * The category names are case sensitive.
311 * eg: Dart_EnableTimelineCategory("all");
312 * Dart_EnableTimelineCategory("GC,API,Isolate");
313 * Dart_EnableTimelineCategory("GC,Debugger,Dart");
314 *
315 * \return True if the categories were successfully enabled, False otherwise.
316 */
317DART_EXPORT bool Dart_SetEnabledTimelineCategory(const char* categories);
318
319/**
320 * Returns a timestamp in microseconds. This timestamp is suitable for
321 * passing into the timeline system, and uses the same monotonic clock
322 * as dart:developer's Timeline.now.
323 *
324 * \return A timestamp that can be passed to the timeline system.
325 */
327
328/**
329 * Returns a raw timestamp in from the monotonic clock.
330 *
331 * \return A raw timestamp from the monotonic clock.
332 */
334
335/**
336 * Returns the frequency of the monotonic clock.
337 *
338 * \return The frequency of the monotonic clock.
339 */
341
355
356/**
357 * Add a timeline event to the embedder stream.
358 *
359 * Note regarding flow events: events must be associated with flow IDs in two
360 * different ways to allow flow events to be serialized correctly in both
361 * Chrome's JSON trace event format and Perfetto's proto trace format. Events
362 * of type |Dart_Timeline_Event_Flow_Begin|, |Dart_Timeline_Event_Flow_Step|,
363 * and |Dart_Timeline_Event_Flow_End| must be reported to support serialization
364 * in Chrome's trace format. The |flow_ids| argument must be supplied when
365 * reporting events of type |Dart_Timeline_Event_Begin|,
366 * |Dart_Timeline_Event_Duration|, |Dart_Timeline_Event_Instant|,
367 * |Dart_Timeline_Event_Async_Begin|, and |Dart_Timeline_Event_Async_Instant| to
368 * support serialization in Perfetto's proto format.
369 *
370 * The Dart VM can use various underlying recorders depending on configuration
371 * and operating system. Many recorders do not support all event types;
372 * unsupported event types are siliently dropped. Some recorders do not accept
373 * timestamps as input, instead implicitly using the time the event is recorded.
374 * For maximum compatibility, record events with the Begin and End types as they
375 * occur instead of using the Duration type or buffering.
376 *
377 * \param label The name of the event. Its lifetime must extend at least until
378 * Dart_Cleanup.
379 * \param timestamp0 The first timestamp of the event.
380 * \param timestamp1_or_id When reporting an event of type
381 * |Dart_Timeline_Event_Duration|, the second (end) timestamp of the event
382 * should be passed through |timestamp1_or_id|. When reporting an event of
383 * type |Dart_Timeline_Event_Async_Begin|, |Dart_Timeline_Event_Async_End|,
384 * or |Dart_Timeline_Event_Async_Instant|, the async ID associated with the
385 * event should be passed through |timestamp1_or_id|. When reporting an
386 * event of type |Dart_Timeline_Event_Flow_Begin|,
387 * |Dart_Timeline_Event_Flow_Step|, or |Dart_Timeline_Event_Flow_End|, the
388 * flow ID associated with the event should be passed through
389 * |timestamp1_or_id|. When reporting an event of type
390 * |Dart_Timeline_Event_Begin| or |Dart_Timeline_Event_End|, the event ID
391 * associated with the event should be passed through |timestamp1_or_id|.
392 * Note that this event ID will only be used by the MacOS recorder. The
393 * argument to |timestamp1_or_id| will not be used when reporting events of
394 * other types.
395 * \param flow_id_count The number of flow IDs associated with this event.
396 * \param flow_ids An array of flow IDs associated with this event. The array
397 * may be reclaimed when this call returns.
398 * \param argument_count The number of argument names and values.
399 * \param argument_names An array of names of the arguments. The lifetime of the
400 * names must extend at least until Dart_Cleanup. The array may be reclaimed
401 * when this call returns.
402 * \param argument_values An array of values of the arguments. The values and
403 * the array may be reclaimed when this call returns.
404 */
406 int64_t timestamp0,
407 int64_t timestamp1_or_id,
408 intptr_t flow_id_count,
409 const int64_t* flow_ids,
411 intptr_t argument_count,
412 const char** argument_names,
413 const char** argument_values);
414
415/**
416 * Associates a name with the current thread. This name will be used to name
417 * threads in the timeline. Can only be called after a call to Dart_Initialize.
418 *
419 * \param name The name of the thread.
420 */
422
423typedef struct {
424 const char* name;
425 const char* value;
427
428#define DART_TIMELINE_RECORDER_CURRENT_VERSION (0x00000002)
429
430typedef struct {
431 /* Set to DART_TIMELINE_RECORDER_CURRENT_VERSION */
432 int32_t version;
433
434 /* The event's type / phase. */
436
437 /* The event's timestamp according to the same clock as
438 * Dart_TimelineGetMicros. For a duration event, this is the beginning time.
439 */
440 int64_t timestamp0;
441
442 /**
443 * For a duration event, this is the end time. For an async event, this is the
444 * async ID. For a flow event, this is the flow ID. For a begin or end event,
445 * this is the event ID (which is only referenced by the MacOS recorder).
446 */
448
449 /* The current isolate of the event, as if by Dart_GetMainPortId, or
450 * ILLEGAL_PORT if the event had no current isolate. */
452
453 /* The current isolate group of the event, as if by
454 * Dart_CurrentIsolateGroupId, or ILLEGAL_PORT if the event had no current
455 * isolate group. */
457
458 /* The callback data associated with the isolate if any. */
460
461 /* The callback data associated with the isolate group if any. */
463
464 /* The name / label of the event. */
465 const char* label;
466
467 /* The stream / category of the event. */
468 const char* stream;
469
473
474/**
475 * Callback provided by the embedder to handle the completion of timeline
476 * events.
477 *
478 * \param event A timeline event that has just been completed. The VM keeps
479 * ownership of the event and any field in it (i.e., the embedder should copy
480 * any values it needs after the callback returns).
481 */
484
485/**
486 * Register a `Dart_TimelineRecorderCallback` to be called as timeline events
487 * are completed.
488 *
489 * The callback will be invoked without a current isolate.
490 *
491 * The callback will be invoked on the thread completing the event. Because
492 * `Dart_RecordTimelineEvent` may be called by any thread, the callback may be
493 * called on any thread.
494 *
495 * The callback may be invoked at any time after `Dart_Initialize` is called and
496 * before `Dart_Cleanup` returns.
497 *
498 * If multiple callbacks are registered, only the last callback registered
499 * will be remembered. Providing a NULL callback will clear the registration
500 * (i.e., a NULL callback produced a no-op instead of a crash).
501 *
502 * Setting a callback is insufficient to receive events through the callback. The
503 * VM flag `timeline_recorder` must also be set to `callback`.
504 */
507
508/*
509 * =======
510 * Metrics
511 * =======
512 */
513
514/**
515 * Return metrics gathered for the VM and individual isolates.
516 */
517DART_EXPORT int64_t
519DART_EXPORT int64_t
521DART_EXPORT int64_t
523DART_EXPORT int64_t
525DART_EXPORT int64_t
527DART_EXPORT int64_t
529
530/*
531 * ========
532 * UserTags
533 * ========
534 */
535
536/*
537 * Gets the current isolate's currently set UserTag instance.
538 *
539 * \return The currently set UserTag instance.
540 */
542
543/*
544 * Gets the current isolate's default UserTag instance.
545 *
546 * \return The default UserTag with label 'Default'
547 */
549
550/*
551 * Creates a new UserTag instance.
552 *
553 * \param label The name of the new UserTag.
554 *
555 * \return The newly created UserTag instance or an error handle.
556 */
558
559/*
560 * Updates the current isolate's UserTag to a new value.
561 *
562 * \param user_tag The UserTag to be set as the current UserTag.
563 *
564 * \return The previously set UserTag instance or an error handle.
565 */
567
568/*
569 * Returns the label of a given UserTag instance.
570 *
571 * \param user_tag The UserTag from which the label will be retrieved.
572 *
573 * \return The UserTag's label. NULL if the user_tag is invalid. The caller is
574 * responsible for freeing the returned label.
575 */
577 Dart_Handle user_tag);
578
579/*
580 * =======
581 * Heap Snapshot
582 * =======
583 */
584
585/**
586 * Callback provided by the caller of `Dart_WriteHeapSnapshot` which is
587 * used to write out chunks of the requested heap snapshot.
588 *
589 * \param context An opaque context which was passed to `Dart_WriteHeapSnapshot`
590 * together with this callback.
591 *
592 * \param buffer Pointer to the buffer containing a chunk of the snapshot.
593 * The callback owns the buffer and needs to `free` it.
594 *
595 * \param size Number of bytes in the `buffer` to be written.
596 *
597 * \param is_last Set to `true` for the last chunk. The callback will not
598 * be invoked again after it was invoked once with `is_last` set to `true`.
599 */
600typedef void (*Dart_HeapSnapshotWriteChunkCallback)(void* context,
601 uint8_t* buffer,
602 intptr_t size,
603 bool is_last);
604
605/**
606 * Generate heap snapshot of the current isolate group and stream it into the
607 * given `callback`. VM would produce snapshot in chunks and send these chunks
608 * one by one back to the embedder by invoking the provided `callback`.
609 *
610 * This API enables embedder to stream snapshot into a file or socket without
611 * allocating a buffer to hold the whole snapshot in memory.
612 *
613 * The isolate group will be paused for the duration of this operation.
614 *
615 * \param write Callback used to write chunks of the heap snapshot.
616 *
617 * \param context Opaque context which would be passed on each invocation of
618 * `write` callback.
619 *
620 * \returns `nullptr` if the operation is successful otherwise error message.
621 * Caller owns error message string and needs to `free` it.
622 */
625 void* context);
626
627#endif // RUNTIME_INCLUDE_DART_TOOLS_API_H_
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
int64_t Dart_Port
Definition dart_api.h:1524
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
#define DART_WARN_UNUSED_RESULT
Definition dart_api.h:66
struct _Dart_IsolateGroup * Dart_IsolateGroup
Definition dart_api.h:89
int64_t Dart_IsolateGroupId
Definition dart_api.h:1208
DART_EXPORT void Dart_SetEmbedderInformationCallback(Dart_EmbedderInformationCallback callback)
DART_EXPORT int64_t Dart_IsolateGroupHeapNewExternalMetric(Dart_IsolateGroup group)
DART_EXPORT bool Dart_InvokeVMServiceMethod(uint8_t *request_json, intptr_t request_json_length, uint8_t **response_json, intptr_t *response_json_length, char **error)
DART_EXPORT int64_t Dart_TimelineGetMicros()
DART_EXPORT void Dart_SetTimelineRecorderCallback(Dart_TimelineRecorderCallback callback)
DART_EXPORT void Dart_RegisterRootServiceRequestCallback(const char *method, Dart_ServiceRequestCallback callback, void *user_data)
DART_EXPORT Dart_Handle Dart_GetCurrentUserTag()
DART_EXPORT char * Dart_SetFileModifiedCallback(Dart_FileModifiedCallback file_modified_callback)
DART_EXPORT void Dart_SetThreadName(const char *name)
bool(* Dart_ServiceStreamListenCallback)(const char *stream_id)
DART_EXPORT int64_t Dart_IsolateGroupHeapOldExternalMetric(Dart_IsolateGroup group)
DART_EXPORT int64_t Dart_TimelineGetTicksFrequency()
DART_EXPORT int64_t Dart_IsolateGroupHeapNewUsedMetric(Dart_IsolateGroup group)
DART_EXPORT int64_t Dart_IsolateGroupHeapOldCapacityMetric(Dart_IsolateGroup group)
void(* Dart_TimelineRecorderCallback)(Dart_TimelineRecorderEvent *event)
DART_EXPORT int64_t Dart_TimelineGetTicks()
DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(const char *method, Dart_ServiceRequestCallback callback, void *user_data)
Dart_Timeline_Event_Type
@ Dart_Timeline_Event_Async_Begin
@ Dart_Timeline_Event_Async_End
@ Dart_Timeline_Event_Begin
@ Dart_Timeline_Event_Counter
@ Dart_Timeline_Event_Flow_End
@ Dart_Timeline_Event_Duration
@ Dart_Timeline_Event_Flow_Begin
@ Dart_Timeline_Event_End
@ Dart_Timeline_Event_Instant
@ Dart_Timeline_Event_Async_Instant
@ Dart_Timeline_Event_Flow_Step
DART_EXPORT char * Dart_WriteHeapSnapshot(Dart_HeapSnapshotWriteChunkCallback write, void *context)
DART_EXPORT Dart_Handle Dart_GetDefaultUserTag()
DART_EXPORT Dart_Handle Dart_SetCurrentUserTag(Dart_Handle user_tag)
DART_EXPORT bool Dart_SetEnabledTimelineCategory(const char *categories)
bool(* Dart_ServiceRequestCallback)(const char *method, const char **param_keys, const char **param_values, intptr_t num_params, void *user_data, const char **json_object)
DART_EXPORT DART_WARN_UNUSED_RESULT char * Dart_GetUserTagLabel(Dart_Handle user_tag)
DART_EXPORT char * Dart_SetServiceStreamCallbacks(Dart_ServiceStreamListenCallback listen_callback, Dart_ServiceStreamCancelCallback cancel_callback)
DART_EXPORT int64_t Dart_IsolateGroupHeapNewCapacityMetric(Dart_IsolateGroup group)
DART_EXPORT bool Dart_IsReloading()
void(* Dart_HeapSnapshotWriteChunkCallback)(void *context, uint8_t *buffer, intptr_t size, bool is_last)
DART_EXPORT Dart_Handle Dart_NewUserTag(const char *label)
DART_EXPORT int64_t Dart_IsolateGroupHeapOldUsedMetric(Dart_IsolateGroup group)
bool(* Dart_FileModifiedCallback)(const char *url, int64_t since)
DART_EXPORT char * Dart_ServiceSendDataEvent(const char *stream_id, const char *event_kind, const uint8_t *bytes, intptr_t bytes_length)
void(* Dart_ServiceStreamCancelCallback)(const char *stream_id)
DART_EXPORT void Dart_RecordTimelineEvent(const char *label, int64_t timestamp0, int64_t timestamp1_or_id, intptr_t flow_id_count, const int64_t *flow_ids, Dart_Timeline_Event_Type type, intptr_t argument_count, const char **argument_names, const char **argument_values)
void(* Dart_EmbedderInformationCallback)(Dart_EmbedderInformation *info)
#define DART_EXPORT
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlKeyEvent * event
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
const char * name
Definition fuchsia.cc:50
int argument_count
Definition fuchsia.cc:52
void write(SkWStream *wStream, const T &text)
Definition skqp.cpp:188
Dart_IsolateGroupId isolate_group
Dart_Timeline_Event_Type type
Dart_TimelineRecorderEvent_Argument * arguments