-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathdart_entry.h
327 lines (274 loc) · 12.8 KB
/
dart_entry.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef RUNTIME_VM_DART_ENTRY_H_
#define RUNTIME_VM_DART_ENTRY_H_
#include "vm/allocation.h"
#include "vm/growable_array.h"
#include "vm/object.h"
#include "vm/raw_object.h"
namespace dart {
// Forward declarations.
class Array;
class Closure;
class FlowGraphDeserializer;
class FlowGraphSerializer;
class Function;
class Instance;
class Integer;
class Library;
class Object;
class String;
// An arguments descriptor array consists of the type argument vector length (0
// if none); total argument count (not counting type argument vector); total
// arguments size (not counting type argument vector); the positional argument
// count; a sequence of (name, position) pairs, sorted by name, for each named
// optional argument; and a terminating null to simplify iterating in generated
// code.
class ArgumentsDescriptor : public ValueObject {
public:
explicit ArgumentsDescriptor(const Array& array);
// Accessors.
intptr_t TypeArgsLen() const; // 0 if no type argument vector is passed.
intptr_t FirstArgIndex() const { return TypeArgsLen() > 0 ? 1 : 0; }
intptr_t CountWithTypeArgs() const { return FirstArgIndex() + Count(); }
intptr_t Count() const; // Excluding type arguments vector.
intptr_t Size() const; // Excluding type arguments vector.
intptr_t SizeWithTypeArgs() const { return FirstArgIndex() + Size(); }
intptr_t PositionalCount() const; // Excluding type arguments vector.
intptr_t NamedCount() const { return Count() - PositionalCount(); }
StringPtr NameAt(intptr_t i) const;
intptr_t PositionAt(intptr_t i) const;
bool MatchesNameAt(intptr_t i, const String& other) const;
// Returns array of argument names in the arguments order.
ArrayPtr GetArgumentNames() const;
void PrintTo(BaseTextBuffer* buffer, bool show_named_positions = false) const;
const char* ToCString() const;
// Generated code support.
static intptr_t type_args_len_offset() {
return Array::element_offset(kTypeArgsLenIndex);
}
static intptr_t count_offset() { return Array::element_offset(kCountIndex); }
static intptr_t size_offset() { return Array::element_offset(kSizeIndex); }
static intptr_t positional_count_offset() {
return Array::element_offset(kPositionalCountIndex);
}
static intptr_t first_named_entry_offset() {
return Array::element_offset(kFirstNamedEntryIndex);
}
static intptr_t name_offset() { return kNameOffset * kCompressedWordSize; }
static intptr_t position_offset() {
return kPositionOffset * kCompressedWordSize;
}
static intptr_t named_entry_size() {
return kNamedEntrySize * kCompressedWordSize;
}
// Constructs an argument descriptor where all arguments are boxed and
// therefore number of parameters equals parameter size.
//
// Right now this is for example the case for all closure functions.
// Functions marked as entry-points may also be created by NewUnboxed because
// we rely that TFA will mark the arguments as nullable for such cases.
static ArrayPtr NewBoxed(intptr_t type_args_len,
intptr_t num_arguments,
const Array& optional_arguments_names,
Heap::Space space = Heap::kOld) {
return New(type_args_len, num_arguments, num_arguments,
optional_arguments_names, space);
}
// Allocate and return an arguments descriptor. The first
// (num_arguments - optional_arguments_names.Length()) arguments are
// positional and the remaining ones are named optional arguments.
// The presence of a type argument vector as first argument (not counted in
// num_arguments) is indicated by a non-zero type_args_len.
static ArrayPtr New(intptr_t type_args_len,
intptr_t num_arguments,
intptr_t size_arguments,
const Array& optional_arguments_names,
Heap::Space space = Heap::kOld);
// Constructs an argument descriptor where all arguments are boxed and
// therefore number of parameters equals parameter size.
//
// Right now this is for example the case for all closure functions.
static ArrayPtr NewBoxed(intptr_t type_args_len,
intptr_t num_arguments,
Heap::Space space = Heap::kOld) {
return New(type_args_len, num_arguments, num_arguments, space);
}
// Allocate and return an arguments descriptor that has no optional
// arguments. All arguments are positional. The presence of a type argument
// vector as first argument (not counted in num_arguments) is indicated
// by a non-zero type_args_len.
static ArrayPtr New(intptr_t type_args_len,
intptr_t num_arguments,
intptr_t size_arguments,
Heap::Space space = Heap::kOld);
// Initialize the preallocated fixed length arguments descriptors cache.
static void Init();
// Clear the preallocated fixed length arguments descriptors cache.
static void Cleanup();
enum { kCachedDescriptorCount = 32 };
// For creating ArgumentDescriptor Slots.
static constexpr bool ContainsCompressedPointers() {
// Use the same state as the backing store.
return Array::ContainsCompressedPointers();
}
void Write(FlowGraphSerializer* s) const;
static ArrayPtr Read(FlowGraphDeserializer* d);
private:
// Absolute indices into the array.
// Keep these in sync with the constants in invocation_mirror_patch.dart.
enum {
kTypeArgsLenIndex,
kCountIndex,
kSizeIndex,
kPositionalCountIndex,
kFirstNamedEntryIndex,
};
private:
// Relative indexes into each named argument entry.
enum {
kNameOffset,
// The least significant bit of the entry in 'kPositionOffset' (second
// least-significant after Smi-encoding) holds the strong-mode checking bit
// for the named argument.
kPositionOffset,
kNamedEntrySize,
};
static intptr_t LengthFor(intptr_t num_named_arguments) {
// Add 1 for the terminating null.
return kFirstNamedEntryIndex + (kNamedEntrySize * num_named_arguments) + 1;
}
static ArrayPtr NewNonCached(intptr_t type_args_len,
intptr_t num_arguments,
intptr_t size_arguments,
bool canonicalize,
Heap::Space space);
// Used by Simulator to parse argument descriptors.
static intptr_t name_index(intptr_t index) {
return kFirstNamedEntryIndex + (index * kNamedEntrySize) + kNameOffset;
}
static intptr_t position_index(intptr_t index) {
return kFirstNamedEntryIndex + (index * kNamedEntrySize) + kPositionOffset;
}
bool IsCached() const;
const Array& array_;
// A cache of VM heap allocated arguments descriptors.
static ArrayPtr cached_args_descriptors_[kCachedDescriptorCount];
friend class Interpreter;
friend class InterpreterHelpers;
friend class VMSerializationRoots;
friend class VMDeserializationRoots;
DISALLOW_COPY_AND_ASSIGN(ArgumentsDescriptor);
};
// DartEntry abstracts functionality needed to resolve dart functions
// and invoke them from C++.
class DartEntry : public AllStatic {
public:
// Invokes the specified instance function or static function.
// The first argument of an instance function is the receiver.
// On success, returns an InstancePtr. On failure, an ErrorPtr.
// This is used when there is no type argument vector and
// no named arguments in the call.
static ObjectPtr InvokeFunction(const Function& function,
const Array& arguments);
#if defined(TESTING)
// Invokes the specified code as if it was a Dart function.
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr InvokeCode(const Code& code,
const Array& arguments_descriptor,
const Array& arguments,
Thread* thread);
#endif
// Invokes the specified instance, static, or closure function.
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr InvokeFunction(const Function& function,
const Array& arguments,
const Array& arguments_descriptor);
// Invokes the first argument in the provided arguments array as a callable
// object, performing any needed dynamic checks if the callable cannot receive
// dynamic invocation.
//
// On success, returns an InstancePtr. On failure, an ErrorPtr.
//
// Used when an ArgumentsDescriptor is not required, that is, when there
// are no type arguments or named arguments.
static ObjectPtr InvokeClosure(Thread* thread, const Array& arguments);
// Invokes the first argument in the provided arguments array as a callable
// object, performing any needed dynamic checks if the callable cannot receive
// dynamic invocation.
//
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr InvokeClosure(Thread* thread,
const Array& arguments,
const Array& arguments_descriptor);
// Invokes the noSuchMethod instance function on the receiver.
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr InvokeNoSuchMethod(Thread* thread,
const Instance& receiver,
const String& target_name,
const Array& arguments,
const Array& arguments_descriptor);
private:
// Resolves the first argument in the provided arguments array to a callable
// compatible with the arguments. Helper method used within InvokeClosure.
//
// If no errors occur, the first argument is changed to be either the resolved
// callable or, if Function::null() is returned, an appropriate target for
// invoking noSuchMethod.
//
// On success, returns a FunctionPtr. On failure, an ErrorPtr.
static ObjectPtr ResolveCallable(Thread* thread,
const Array& arguments,
const Array& arguments_descriptor);
// Invokes a function returned by ResolveCallable, performing any dynamic
// checks needed if the function cannot receive dynamic invocation. Helper
// method used within InvokeClosure.
//
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr InvokeCallable(Thread* thread,
const Function& callable_function,
const Array& arguments,
const Array& arguments_descriptor);
};
// Utility functions to call from VM into Dart bootstrap libraries.
// Each may return an exception object.
class DartLibraryCalls : public AllStatic {
public:
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr InstanceCreate(const Library& library,
const String& exception_name,
const String& constructor_name,
const Array& arguments);
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr ToString(const Instance& receiver);
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr HashCode(const Instance& receiver);
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr Equals(const Instance& left, const Instance& right);
// Returns the handler if one has been registered for this port id.
static ObjectPtr LookupHandler(Dart_Port port_id);
// Returns handler on success, an ErrorPtr on failure, null if can't find
// handler for this port id.
static ObjectPtr HandleMessage(Dart_Port port_id, const Instance& message);
// Invokes the finalizer to run its callbacks.
static ObjectPtr HandleFinalizerMessage(const FinalizerBase& finalizer);
// Returns a list of open ReceivePorts.
static ObjectPtr LookupOpenPorts();
// Returns null on success, an ErrorPtr on failure.
static ObjectPtr DrainMicrotaskQueue();
// Ensures that the isolate's _pendingImmediateCallback is set to
// _startMicrotaskLoop from dart:async.
// Returns null on success, an ErrorPtr on failure.
static ObjectPtr EnsureScheduleImmediate();
// Runs the `_rehashObjects()` function in `dart:compact_hash`.
static ObjectPtr RehashObjectsInDartCompactHash(
Thread* thread,
const Object& array_or_growable_array);
// Runs the `_rehashObjects()` function in `dart:core`.
static ObjectPtr RehashObjectsInDartCore(
Thread* thread,
const Object& array_or_growable_array);
};
} // namespace dart
#endif // RUNTIME_VM_DART_ENTRY_H_