Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
dart_api_impl.cc
Go to the documentation of this file.
1// Copyright (c) 2013, 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#include "include/dart_api.h"
7
8#include <cstring>
9#include <memory>
10#include <utility>
11
12#include "lib/stacktrace.h"
13#include "platform/assert.h"
14#include "platform/unicode.h"
15#include "vm/app_snapshot.h"
16#include "vm/class_finalizer.h"
18#include "vm/dart.h"
19#include "vm/dart_api_impl.h"
20#include "vm/dart_api_message.h"
21#include "vm/dart_api_state.h"
22#include "vm/dart_entry.h"
23#include "vm/debugger.h"
24#include "vm/dwarf.h"
25#include "vm/elf.h"
26#include "vm/exceptions.h"
27#include "vm/flags.h"
28#include "vm/growable_array.h"
29#include "vm/heap/verifier.h"
30#include "vm/image_snapshot.h"
31#include "vm/isolate_reload.h"
32#include "vm/kernel_isolate.h"
33#include "vm/lockers.h"
34#include "vm/message.h"
35#include "vm/message_handler.h"
36#include "vm/message_snapshot.h"
37#include "vm/native_entry.h"
38#include "vm/native_symbol.h"
39#include "vm/object.h"
40#include "vm/object_graph.h"
41#include "vm/object_store.h"
42#include "vm/os.h"
43#include "vm/os_thread.h"
44#include "vm/port.h"
45#include "vm/profiler.h"
46#include "vm/profiler_service.h"
47#include "vm/program_visitor.h"
48#include "vm/resolver.h"
49#include "vm/reusable_handles.h"
50#include "vm/service.h"
51#include "vm/service_event.h"
52#include "vm/service_isolate.h"
53#include "vm/stack_frame.h"
54#include "vm/symbols.h"
55#include "vm/tags.h"
56#include "vm/uri.h"
57#include "vm/version.h"
58#include "vm/zone_text_buffer.h"
59
60#if !defined(DART_PRECOMPILED_RUNTIME)
62#include "vm/kernel_loader.h"
63#endif // !defined(DART_PRECOMPILED_RUNTIME)
64
65namespace dart {
66
67// Facilitate quick access to the current zone once we have the current thread.
68#define Z (T->zone())
69
70DECLARE_FLAG(bool, print_class_table);
71#if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
72DEFINE_FLAG(bool,
73 check_function_fingerprints,
74 true,
75 "Check function fingerprints");
76#endif // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
78 verify_acquired_data,
79 false,
80 "Verify correct API acquire/release of typed data.");
82 dump_tables,
83 false,
84 "Dump common hash tables before snapshotting.");
86 enable_deprecated_wait_for,
87 false,
88 "Enable deprecated dart:cli waitFor. "
89 "This feature will be fully removed in Dart 3.4 release. "
90 "See https://dartbug.com/52121.");
91
92#define CHECK_ERROR_HANDLE(error) \
93 { \
94 ErrorPtr err = (error); \
95 if (err != Error::null()) { \
96 return Api::NewHandle(T, err); \
97 } \
98 }
99
100ThreadLocalKey Api::api_native_key_ = kUnsetThreadLocalKey;
101Dart_Handle Api::true_handle_ = nullptr;
102Dart_Handle Api::false_handle_ = nullptr;
103Dart_Handle Api::null_handle_ = nullptr;
104Dart_Handle Api::empty_string_handle_ = nullptr;
105Dart_Handle Api::no_callbacks_error_handle_ = nullptr;
106Dart_Handle Api::unwind_in_progress_error_handle_ = nullptr;
107
108const char* CanonicalFunction(const char* func) {
109 if (strncmp(func, "dart::", 6) == 0) {
110 return func + 6;
111 } else {
112 return func;
113 }
114}
115
116#if defined(DEBUG)
117// An object visitor which will iterate over all the function objects in the
118// heap and check if the result type and parameter types are canonicalized
119// or not. An assertion is raised if a type is not canonicalized.
120class CheckFunctionTypesVisitor : public ObjectVisitor {
121 public:
122 explicit CheckFunctionTypesVisitor(Thread* thread)
123 : classHandle_(Class::Handle(thread->zone())),
124 funcHandle_(Function::Handle(thread->zone())),
125 typeHandle_(AbstractType::Handle(thread->zone())) {}
126
127 void VisitObject(ObjectPtr obj) override {
128 if (obj->IsFunction()) {
129 funcHandle_ ^= obj;
130 classHandle_ ^= funcHandle_.Owner();
131 // Verify that the result type of a function is canonical or a
132 // TypeParameter.
133 typeHandle_ ^= funcHandle_.result_type();
134 ASSERT(typeHandle_.IsTypeParameter() || typeHandle_.IsCanonical());
135 // Verify that the types in the function signature are all canonical or
136 // a TypeParameter.
137 const intptr_t num_parameters = funcHandle_.NumParameters();
138 for (intptr_t i = 0; i < num_parameters; i++) {
139 typeHandle_ = funcHandle_.ParameterTypeAt(i);
140 ASSERT(typeHandle_.IsTypeParameter() || typeHandle_.IsCanonical());
141 }
142 }
143 }
144
145 private:
146 Class& classHandle_;
147 Function& funcHandle_;
148 AbstractType& typeHandle_;
149};
150#endif // #if defined(DEBUG).
151
152static InstancePtr GetListInstance(Zone* zone, const Object& obj) {
153 if (obj.IsInstance()) {
155 const Type& list_rare_type =
156 Type::Handle(zone, object_store->non_nullable_list_rare_type());
157 ASSERT(!list_rare_type.IsNull());
158 const Instance& instance = Instance::Cast(obj);
159 const Class& obj_class = Class::Handle(zone, obj.clazz());
160 if (Class::IsSubtypeOf(obj_class, Object::null_type_arguments(),
161 Nullability::kNonNullable, list_rare_type,
162 Heap::kNew)) {
163 return instance.ptr();
164 }
165 }
166 return Instance::null();
167}
168
169static InstancePtr GetMapInstance(Zone* zone, const Object& obj) {
170 if (obj.IsInstance()) {
172 const Type& map_rare_type =
173 Type::Handle(zone, object_store->non_nullable_map_rare_type());
174 ASSERT(!map_rare_type.IsNull());
175 const Instance& instance = Instance::Cast(obj);
176 const Class& obj_class = Class::Handle(zone, obj.clazz());
177 if (Class::IsSubtypeOf(obj_class, Object::null_type_arguments(),
178 Nullability::kNonNullable, map_rare_type,
179 Heap::kNew)) {
180 return instance.ptr();
181 }
182 }
183 return Instance::null();
184}
185
186static bool IsCompiletimeErrorObject(Zone* zone, const Object& obj) {
187#if defined(DART_PRECOMPILED_RUNTIME)
188 // All compile-time errors were handled at snapshot generation time and
189 // compiletime_error_class was removed.
190 return false;
191#else
192 auto isolate_group = Thread::Current()->isolate_group();
193 const Class& error_class = Class::Handle(
194 zone, isolate_group->object_store()->compiletime_error_class());
195 ASSERT(!error_class.IsNull());
196 return (obj.GetClassId() == error_class.id());
197#endif
198}
199
201 int arg_index,
202 Dart_Handle* str,
203 void** peer) {
204 ASSERT(peer != nullptr);
205 if (Api::StringGetPeerHelper(arguments, arg_index, peer)) {
206 *str = nullptr;
207 return true;
208 }
209 Thread* thread = arguments->thread();
210 ASSERT(thread == Thread::Current());
211 *peer = nullptr;
213 Object& obj = thread->ObjectHandle();
214 obj = arguments->NativeArgAt(arg_index);
215 if (IsStringClassId(obj.GetClassId())) {
216 ASSERT(thread->api_top_scope() != nullptr);
217 *str = Api::NewHandle(thread, obj.ptr());
218 return true;
219 }
220 if (obj.IsNull()) {
221 *str = Api::Null();
222 return true;
223 }
224 return false;
225}
226
228 int arg_index,
229 int64_t* value) {
230 ASSERT(value != nullptr);
231 return Api::GetNativeIntegerArgument(arguments, arg_index, value);
232}
233
235 int arg_index,
236 uint64_t* value) {
237 ASSERT(value != nullptr);
238 int64_t arg_value = 0;
239 if (Api::GetNativeIntegerArgument(arguments, arg_index, &arg_value)) {
240 *value = static_cast<uint64_t>(arg_value);
241 return true;
242 }
243 return false;
244}
245
247 int arg_index,
248 double* value) {
249 ASSERT(value != nullptr);
250 return Api::GetNativeDoubleArgument(arguments, arg_index, value);
251}
252
254 int arg_index,
255 int num_fields,
256 intptr_t* field_values,
257 const char* current_func) {
258 ASSERT(field_values != nullptr);
259 if (Api::GetNativeFieldsOfArgument(arguments, arg_index, num_fields,
260 field_values)) {
261 return Api::Success();
262 }
263 Thread* thread = arguments->thread();
264 ASSERT(thread == Thread::Current());
266 Object& obj = thread->ObjectHandle();
267 obj = arguments->NativeArgAt(arg_index);
268 if (obj.IsNull()) {
269 memset(field_values, 0, (num_fields * sizeof(field_values[0])));
270 return Api::Success();
271 }
272 // We did not succeed in extracting the native fields report the
273 // appropriate error.
274 if (!obj.IsInstance()) {
275 return Api::NewError(
276 "%s expects argument at index '%d' to be of"
277 " type Instance.",
278 current_func, arg_index);
279 }
280 const Instance& instance = Instance::Cast(obj);
281 int field_count = instance.NumNativeFields();
282 ASSERT(num_fields != field_count);
283 return Api::NewError("%s: expected %d 'num_fields' but was passed in %d.",
284 current_func, field_count, num_fields);
285}
286
287static FunctionPtr FindCoreLibPrivateFunction(Zone* zone, const String& name) {
288 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
289 ASSERT(!core_lib.IsNull());
290 const Function& function =
292 ASSERT(!function.IsNull());
293 return function.ptr();
294}
295
297 const String& name,
298 const Instance& arg0) {
299 const intptr_t kNumArgs = 1;
300 const Function& function =
302 const Array& args = Array::Handle(zone, Array::New(kNumArgs));
303 args.SetAt(0, arg0);
305}
306
308 const String& name,
309 const Instance& arg0,
310 const Instance& arg1) {
311 const intptr_t kNumArgs = 2;
312 const Function& function =
314 const Array& args = Array::Handle(zone, Array::New(kNumArgs));
315 args.SetAt(0, arg0);
316 args.SetAt(1, arg1);
318}
319
321 const String& name,
322 const Instance& arg0,
323 const Instance& arg1,
324 const Instance& arg2) {
325 const intptr_t kNumArgs = 3;
326 const Function& function =
328 const Array& args = Array::Handle(Array::New(kNumArgs));
329 args.SetAt(0, arg0);
330 args.SetAt(1, arg1);
331 args.SetAt(2, arg2);
333}
334
335static const char* GetErrorString(Thread* thread, const Object& obj) {
336 // This function requires an API scope to be present.
337 if (obj.IsError()) {
338 ASSERT(thread->api_top_scope() != nullptr);
339 const Error& error = Error::Cast(obj);
340 const char* str = error.ToErrorCString();
341 intptr_t len = strlen(str) + 1;
342 char* str_copy = Api::TopScope(thread)->zone()->Alloc<char>(len);
343 strncpy(str_copy, str, len);
344 // Strip a possible trailing '\n'.
345 if ((len > 1) && (str_copy[len - 2] == '\n')) {
346 str_copy[len - 2] = '\0';
347 }
348 return str_copy;
349 } else {
350 return "";
351 }
352}
353
354Dart_Handle Api::InitNewHandle(Thread* thread, ObjectPtr raw) {
355 LocalHandles* local_handles = Api::TopScope(thread)->local_handles();
356 ASSERT(local_handles != nullptr);
357 LocalHandle* ref = local_handles->AllocateHandle();
358 ref->set_ptr(raw);
359 return ref->apiHandle();
360}
361
363 if (raw == Object::null()) {
364 return Null();
365 }
366 if (raw == Bool::True().ptr()) {
367 return True();
368 }
369 if (raw == Bool::False().ptr()) {
370 return False();
371 }
373 return InitNewHandle(thread, raw);
374}
375
377#if defined(DEBUG)
378 Thread* thread = Thread::Current();
380 ASSERT(thread->IsDartMutatorThread());
381 ASSERT(thread->isolate() != nullptr);
384#endif
385 return (reinterpret_cast<LocalHandle*>(object))->ptr();
386}
387
388#define DEFINE_UNWRAP(type) \
389 const type& Api::Unwrap##type##Handle(Zone* zone, Dart_Handle dart_handle) { \
390 const Object& obj = Object::Handle(zone, Api::UnwrapHandle(dart_handle)); \
391 if (obj.Is##type()) { \
392 return type::Cast(obj); \
393 } \
394 return type::Handle(zone); \
395 }
397#undef DEFINE_UNWRAP
398
399const String& Api::UnwrapStringHandle(const ReusableObjectHandleScope& reuse,
400 Dart_Handle dart_handle) {
401 Object& ref = reuse.Handle();
402 ref = Api::UnwrapHandle(dart_handle);
403 if (ref.IsString()) {
404 return String::Cast(ref);
405 }
406 return Object::null_string();
407}
408
410 const ReusableObjectHandleScope& reuse,
411 Dart_Handle dart_handle) {
412 Object& ref = reuse.Handle();
413 ref = Api::UnwrapHandle(dart_handle);
414 if (ref.IsInstance()) {
415 return Instance::Cast(ref);
416 }
417 return Object::null_instance();
418}
419
421 Isolate* isolate = thread->isolate();
422 if (!isolate->AllowClassFinalization()) {
423 // Class finalization is blocked for the isolate. Do nothing.
424 return Api::Success();
425 }
427 return Api::Success();
428 }
429 ASSERT(thread->sticky_error() != Object::null());
430 return Api::NewHandle(thread, thread->sticky_error());
431}
432
434 return reinterpret_cast<Dart_Isolate>(isolate);
435}
436
438 return reinterpret_cast<Dart_IsolateGroup>(isolate_group);
439}
440
445 // Ensure we transition safepoint state to VM if we are not already in
446 // that state.
447 TransitionToVM transition(T);
448 HANDLESCOPE(T);
449
450 va_list args;
451 va_start(args, format);
452 char* buffer = OS::VSCreate(Z, format, args);
453 va_end(args);
454
456 return Api::NewHandle(T, ApiError::New(message));
457}
458
463 // Ensure we transition safepoint state to VM if we are not already in
464 // that state.
465 TransitionToVM transition(T);
466 HANDLESCOPE(T);
467
468 va_list args;
469 va_start(args, format);
470 char* buffer = OS::VSCreate(Z, format, args);
471 va_end(args);
472
474 const Array& arguments = Array::Handle(Z, Array::New(1));
475 arguments.SetAt(0, message);
479 Symbols::ArgumentError(), Symbols::Dot(), arguments));
480 if (!error.IsError()) {
482 }
483 return Api::NewHandle(T, error.ptr());
484}
485
487 Isolate* isolate = Isolate::Current();
488 Thread* thread = Thread::Current();
489 ASSERT(thread->IsDartMutatorThread());
490 CHECK_ISOLATE(isolate);
491
492 // Check against all of the handles in the current isolate as well as the
493 // read-only handles.
494 return thread->IsValidHandle(handle) ||
496 reinterpret_cast<Dart_PersistentHandle>(handle)) ||
498 reinterpret_cast<Dart_WeakPersistentHandle>(handle)) ||
500 Dart::IsReadOnlyHandle(reinterpret_cast<uword>(handle));
501}
502
504 ASSERT(thread != nullptr);
505 ApiLocalScope* scope = thread->api_top_scope();
506 ASSERT(scope != nullptr);
507 return scope;
508}
509
510void Api::Init() {
511 if (api_native_key_ == kUnsetThreadLocalKey) {
512 api_native_key_ = OSThread::CreateThreadLocal();
513 }
514 ASSERT(api_native_key_ != kUnsetThreadLocalKey);
515}
516
518 ASSERT(raw->untag()->InVMIsolateHeap());
520 ref->set_ptr(raw);
521 return ref->apiHandle();
522}
523
525 Isolate* isolate = Isolate::Current();
526 ASSERT(isolate != nullptr);
527 ASSERT(isolate == Dart::vm_isolate());
528 ApiState* state = isolate->group()->api_state();
529 ASSERT(state != nullptr);
530
531 ASSERT(true_handle_ == nullptr);
532 true_handle_ = InitNewReadOnlyApiHandle(Bool::True().ptr());
533
534 ASSERT(false_handle_ == nullptr);
535 false_handle_ = InitNewReadOnlyApiHandle(Bool::False().ptr());
536
537 ASSERT(null_handle_ == nullptr);
538 null_handle_ = InitNewReadOnlyApiHandle(Object::null());
539
540 ASSERT(empty_string_handle_ == nullptr);
541 empty_string_handle_ = InitNewReadOnlyApiHandle(Symbols::Empty().ptr());
542
543 ASSERT(no_callbacks_error_handle_ == nullptr);
544 no_callbacks_error_handle_ =
545 InitNewReadOnlyApiHandle(Object::no_callbacks_error().ptr());
546
547 ASSERT(unwind_in_progress_error_handle_ == nullptr);
548 unwind_in_progress_error_handle_ =
549 InitNewReadOnlyApiHandle(Object::unwind_in_progress_error().ptr());
550}
551
553 true_handle_ = nullptr;
554 false_handle_ = nullptr;
555 null_handle_ = nullptr;
556 empty_string_handle_ = nullptr;
557 no_callbacks_error_handle_ = nullptr;
558 unwind_in_progress_error_handle_ = nullptr;
559}
560
562 int arg_index,
563 void** peer) {
564 NoSafepointScope no_safepoint_scope;
565 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
566 if (!raw_obj->IsHeapObject()) {
567 return false;
568 }
569 intptr_t cid = raw_obj->GetClassId();
570 if (cid == kOneByteStringCid || cid == kTwoByteStringCid) {
571 auto isolate_group = arguments->thread()->isolate_group();
572 *peer = isolate_group->heap()->GetPeer(raw_obj);
573 return (*peer != nullptr);
574 }
575 return false;
576}
577
578bool Api::GetNativeReceiver(NativeArguments* arguments, intptr_t* value) {
579 NoSafepointScope no_safepoint_scope;
580 ObjectPtr raw_obj = arguments->NativeArg0();
581 if (raw_obj->IsHeapObject()) {
582 intptr_t cid = raw_obj->GetClassId();
583 if (cid >= kNumPredefinedCids) {
584 ASSERT(Instance::Cast(Object::Handle(raw_obj)).IsValidNativeIndex(0));
585 TypedDataPtr native_fields =
586 reinterpret_cast<CompressedTypedDataPtr*>(
587 UntaggedObject::ToAddr(raw_obj) + sizeof(UntaggedObject))
588 ->Decompress(raw_obj->heap_base());
589 if (native_fields == TypedData::null()) {
590 *value = 0;
591 } else {
592 *value = *bit_cast<intptr_t*, uint8_t*>(native_fields->untag()->data());
593 }
594 return true;
595 }
596 }
597 return false;
598}
599
601 int arg_index,
602 bool* value) {
603 NoSafepointScope no_safepoint_scope;
604 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
605 if (raw_obj->IsHeapObject()) {
606 intptr_t cid = raw_obj->GetClassId();
607 if (cid == kBoolCid) {
608 *value = (raw_obj == Object::bool_true().ptr());
609 return true;
610 }
611 if (cid == kNullCid) {
612 *value = false;
613 return true;
614 }
615 }
616 return false;
617}
618
620 int arg_index,
621 int64_t* value) {
622 NoSafepointScope no_safepoint_scope;
623 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
624 if (raw_obj->IsHeapObject()) {
625 intptr_t cid = raw_obj->GetClassId();
626 if (cid == kMintCid) {
627 *value = static_cast<MintPtr>(raw_obj)->untag()->value_;
628 return true;
629 }
630 return false;
631 }
632 *value = Smi::Value(static_cast<SmiPtr>(raw_obj));
633 return true;
634}
635
637 int arg_index,
638 double* value) {
639 NoSafepointScope no_safepoint_scope;
640 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
641 if (raw_obj->IsHeapObject()) {
642 intptr_t cid = raw_obj->GetClassId();
643 if (cid == kDoubleCid) {
644 *value = static_cast<DoublePtr>(raw_obj)->untag()->value_;
645 return true;
646 }
647 if (cid == kMintCid) {
648 *value =
649 static_cast<double>(static_cast<MintPtr>(raw_obj)->untag()->value_);
650 return true;
651 }
652 return false;
653 }
654 *value = static_cast<double>(Smi::Value(static_cast<SmiPtr>(raw_obj)));
655 return true;
656}
657
659 int arg_index,
660 int num_fields,
661 intptr_t* field_values) {
662 NoSafepointScope no_safepoint_scope;
663 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
664 intptr_t cid = raw_obj->GetClassIdMayBeSmi();
665 int class_num_fields = arguments->thread()
666 ->isolate_group()
667 ->class_table()
668 ->At(cid)
669 ->untag()
670 ->num_native_fields_;
671 if (num_fields != class_num_fields) {
672 // No native fields or mismatched native field count.
673 return false;
674 }
675 TypedDataPtr native_fields =
676 reinterpret_cast<CompressedTypedDataPtr*>(
677 UntaggedObject::ToAddr(raw_obj) + sizeof(UntaggedObject))
678 ->Decompress(raw_obj->heap_base());
679 if (native_fields == TypedData::null()) {
680 // Native fields not initialized.
681 memset(field_values, 0, (num_fields * sizeof(field_values[0])));
682 return true;
683 }
684 ASSERT(class_num_fields == Smi::Value(native_fields->untag()->length()));
685 intptr_t* native_values =
686 reinterpret_cast<intptr_t*>(native_fields->untag()->data());
687 memmove(field_values, native_values, (num_fields * sizeof(field_values[0])));
688 return true;
689}
690
695
697 ASSERT(IsolateGroup::Current()->api_state()->IsValidPersistentHandle(handle));
698 return reinterpret_cast<PersistentHandle*>(handle);
699}
700
703#if defined(DEBUG)
705 ASSERT(state->IsValidWeakPersistentHandle(handle));
706#endif
707 return reinterpret_cast<FinalizablePersistentHandle*>(handle);
708}
710 Dart_FinalizableHandle handle) {
711#if defined(DEBUG)
713 ASSERT(state->IsValidFinalizableHandle(handle));
714#endif
715 return reinterpret_cast<FinalizablePersistentHandle*>(handle);
716}
717
718void FinalizablePersistentHandle::Finalize(
719 IsolateGroup* isolate_group,
721 if (!handle->ptr()->IsHeapObject()) {
722 return; // Free handle.
723 }
725 ASSERT(callback != nullptr);
726 void* peer = handle->peer();
727 ApiState* state = isolate_group->api_state();
728 ASSERT(state != nullptr);
729
730 if (!handle->auto_delete()) {
731 // Clear handle before running finalizer, finalizer can free the handle.
732 state->ClearWeakPersistentHandle(handle);
733 }
734
735 (*callback)(isolate_group->embedder_data(), peer);
736
737 if (handle->auto_delete()) {
738 state->FreeWeakPersistentHandle(handle);
739 }
740}
741
742// --- Handles ---
743
745 Thread* thread = Thread::Current();
746 TransitionNativeToVM transition(thread);
747 return Api::IsError(handle);
748}
749
751 Isolate* isolate = reinterpret_cast<Isolate*>(handle);
752 CHECK_ISOLATE(isolate);
754}
755
757 Thread* thread = Thread::Current();
758 TransitionNativeToVM transition(thread);
759 return Api::ClassId(object) == kApiErrorCid;
760}
761
763 Thread* thread = Thread::Current();
764 TransitionNativeToVM transition(thread);
765 return Api::ClassId(object) == kUnhandledExceptionCid;
766}
767
772 UnhandledException::Cast(Object::Handle(Z, Api::UnwrapHandle(object)));
773 const Instance& exc = Instance::Handle(Z, error.exception());
774 return IsCompiletimeErrorObject(Z, exc);
775 }
776
777 Thread* thread = Thread::Current();
778 TransitionNativeToVM transition(thread);
779 return Api::ClassId(object) == kLanguageErrorCid;
780}
781
783 Thread* thread = Thread::Current();
784 TransitionNativeToVM transition(thread);
785 return Api::ClassId(object) == kUnwindErrorCid;
786}
787
791 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
792 return GetErrorString(T, obj);
793}
794
797 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
798 return obj.IsUnhandledException();
799}
800
803 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
804 if (obj.IsUnhandledException()) {
805 const UnhandledException& error = UnhandledException::Cast(obj);
806 return Api::NewHandle(T, error.exception());
807 } else if (obj.IsError()) {
808 return Api::NewError("This error is not an unhandled exception error.");
809 } else {
810 return Api::NewError("Can only get exceptions from error handles.");
811 }
812}
813
816 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
817 if (obj.IsUnhandledException()) {
818 const UnhandledException& error = UnhandledException::Cast(obj);
819 return Api::NewHandle(T, error.stacktrace());
820 } else if (obj.IsError()) {
821 return Api::NewError("This error is not an unhandled exception error.");
822 } else {
823 return Api::NewError("Can only get stacktraces from error handles.");
824 }
825}
826
834
842
846
848 intptr_t class_id = Api::ClassId(exception);
849 if ((class_id == kApiErrorCid) || (class_id == kLanguageErrorCid)) {
850 const Object& excp = Object::Handle(Z, Api::UnwrapHandle(exception));
851 obj = String::New(GetErrorString(T, excp));
852 } else {
853 obj = Api::UnwrapInstanceHandle(Z, exception).ptr();
854 if (obj.IsNull()) {
855 RETURN_TYPE_ERROR(Z, exception, Instance);
856 }
857 }
858 const StackTrace& stacktrace = StackTrace::Handle(Z);
859 return Api::NewHandle(T, UnhandledException::New(obj, stacktrace));
860}
861
863 Thread* thread = Thread::Current();
864 CHECK_ISOLATE(thread->isolate());
865 TransitionNativeToVM transition(thread);
866 const Object& obj = Object::Handle(thread->zone(), Api::UnwrapHandle(handle));
867 if (!obj.IsError()) {
868 FATAL(
869 "%s expects argument 'handle' to be an error handle. "
870 "Did you forget to check Dart_IsError first?",
872 }
873 if (thread->top_exit_frame_info() == 0) {
874 // There are no dart frames on the stack so it would be illegal to
875 // propagate an error here.
876 FATAL("No Dart frames on stack, cannot propagate error.");
877 }
878 // Unwind all the API scopes till the exit frame before propagating.
879 const Error* error;
880 {
881 // We need to preserve the error object across the destruction of zones
882 // when the ApiScopes are unwound. By using NoSafepointScope, we can ensure
883 // that GC won't touch the raw error object before creating a valid
884 // handle for it in the surviving zone.
885 NoSafepointScope no_safepoint;
886 ErrorPtr raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).ptr();
887 thread->UnwindScopes(thread->top_exit_frame_info());
888 // Note that thread's zone is different here than at the beginning of this
889 // function.
890 error = &Error::Handle(thread->zone(), raw_error);
891 }
893 UNREACHABLE();
894}
895
898 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
899 if (obj.IsString()) {
900 return Api::NewHandle(T, obj.ptr());
901 } else if (obj.IsInstance()) {
903 const Instance& receiver = Instance::Cast(obj);
905 } else {
907 // This is a VM internal object. Call the C++ method of printing.
908 return Api::NewHandle(T, String::New(obj.ToCString()));
909 }
910}
911
914 {
915 NoSafepointScope no_safepoint_scope;
916 if (Api::UnwrapHandle(obj1) == Api::UnwrapHandle(obj2)) {
917 return true;
918 }
919 }
920 const Object& object1 = Object::Handle(Z, Api::UnwrapHandle(obj1));
921 const Object& object2 = Object::Handle(Z, Api::UnwrapHandle(obj2));
922 if (object1.IsInstance() && object2.IsInstance()) {
923 return Instance::Cast(object1).IsIdenticalTo(Instance::Cast(object2));
924 }
925 return false;
926}
927
930 Thread* thread = Thread::Current();
931 Isolate* isolate = thread->isolate();
932 CHECK_ISOLATE(isolate);
933 ApiState* state = isolate->group()->api_state();
934 ASSERT(state != nullptr);
935 TransitionNativeToVM transition(thread);
936 NoSafepointScope no_safepoint_scope;
938 return Api::NewHandle(thread, ref->ptr());
939}
940
943 Thread* thread = Thread::Current();
944 Isolate* isolate = thread->isolate();
945 CHECK_ISOLATE(isolate);
946 ApiState* state = isolate->group()->api_state();
947 ASSERT(state != nullptr);
948 TransitionNativeToVM transition(thread);
949 NoSafepointScope no_safepoint_scope;
952 if (weak_ref->IsFinalizedNotFreed()) {
953 return Dart_Null();
954 }
955 return Api::NewHandle(thread, weak_ref->ptr());
956}
957
959 Thread* thread = Thread::Current();
960 Isolate* isolate = thread->isolate();
961 CHECK_ISOLATE(isolate);
962 ApiState* state = isolate->group()->api_state();
963 ASSERT(state != nullptr);
964 TransitionNativeToVM transition(thread);
965 NoSafepointScope no_safepoint_scope;
968 return Api::NewHandle(thread, weak_ref->ptr());
969}
970
973 Isolate* I = T->isolate();
974 ApiState* state = I->group()->api_state();
975 ASSERT(state != nullptr);
976 const Object& old_ref = Object::Handle(Z, Api::UnwrapHandle(object));
977 PersistentHandle* new_ref = state->AllocatePersistentHandle();
978 new_ref->set_ptr(old_ref);
979 return new_ref->apiHandle();
980}
981
983 Dart_Handle obj2) {
985 Isolate* I = T->isolate();
986 ApiState* state = I->group()->api_state();
987 ASSERT(state != nullptr);
988 ASSERT(state->IsValidPersistentHandle(obj1));
989 const Object& obj2_ref = Object::Handle(Z, Api::UnwrapHandle(obj2));
991 obj1_ref->set_ptr(obj2_ref);
992}
993
994static bool IsFfiCompound(Thread* T, const Object& obj) {
995 if (obj.IsNull()) {
996 return false;
997 }
998
999 // CFE guarantees we can only have direct subclasses of `Struct` and `Union`
1000 // (no implementations or indirect subclasses are allowed).
1001 const auto& klass = Class::Handle(Z, obj.clazz());
1002 const auto& super_klass = Class::Handle(Z, klass.SuperClass());
1003 if (super_klass.IsNull()) {
1004 // This means klass is Object.
1005 return false;
1006 }
1007 if (super_klass.Name() != Symbols::Struct().ptr() &&
1008 super_klass.Name() != Symbols::Union().ptr()) {
1009 return false;
1010 }
1011 const auto& library = Library::Handle(Z, super_klass.library());
1012 return library.url() == Symbols::DartFfi().ptr();
1013}
1014
1016 Thread* thread,
1017 const Object& ref,
1018 void* peer,
1019 intptr_t external_allocation_size,
1021 if (!ref.ptr()->IsHeapObject()) {
1022 return nullptr;
1023 }
1024 if (ref.IsPointer()) {
1025 return nullptr;
1026 }
1027 if (IsFfiCompound(thread, ref)) {
1028 return nullptr;
1029 }
1030
1031 FinalizablePersistentHandle* finalizable_ref =
1033 callback, external_allocation_size,
1034 /*auto_delete=*/false);
1035 return finalizable_ref == nullptr
1036 ? nullptr
1037 : finalizable_ref->ApiWeakPersistentHandle();
1038}
1039
1041 Thread* T,
1042 Dart_Handle object,
1043 void* peer,
1044 intptr_t external_allocation_size,
1046 const auto& ref = Object::Handle(Z, Api::UnwrapHandle(object));
1047 return AllocateWeakPersistentHandle(T, ref, peer, external_allocation_size,
1048 callback);
1049}
1050
1052 Thread* thread,
1053 const Object& ref,
1054 void* peer,
1055 intptr_t external_allocation_size,
1057 if (!ref.ptr()->IsHeapObject()) {
1058 return nullptr;
1059 }
1060 if (ref.IsPointer()) {
1061 return nullptr;
1062 }
1063 if (IsFfiCompound(thread, ref)) {
1064 return nullptr;
1065 }
1066
1067 FinalizablePersistentHandle* finalizable_ref =
1069 callback, external_allocation_size,
1070 /*auto_delete=*/true);
1071 return finalizable_ref == nullptr ? nullptr
1072 : finalizable_ref->ApiFinalizableHandle();
1073}
1074
1076 Thread* T,
1077 Dart_Handle object,
1078 void* peer,
1079 intptr_t external_allocation_size,
1081 const auto& ref = Object::Handle(Z, Api::UnwrapHandle(object));
1082 return AllocateFinalizableHandle(T, ref, peer, external_allocation_size,
1083 callback);
1084}
1085
1088 void* peer,
1089 intptr_t external_allocation_size,
1092 if (callback == nullptr) {
1093 return nullptr;
1094 }
1095
1096 return AllocateWeakPersistentHandle(T, object, peer, external_allocation_size,
1097 callback);
1098}
1099
1102 void* peer,
1103 intptr_t external_allocation_size,
1106 if (callback == nullptr) {
1107 return nullptr;
1108 }
1109
1110 return AllocateFinalizableHandle(T, object, peer, external_allocation_size,
1111 callback);
1112}
1113
1116 IsolateGroup* isolate_group = T->isolate_group();
1117 CHECK_ISOLATE_GROUP(isolate_group);
1118 TransitionToVM transition(T);
1119 ApiState* state = isolate_group->api_state();
1120 ASSERT(state != nullptr);
1121 ASSERT(state->IsActivePersistentHandle(object));
1123 if (!Api::IsProtectedHandle(object)) {
1125 state->FreePersistentHandle(ref);
1126 }
1127}
1128
1132 IsolateGroup* isolate_group = T->isolate_group();
1133 CHECK_ISOLATE_GROUP(isolate_group);
1134 TransitionToVM transition(T);
1135 ApiState* state = isolate_group->api_state();
1136 ASSERT(state != nullptr);
1137 ASSERT(state->IsActiveWeakPersistentHandle(object));
1138 auto weak_ref = FinalizablePersistentHandle::Cast(object);
1139 weak_ref->EnsureFreedExternal(isolate_group);
1140 state->FreeWeakPersistentHandle(weak_ref);
1141}
1142
1145 Dart_Handle strong_ref_to_object) {
1146 if (!::Dart_IdentityEquals(strong_ref_to_object,
1147 HandleFromFinalizable(object))) {
1148 FATAL(
1149 "%s expects arguments 'object' and 'strong_ref_to_object' to point to "
1150 "the same object.",
1151 CURRENT_FUNC);
1152 }
1153
1154 auto wph_object = reinterpret_cast<Dart_WeakPersistentHandle>(object);
1155
1157}
1158
1159// --- Initialization and Globals ---
1160
1162 return Version::String();
1163}
1164
1166 if (params == nullptr) {
1167 return Utils::StrDup(
1168 "Dart_Initialize: "
1169 "Dart_InitializeParams is null.");
1170 }
1171
1173 return Utils::StrDup(
1174 "Dart_Initialize: "
1175 "Invalid Dart_InitializeParams version.");
1176 }
1177
1178 return Dart::Init(params);
1179}
1180
1185
1186DART_EXPORT char* Dart_SetVMFlags(int argc, const char** argv) {
1188}
1189
1190DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name) {
1191 return Flags::IsSet(flag_name);
1192}
1193
1194#define ISOLATE_GROUP_METRIC_API(type, variable, name, unit) \
1195 DART_EXPORT int64_t Dart_IsolateGroup##variable##Metric( \
1196 Dart_IsolateGroup isolate_group) { \
1197 if (isolate_group == nullptr) { \
1198 FATAL("%s expects argument 'isolate_group' to be non-null.", \
1199 CURRENT_FUNC); \
1200 } \
1201 IsolateGroup* group = reinterpret_cast<IsolateGroup*>(isolate_group); \
1202 return group->Get##variable##Metric()->Value(); \
1203 }
1205#undef ISOLATE_GROUP_METRIC_API
1206
1207#if !defined(PRODUCT)
1208#define ISOLATE_METRIC_API(type, variable, name, unit) \
1209 DART_EXPORT int64_t Dart_Isolate##variable##Metric(Dart_Isolate isolate) { \
1210 if (isolate == nullptr) { \
1211 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC); \
1212 } \
1213 Isolate* iso = reinterpret_cast<Isolate*>(isolate); \
1214 return iso->Get##variable##Metric()->Value(); \
1215 }
1217#undef ISOLATE_METRIC_API
1218#else // !defined(PRODUCT)
1219#define ISOLATE_METRIC_API(type, variable, name, unit) \
1220 DART_EXPORT int64_t Dart_Isolate##variable##Metric(Dart_Isolate isolate) { \
1221 return -1; \
1222 }
1224#undef ISOLATE_METRIC_API
1225#endif // !defined(PRODUCT)
1226
1227// --- Isolates ---
1228
1230 bool is_new_group,
1231 const char* name,
1232 void* isolate_data,
1233 char** error) {
1235
1236 auto source = group->source();
1237 Isolate* I = Dart::CreateIsolate(name, source->flags, group);
1238 if (I == nullptr) {
1239 if (error != nullptr) {
1240 *error = Utils::StrDup("Isolate creation failed");
1241 }
1242 return static_cast<Dart_Isolate>(nullptr);
1243 }
1244
1246 bool success = false;
1247 {
1248 StackZone zone(T);
1249 HandleScope handle_scope(T);
1250
1251#if defined(SUPPORT_TIMELINE)
1252 TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
1253 "InitializeIsolate");
1254 tbes.SetNumArguments(1);
1255 tbes.CopyArgument(0, "isolateName", I->name());
1256#endif
1257
1258 // We enter an API scope here as InitializeIsolate could compile some
1259 // bootstrap library files which call out to a tag handler that may create
1260 // Api Handles when an error is encountered.
1261 T->EnterApiScope();
1262 auto& error_obj = Error::Handle(Z);
1263 if (is_new_group) {
1264 error_obj = Dart::InitializeIsolateGroup(
1265 T, source->snapshot_data, source->snapshot_instructions,
1266 source->kernel_buffer, source->kernel_buffer_size);
1267 }
1268 if (error_obj.IsNull()) {
1269 error_obj = Dart::InitializeIsolate(T, is_new_group, isolate_data);
1270 }
1271 if (error_obj.IsNull()) {
1272#if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
1273 if (FLAG_check_function_fingerprints && !FLAG_precompiled_mode) {
1274 Library::CheckFunctionFingerprints();
1275 }
1276#endif // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
1277 success = true;
1278 } else if (error != nullptr) {
1279 *error = Utils::StrDup(error_obj.ToErrorCString());
1280 }
1281 // We exit the API scope entered above.
1282 T->ExitApiScope();
1283 }
1284
1285 if (success) {
1286 // A Thread structure has been associated to the thread, we do the
1287 // safepoint transition explicitly here instead of using the
1288 // TransitionXXX scope objects as the reverse transition happens
1289 // outside this scope in Dart_ShutdownIsolate/Dart_ExitIsolate.
1290 T->set_execution_state(Thread::kThreadInNative);
1291 T->EnterSafepoint();
1292 if (error != nullptr) {
1293 *error = nullptr;
1294 }
1295 return Api::CastIsolate(I);
1296 }
1297
1299 return static_cast<Dart_Isolate>(nullptr);
1300}
1301
1303 const char* name,
1304 char** error) {
1307
1308 auto spawning_group = group;
1309
1310 Isolate* isolate = reinterpret_cast<Isolate*>(
1311 CreateIsolate(spawning_group, /*is_new_group=*/false, name,
1312 /*isolate_data=*/nullptr, error));
1313 if (isolate == nullptr) return nullptr;
1314
1315 auto source = spawning_group->source();
1316 ASSERT(isolate->source() == source);
1317
1318 return isolate;
1319}
1320
1324
1326Dart_CreateIsolateGroup(const char* script_uri,
1327 const char* name,
1328 const uint8_t* snapshot_data,
1329 const uint8_t* snapshot_instructions,
1331 void* isolate_group_data,
1332 void* isolate_data,
1333 char** error) {
1335
1336 Dart_IsolateFlags api_flags;
1337 if (flags == nullptr) {
1338 Isolate::FlagsInitialize(&api_flags);
1339 flags = &api_flags;
1340 }
1341
1342 const char* non_null_name = name == nullptr ? "isolate" : name;
1343 std::unique_ptr<IsolateGroupSource> source(
1344 new IsolateGroupSource(script_uri, non_null_name, snapshot_data,
1345 snapshot_instructions, nullptr, -1, *flags));
1346 auto group = new IsolateGroup(std::move(source), isolate_group_data, *flags,
1347 /*is_vm_isolate=*/false);
1348 group->CreateHeap(
1349 /*is_vm_isolate=*/false,
1350 flags->is_service_isolate || flags->is_kernel_isolate);
1352 Dart_Isolate isolate = CreateIsolate(group, /*is_new_group=*/true,
1353 non_null_name, isolate_data, error);
1354 if (isolate != nullptr) {
1355 group->set_initial_spawn_successful();
1356 }
1357 return isolate;
1358}
1359
1362 const char* name,
1363 const uint8_t* kernel_buffer,
1364 intptr_t kernel_buffer_size,
1366 void* isolate_group_data,
1367 void* isolate_data,
1368 char** error) {
1370
1371 Dart_IsolateFlags api_flags;
1372 if (flags == nullptr) {
1373 Isolate::FlagsInitialize(&api_flags);
1374 flags = &api_flags;
1375 }
1376
1377 const char* non_null_name = name == nullptr ? "isolate" : name;
1378 std::shared_ptr<IsolateGroupSource> source(
1379 new IsolateGroupSource(script_uri, non_null_name, nullptr, nullptr,
1380 kernel_buffer, kernel_buffer_size, *flags));
1381 auto group = new IsolateGroup(source, isolate_group_data, *flags,
1382 /*is_vm_isolate=*/false);
1384 group->CreateHeap(
1385 /*is_vm_isolate=*/false,
1386 flags->is_service_isolate || flags->is_kernel_isolate);
1387 Dart_Isolate isolate = CreateIsolate(group, /*is_new_group=*/true,
1388 non_null_name, isolate_data, error);
1389 if (isolate != nullptr) {
1390 group->set_initial_spawn_successful();
1391 }
1392 return isolate;
1393}
1394
1397 const char* name,
1398 Dart_IsolateShutdownCallback shutdown_callback,
1399 Dart_IsolateCleanupCallback cleanup_callback,
1400 void* child_isolate_data,
1401 char** error) {
1403 auto member = reinterpret_cast<Isolate*>(group_member);
1404 if (member->IsScheduled()) {
1405 FATAL("The given member isolate (%s) must not have been entered.",
1406 member->name());
1407 }
1408
1409 *error = nullptr;
1410
1411 Isolate* isolate;
1412 isolate = CreateWithinExistingIsolateGroup(member->group(), name, error);
1413 if (isolate != nullptr) {
1414 isolate->set_origin_id(member->origin_id());
1415 isolate->set_init_callback_data(child_isolate_data);
1416 isolate->set_on_shutdown_callback(shutdown_callback);
1417 isolate->set_on_cleanup_callback(cleanup_callback);
1418 }
1419
1420 return Api::CastIsolate(isolate);
1421}
1422
1425 auto I = T->isolate();
1427
1428 // The Thread structure is disassociated from the isolate, we do the
1429 // safepoint transition explicitly here instead of using the TransitionXXX
1430 // scope objects as the original transition happened outside this scope in
1431 // Dart_EnterIsolate/Dart_CreateIsolateGroup.
1432 ASSERT(T->execution_state() == Thread::kThreadInNative);
1433 T->ExitSafepoint();
1434 T->set_execution_state(Thread::kThreadInVM);
1435
1436 I->WaitForOutstandingSpawns();
1437
1438 // Release any remaining API scopes.
1439 ApiLocalScope* scope = T->api_top_scope();
1440 while (scope != nullptr) {
1441 ApiLocalScope* previous = scope->previous();
1442 delete scope;
1443 scope = previous;
1444 }
1445 T->set_api_top_scope(nullptr);
1446
1447 {
1448 StackZone zone(T);
1449 HandleScope handle_scope(T);
1451 }
1453}
1454
1458
1460 Isolate* isolate = Isolate::Current();
1461 CHECK_ISOLATE(isolate);
1462 NoSafepointScope no_safepoint_scope;
1463 return isolate->init_callback_data();
1464}
1465
1467 if (isolate == nullptr) {
1468 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
1469 }
1470 // TODO(http://dartbug.com/16615): Validate isolate parameter.
1471 return reinterpret_cast<Isolate*>(isolate)->init_callback_data();
1472}
1473
1477
1479 IsolateGroup* isolate_group = IsolateGroup::Current();
1480 CHECK_ISOLATE_GROUP(isolate_group);
1481 NoSafepointScope no_safepoint_scope;
1482 return isolate_group->embedder_data();
1483}
1484
1486 IsolateGroup* isolate_group = IsolateGroup::Current();
1487 CHECK_ISOLATE_GROUP(isolate_group);
1488 return isolate_group->id();
1489}
1490
1492 if (isolate == nullptr) {
1493 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
1494 }
1495 // TODO(http://dartbug.com/16615): Validate isolate parameter.
1496 return reinterpret_cast<Isolate*>(isolate)->group()->embedder_data();
1497}
1498
1501 Isolate* I = T->isolate();
1502 return Api::NewHandle(
1503 T, String::NewFormatted("(%" Pd64 ") '%s'",
1504 static_cast<int64_t>(I->main_port()), I->name()));
1505}
1506
1508 Thread* thread = Thread::Current();
1509 if (thread == nullptr) {
1510 return nullptr;
1511 }
1512 Isolate* I = thread->isolate();
1513 if (I == nullptr) {
1514 return nullptr;
1515 }
1516 int64_t main_port = static_cast<int64_t>(I->main_port());
1517 const char* fmt = "%s (%" Pd64 ")";
1518 int length = snprintf(nullptr, 0, fmt, I->name(), main_port) + 1;
1519 char* res = Api::TopScope(thread)->zone()->Alloc<char>(length);
1520 snprintf(res, length, fmt, I->name(), main_port);
1521 return res;
1522}
1523
1525 if (isolate == nullptr) {
1526 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
1527 }
1528 // TODO(http://dartbug.com/16615): Validate isolate parameter.
1529 Isolate* I = reinterpret_cast<Isolate*>(isolate);
1530 int64_t main_port = static_cast<int64_t>(I->main_port());
1531 return OS::SCreate(nullptr, "isolates/%" Pd64, main_port);
1532}
1533
1536 // TODO(http://dartbug.com/16615): Validate isolate parameter.
1537 Isolate* iso = reinterpret_cast<Isolate*>(isolate);
1538 if (iso->IsScheduled()) {
1539 FATAL(
1540 "Isolate %s is already scheduled on mutator thread %p, "
1541 "failed to schedule from os thread 0x%" Px "\n",
1542 iso->name(), iso->scheduled_mutator_thread(),
1544 }
1546 // A Thread structure has been associated to the thread, we do the
1547 // safepoint transition explicitly here instead of using the
1548 // TransitionXXX scope objects as the reverse transition happens
1549 // outside this scope in Dart_ExitIsolate/Dart_ShutdownIsolate.
1551 T->set_execution_state(Thread::kThreadInNative);
1552 T->EnterSafepoint();
1553}
1554
1556#if !defined(PRODUCT)
1557 if (!FLAG_profiler) {
1558 FLAG_profiler = true;
1560 }
1561#endif // !defined(PRODUCT)
1562}
1563
1565#if !defined(PRODUCT)
1566 if (FLAG_profiler) {
1568 FLAG_profiler = false;
1569 }
1570#endif // !defined(PRODUCT)
1571}
1572
1574#if !defined(PRODUCT)
1575 OSThread* os_thread = OSThread::Current();
1576 if (os_thread == nullptr) {
1577 return;
1578 }
1579 os_thread->DisableThreadInterrupts();
1580#endif // !defined(PRODUCT)
1581}
1582
1584#if !defined(PRODUCT)
1585 OSThread* os_thread = OSThread::Current();
1586 if (os_thread == nullptr) {
1587 return;
1588 }
1589 os_thread->EnableThreadInterrupts();
1590#endif // !defined(PRODUCT)
1591}
1592
1593DART_EXPORT void Dart_AddSymbols(const char* dso_name,
1594 void* buffer,
1595 intptr_t buffer_size) {
1597}
1598
1600 char** error) {
1601#if defined(PRODUCT)
1602 return false;
1603#else
1604 if (!FLAG_profiler) {
1605 if (error != nullptr) {
1606 *error = Utils::StrDup("The profiler is not running.");
1607 }
1608 return false;
1609 }
1610
1611 const intptr_t kBufferLength = 512;
1612 char method[kBufferLength];
1613
1614 // clang-format off
1615 intptr_t method_length = snprintf(method, kBufferLength, "{"
1616 "\"jsonrpc\": \"2.0\","
1617 "\"method\": \"_writeCpuProfileTimeline\","
1618 "\"id\": \"\","
1619 "\"params\": {"
1620 " \"isolateId\": \"isolates/%" Pd64 "\","
1621 " \"tags\": \"None\""
1622 "}"
1623 "}", main_port);
1624 // clang-format on
1625 ASSERT(method_length <= kBufferLength);
1626
1627 char* response = nullptr;
1628 intptr_t response_length;
1629 bool success = Dart_InvokeVMServiceMethod(
1630 reinterpret_cast<uint8_t*>(method), method_length,
1631 reinterpret_cast<uint8_t**>(&response), &response_length, error);
1632 free(response);
1633 return success;
1634#endif
1635}
1636
1638#if defined(PRODUCT)
1639 return false;
1640#else
1641 Isolate* isolate = Isolate::Current();
1642 CHECK_ISOLATE(isolate);
1643 NoSafepointScope no_safepoint_scope;
1644 return isolate->message_handler()->should_pause_on_start();
1645#endif
1646}
1647
1649#if defined(PRODUCT)
1650 if (should_pause) {
1651 FATAL("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
1652 }
1653#else
1654 Isolate* isolate = Isolate::Current();
1655 CHECK_ISOLATE(isolate);
1656 NoSafepointScope no_safepoint_scope;
1657 if (isolate->is_runnable()) {
1658 FATAL("%s expects the current isolate to not be runnable yet.",
1659 CURRENT_FUNC);
1660 }
1661 isolate->message_handler()->set_should_pause_on_start(should_pause);
1662#endif
1663}
1664
1666#if defined(PRODUCT)
1667 return false;
1668#else
1669 Isolate* isolate = Isolate::Current();
1670 CHECK_ISOLATE(isolate);
1671 NoSafepointScope no_safepoint_scope;
1672 return isolate->message_handler()->is_paused_on_start();
1673#endif
1674}
1675
1677#if defined(PRODUCT)
1678 if (paused) {
1679 FATAL("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
1680 }
1681#else
1682 Isolate* isolate = Isolate::Current();
1683 CHECK_ISOLATE(isolate);
1684 NoSafepointScope no_safepoint_scope;
1685 if (isolate->message_handler()->is_paused_on_start() != paused) {
1686 isolate->message_handler()->PausedOnStart(paused);
1687 }
1688#endif
1689}
1690
1692#if defined(PRODUCT)
1693 return false;
1694#else
1695 Isolate* isolate = Isolate::Current();
1696 CHECK_ISOLATE(isolate);
1697 NoSafepointScope no_safepoint_scope;
1698 return isolate->message_handler()->should_pause_on_exit();
1699#endif
1700}
1701
1703#if defined(PRODUCT)
1704 if (should_pause) {
1705 FATAL("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
1706 }
1707#else
1708 Isolate* isolate = Isolate::Current();
1709 CHECK_ISOLATE(isolate);
1710 NoSafepointScope no_safepoint_scope;
1711 isolate->message_handler()->set_should_pause_on_exit(should_pause);
1712#endif
1713}
1714
1716#if defined(PRODUCT)
1717 return false;
1718#else
1719 Isolate* isolate = Isolate::Current();
1720 CHECK_ISOLATE(isolate);
1721 NoSafepointScope no_safepoint_scope;
1722 return isolate->message_handler()->is_paused_on_exit();
1723#endif
1724}
1725
1727#if defined(PRODUCT)
1728 if (paused) {
1729 FATAL("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
1730 }
1731#else
1732 Isolate* isolate = Isolate::Current();
1733 CHECK_ISOLATE(isolate);
1734 NoSafepointScope no_safepoint_scope;
1735 if (isolate->message_handler()->is_paused_on_exit() != paused) {
1736 isolate->message_handler()->PausedOnExit(paused);
1737 }
1738#endif
1739}
1740
1742 Thread* thread = Thread::Current();
1743 DARTSCOPE(thread);
1744 Isolate* isolate = thread->isolate();
1745 CHECK_ISOLATE(isolate);
1746 NoSafepointScope no_safepoint_scope;
1747 const Error& error_handle = Api::UnwrapErrorHandle(Z, error);
1748 if ((isolate->sticky_error() != Error::null()) &&
1749 (error_handle.ptr() != Object::null())) {
1750 FATAL("%s expects there to be no sticky error.", CURRENT_FUNC);
1751 }
1752 if (!error_handle.IsUnhandledException() &&
1753 (error_handle.ptr() != Object::null())) {
1754 FATAL("%s expects the error to be an unhandled exception error or null.",
1755 CURRENT_FUNC);
1756 }
1757 isolate->SetStickyError(error_handle.ptr());
1758}
1759
1762 Isolate* isolate = T->isolate();
1763 CHECK_ISOLATE(isolate);
1764 NoSafepointScope no_safepoint_scope;
1765 return isolate->sticky_error() != Error::null();
1766}
1767
1770 Isolate* I = T->isolate();
1772 {
1773 NoSafepointScope no_safepoint_scope;
1774 if (I->sticky_error() == Error::null()) {
1775 return Api::Null();
1776 }
1777 }
1778 TransitionNativeToVM transition(T);
1779 return Api::NewHandle(T, I->sticky_error());
1780}
1781
1782DART_EXPORT void Dart_NotifyIdle(int64_t deadline) {
1784 CHECK_ISOLATE(T->isolate());
1786 TransitionNativeToVM transition(T);
1787 T->isolate()->group()->idle_time_handler()->NotifyIdle(deadline);
1788}
1789
1792 CHECK_ISOLATE(T->isolate());
1794 TransitionNativeToVM transition(T);
1795 T->heap()->NotifyDestroyed();
1796}
1797
1799#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1801#endif
1802}
1803
1805#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1807#endif
1808}
1809
1811 Dart_HeapSamplingCreateCallback create_callback,
1812 Dart_HeapSamplingDeleteCallback delete_callback) {
1813#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1814 HeapProfileSampler::SetSamplingCallback(create_callback, delete_callback);
1815#endif
1816}
1817
1820 void* context,
1821 bool force_gc) {
1822#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1826 /*bypass_safepoint=*/false);
1827 if (force_gc) {
1828 group->heap()->CollectAllGarbage(GCReason::kDebugging);
1829 }
1830 group->heap()->ReportSurvivingAllocations(callback, context);
1831 Thread::ExitIsolateGroupAsHelper(/*bypass_safepoint=*/false);
1832 });
1833#endif
1834}
1835
1837#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1839#endif
1840}
1841
1846
1847 // For each isolate's global variables, we might also clear:
1848 // - RegExp backtracking stack (both bytecode and compiled versions)
1849 // - String -> RegExp cache
1850 // - BigInt division/remainder cache
1851 // - double.toString cache
1852 // But cache invalidation code might be larger than the expected size of some
1853 // caches.
1854}
1855
1859 CHECK_ISOLATE(T->isolate());
1860 TransitionNativeToVM transition(T);
1861 return T->heap()->SetMode(mode);
1862}
1863
1866 CHECK_ISOLATE(T->isolate());
1867 // The Thread structure is disassociated from the isolate, we do the
1868 // safepoint transition explicitly here instead of using the TransitionXXX
1869 // scope objects as the original transition happened outside this scope in
1870 // Dart_EnterIsolate/Dart_CreateIsolateGroup.
1871 ASSERT(T->execution_state() == Thread::kThreadInNative);
1872 T->ExitSafepoint();
1873 T->set_execution_state(Thread::kThreadInVM);
1875}
1876
1878Dart_CreateSnapshot(uint8_t** vm_snapshot_data_buffer,
1879 intptr_t* vm_snapshot_data_size,
1880 uint8_t** isolate_snapshot_data_buffer,
1881 intptr_t* isolate_snapshot_data_size,
1882 bool is_core) {
1883#if defined(DART_PRECOMPILED_RUNTIME)
1884 return Api::NewError("Cannot create snapshots on an AOT runtime.");
1885#else
1888 if (vm_snapshot_data_buffer != nullptr) {
1889 CHECK_NULL(vm_snapshot_data_size);
1890 }
1891 CHECK_NULL(isolate_snapshot_data_buffer);
1892 CHECK_NULL(isolate_snapshot_data_size);
1893 // Finalize all classes if needed.
1895 if (Api::IsError(state)) {
1896 return state;
1897 }
1898 NoBackgroundCompilerScope no_bg_compiler(T);
1899
1900#if defined(DEBUG)
1901 T->isolate_group()->heap()->CollectAllGarbage(GCReason::kDebugging);
1902 {
1903 HeapIterationScope iteration(T);
1904 CheckFunctionTypesVisitor check_canonical(T);
1905 iteration.IterateObjects(&check_canonical);
1906 }
1907#endif // #if defined(DEBUG)
1908
1909 ZoneWriteStream vm_snapshot_data(Api::TopScope(T)->zone(),
1911 ZoneWriteStream isolate_snapshot_data(Api::TopScope(T)->zone(),
1913 const Snapshot::Kind snapshot_kind =
1915 FullSnapshotWriter writer(
1916 snapshot_kind, &vm_snapshot_data, &isolate_snapshot_data,
1917 nullptr /* vm_image_writer */, nullptr /* isolate_image_writer */);
1918 writer.WriteFullSnapshot();
1919 if (vm_snapshot_data_buffer != nullptr) {
1920 *vm_snapshot_data_buffer = vm_snapshot_data.buffer();
1921 *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
1922 }
1923 *isolate_snapshot_data_buffer = isolate_snapshot_data.buffer();
1924 *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
1925 return Api::Success();
1926#endif
1927}
1928
1929DART_EXPORT bool Dart_IsKernel(const uint8_t* buffer, intptr_t buffer_size) {
1930 if (buffer_size < 4) {
1931 return false;
1932 }
1933 return (buffer[0] == 0x90) && (buffer[1] == 0xab) && (buffer[2] == 0xcd) &&
1934 (buffer[3] == 0xef);
1935}
1936
1940 if (isolate == nullptr) {
1941 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
1942 }
1943 // TODO(16615): Validate isolate parameter.
1944 const char* error = reinterpret_cast<Isolate*>(isolate)->MakeRunnable();
1945 if (error != nullptr) {
1946 return Utils::StrDup(error);
1947 }
1948 return nullptr;
1949}
1950
1951// --- Messages and Ports ---
1952
1954 Dart_MessageNotifyCallback message_notify_callback) {
1955 Isolate* isolate = Isolate::Current();
1956 CHECK_ISOLATE(isolate);
1957
1958 {
1959 NoSafepointScope no_safepoint_scope;
1960 isolate->set_message_notify_callback(message_notify_callback);
1961 }
1962
1963 if (message_notify_callback != nullptr && isolate->HasPendingMessages()) {
1965
1966 // If a new handler gets installed and there are pending messages in the
1967 // queue (e.g. OOB messages for doing vm service work) we need to notify
1968 // the newly registered callback, otherwise the embedder might never get
1969 // notified about the pending messages.
1970 message_notify_callback(Api::CastIsolate(isolate));
1971
1973 }
1974}
1975
1977 Isolate* isolate = Isolate::Current();
1978 CHECK_ISOLATE(isolate);
1979 NoSafepointScope no_safepoint_scope;
1980 return isolate->message_notify_callback();
1981}
1982
1987
1988static void RunLoopDone(uword param) {
1989 RunLoopData* data = reinterpret_cast<RunLoopData*>(param);
1990 ASSERT(data->monitor != nullptr);
1991 MonitorLocker ml(data->monitor);
1992 data->done = true;
1993 ml.Notify();
1994}
1995
1997 Isolate* I;
1998 bool result;
1999 {
2001 I = T->isolate();
2004 }
2006 // The message handler run loop does not expect to have a current isolate
2007 // so we exit the isolate here and enter it again after the runloop is done.
2009 {
2010 Monitor monitor;
2011 MonitorLocker ml(&monitor);
2013 data.monitor = &monitor;
2014 data.done = false;
2015 result =
2016 I->message_handler()->Run(I->group()->thread_pool(), nullptr,
2017 RunLoopDone, reinterpret_cast<uword>(&data));
2018 if (result) {
2019 while (!data.done) {
2020 ml.Wait();
2021 }
2022 }
2023 }
2025 if (!result) {
2027 TransitionNativeToVM transition(T);
2028 return Api::NewError("Run method in isolate message handler failed");
2029 } else if (I->sticky_error() != Object::null()) {
2031 TransitionNativeToVM transition(T);
2032 return Api::NewHandle(T, I->StealStickyError());
2033 }
2034 if (FLAG_print_class_table) {
2036 I->group()->class_table()->Print();
2037 }
2038 return Api::Success();
2039}
2040
2041DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal,
2042 Dart_Port on_error_port,
2043 Dart_Port on_exit_port,
2044 char** error) {
2045 auto thread = Thread::Current();
2046 auto isolate = thread->isolate();
2047 CHECK_ISOLATE(isolate);
2048 *error = nullptr;
2049
2050 if (thread->api_top_scope() != nullptr) {
2051 *error = Utils::StrDup("There must not be an active api scope.");
2052 return false;
2053 }
2054
2055 if (!isolate->is_runnable()) {
2056 const char* error_msg = isolate->MakeRunnable();
2057 if (error_msg != nullptr) {
2058 *error = Utils::StrDup(error_msg);
2059 return false;
2060 }
2061 }
2062
2063 isolate->SetErrorsFatal(errors_are_fatal);
2064
2065 if (on_error_port != ILLEGAL_PORT || on_exit_port != ILLEGAL_PORT) {
2066 auto thread = Thread::Current();
2067 TransitionNativeToVM transition(thread);
2068 StackZone zone(thread);
2069
2070 if (on_error_port != ILLEGAL_PORT) {
2071 const auto& port =
2072 SendPort::Handle(thread->zone(), SendPort::New(on_error_port));
2073 isolate->AddErrorListener(port);
2074 }
2075 if (on_exit_port != ILLEGAL_PORT) {
2076 const auto& port =
2077 SendPort::Handle(thread->zone(), SendPort::New(on_exit_port));
2078 isolate->AddExitListener(port, Instance::null_instance());
2079 }
2080 }
2081
2083 isolate->Run();
2084 return true;
2085}
2086
2089 Isolate* I = T->isolate();
2093 TransitionNativeToVM transition(T);
2094 if (I->message_handler()->HandleNextMessage() != MessageHandler::kOK) {
2095 return Api::NewHandle(T, T->StealStickyError());
2096 }
2097 return Api::Success();
2098}
2099
2101#if defined(PRODUCT)
2102 return true;
2103#else
2105 Isolate* I = T->isolate();
2109 TransitionNativeToVM transition(T);
2110 ASSERT(I->GetAndClearResumeRequest() == false);
2112 I->message_handler()->HandleOOBMessages();
2113 bool resume = I->GetAndClearResumeRequest();
2114 return (status != MessageHandler::kOK) || resume;
2115#endif
2116}
2117
2119#if defined(PRODUCT)
2120 return false;
2121#else
2122 Isolate* isolate = Isolate::Current();
2123 ASSERT(isolate);
2124 NoSafepointScope no_safepoint_scope;
2125 return isolate->message_handler()->HasOOBMessages();
2126#endif
2127}
2128
2130 Isolate* isolate = Isolate::Current();
2131 ASSERT(isolate);
2132 NoSafepointScope no_safepoint_scope;
2133 return isolate->HasLivePorts();
2134}
2135
2139 NoSafepointScope no_safepoint_scope;
2140 if (port_id == ILLEGAL_PORT) {
2141 return false;
2142 }
2143
2144 const Object& object = Object::Handle(Z, Api::UnwrapHandle(handle));
2145 return PortMap::PostMessage(WriteMessage(/* same_group */ false, object,
2146 port_id, Message::kNormalPriority));
2147}
2148
2152 if (port_id == ILLEGAL_PORT) {
2153 return Api::NewError("%s: illegal port_id %" Pd64 ".", CURRENT_FUNC,
2154 port_id);
2155 }
2156 int64_t origin_id = PortMap::GetOriginId(port_id);
2157 return Api::NewHandle(T, SendPort::New(port_id, origin_id));
2158}
2159
2161 Dart_Port* port_id) {
2165 const SendPort& send_port = Api::UnwrapSendPortHandle(Z, port);
2166 if (send_port.IsNull()) {
2168 }
2169 if (port_id == nullptr) {
2170 RETURN_NULL_ERROR(port_id);
2171 }
2172 *port_id = send_port.Id();
2173 return Api::Success();
2174}
2175
2177 Isolate* isolate = Isolate::Current();
2178 CHECK_ISOLATE(isolate);
2179 return isolate->main_port();
2180}
2181
2182// --- Scopes ----
2183
2185 Thread* thread = Thread::Current();
2186 Isolate* isolate = thread->isolate();
2187 CHECK_ISOLATE(isolate);
2188 TransitionNativeToVM transition(thread);
2189 thread->EnterApiScope();
2190}
2191
2193 Thread* thread = Thread::Current();
2194 CHECK_API_SCOPE(thread);
2195 TransitionNativeToVM transition(thread);
2196 thread->ExitApiScope();
2197}
2198
2199DART_EXPORT uint8_t* Dart_ScopeAllocate(intptr_t size) {
2200 Zone* zone;
2201 Thread* thread = Thread::Current();
2202 if (thread != nullptr) {
2203 ApiLocalScope* scope = thread->api_top_scope();
2204 zone = scope->zone();
2205 } else {
2207 if (scope == nullptr) return nullptr;
2208 zone = scope->zone();
2209 }
2210 return reinterpret_cast<uint8_t*>(zone->AllocUnsafe(size));
2211}
2212
2213// --- Objects ----
2214
2216 ASSERT(Isolate::Current() != nullptr);
2217 return Api::Null();
2218}
2219
2222 return Api::UnwrapHandle(object) == Object::null();
2223}
2224
2229
2236
2243
2250
2252 Dart_Handle obj2,
2253 bool* value) {
2256 const Instance& expected =
2257 Instance::CheckedHandle(Z, Api::UnwrapHandle(obj1));
2258 const Instance& actual = Instance::CheckedHandle(Z, Api::UnwrapHandle(obj2));
2259 const Object& result =
2260 Object::Handle(Z, DartLibraryCalls::Equals(expected, actual));
2261 if (result.IsBool()) {
2262 *value = Bool::Cast(result).value();
2263 return Api::Success();
2264 } else if (result.IsError()) {
2265 return Api::NewHandle(T, result.ptr());
2266 } else {
2267 return Api::NewError("Expected boolean result from ==");
2268 }
2269}
2270
2271// Assumes type is non-null.
2272static bool InstanceIsType(const Thread* thread,
2273 const Instance& instance,
2274 const Type& type) {
2275 ASSERT(!type.IsNull());
2276 CHECK_CALLBACK_STATE(thread);
2277 return instance.IsInstanceOf(type, Object::null_type_arguments(),
2278 Object::null_type_arguments());
2279}
2280
2283 bool* value) {
2285
2286 const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
2287 if (type_obj.IsNull()) {
2288 *value = false;
2290 }
2291 if (!type_obj.IsFinalized()) {
2292 return Api::NewError(
2293 "%s expects argument 'type' to be a fully resolved type.",
2294 CURRENT_FUNC);
2295 }
2296 if (object == Api::Null()) {
2297 *value = false;
2298 return Api::Success();
2299 }
2300 const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
2301 if (instance.IsNull()) {
2302 *value = false;
2303 RETURN_TYPE_ERROR(Z, object, Instance);
2304 }
2305 *value = InstanceIsType(T, instance, type_obj);
2306 return Api::Success();
2307}
2308
2310 Thread* thread = Thread::Current();
2311 CHECK_ISOLATE(thread->isolate());
2312 TransitionNativeToVM transition(thread);
2314 Object& ref = thread->ObjectHandle();
2315 ref = Api::UnwrapHandle(object);
2316 return ref.IsInstance();
2317}
2318
2320 Thread* thread = Thread::Current();
2321 CHECK_ISOLATE(thread->isolate());
2322 TransitionNativeToVM transition(thread);
2323 return IsNumberClassId(Api::ClassId(object));
2324}
2325
2327 Thread* thread = Thread::Current();
2328 CHECK_ISOLATE(thread->isolate());
2329 TransitionNativeToVM transition(thread);
2330 return IsIntegerClassId(Api::ClassId(object));
2331}
2332
2334 Thread* thread = Thread::Current();
2335 CHECK_ISOLATE(thread->isolate());
2336 TransitionNativeToVM transition(thread);
2337 return Api::ClassId(object) == kDoubleCid;
2338}
2339
2341 Thread* thread = Thread::Current();
2342 CHECK_ISOLATE(thread->isolate());
2343 TransitionNativeToVM transition(thread);
2344 return Api::ClassId(object) == kBoolCid;
2345}
2346
2348 Thread* thread = Thread::Current();
2349 CHECK_ISOLATE(thread->isolate());
2350 TransitionNativeToVM transition(thread);
2351 return IsStringClassId(Api::ClassId(object));
2352}
2353
2355 Thread* thread = Thread::Current();
2356 CHECK_ISOLATE(thread->isolate());
2357 TransitionNativeToVM transition(thread);
2358 return IsOneByteStringClassId(Api::ClassId(object));
2359}
2360
2363 if (IsBuiltinListClassId(Api::ClassId(object))) {
2364 return true;
2365 }
2366
2367 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
2368 return GetListInstance(Z, obj) != Instance::null();
2369}
2370
2373 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
2374 return GetMapInstance(Z, obj) != Instance::null();
2375}
2376
2378 Thread* thread = Thread::Current();
2379 CHECK_ISOLATE(thread->isolate());
2380 TransitionNativeToVM transition(thread);
2381 return Api::ClassId(object) == kLibraryCid;
2382}
2383
2385 Thread* thread = Thread::Current();
2386 CHECK_ISOLATE(thread->isolate());
2387 TransitionNativeToVM transition(thread);
2388 return IsTypeClassId(Api::ClassId(handle));
2389}
2390
2392 Thread* thread = Thread::Current();
2393 CHECK_ISOLATE(thread->isolate());
2394 TransitionNativeToVM transition(thread);
2395 return Api::ClassId(handle) == kFunctionCid;
2396}
2397
2399 Thread* thread = Thread::Current();
2400 CHECK_ISOLATE(thread->isolate());
2401 TransitionNativeToVM transition(thread);
2402 return Api::ClassId(handle) == kFieldCid;
2403}
2404
2406 Thread* thread = Thread::Current();
2407 CHECK_ISOLATE(thread->isolate());
2408 TransitionNativeToVM transition(thread);
2409 return Api::ClassId(handle) == kTypeParameterCid;
2410}
2411
2413 Thread* thread = Thread::Current();
2414 CHECK_ISOLATE(thread->isolate());
2415 TransitionNativeToVM transition(thread);
2416 return Api::ClassId(object) == kClosureCid;
2417}
2418
2422 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
2423 if (obj.IsClosure()) {
2424 const Closure& closure = Closure::Cast(obj);
2425 const Function& func = Function::Handle(Z, closure.function());
2426 return func.IsImplicitClosureFunction();
2427 }
2428 return false;
2429}
2430
2432 Thread* thread = Thread::Current();
2433 CHECK_ISOLATE(thread->isolate());
2434 TransitionNativeToVM transition(thread);
2435 intptr_t cid = Api::ClassId(handle);
2438}
2439
2441 Thread* thread = Thread::Current();
2442 CHECK_ISOLATE(thread->isolate());
2443 TransitionNativeToVM transition(thread);
2444 return Api::ClassId(handle) == kByteBufferCid;
2445}
2446
2450 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
2451 if (obj.IsInstance()) {
2452 const Class& obj_class = Class::Handle(Z, obj.clazz());
2453 return obj_class.is_future_subtype();
2454 }
2455 return false;
2456}
2457
2458// --- Instances ----
2459
2463 auto isolate_group = T->isolate_group();
2465 if (obj.IsNull()) {
2466 return Api::NewHandle(T, isolate_group->object_store()->null_type());
2467 }
2468 if (!obj.IsInstance()) {
2470 }
2471 const AbstractType& type =
2472 AbstractType::Handle(Instance::Cast(obj).GetType(Heap::kNew));
2473 return Api::NewHandle(T, type.Canonicalize(T));
2474}
2475
2478 const Function& func = Api::UnwrapFunctionHandle(Z, function);
2479 if (func.IsNull()) {
2481 }
2482 return Api::NewHandle(T, func.UserVisibleName());
2483}
2484
2487 const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
2488 if (type_obj.IsNull()) {
2489 RETURN_TYPE_ERROR(Z, cls_type, Type);
2490 }
2491 const Class& klass = Class::Handle(Z, type_obj.type_class());
2492 if (klass.IsNull()) {
2493 return Api::NewError(
2494 "cls_type must be a Type object which represents a Class.");
2495 }
2496 return Api::NewHandle(T, klass.UserVisibleName());
2497}
2498
2501 const Function& func = Api::UnwrapFunctionHandle(Z, function);
2502 if (func.IsNull()) {
2504 }
2505 if (func.IsNonImplicitClosureFunction()) {
2506 FunctionPtr parent_function = func.parent_function();
2507 return Api::NewHandle(T, parent_function);
2508 }
2509 const Class& owner = Class::Handle(Z, func.Owner());
2510 ASSERT(!owner.IsNull());
2511 if (owner.IsTopLevel()) {
2512// Top-level functions are implemented as members of a hidden class. We hide
2513// that class here and instead answer the library.
2514#if defined(DEBUG)
2515 const Library& lib = Library::Handle(Z, owner.library());
2516 if (lib.IsNull()) {
2517 ASSERT(owner.IsDynamicClass() || owner.IsVoidClass() ||
2518 owner.IsNeverClass());
2519 }
2520#endif
2521 return Api::NewHandle(T, owner.library());
2522 } else {
2523 return Api::NewHandle(T, owner.RareType());
2524 }
2525}
2526
2528 bool* is_static) {
2530 if (is_static == nullptr) {
2531 RETURN_NULL_ERROR(is_static);
2532 }
2533 const Function& func = Api::UnwrapFunctionHandle(Z, function);
2534 if (func.IsNull()) {
2536 }
2537 *is_static = func.is_static();
2538 return Api::Success();
2539}
2540
2543 const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure);
2544 if (closure_obj.IsNull() || !closure_obj.IsClosure()) {
2545 RETURN_TYPE_ERROR(Z, closure, Instance);
2546 }
2547
2549
2550 FunctionPtr rf = Closure::Cast(closure_obj).function();
2551 return Api::NewHandle(T, rf);
2552}
2553
2556 const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
2557 const Class& klass = Class::Handle(Z, type_obj.type_class());
2558 if (klass.IsNull()) {
2559 return Api::NewError(
2560 "cls_type must be a Type object which represents a Class.");
2561 }
2562 const Library& library = Library::Handle(klass.library());
2563 if (library.IsNull()) {
2564 return Dart_Null();
2565 }
2566 return Api::NewHandle(Thread::Current(), library.ptr());
2567}
2568
2569// --- Numbers, Integers and Doubles ----
2570
2572 bool* fits) {
2573 // Fast path for Smis and Mints.
2574 Thread* thread = Thread::Current();
2575 API_TIMELINE_DURATION(thread);
2576 Isolate* isolate = thread->isolate();
2577 CHECK_ISOLATE(isolate);
2578 if (Api::IsSmi(integer)) {
2579 *fits = true;
2580 return Api::Success();
2581 }
2582 // Slow path for mints and type error.
2583 DARTSCOPE(thread);
2584 if (Api::ClassId(integer) == kMintCid) {
2585 *fits = true;
2586 return Api::Success();
2587 }
2588 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2589 ASSERT(int_obj.IsNull());
2590 RETURN_TYPE_ERROR(Z, integer, Integer);
2591}
2592
2594 bool* fits) {
2595 // Fast path for Smis.
2596 Thread* thread = Thread::Current();
2597 Isolate* isolate = thread->isolate();
2598 CHECK_ISOLATE(isolate);
2599 API_TIMELINE_DURATION(thread);
2600 if (Api::IsSmi(integer)) {
2601 *fits = (Api::SmiValue(integer) >= 0);
2602 return Api::Success();
2603 }
2604 // Slow path for Mints.
2605 DARTSCOPE(thread);
2606 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2607 if (int_obj.IsNull()) {
2608 RETURN_TYPE_ERROR(Z, integer, Integer);
2609 }
2610 ASSERT(int_obj.IsMint());
2611 *fits = !int_obj.IsNegative();
2612 return Api::Success();
2613}
2614
2616 // Fast path for Smis.
2617 Thread* thread = Thread::Current();
2618 Isolate* isolate = thread->isolate();
2619 CHECK_ISOLATE(isolate);
2620 API_TIMELINE_DURATION(thread);
2621 DARTSCOPE(thread);
2622 CHECK_CALLBACK_STATE(thread);
2623 return Api::NewHandle(thread, Integer::New(value));
2624}
2625
2632 }
2633 return Api::NewError("%s: Cannot create Dart integer from value %" Pu64,
2635}
2636
2641 const String& str_obj = String::Handle(Z, String::New(str));
2642 IntegerPtr integer = Integer::New(str_obj);
2643 if (integer == Integer::null()) {
2644 return Api::NewError("%s: Cannot create Dart integer from string %s",
2645 CURRENT_FUNC, str);
2646 }
2647 return Api::NewHandle(T, integer);
2648}
2649
2651 int64_t* value) {
2652 // Fast path for Smis.
2653 Thread* thread = Thread::Current();
2654 Isolate* isolate = thread->isolate();
2655 CHECK_ISOLATE(isolate);
2656 if (Api::IsSmi(integer)) {
2657 *value = Api::SmiValue(integer);
2658 return Api::Success();
2659 }
2660 // Slow path for Mints.
2661 DARTSCOPE(thread);
2662 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2663 if (int_obj.IsNull()) {
2664 RETURN_TYPE_ERROR(Z, integer, Integer);
2665 }
2666 ASSERT(int_obj.IsMint());
2667 *value = int_obj.AsInt64Value();
2668 return Api::Success();
2669}
2670
2672 uint64_t* value) {
2673 // Fast path for Smis.
2674 Thread* thread = Thread::Current();
2675 Isolate* isolate = thread->isolate();
2676 CHECK_ISOLATE(isolate);
2677 if (Api::IsSmi(integer)) {
2678 intptr_t smi_value = Api::SmiValue(integer);
2679 if (smi_value >= 0) {
2680 *value = smi_value;
2681 return Api::Success();
2682 }
2683 }
2684 // Slow path for Mints.
2685 DARTSCOPE(thread);
2686 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2687 if (int_obj.IsNull()) {
2688 RETURN_TYPE_ERROR(Z, integer, Integer);
2689 }
2690 if (int_obj.IsSmi()) {
2691 ASSERT(int_obj.IsNegative());
2692 } else {
2693 ASSERT(int_obj.IsMint());
2694 if (!int_obj.IsNegative()) {
2695 *value = int_obj.AsInt64Value();
2696 return Api::Success();
2697 }
2698 }
2699 return Api::NewError("%s: Integer %s cannot be represented as a uint64_t.",
2700 CURRENT_FUNC, int_obj.ToCString());
2701}
2702
2704 const char** value) {
2707 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2708 if (int_obj.IsNull()) {
2709 RETURN_TYPE_ERROR(Z, integer, Integer);
2710 }
2711 Zone* scope_zone = Api::TopScope(Thread::Current())->zone();
2712 *value = int_obj.ToHexCString(scope_zone);
2713 return Api::Success();
2714}
2715
2721
2723 double* value) {
2725 const Double& obj = Api::UnwrapDoubleHandle(Z, double_obj);
2726 if (obj.IsNull()) {
2727 RETURN_TYPE_ERROR(Z, double_obj, Double);
2728 }
2729 *value = obj.value();
2730 return Api::Success();
2731}
2732
2734 Dart_Handle cls_type,
2737 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
2738 if (lib.IsNull()) {
2739 RETURN_TYPE_ERROR(Z, library, Library);
2740 }
2741
2742 const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
2743 if (type_obj.IsNull()) {
2744 RETURN_TYPE_ERROR(Z, cls_type, Type);
2745 }
2746
2747 const Class& klass = Class::Handle(Z, type_obj.type_class());
2748 if (klass.IsNull()) {
2749 return Api::NewError(
2750 "cls_type must be a Type object which represents a Class");
2751 }
2752
2753 const auto& error = klass.EnsureIsFinalized(Thread::Current());
2754 if (error != Error::null()) {
2755 return Api::NewHandle(T, error);
2756 }
2757
2758 const String& func_name = Api::UnwrapStringHandle(Z, function_name);
2759 if (func_name.IsNull()) {
2761 }
2762
2763 Function& func =
2765 if (func.IsNull()) {
2766 return Dart_Null();
2767 }
2768
2769 if (!func.is_static()) {
2770 return Api::NewError("function_name must refer to a static method.");
2771 }
2772
2773 if (func.kind() != UntaggedFunction::kRegularFunction) {
2774 return Api::NewError(
2775 "function_name must be the name of a regular function.");
2776 }
2777 func = func.ImplicitClosureFunction();
2778 if (func.IsNull()) {
2779 return Dart_Null();
2780 }
2781
2782 return Api::NewHandle(T, func.ImplicitStaticClosure());
2783}
2784
2785// --- Booleans ----
2786
2788 ASSERT(Isolate::Current() != nullptr);
2789 return Api::True();
2790}
2791
2793 ASSERT(Isolate::Current() != nullptr);
2794 return Api::False();
2795}
2796
2798 Isolate* isolate = Isolate::Current();
2799 CHECK_ISOLATE(isolate);
2800 return value ? Api::True() : Api::False();
2801}
2802
2804 bool* value) {
2806 const Bool& obj = Api::UnwrapBoolHandle(Z, boolean_obj);
2807 if (obj.IsNull()) {
2808 RETURN_TYPE_ERROR(Z, boolean_obj, Bool);
2809 }
2810 *value = obj.value();
2811 return Api::Success();
2812}
2813
2814// --- Strings ---
2815
2817 Thread* thread = Thread::Current();
2818 DARTSCOPE(thread);
2819 {
2820 ReusableObjectHandleScope reused_obj_handle(thread);
2821 const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
2822 if (!str_obj.IsNull()) {
2823 *len = str_obj.Length();
2824 return Api::Success();
2825 }
2826 }
2827 RETURN_TYPE_ERROR(thread->zone(), str, String);
2828}
2829
2831 Thread* thread = Thread::Current();
2832 DARTSCOPE(thread);
2833 {
2834 ReusableObjectHandleScope reused_obj_handle(thread);
2835 const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
2836 if (!str_obj.IsNull()) {
2837 *len = Utf8::Length(str_obj);
2838 return Api::Success();
2839 }
2840 }
2841 RETURN_TYPE_ERROR(thread->zone(), str, String);
2842}
2843
2847 if (str == nullptr) {
2848 RETURN_NULL_ERROR(str);
2849 }
2851 return Api::NewHandle(T, String::New(str));
2852}
2853
2855 intptr_t length) {
2858 if (utf8_array == nullptr && length != 0) {
2859 RETURN_NULL_ERROR(utf8_array);
2860 }
2862 if (!Utf8::IsValid(utf8_array, length)) {
2863 return Api::NewError("%s expects argument 'str' to be valid UTF-8.",
2864 CURRENT_FUNC);
2865 }
2867 return Api::NewHandle(T, String::FromUTF8(utf8_array, length));
2868}
2869
2871 intptr_t length) {
2873 if (utf16_array == nullptr && length != 0) {
2874 RETURN_NULL_ERROR(utf16_array);
2875 }
2878 return Api::NewHandle(T, String::FromUTF16(utf16_array, length));
2879}
2880
2882 intptr_t length) {
2885 if (utf32_array == nullptr && length != 0) {
2886 RETURN_NULL_ERROR(utf32_array);
2887 }
2890 return Api::NewHandle(T, String::FromUTF32(utf32_array, length));
2891}
2892
2894 const char** cstr) {
2897 if (cstr == nullptr) {
2898 RETURN_NULL_ERROR(cstr);
2899 }
2900 const String& str_obj = Api::UnwrapStringHandle(Z, object);
2901 if (str_obj.IsNull()) {
2902 RETURN_TYPE_ERROR(Z, object, String);
2903 }
2904 intptr_t string_length = Utf8::Length(str_obj);
2905 char* res = Api::TopScope(T)->zone()->Alloc<char>(string_length + 1);
2906 if (res == nullptr) {
2907 return Api::NewError("Unable to allocate memory");
2908 }
2909 const char* string_value = str_obj.ToCString();
2910 memmove(res, string_value, string_length + 1);
2911 ASSERT(res[string_length] == '\0');
2912 *cstr = res;
2913 return Api::Success();
2914}
2915
2917 uint8_t** utf8_array,
2918 intptr_t* length) {
2921 if (utf8_array == nullptr) {
2922 RETURN_NULL_ERROR(utf8_array);
2923 }
2924 if (length == nullptr) {
2926 }
2927 const String& str_obj = Api::UnwrapStringHandle(Z, str);
2928 if (str_obj.IsNull()) {
2929 RETURN_TYPE_ERROR(Z, str, String);
2930 }
2931 intptr_t str_len = Utf8::Length(str_obj);
2932 *utf8_array = Api::TopScope(T)->zone()->Alloc<uint8_t>(str_len);
2933 if (*utf8_array == nullptr) {
2934 return Api::NewError("Unable to allocate memory");
2935 }
2936 str_obj.ToUTF8(*utf8_array, str_len);
2937 *length = str_len;
2938 return Api::Success();
2939}
2940
2942 uint8_t* utf8_array,
2943 intptr_t length) {
2946 if (utf8_array == nullptr) {
2947 RETURN_NULL_ERROR(utf8_array);
2948 }
2949 const String& str_obj = Api::UnwrapStringHandle(Z, str);
2950 if (str_obj.IsNull()) {
2951 RETURN_TYPE_ERROR(Z, str, String);
2952 }
2953 intptr_t str_len = Utf8::Length(str_obj);
2954 if (length < str_len) {
2955 return Api::NewError(
2956 "Provided buffer is not large enough to hold "
2957 "the UTF-8 representation of the string");
2958 }
2959 str_obj.ToUTF8(utf8_array, str_len);
2960 return Api::Success();
2961}
2962
2964 uint8_t* latin1_array,
2965 intptr_t* length) {
2968 if (latin1_array == nullptr) {
2969 RETURN_NULL_ERROR(latin1_array);
2970 }
2971 if (length == nullptr) {
2973 }
2974 const String& str_obj = Api::UnwrapStringHandle(Z, str);
2975 if (str_obj.IsNull() || !str_obj.IsOneByteString()) {
2976 RETURN_TYPE_ERROR(Z, str, String);
2977 }
2978 intptr_t str_len = str_obj.Length();
2979 intptr_t copy_len = (str_len > *length) ? *length : str_len;
2980
2981 // We have already asserted that the string object is a Latin-1 string
2982 // so we can copy the characters over using a simple loop.
2983 for (intptr_t i = 0; i < copy_len; i++) {
2984 latin1_array[i] = str_obj.CharAt(i);
2985 }
2986 *length = copy_len;
2987 return Api::Success();
2988}
2989
2991 uint16_t* utf16_array,
2992 intptr_t* length) {
2995 const String& str_obj = Api::UnwrapStringHandle(Z, str);
2996 if (str_obj.IsNull()) {
2997 RETURN_TYPE_ERROR(Z, str, String);
2998 }
2999 intptr_t str_len = str_obj.Length();
3000 intptr_t copy_len = (str_len > *length) ? *length : str_len;
3001 for (intptr_t i = 0; i < copy_len; i++) {
3002 utf16_array[i] = str_obj.CharAt(i);
3003 }
3004 *length = copy_len;
3005 return Api::Success();
3006}
3007
3009 intptr_t* size) {
3010 Thread* thread = Thread::Current();
3011 CHECK_ISOLATE(thread->isolate());
3012 TransitionNativeToVM transition(thread);
3013 if (size == nullptr) {
3014 RETURN_NULL_ERROR(size);
3015 }
3016 {
3017 ReusableObjectHandleScope reused_obj_handle(thread);
3018 const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
3019 if (!str_obj.IsNull()) {
3020 *size = (str_obj.Length() * str_obj.CharSize());
3021 return Api::Success();
3022 }
3023 }
3024 RETURN_TYPE_ERROR(thread->zone(), str, String);
3025}
3026
3028 intptr_t* char_size,
3029 intptr_t* str_len,
3030 void** peer) {
3031 Thread* thread = Thread::Current();
3032 CHECK_ISOLATE(thread->isolate());
3033 TransitionNativeToVM transition(thread);
3034 {
3035 ReusableObjectHandleScope reused_obj_handle(thread);
3036 const String& str = Api::UnwrapStringHandle(reused_obj_handle, object);
3037 if (!str.IsNull()) {
3038 NoSafepointScope no_safepoint_scope;
3039 *peer = thread->heap()->GetPeer(str.ptr());
3040 *char_size = str.CharSize();
3041 *str_len = str.Length();
3042 return Api::Success();
3043 }
3044 }
3045 RETURN_TYPE_ERROR(thread->zone(), object, String);
3046}
3047
3048// --- Lists ---
3049
3053
3054static TypeArgumentsPtr TypeArgumentsForElementType(
3056 Dart_CoreType_Id element_type_id) {
3057 switch (element_type_id) {
3059 return TypeArguments::null();
3060 case Dart_CoreType_Int:
3061 return store->type_argument_legacy_int();
3063 return store->type_argument_legacy_string();
3064 }
3065 UNREACHABLE();
3066 return TypeArguments::null();
3067}
3068
3070 intptr_t length) {
3072 if (element_type_id != Dart_CoreType_Dynamic) {
3073 return Api::NewError(
3074 "Cannot use legacy types with --sound-null-safety enabled. "
3075 "Use Dart_NewListOfType or Dart_NewListOfTypeFilled instead.");
3076 }
3079 const Array& arr = Array::Handle(Z, Array::New(length));
3080 if (element_type_id != Dart_CoreType_Dynamic) {
3082 Z, TypeArgumentsForElementType(T->isolate_group()->object_store(),
3083 element_type_id)));
3084 }
3085 return Api::NewHandle(T, arr.ptr());
3086}
3087
3088static bool CanTypeContainNull(const Type& type) {
3089 return (type.nullability() == Nullability::kLegacy) ||
3090 (type.nullability() == Nullability::kNullable);
3091}
3092
3094 intptr_t length) {
3098 const Type& type = Api::UnwrapTypeHandle(Z, element_type);
3099 if (type.IsNull()) {
3100 RETURN_TYPE_ERROR(Z, element_type, Type);
3101 }
3102 if (!type.IsFinalized()) {
3103 return Api::NewError(
3104 "%s expects argument 'type' to be a fully resolved type.",
3105 CURRENT_FUNC);
3106 }
3107 if ((length > 0) && !CanTypeContainNull(type)) {
3108 return Api::NewError("%s expects argument 'type' to be a nullable type.",
3109 CURRENT_FUNC);
3110 }
3112}
3113
3115 Dart_Handle fill_object,
3116 intptr_t length) {
3120 const Type& type = Api::UnwrapTypeHandle(Z, element_type);
3121 if (type.IsNull()) {
3122 RETURN_TYPE_ERROR(Z, element_type, Type);
3123 }
3124 if (!type.IsFinalized()) {
3125 return Api::NewError(
3126 "%s expects argument 'type' to be a fully resolved type.",
3127 CURRENT_FUNC);
3128 }
3129 const Instance& instance = Api::UnwrapInstanceHandle(Z, fill_object);
3130 if (!instance.IsNull() && !InstanceIsType(T, instance, type)) {
3131 return Api::NewError(
3132 "%s expects argument 'fill_object' to have the same type as "
3133 "'element_type'.",
3134 CURRENT_FUNC);
3135 }
3136 if ((length > 0) && instance.IsNull() && !CanTypeContainNull(type)) {
3137 return Api::NewError(
3138 "%s expects argument 'fill_object' to be non-null for a non-nullable "
3139 "'element_type'.",
3140 CURRENT_FUNC);
3141 }
3143 for (intptr_t i = 0; i < arr.Length(); ++i) {
3144 arr.SetAt(i, instance);
3145 }
3146 return Api::NewHandle(T, arr.ptr());
3147}
3148
3149#define GET_LIST_LENGTH(zone, type, obj, len) \
3150 type& array = type::Handle(zone); \
3151 array ^= obj.ptr(); \
3152 *len = array.Length(); \
3153 return Api::Success();
3154
3157 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3158 if (obj.IsError()) {
3159 // Pass through errors.
3160 return list;
3161 }
3162 if (obj.IsTypedDataBase()) {
3163 GET_LIST_LENGTH(Z, TypedDataBase, obj, len);
3164 }
3165 if (obj.IsArray()) {
3166 GET_LIST_LENGTH(Z, Array, obj, len);
3167 }
3168 if (obj.IsGrowableObjectArray()) {
3170 }
3172
3173 // Now check and handle a dart object that implements the List interface.
3175 if (instance.IsNull()) {
3176 return Api::NewArgumentError(
3177 "Object does not implement the List interface");
3178 }
3179 const Object& retval =
3180 Object::Handle(Z, CallStatic1Arg(Z, Symbols::_listLength(), instance));
3181 if (retval.IsSmi()) {
3182 *len = Smi::Cast(retval).Value();
3183 return Api::Success();
3184 } else if (retval.IsMint()) {
3185 int64_t mint_value = Mint::Cast(retval).value();
3186 if (mint_value >= kIntptrMin && mint_value <= kIntptrMax) {
3187 *len = static_cast<intptr_t>(mint_value);
3188 return Api::Success();
3189 }
3190 return Api::NewError(
3191 "Length of List object is greater than the "
3192 "maximum value that 'len' parameter can hold");
3193 } else if (retval.IsError()) {
3194 return Api::NewHandle(T, retval.ptr());
3195 } else {
3196 return Api::NewError("Length of List object is not an integer");
3197 }
3198}
3199
3200#define GET_LIST_ELEMENT(thread, type, obj, index) \
3201 const type& array_obj = type::Cast(obj); \
3202 if ((index >= 0) && (index < array_obj.Length())) { \
3203 return Api::NewHandle(thread, array_obj.At(index)); \
3204 } \
3205 return Api::NewError("Invalid index passed into access list element");
3206
3209 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3210 if (obj.IsArray()) {
3211 GET_LIST_ELEMENT(T, Array, obj, index);
3212 } else if (obj.IsGrowableObjectArray()) {
3214 } else if (obj.IsError()) {
3215 return list;
3216 } else {
3218 // Check and handle a dart object that implements the List interface.
3220 if (!instance.IsNull()) {
3221 return Api::NewHandle(
3222 T, CallStatic2Args(Z, Symbols::_listGetAt(), instance,
3223 Instance::Handle(Z, Integer::New(index))));
3224 }
3225 return Api::NewArgumentError(
3226 "Object does not implement the 'List' interface");
3227 }
3228}
3229
3230#define GET_LIST_RANGE(thread, type, obj, offset, length) \
3231 const type& array_obj = type::Cast(obj); \
3232 if ((offset >= 0) && (offset + length <= array_obj.Length())) { \
3233 for (intptr_t index = 0; index < length; ++index) { \
3234 result[index] = Api::NewHandle(thread, array_obj.At(index + offset)); \
3235 } \
3236 return Api::Success(); \
3237 } \
3238 return Api::NewError("Invalid offset/length passed into access list");
3239
3241 intptr_t offset,
3242 intptr_t length,
3245 if (result == nullptr) {
3247 }
3248 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3249 if (obj.IsArray()) {
3251 } else if (obj.IsGrowableObjectArray()) {
3253 } else if (obj.IsError()) {
3254 return list;
3255 } else {
3257 // Check and handle a dart object that implements the List interface.
3259 if (!instance.IsNull()) {
3260 const intptr_t kNumArgs = 2;
3262 Z, FindCoreLibPrivateFunction(Z, Symbols::_listGetAt()));
3263 const Array& args = Array::Handle(Z, Array::New(kNumArgs));
3264 args.SetAt(0, instance);
3265 Instance& index = Instance::Handle(Z);
3266 for (intptr_t i = 0; i < length; ++i) {
3267 index = Integer::New(i);
3268 args.SetAt(1, index);
3271 if (Api::IsError(value)) return value;
3272 result[i] = value;
3273 }
3274 return Api::Success();
3275 }
3276 return Api::NewArgumentError(
3277 "Object does not implement the 'List' interface");
3278 }
3279}
3280
3281#define SET_LIST_ELEMENT(type, obj, index, value) \
3282 const type& array = type::Cast(obj); \
3283 const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value)); \
3284 if (!value_obj.IsNull() && !value_obj.IsInstance()) { \
3285 RETURN_TYPE_ERROR(Z, value, Instance); \
3286 } \
3287 if ((index >= 0) && (index < array.Length())) { \
3288 array.SetAt(index, value_obj); \
3289 return Api::Success(); \
3290 } \
3291 return Api::NewError("Invalid index passed into set list element");
3292
3294 intptr_t index,
3295 Dart_Handle value) {
3297 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3298 // If the list is immutable we call into Dart for the indexed setter to
3299 // get the unsupported operation exception as the result.
3300 if (obj.IsArray() && !Array::Cast(obj).IsImmutable()) {
3301 SET_LIST_ELEMENT(Array, obj, index, value);
3302 } else if (obj.IsGrowableObjectArray()) {
3304 } else if (obj.IsError()) {
3305 return list;
3306 } else {
3308
3309 // Check and handle a dart object that implements the List interface.
3311 if (!instance.IsNull()) {
3312 const Integer& index_obj = Integer::Handle(Z, Integer::New(index));
3313 const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));
3314 if (!value_obj.IsNull() && !value_obj.IsInstance()) {
3316 }
3317 return Api::NewHandle(
3318 T, CallStatic3Args(Z, Symbols::_listSetAt(), instance, index_obj,
3319 Instance::Cast(value_obj)));
3320 }
3321 return Api::NewArgumentError(
3322 "Object does not implement the 'List' interface");
3323 }
3324}
3325
3326static ObjectPtr ResolveConstructor(const char* current_func,
3327 const Class& cls,
3328 const String& class_name,
3329 const String& dotted_name,
3330 int num_args);
3331
3332static ObjectPtr ThrowArgumentError(const char* exception_message) {
3333 Thread* thread = Thread::Current();
3334 Zone* zone = thread->zone();
3335 // Lookup the class ArgumentError in dart:core.
3336 const String& lib_url = String::Handle(String::New("dart:core"));
3337 const String& class_name = String::Handle(String::New("ArgumentError"));
3338 const Library& lib =
3339 Library::Handle(zone, Library::LookupLibrary(thread, lib_url));
3340 if (lib.IsNull()) {
3342 "%s: library '%s' not found.", CURRENT_FUNC, lib_url.ToCString()));
3343 return ApiError::New(message);
3344 }
3345 const Class& cls =
3347 ASSERT(!cls.IsNull());
3348 Object& result = Object::Handle(zone);
3349 String& dot_name = String::Handle(String::New("."));
3350 String& constr_name = String::Handle(String::Concat(class_name, dot_name));
3351 result = ResolveConstructor(CURRENT_FUNC, cls, class_name, constr_name, 1);
3352 if (result.IsError()) return result.ptr();
3353 ASSERT(result.IsFunction());
3354 Function& constructor = Function::Handle(zone);
3355 constructor ^= result.ptr();
3356 if (!constructor.IsGenerativeConstructor()) {
3357 const String& message = String::Handle(
3358 String::NewFormatted("%s: class '%s' is not a constructor.",
3359 CURRENT_FUNC, class_name.ToCString()));
3360 return ApiError::New(message);
3361 }
3362 Instance& exception = Instance::Handle(zone);
3363 exception = Instance::New(cls);
3364 const Array& args = Array::Handle(zone, Array::New(2));
3365 args.SetAt(0, exception);
3366 args.SetAt(1, String::Handle(String::New(exception_message)));
3367 result = DartEntry::InvokeFunction(constructor, args);
3368 if (result.IsError()) return result.ptr();
3369 ASSERT(result.IsNull());
3370
3371 if (thread->top_exit_frame_info() == 0) {
3372 // There are no dart frames on the stack so it would be illegal to
3373 // throw an exception here.
3374 const String& message = String::Handle(
3375 String::New("No Dart frames on stack, cannot throw exception"));
3376 return ApiError::New(message);
3377 }
3378 // Unwind all the API scopes till the exit frame before throwing an
3379 // exception.
3380 const Instance* saved_exception;
3381 {
3382 NoSafepointScope no_safepoint;
3383 InstancePtr raw_exception = exception.ptr();
3384 thread->UnwindScopes(thread->top_exit_frame_info());
3385 saved_exception = &Instance::Handle(raw_exception);
3386 }
3387 Exceptions::Throw(thread, *saved_exception);
3388 const String& message =
3389 String::Handle(String::New("Exception was not thrown, internal error"));
3390 return ApiError::New(message);
3391}
3392
3393// TODO(sgjesse): value should always be smaller then 0xff. Add error handling.
3394#define GET_LIST_ELEMENT_AS_BYTES(type, obj, native_array, offset, length) \
3395 const type& array = type::Cast(obj); \
3396 if (Utils::RangeCheck(offset, length, array.Length())) { \
3397 Object& element = Object::Handle(Z); \
3398 for (int i = 0; i < length; i++) { \
3399 element = array.At(offset + i); \
3400 if (!element.IsInteger()) { \
3401 return Api::NewHandle( \
3402 T, ThrowArgumentError("List contains non-int elements")); \
3403 } \
3404 const Integer& integer = Integer::Cast(element); \
3405 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \
3406 ASSERT(integer.AsInt64Value() <= 0xff); \
3407 } \
3408 return Api::Success(); \
3409 } \
3410 return Api::NewError("Invalid length passed into access array elements");
3411
3413 intptr_t offset,
3414 uint8_t* native_array,
3415 intptr_t length) {
3417 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3418 if (obj.IsTypedDataBase()) {
3419 const TypedDataBase& array = TypedDataBase::Cast(obj);
3420 if (array.ElementSizeInBytes() == 1) {
3421 if (Utils::RangeCheck(offset, length, array.Length())) {
3422 NoSafepointScope no_safepoint;
3423 memmove(native_array,
3424 reinterpret_cast<uint8_t*>(array.DataAddr(offset)), length);
3425 return Api::Success();
3426 }
3427 return Api::NewError("Invalid length passed into access list elements");
3428 }
3429 }
3430 if (obj.IsArray()) {
3431 GET_LIST_ELEMENT_AS_BYTES(Array, obj, native_array, offset, length);
3432 }
3433 if (obj.IsGrowableObjectArray()) {
3435 length);
3436 }
3437 if (obj.IsError()) {
3438 return list;
3439 }
3441
3442 // Check and handle a dart object that implements the List interface.
3444 if (!instance.IsNull()) {
3445 const int kNumArgs = 2;
3447 Z, FindCoreLibPrivateFunction(Z, Symbols::_listGetAt()));
3449 Integer& intobj = Integer::Handle(Z);
3450 const Array& args = Array::Handle(Z, Array::New(kNumArgs));
3451 args.SetAt(0, instance); // Set up the receiver as the first argument.
3452 for (int i = 0; i < length; i++) {
3453 HANDLESCOPE(T);
3454 intobj = Integer::New(offset + i);
3455 args.SetAt(1, intobj);
3457 if (result.IsError()) {
3458 return Api::NewHandle(T, result.ptr());
3459 }
3460 if (!result.IsInteger()) {
3461 return Api::NewError(
3462 "%s expects the argument 'list' to be "
3463 "a List of int",
3464 CURRENT_FUNC);
3465 }
3466 const Integer& integer_result = Integer::Cast(result);
3467 ASSERT(integer_result.AsInt64Value() <= 0xff);
3468 // TODO(hpayer): value should always be smaller then 0xff. Add error
3469 // handling.
3470 native_array[i] =
3471 static_cast<uint8_t>(integer_result.AsInt64Value() & 0xff);
3472 }
3473 return Api::Success();
3474 }
3475 return Api::NewArgumentError(
3476 "Object does not implement the 'List' interface");
3477}
3478
3479#define SET_LIST_ELEMENT_AS_BYTES(type, obj, native_array, offset, length) \
3480 const type& array = type::Cast(obj); \
3481 Integer& integer = Integer::Handle(Z); \
3482 if (Utils::RangeCheck(offset, length, array.Length())) { \
3483 for (int i = 0; i < length; i++) { \
3484 integer = Integer::New(native_array[i]); \
3485 array.SetAt(offset + i, integer); \
3486 } \
3487 return Api::Success(); \
3488 } \
3489 return Api::NewError("Invalid length passed into set array elements");
3490
3492 intptr_t offset,
3493 const uint8_t* native_array,
3494 intptr_t length) {
3496 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3497 if (obj.IsTypedDataBase()) {
3498 const TypedDataBase& array = TypedDataBase::Cast(obj);
3499 if (array.ElementSizeInBytes() == 1) {
3500 if (Utils::RangeCheck(offset, length, array.Length())) {
3501 NoSafepointScope no_safepoint;
3502 memmove(reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
3503 native_array, length);
3504 return Api::Success();
3505 }
3506 return Api::NewError("Invalid length passed into access list elements");
3507 }
3508 }
3509 if (obj.IsArray() && !Array::Cast(obj).IsImmutable()) {
3510 // If the list is immutable we call into Dart for the indexed setter to
3511 // get the unsupported operation exception as the result.
3512 SET_LIST_ELEMENT_AS_BYTES(Array, obj, native_array, offset, length);
3513 }
3514 if (obj.IsGrowableObjectArray()) {
3516 length);
3517 }
3518 if (obj.IsError()) {
3519 return list;
3520 }
3522
3523 // Check and handle a dart object that implements the List interface.
3525 if (!instance.IsNull()) {
3526 const int kNumArgs = 3;
3528 Z, FindCoreLibPrivateFunction(Z, Symbols::_listSetAt()));
3529 Integer& indexobj = Integer::Handle(Z);
3530 Integer& valueobj = Integer::Handle(Z);
3531 const Array& args = Array::Handle(Z, Array::New(kNumArgs));
3532 args.SetAt(0, instance); // Set up the receiver as the first argument.
3533 for (int i = 0; i < length; i++) {
3534 indexobj = Integer::New(offset + i);
3535 valueobj = Integer::New(native_array[i]);
3536 args.SetAt(1, indexobj);
3537 args.SetAt(2, valueobj);
3538 const Object& result =
3540 if (result.IsError()) {
3541 return Api::NewHandle(T, result.ptr());
3542 }
3543 }
3544 return Api::Success();
3545 }
3546 return Api::NewArgumentError(
3547 "Object does not implement the 'List' interface");
3548}
3549
3550// --- Maps ---
3551
3555 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(map));
3557 if (!instance.IsNull()) {
3558 const Object& key_obj = Object::Handle(Api::UnwrapHandle(key));
3559 if (!(key_obj.IsInstance() || key_obj.IsNull())) {
3560 return Api::NewError("Key is not an instance");
3561 }
3562 return Api::NewHandle(T, CallStatic2Args(Z, Symbols::_mapGet(), instance,
3563 Instance::Cast(key_obj)));
3564 }
3565 return Api::NewArgumentError("Object does not implement the 'Map' interface");
3566}
3567
3571 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(map));
3573 if (!instance.IsNull()) {
3574 const Object& key_obj = Object::Handle(Z, Api::UnwrapHandle(key));
3575 if (!(key_obj.IsInstance() || key_obj.IsNull())) {
3576 return Api::NewError("Key is not an instance");
3577 }
3578 return Api::NewHandle(
3579 T, CallStatic2Args(Z, Symbols::_mapContainsKey(), instance,
3580 Instance::Cast(key_obj)));
3581 }
3582 return Api::NewArgumentError("Object does not implement the 'Map' interface");
3583}
3584
3590 if (!instance.IsNull()) {
3591 return Api::NewHandle(T, CallStatic1Arg(Z, Symbols::_mapKeys(), instance));
3592 }
3593 return Api::NewArgumentError("Object does not implement the 'Map' interface");
3594}
3595
3596// --- Typed Data ---
3597
3598// Helper method to get the type of a TypedData object.
3599static Dart_TypedData_Type GetType(intptr_t class_id) {
3601 switch (class_id) {
3602 case kByteDataViewCid:
3605 break;
3606 case kTypedDataInt8ArrayCid:
3607 case kTypedDataInt8ArrayViewCid:
3608 case kUnmodifiableTypedDataInt8ArrayViewCid:
3609 case kExternalTypedDataInt8ArrayCid:
3611 break;
3612 case kTypedDataUint8ArrayCid:
3613 case kTypedDataUint8ArrayViewCid:
3614 case kUnmodifiableTypedDataUint8ArrayViewCid:
3615 case kExternalTypedDataUint8ArrayCid:
3617 break;
3618 case kTypedDataUint8ClampedArrayCid:
3619 case kTypedDataUint8ClampedArrayViewCid:
3620 case kUnmodifiableTypedDataUint8ClampedArrayViewCid:
3621 case kExternalTypedDataUint8ClampedArrayCid:
3623 break;
3624 case kTypedDataInt16ArrayCid:
3625 case kTypedDataInt16ArrayViewCid:
3626 case kUnmodifiableTypedDataInt16ArrayViewCid:
3627 case kExternalTypedDataInt16ArrayCid:
3629 break;
3630 case kTypedDataUint16ArrayCid:
3631 case kTypedDataUint16ArrayViewCid:
3632 case kUnmodifiableTypedDataUint16ArrayViewCid:
3633 case kExternalTypedDataUint16ArrayCid:
3635 break;
3636 case kTypedDataInt32ArrayCid:
3637 case kTypedDataInt32ArrayViewCid:
3638 case kUnmodifiableTypedDataInt32ArrayViewCid:
3639 case kExternalTypedDataInt32ArrayCid:
3641 break;
3642 case kTypedDataUint32ArrayCid:
3643 case kTypedDataUint32ArrayViewCid:
3644 case kUnmodifiableTypedDataUint32ArrayViewCid:
3645 case kExternalTypedDataUint32ArrayCid:
3647 break;
3648 case kTypedDataInt64ArrayCid:
3649 case kTypedDataInt64ArrayViewCid:
3650 case kUnmodifiableTypedDataInt64ArrayViewCid:
3651 case kExternalTypedDataInt64ArrayCid:
3653 break;
3654 case kTypedDataUint64ArrayCid:
3655 case kTypedDataUint64ArrayViewCid:
3656 case kUnmodifiableTypedDataUint64ArrayViewCid:
3657 case kExternalTypedDataUint64ArrayCid:
3659 break;
3660 case kTypedDataFloat32ArrayCid:
3661 case kTypedDataFloat32ArrayViewCid:
3662 case kUnmodifiableTypedDataFloat32ArrayViewCid:
3663 case kExternalTypedDataFloat32ArrayCid:
3665 break;
3666 case kTypedDataFloat64ArrayCid:
3667 case kTypedDataFloat64ArrayViewCid:
3668 case kUnmodifiableTypedDataFloat64ArrayViewCid:
3669 case kExternalTypedDataFloat64ArrayCid:
3671 break;
3672 case kTypedDataInt32x4ArrayCid:
3673 case kTypedDataInt32x4ArrayViewCid:
3674 case kUnmodifiableTypedDataInt32x4ArrayViewCid:
3675 case kExternalTypedDataInt32x4ArrayCid:
3677 break;
3678 case kTypedDataFloat32x4ArrayCid:
3679 case kTypedDataFloat32x4ArrayViewCid:
3680 case kUnmodifiableTypedDataFloat32x4ArrayViewCid:
3681 case kExternalTypedDataFloat32x4ArrayCid:
3683 break;
3684 case kTypedDataFloat64x2ArrayCid:
3685 case kTypedDataFloat64x2ArrayViewCid:
3686 case kUnmodifiableTypedDataFloat64x2ArrayViewCid:
3687 case kExternalTypedDataFloat64x2ArrayCid:
3689 break;
3690 default:
3692 break;
3693 }
3694 return type;
3695}
3696
3698 Thread* thread = Thread::Current();
3699 API_TIMELINE_DURATION(thread);
3700 TransitionNativeToVM transition(thread);
3701 intptr_t class_id = Api::ClassId(object);
3702 if (IsTypedDataClassId(class_id) || IsTypedDataViewClassId(class_id) ||
3704 return GetType(class_id);
3705 }
3707}
3708
3711 Thread* thread = Thread::Current();
3712 API_TIMELINE_DURATION(thread);
3713 TransitionNativeToVM transition(thread);
3714 intptr_t class_id = Api::ClassId(object);
3715 if (IsExternalTypedDataClassId(class_id)) {
3716 return GetType(class_id);
3717 }
3718 if (IsTypedDataViewClassId(class_id) ||
3720 // Check if data object of the view is external.
3721 Zone* zone = thread->zone();
3722 const auto& view_obj = Api::UnwrapTypedDataViewHandle(zone, object);
3723 ASSERT(!view_obj.IsNull());
3724 const auto& data_obj = Instance::Handle(zone, view_obj.typed_data());
3726 return GetType(class_id);
3727 }
3728 }
3730}
3731
3732static Dart_Handle NewByteData(Thread* thread, intptr_t length) {
3733 CHECK_LENGTH(length, TypedData::MaxElements(kTypedDataUint8ArrayCid));
3734 const TypedData& array =
3735 TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, length));
3736 return Api::NewHandle(thread,
3738}
3739
3740static Dart_Handle NewTypedData(Thread* thread, intptr_t cid, intptr_t length) {
3742 return Api::NewHandle(thread, TypedData::New(cid, length));
3743}
3744
3746 intptr_t cid,
3747 void* data,
3748 intptr_t length,
3749 void* peer,
3750 intptr_t external_allocation_size,
3752 bool unmodifiable) {
3754 Zone* zone = thread->zone();
3757 zone,
3758 ExternalTypedData::New(cid, reinterpret_cast<uint8_t*>(data), length,
3759 thread->heap()->SpaceForExternal(bytes)));
3760 if (callback != nullptr) {
3761 AllocateFinalizableHandle(thread, result, peer, external_allocation_size,
3762 callback);
3763 }
3764 if (unmodifiable) {
3765 result.SetImmutable(); // Can pass by reference.
3766 const intptr_t view_cid = cid - kTypedDataCidRemainderExternal +
3768 result = TypedDataView::New(view_cid, ExternalTypedData::Cast(result), 0,
3769 length);
3770 }
3771 return Api::NewHandle(thread, result.ptr());
3772}
3773
3775 void* data,
3776 intptr_t length,
3777 void* peer,
3778 intptr_t external_allocation_size,
3780 bool unmodifiable) {
3781 Zone* zone = thread->zone();
3783 thread, kExternalTypedDataUint8ArrayCid, data, length, peer,
3784 external_allocation_size, callback, false);
3785 if (Api::IsError(ext_data)) {
3786 return ext_data;
3787 }
3788 const ExternalTypedData& array =
3789 Api::UnwrapExternalTypedDataHandle(zone, ext_data);
3790 if (unmodifiable) {
3791 array.SetImmutable(); // Can pass by reference.
3792 }
3793 return Api::NewHandle(
3796 array, 0, length));
3797}
3798
3800 intptr_t length) {
3803 switch (type) {
3805 return NewByteData(T, length);
3807 return NewTypedData(T, kTypedDataInt8ArrayCid, length);
3809 return NewTypedData(T, kTypedDataUint8ArrayCid, length);
3811 return NewTypedData(T, kTypedDataUint8ClampedArrayCid, length);
3813 return NewTypedData(T, kTypedDataInt16ArrayCid, length);
3815 return NewTypedData(T, kTypedDataUint16ArrayCid, length);
3817 return NewTypedData(T, kTypedDataInt32ArrayCid, length);
3819 return NewTypedData(T, kTypedDataUint32ArrayCid, length);
3821 return NewTypedData(T, kTypedDataInt64ArrayCid, length);
3823 return NewTypedData(T, kTypedDataUint64ArrayCid, length);
3825 return NewTypedData(T, kTypedDataFloat32ArrayCid, length);
3827 return NewTypedData(T, kTypedDataFloat64ArrayCid, length);
3829 return NewTypedData(T, kTypedDataInt32x4ArrayCid, length);
3831 return NewTypedData(T, kTypedDataFloat32x4ArrayCid, length);
3833 return NewTypedData(T, kTypedDataFloat64x2ArrayCid, length);
3834 default:
3835 return Api::NewError("%s expects argument 'type' to be of 'TypedData'",
3836 CURRENT_FUNC);
3837 }
3838 UNREACHABLE();
3839 return Api::Null();
3840}
3841
3844 void* data,
3845 intptr_t length,
3846 void* peer,
3847 intptr_t external_allocation_size,
3849 bool unmodifiable) {
3851 if (data == nullptr && length != 0) {
3853 }
3855 switch (type) {
3857 return NewExternalByteData(T, data, length, peer,
3858 external_allocation_size, callback,
3859 unmodifiable);
3861 return NewExternalTypedData(T, kExternalTypedDataInt8ArrayCid, data,
3862 length, peer, external_allocation_size,
3863 callback, unmodifiable);
3865 return NewExternalTypedData(T, kExternalTypedDataUint8ArrayCid, data,
3866 length, peer, external_allocation_size,
3867 callback, unmodifiable);
3869 return NewExternalTypedData(T, kExternalTypedDataUint8ClampedArrayCid,
3870 data, length, peer, external_allocation_size,
3871 callback, unmodifiable);
3873 return NewExternalTypedData(T, kExternalTypedDataInt16ArrayCid, data,
3874 length, peer, external_allocation_size,
3875 callback, unmodifiable);
3877 return NewExternalTypedData(T, kExternalTypedDataUint16ArrayCid, data,
3878 length, peer, external_allocation_size,
3879 callback, unmodifiable);
3881 return NewExternalTypedData(T, kExternalTypedDataInt32ArrayCid, data,
3882 length, peer, external_allocation_size,
3883 callback, unmodifiable);
3885 return NewExternalTypedData(T, kExternalTypedDataUint32ArrayCid, data,
3886 length, peer, external_allocation_size,
3887 callback, unmodifiable);
3889 return NewExternalTypedData(T, kExternalTypedDataInt64ArrayCid, data,
3890 length, peer, external_allocation_size,
3891 callback, unmodifiable);
3893 return NewExternalTypedData(T, kExternalTypedDataUint64ArrayCid, data,
3894 length, peer, external_allocation_size,
3895 callback, unmodifiable);
3897 return NewExternalTypedData(T, kExternalTypedDataFloat32ArrayCid, data,
3898 length, peer, external_allocation_size,
3899 callback, unmodifiable);
3901 return NewExternalTypedData(T, kExternalTypedDataFloat64ArrayCid, data,
3902 length, peer, external_allocation_size,
3903 callback, unmodifiable);
3905 return NewExternalTypedData(T, kExternalTypedDataInt32x4ArrayCid, data,
3906 length, peer, external_allocation_size,
3907 callback, unmodifiable);
3909 return NewExternalTypedData(T, kExternalTypedDataFloat32x4ArrayCid, data,
3910 length, peer, external_allocation_size,
3911 callback, unmodifiable);
3913 return NewExternalTypedData(T, kExternalTypedDataFloat64x2ArrayCid, data,
3914 length, peer, external_allocation_size,
3915 callback, unmodifiable);
3916 default:
3917 return Api::NewError(
3918 "%s expects argument 'type' to be of"
3919 " 'external TypedData'",
3920 CURRENT_FUNC);
3921 }
3922 UNREACHABLE();
3923 return Api::Null();
3924}
3925
3927 void* data,
3928 intptr_t length) {
3930 nullptr, false);
3931}
3932
3935 void* data,
3936 intptr_t length,
3937 void* peer,
3938 intptr_t external_allocation_size,
3941 type, data, length, peer, external_allocation_size, callback, false);
3942}
3943
3946 const void* data,
3947 intptr_t length,
3948 void* peer,
3949 intptr_t external_allocation_size,
3952 type, const_cast<void*>(data), length, peer, external_allocation_size,
3953 callback, true);
3954}
3955
3957 const String& class_name,
3958 const String& constructor_name,
3959 intptr_t num_args) {
3960 const Library& lib = Library::Handle(
3961 thread->isolate_group()->object_store()->typed_data_library());
3962 ASSERT(!lib.IsNull());
3963 const Class& cls =
3965 ASSERT(!cls.IsNull());
3966 return ResolveConstructor(CURRENT_FUNC, cls, class_name, constructor_name,
3967 num_args);
3968}
3969
3972 intptr_t class_id = Api::ClassId(typed_data);
3973 if (!IsExternalTypedDataClassId(class_id) &&
3974 !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id)) {
3975 RETURN_TYPE_ERROR(Z, typed_data, 'TypedData');
3976 }
3978 result = GetByteBufferConstructor(T, Symbols::_ByteBuffer(),
3979 Symbols::_ByteBufferDot_New(), 1);
3980 ASSERT(!result.IsNull());
3981 ASSERT(result.IsFunction());
3982 const Function& factory = Function::Cast(result);
3983 ASSERT(!factory.IsGenerativeConstructor());
3984
3985 // Create the argument list.
3986 const Array& args = Array::Handle(Z, Array::New(2));
3987 // Factories get type arguments.
3988 args.SetAt(0, Object::null_type_arguments());
3989 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(typed_data));
3990 args.SetAt(1, obj);
3991
3992 // Invoke the factory constructor and return the new object.
3994 ASSERT(result.IsInstance() || result.IsNull() || result.IsError());
3995 return Api::NewHandle(T, result.ptr());
3996}
3997
3998// Structure to record acquired typed data for verification purposes.
4000 public:
4001 AcquiredData(void* data, intptr_t size_in_bytes, bool copy)
4002 : size_in_bytes_(size_in_bytes), data_(data), data_copy_(nullptr) {
4003 if (copy) {
4004 data_copy_ = malloc(size_in_bytes_);
4005 memmove(data_copy_, data_, size_in_bytes_);
4006 }
4007 }
4008
4009 // The pointer to hand out via the API.
4010 void* GetData() const { return data_copy_ != nullptr ? data_copy_ : data_; }
4011
4012 // Writes back and deletes/zaps, if a copy was made.
4014 if (data_copy_ != nullptr) {
4015 memmove(data_, data_copy_, size_in_bytes_);
4016 memset(data_copy_, kZapReleasedByte, size_in_bytes_);
4017 free(data_copy_);
4018 }
4019 }
4020
4021 private:
4022 static constexpr uint8_t kZapReleasedByte = 0xda;
4023 intptr_t size_in_bytes_;
4024 void* data_;
4025 void* data_copy_;
4026
4028};
4029
4032 void** data,
4033 intptr_t* len) {
4035 Isolate* I = T->isolate();
4036 intptr_t class_id = Api::ClassId(object);
4037 if (!IsExternalTypedDataClassId(class_id) &&
4038 !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id) &&
4040 RETURN_TYPE_ERROR(Z, object, 'TypedData');
4041 }
4042 if (type == nullptr) {
4044 }
4045 if (data == nullptr) {
4047 }
4048 if (len == nullptr) {
4049 RETURN_NULL_ERROR(len);
4050 }
4051 // Get the type of typed data object.
4052 *type = GetType(class_id);
4053 intptr_t length = 0;
4054 intptr_t size_in_bytes = 0;
4055 void* data_tmp = nullptr;
4056 bool external = false;
4057 T->IncrementNoSafepointScopeDepth();
4059 if (IsExternalTypedDataClassId(class_id)) {
4060 const ExternalTypedData& obj =
4061 Api::UnwrapExternalTypedDataHandle(Z, object);
4062 ASSERT(!obj.IsNull());
4063 length = obj.Length();
4064 size_in_bytes = length * ExternalTypedData::ElementSizeInBytes(class_id);
4065 data_tmp = obj.DataAddr(0);
4066 external = true;
4067 } else if (IsTypedDataClassId(class_id)) {
4068 const TypedData& obj = Api::UnwrapTypedDataHandle(Z, object);
4069 ASSERT(!obj.IsNull());
4070 length = obj.Length();
4071 size_in_bytes = length * TypedData::ElementSizeInBytes(class_id);
4072 data_tmp = obj.DataAddr(0);
4073 } else {
4074 ASSERT(IsTypedDataViewClassId(class_id) ||
4076 const auto& view_obj = Api::UnwrapTypedDataViewHandle(Z, object);
4077 ASSERT(!view_obj.IsNull());
4078 Smi& val = Smi::Handle();
4079 val = view_obj.length();
4080 length = val.Value();
4081 size_in_bytes = length * TypedDataView::ElementSizeInBytes(class_id);
4082 val = view_obj.offset_in_bytes();
4083 intptr_t offset_in_bytes = val.Value();
4084 const auto& obj = Instance::Handle(view_obj.typed_data());
4085 if (TypedData::IsTypedData(obj)) {
4086 const TypedData& data_obj = TypedData::Cast(obj);
4087 data_tmp = data_obj.DataAddr(offset_in_bytes);
4088 } else {
4090 const ExternalTypedData& data_obj = ExternalTypedData::Cast(obj);
4091 data_tmp = data_obj.DataAddr(offset_in_bytes);
4092 external = true;
4093 }
4094 }
4095 if (FLAG_verify_acquired_data) {
4096 {
4097 NoSafepointScope no_safepoint(T);
4098 bool sweep_in_progress;
4099 {
4100 PageSpace* old_space = T->heap()->old_space();
4101 MonitorLocker ml(old_space->tasks_lock());
4102 sweep_in_progress = (old_space->phase() == PageSpace::kSweepingLarge) ||
4103 (old_space->phase() == PageSpace::kSweepingRegular);
4104 }
4105 if (!sweep_in_progress) {
4106 if (external) {
4107 ASSERT(!T->heap()->Contains(reinterpret_cast<uword>(data_tmp)));
4108 } else {
4109 ASSERT(T->heap()->Contains(reinterpret_cast<uword>(data_tmp)));
4110 }
4111 }
4112 }
4113 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
4114 WeakTable* table = I->group()->api_state()->acquired_table();
4115 intptr_t current = table->GetValue(obj.ptr());
4116 if (current != 0) {
4117 return Api::NewError("Data was already acquired for this object.");
4118 }
4119 // Do not make a copy if the data is external. Some callers expect external
4120 // data to remain in place, even though the API spec doesn't guarantee it.
4121 // TODO(koda/asiva): Make final decision and document it.
4122 AcquiredData* ad = new AcquiredData(data_tmp, size_in_bytes, !external);
4123 table->SetValue(obj.ptr(), reinterpret_cast<intptr_t>(ad));
4124 data_tmp = ad->GetData();
4125 }
4126 *data = data_tmp;
4127 *len = length;
4128 return Api::Success();
4129}
4130
4133 Isolate* I = T->isolate();
4134 intptr_t class_id = Api::ClassId(object);
4135 if (!IsExternalTypedDataClassId(class_id) &&
4136 !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id) &&
4138 RETURN_TYPE_ERROR(Z, object, 'TypedData');
4139 }
4140 if (FLAG_verify_acquired_data) {
4141 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
4142 WeakTable* table = I->group()->api_state()->acquired_table();
4143 intptr_t current = table->GetValue(obj.ptr());
4144 if (current == 0) {
4145 return Api::NewError("Data was not acquired for this object.");
4146 }
4147 AcquiredData* ad = reinterpret_cast<AcquiredData*>(current);
4148 table->SetValue(obj.ptr(), 0); // Delete entry from table.
4149 delete ad;
4150 }
4151 T->DecrementNoSafepointScopeDepth();
4153 return Api::Success();
4154}
4155
4157 Thread* thread = Thread::Current();
4158 Zone* zone = thread->zone();
4159 Isolate* isolate = thread->isolate();
4160 CHECK_ISOLATE(isolate);
4161 TransitionNativeToVM transition(thread);
4162 intptr_t class_id = Api::ClassId(object);
4163 if (class_id != kByteBufferCid) {
4164 RETURN_TYPE_ERROR(zone, object, 'ByteBuffer');
4165 }
4166 const Instance& instance = Api::UnwrapInstanceHandle(zone, object);
4167 ASSERT(!instance.IsNull());
4168 return Api::NewHandle(thread, ByteBuffer::Data(instance));
4169}
4170
4171// --- Invoking Constructors, Methods, and Field accessors ---
4172
4173static ObjectPtr ResolveConstructor(const char* current_func,
4174 const Class& cls,
4175 const String& class_name,
4176 const String& constr_name,
4177 int num_args) {
4178 // The constructor must be present in the interface.
4179 Function& constructor = Function::Handle();
4181 constructor = cls.LookupFunctionAllowPrivate(constr_name);
4182 }
4183 if (constructor.IsNull() ||
4184 (!constructor.IsGenerativeConstructor() && !constructor.IsFactory())) {
4185 const String& lookup_class_name = String::Handle(cls.Name());
4186 if (!class_name.Equals(lookup_class_name)) {
4187 // When the class name used to build the constructor name is
4188 // different than the name of the class in which we are doing
4189 // the lookup, it can be confusing to the user to figure out
4190 // what's going on. Be a little more explicit for these error
4191 // messages.
4193 "%s: could not find factory '%s' in class '%s'.", current_func,
4194 constr_name.ToCString(), lookup_class_name.ToCString()));
4195 return ApiError::New(message);
4196 } else {
4197 const String& message = String::Handle(
4198 String::NewFormatted("%s: could not find constructor '%s'.",
4199 current_func, constr_name.ToCString()));
4200 return ApiError::New(message);
4201 }
4202 }
4203 const int kTypeArgsLen = 0;
4204 const int extra_args = 1;
4205 String& error_message = String::Handle();
4206 if (!constructor.AreValidArgumentCounts(kTypeArgsLen, num_args + extra_args,
4207 0, &error_message)) {
4209 "%s: wrong argument count for "
4210 "constructor '%s': %s.",
4211 current_func, constr_name.ToCString(), error_message.ToCString()));
4212 return ApiError::New(message);
4213 }
4214 ErrorPtr error = constructor.VerifyCallEntryPoint();
4215 if (error != Error::null()) return error;
4216 return constructor.ptr();
4217}
4218
4220 Dart_Handle constructor_name,
4221 int number_of_arguments,
4222 Dart_Handle* arguments) {
4226
4227 if (number_of_arguments < 0) {
4228 return Api::NewError(
4229 "%s expects argument 'number_of_arguments' to be non-negative.",
4230 CURRENT_FUNC);
4231 }
4232
4233 // Get the class to instantiate.
4234 Object& unchecked_type = Object::Handle(Api::UnwrapHandle(type));
4235 if (unchecked_type.IsNull() || !unchecked_type.IsType()) {
4237 }
4238 Type& type_obj = Type::Handle();
4239 type_obj ^= unchecked_type.ptr();
4240 if (!type_obj.IsFinalized()) {
4241 return Api::NewError(
4242 "%s expects argument 'type' to be a fully resolved type.",
4243 CURRENT_FUNC);
4244 }
4245 Class& cls = Class::Handle(Z, type_obj.type_class());
4247
4248 TypeArguments& type_arguments =
4250
4251 const String& base_constructor_name = String::Handle(Z, cls.Name());
4252
4253 // And get the name of the constructor to invoke.
4254 String& dot_name = String::Handle(Z);
4255 result = Api::UnwrapHandle(constructor_name);
4256 if (result.IsNull()) {
4257 dot_name = Symbols::Dot().ptr();
4258 } else if (result.IsString()) {
4259 dot_name = String::Concat(Symbols::Dot(), String::Cast(result));
4260 } else {
4261 RETURN_TYPE_ERROR(Z, constructor_name, String);
4262 }
4263
4264 // Resolve the constructor.
4265 String& constr_name =
4266 String::Handle(String::Concat(base_constructor_name, dot_name));
4267 result = ResolveConstructor("Dart_New", cls, base_constructor_name,
4268 constr_name, number_of_arguments);
4269 if (result.IsError()) {
4270 return Api::NewHandle(T, result.ptr());
4271 }
4272 ASSERT(result.IsFunction());
4273 Function& constructor = Function::Handle(Z);
4274 constructor ^= result.ptr();
4275
4276 Instance& new_object = Instance::Handle(Z);
4277 if (constructor.IsGenerativeConstructor()) {
4279#if defined(DEBUG)
4280 if (!cls.is_allocated() &&
4282 return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
4283 }
4284#endif
4285 // Create the new object.
4286 new_object = Instance::New(cls);
4287 }
4288
4289 // Create the argument list.
4290 intptr_t arg_index = 0;
4291 int extra_args = 1;
4292 const Array& args =
4293 Array::Handle(Z, Array::New(number_of_arguments + extra_args));
4294 if (constructor.IsGenerativeConstructor()) {
4295 // Constructors get the uninitialized object.
4296 if (!type_arguments.IsNull()) {
4297 // The type arguments will be null if the class has no type parameters, in
4298 // which case the following call would fail because there is no slot
4299 // reserved in the object for the type vector.
4300 new_object.SetTypeArguments(type_arguments);
4301 }
4302 args.SetAt(arg_index++, new_object);
4303 } else {
4304 // Factories get type arguments.
4305 args.SetAt(arg_index++, type_arguments);
4306 }
4307 Object& argument = Object::Handle(Z);
4308 for (int i = 0; i < number_of_arguments; i++) {
4309 argument = Api::UnwrapHandle(arguments[i]);
4310 if (!argument.IsNull() && !argument.IsInstance()) {
4311 if (argument.IsError()) {
4312 return Api::NewHandle(T, argument.ptr());
4313 } else {
4314 return Api::NewError(
4315 "%s expects arguments[%d] to be an Instance handle.", CURRENT_FUNC,
4316 i);
4317 }
4318 }
4319 args.SetAt(arg_index++, argument);
4320 }
4321
4322 const int kTypeArgsLen = 0;
4323 Array& args_descriptor_array = Array::Handle(
4324 Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length()));
4325
4326 ArgumentsDescriptor args_descriptor(args_descriptor_array);
4327 ObjectPtr type_error = constructor.DoArgumentTypesMatch(
4328 args, args_descriptor, type_arguments, Object::empty_type_arguments());
4329 if (type_error != Error::null()) {
4330 return Api::NewHandle(T, type_error);
4331 }
4332
4333 // Invoke the constructor and return the new object.
4334 result = DartEntry::InvokeFunction(constructor, args);
4335 if (result.IsError()) {
4336 return Api::NewHandle(T, result.ptr());
4337 }
4338
4339 if (constructor.IsGenerativeConstructor()) {
4340 ASSERT(result.IsNull());
4341 } else {
4342 ASSERT(result.IsNull() || result.IsInstance());
4343 new_object ^= result.ptr();
4344 }
4345 return Api::NewHandle(T, new_object.ptr());
4346}
4347
4348static InstancePtr AllocateObject(Thread* thread, const Class& cls) {
4349 if (!cls.is_fields_marked_nullable()) {
4350 // Mark all fields as nullable.
4351 Zone* zone = thread->zone();
4352 Class& iterate_cls = Class::Handle(zone, cls.ptr());
4353 Field& field = Field::Handle(zone);
4354 Array& fields = Array::Handle(zone);
4355 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
4356 if (!cls.is_fields_marked_nullable()) {
4357 while (!iterate_cls.IsNull()) {
4358 ASSERT(iterate_cls.is_finalized());
4359 iterate_cls.set_is_fields_marked_nullable();
4360 fields = iterate_cls.fields();
4361 iterate_cls = iterate_cls.SuperClass();
4362 for (int field_num = 0; field_num < fields.Length(); field_num++) {
4363 field ^= fields.At(field_num);
4364 if (field.is_static()) {
4365 continue;
4366 }
4367 field.RecordStore(Object::null_object());
4368 }
4369 }
4370 }
4371 }
4372
4373 // Allocate an object for the given class.
4374 return Instance::New(cls);
4375}
4376
4380
4381 const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
4382 // Get the class to instantiate.
4383 if (type_obj.IsNull()) {
4385 }
4386
4387 if (!type_obj.IsFinalized()) {
4388 return Api::NewError(
4389 "%s expects argument 'type' to be a fully resolved type.",
4390 CURRENT_FUNC);
4391 }
4392
4393 const Class& cls = Class::Handle(Z, type_obj.type_class());
4394 const TypeArguments& type_arguments =
4396
4398#if defined(DEBUG)
4400 return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
4401 }
4402#endif
4404 const Instance& new_obj = Instance::Handle(Z, AllocateObject(T, cls));
4405 if (!type_arguments.IsNull()) {
4406 new_obj.SetTypeArguments(type_arguments);
4407 }
4408 return Api::NewHandle(T, new_obj.ptr());
4409}
4410
4413 intptr_t num_native_fields,
4414 const intptr_t* native_fields) {
4417
4418 const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
4419 // Get the class to instantiate.
4420 if (type_obj.IsNull()) {
4422 }
4423 if (native_fields == nullptr) {
4424 RETURN_NULL_ERROR(native_fields);
4425 }
4426 const Class& cls = Class::Handle(Z, type_obj.type_class());
4428#if defined(DEBUG)
4430 return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
4431 }
4432#endif
4434 if (num_native_fields != cls.num_native_fields()) {
4435 return Api::NewError(
4436 "%s: invalid number of native fields %" Pd " passed in, expected %d",
4437 CURRENT_FUNC, num_native_fields, cls.num_native_fields());
4438 }
4440 instance.SetNativeFields(num_native_fields, native_fields);
4441 return Api::NewHandle(T, instance.ptr());
4442}
4443
4445 int num_args,
4446 Dart_Handle* arguments,
4447 int extra_args,
4448 Array* args) {
4449 Zone* zone = thread->zone();
4450 // Check for malformed arguments in the arguments list.
4451 *args = Array::New(num_args + extra_args);
4452 Object& arg = Object::Handle(zone);
4453 for (int i = 0; i < num_args; i++) {
4454 arg = Api::UnwrapHandle(arguments[i]);
4455 if (!arg.IsNull() && !arg.IsInstance()) {
4456 *args = Array::null();
4457 if (arg.IsError()) {
4458 return Api::NewHandle(thread, arg.ptr());
4459 } else {
4460 return Api::NewError(
4461 "%s expects arguments[%d] to be an Instance handle.", "Dart_Invoke",
4462 i);
4463 }
4464 }
4465 args->SetAt((i + extra_args), arg);
4466 }
4467 return Api::Success();
4468}
4469
4472 int number_of_arguments,
4473 Dart_Handle* arguments) {
4477
4478 if (number_of_arguments < 0) {
4479 return Api::NewError(
4480 "%s expects argument 'number_of_arguments' to be non-negative.",
4481 CURRENT_FUNC);
4482 }
4483 const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
4484 if (instance.IsNull()) {
4485 RETURN_TYPE_ERROR(Z, object, Instance);
4486 }
4487
4488 // Since we have allocated an object it would mean that the type
4489 // is finalized.
4490 // TODO(asiva): How do we ensure that a constructor is not called more than
4491 // once for the same object.
4492
4493 // Construct name of the constructor to invoke.
4494 const String& constructor_name = Api::UnwrapStringHandle(Z, name);
4495 AbstractType& type_obj =
4497 const Class& cls = Class::Handle(Z, type_obj.type_class());
4498 const String& class_name = String::Handle(Z, cls.Name());
4499 const Array& strings = Array::Handle(Z, Array::New(3));
4500 strings.SetAt(0, class_name);
4501 strings.SetAt(1, Symbols::Dot());
4502 if (constructor_name.IsNull()) {
4503 strings.SetAt(2, Symbols::Empty());
4504 } else {
4505 strings.SetAt(2, constructor_name);
4506 }
4507 const String& dot_name = String::Handle(Z, String::ConcatAll(strings));
4508 TypeArguments& type_arguments = TypeArguments::Handle(Z);
4509 if (type_obj.IsType()) {
4510 type_arguments = Type::Cast(type_obj).GetInstanceTypeArguments(T);
4511 }
4512 const Function& constructor =
4514 const int kTypeArgsLen = 0;
4515 const int extra_args = 1;
4516 if (!constructor.IsNull() && constructor.IsGenerativeConstructor() &&
4517 constructor.AreValidArgumentCounts(
4518 kTypeArgsLen, number_of_arguments + extra_args, 0, nullptr)) {
4520 // Create the argument list.
4523 result =
4524 SetupArguments(T, number_of_arguments, arguments, extra_args, &args);
4525 if (!Api::IsError(result)) {
4526 args.SetAt(0, instance);
4527
4528 const int kTypeArgsLen = 0;
4529 const Array& args_descriptor_array = Array::Handle(
4530 Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length()));
4531 ArgumentsDescriptor args_descriptor(args_descriptor_array);
4532 ObjectPtr type_error = constructor.DoArgumentTypesMatch(
4533 args, args_descriptor, type_arguments);
4534 if (type_error != Error::null()) {
4535 return Api::NewHandle(T, type_error);
4536 }
4537
4538 const Object& retval =
4540 if (retval.IsError()) {
4541 result = Api::NewHandle(T, retval.ptr());
4542 } else {
4543 result = Api::NewHandle(T, instance.ptr());
4544 }
4545 }
4546 return result;
4547 }
4548 return Api::NewError("%s expects argument 'name' to be a valid constructor.",
4549 CURRENT_FUNC);
4550}
4551
4554 int number_of_arguments,
4555 Dart_Handle* arguments) {
4559
4562 if (function_name.IsNull()) {
4564 }
4565 if (number_of_arguments < 0) {
4566 return Api::NewError(
4567 "%s expects argument 'number_of_arguments' to be non-negative.",
4568 CURRENT_FUNC);
4569 }
4571 if (obj.IsError()) {
4572 return target;
4573 }
4576 // This API does not provide a way to pass named parameters.
4577 const Array& arg_names = Object::empty_array();
4578 const bool respect_reflectable = false;
4579 const bool check_is_entrypoint = FLAG_verify_entry_points;
4580 if (obj.IsType()) {
4581 if (!Type::Cast(obj).IsFinalized()) {
4582 return Api::NewError(
4583 "%s expects argument 'target' to be a fully resolved type.",
4584 CURRENT_FUNC);
4585 }
4586
4587 const Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
4589 const Library& lib = Library::Handle(Z, cls.library());
4591 }
4592
4593 // Setup args and check for malformed arguments in the arguments list.
4594 result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
4595 if (Api::IsError(result)) {
4596 return result;
4597 }
4598 return Api::NewHandle(
4599 T, cls.Invoke(function_name, args, arg_names, respect_reflectable,
4600 check_is_entrypoint));
4601 } else if (obj.IsNull() || obj.IsInstance()) {
4602 // Since we have allocated an object it would mean that the type of the
4603 // receiver is already resolved and finalized, hence it is not necessary
4604 // to check here.
4606 instance ^= obj.ptr();
4607
4608 // Setup args and check for malformed arguments in the arguments list.
4609 result = SetupArguments(T, number_of_arguments, arguments, 1, &args);
4610 if (Api::IsError(result)) {
4611 return result;
4612 }
4613 args.SetAt(0, instance);
4614 return Api::NewHandle(
4615 T, instance.Invoke(function_name, args, arg_names, respect_reflectable,
4616 check_is_entrypoint));
4617 } else if (obj.IsLibrary()) {
4618 // Check whether class finalization is needed.
4619 const Library& lib = Library::Cast(obj);
4620
4621 // Check that the library is loaded.
4622 if (!lib.Loaded()) {
4623 return Api::NewError("%s expects library argument 'target' to be loaded.",
4624 CURRENT_FUNC);
4625 }
4626
4629 }
4630
4631 // Setup args and check for malformed arguments in the arguments list.
4632 result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
4633 if (Api::IsError(result)) {
4634 return result;
4635 }
4636
4637 return Api::NewHandle(
4638 T, lib.Invoke(function_name, args, arg_names, respect_reflectable,
4639 check_is_entrypoint));
4640 } else {
4641 return Api::NewError(
4642 "%s expects argument 'target' to be an object, type, or library.",
4643 CURRENT_FUNC);
4644 }
4645}
4646
4648 int number_of_arguments,
4649 Dart_Handle* arguments) {
4653 const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure);
4654 if (closure_obj.IsNull() || !closure_obj.IsCallable(nullptr)) {
4655 RETURN_TYPE_ERROR(Z, closure, Instance);
4656 }
4657 if (number_of_arguments < 0) {
4658 return Api::NewError(
4659 "%s expects argument 'number_of_arguments' to be non-negative.",
4660 CURRENT_FUNC);
4661 }
4662
4663 // Set up arguments to include the closure as the first argument.
4664 const Array& args = Array::Handle(Z, Array::New(number_of_arguments + 1));
4665 Object& obj = Object::Handle(Z);
4666 args.SetAt(0, closure_obj);
4667 for (int i = 0; i < number_of_arguments; i++) {
4668 obj = Api::UnwrapHandle(arguments[i]);
4669 if (!obj.IsNull() && !obj.IsInstance()) {
4670 RETURN_TYPE_ERROR(Z, arguments[i], Instance);
4671 }
4672 args.SetAt(i + 1, obj);
4673 }
4674 // Now try to invoke the closure.
4676}
4677
4682
4683 String& field_name =
4685 if (field_name.IsNull()) {
4687 }
4688 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
4689 const bool throw_nsm_if_absent = true;
4690 const bool respect_reflectable = false;
4691 const bool check_is_entrypoint = FLAG_verify_entry_points;
4692
4693 if (obj.IsType()) {
4694 if (!Type::Cast(obj).IsFinalized()) {
4695 return Api::NewError(
4696 "%s expects argument 'container' to be a fully resolved type.",
4697 CURRENT_FUNC);
4698 }
4699 Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
4700 if (Library::IsPrivate(field_name)) {
4701 const Library& lib = Library::Handle(Z, cls.library());
4702 field_name = lib.PrivateName(field_name);
4703 }
4704 return Api::NewHandle(
4705 T, cls.InvokeGetter(field_name, throw_nsm_if_absent,
4706 respect_reflectable, check_is_entrypoint));
4707 } else if (obj.IsNull() || obj.IsInstance()) {
4709 instance ^= obj.ptr();
4710 if (Library::IsPrivate(field_name)) {
4711 const Class& cls = Class::Handle(Z, instance.clazz());
4712 const Library& lib = Library::Handle(Z, cls.library());
4713 field_name = lib.PrivateName(field_name);
4714 }
4715 return Api::NewHandle(T,
4716 instance.InvokeGetter(field_name, respect_reflectable,
4717 check_is_entrypoint));
4718 } else if (obj.IsLibrary()) {
4719 const Library& lib = Library::Cast(obj);
4720 // Check that the library is loaded.
4721 if (!lib.Loaded()) {
4722 return Api::NewError(
4723 "%s expects library argument 'container' to be loaded.",
4724 CURRENT_FUNC);
4725 }
4726 if (Library::IsPrivate(field_name)) {
4727 field_name = lib.PrivateName(field_name);
4728 }
4729 return Api::NewHandle(
4730 T, lib.InvokeGetter(field_name, throw_nsm_if_absent,
4731 respect_reflectable, check_is_entrypoint));
4732 } else if (obj.IsError()) {
4733 return container;
4734 } else {
4735 return Api::NewError(
4736 "%s expects argument 'container' to be an object, type, or library.",
4737 CURRENT_FUNC);
4738 }
4739}
4740
4743 Dart_Handle value) {
4747
4748 String& field_name =
4750 if (field_name.IsNull()) {
4752 }
4753
4754 // Since null is allowed for value, we don't use UnwrapInstanceHandle.
4755 const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));
4756 if (!value_obj.IsNull() && !value_obj.IsInstance()) {
4758 }
4759 Instance& value_instance = Instance::Handle(Z);
4760 value_instance ^= value_obj.ptr();
4761
4762 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
4763 const bool respect_reflectable = false;
4764 const bool check_is_entrypoint = FLAG_verify_entry_points;
4765
4766 if (obj.IsType()) {
4767 if (!Type::Cast(obj).IsFinalized()) {
4768 return Api::NewError(
4769 "%s expects argument 'container' to be a fully resolved type.",
4770 CURRENT_FUNC);
4771 }
4772
4773 // To access a static field we may need to use the Field or the
4774 // setter Function.
4775 Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
4776 if (Library::IsPrivate(field_name)) {
4777 const Library& lib = Library::Handle(Z, cls.library());
4778 field_name = lib.PrivateName(field_name);
4779 }
4780 return Api::NewHandle(
4781 T, cls.InvokeSetter(field_name, value_instance, respect_reflectable,
4782 check_is_entrypoint));
4783 } else if (obj.IsNull() || obj.IsInstance()) {
4785 instance ^= obj.ptr();
4786 if (Library::IsPrivate(field_name)) {
4787 const Class& cls = Class::Handle(Z, instance.clazz());
4788 const Library& lib = Library::Handle(Z, cls.library());
4789 field_name = lib.PrivateName(field_name);
4790 }
4791 return Api::NewHandle(
4792 T, instance.InvokeSetter(field_name, value_instance,
4793 respect_reflectable, check_is_entrypoint));
4794 } else if (obj.IsLibrary()) {
4795 // To access a top-level we may need to use the Field or the
4796 // setter Function. The setter function may either be in the
4797 // library or in the field's owner class, depending.
4798 const Library& lib = Library::Cast(obj);
4799 // Check that the library is loaded.
4800 if (!lib.Loaded()) {
4801 return Api::NewError(
4802 "%s expects library argument 'container' to be loaded.",
4803 CURRENT_FUNC);
4804 }
4805
4806 if (Library::IsPrivate(field_name)) {
4807 field_name = lib.PrivateName(field_name);
4808 }
4809 return Api::NewHandle(
4810 T, lib.InvokeSetter(field_name, value_instance, respect_reflectable,
4811 check_is_entrypoint));
4812 } else if (obj.IsError()) {
4813 return container;
4814 }
4815 return Api::NewError(
4816 "%s expects argument 'container' to be an object, type, or library.",
4817 CURRENT_FUNC);
4818}
4819
4820// --- Exceptions ----
4821
4823 Thread* thread = Thread::Current();
4824 Zone* zone = thread->zone();
4825 Isolate* isolate = thread->isolate();
4826 CHECK_ISOLATE(isolate);
4827 CHECK_CALLBACK_STATE(thread);
4828 if (::Dart_IsError(exception)) {
4829 ::Dart_PropagateError(exception);
4830 }
4831 TransitionNativeToVM transition(thread);
4832 const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
4833 if (excp.IsNull()) {
4834 RETURN_TYPE_ERROR(zone, exception, Instance);
4835 }
4836 if (thread->top_exit_frame_info() == 0) {
4837 // There are no dart frames on the stack so it would be illegal to
4838 // throw an exception here.
4839 return Api::NewError("No Dart frames on stack, cannot throw exception");
4840 }
4841 // Unwind all the API scopes till the exit frame before throwing an
4842 // exception.
4843 const Instance* saved_exception;
4844 {
4845 NoSafepointScope no_safepoint;
4846 InstancePtr raw_exception =
4847 Api::UnwrapInstanceHandle(zone, exception).ptr();
4848 thread->UnwindScopes(thread->top_exit_frame_info());
4849 saved_exception = &Instance::Handle(raw_exception);
4850 }
4851 Exceptions::Throw(thread, *saved_exception);
4852 return Api::NewError("Exception was not thrown, internal error");
4853}
4854
4856 Dart_Handle stacktrace) {
4857 Thread* thread = Thread::Current();
4858 Zone* zone = thread->zone();
4859 Isolate* isolate = thread->isolate();
4860 CHECK_ISOLATE(isolate);
4861 CHECK_CALLBACK_STATE(thread);
4862 TransitionNativeToVM transition(thread);
4863 {
4864 const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
4865 if (excp.IsNull()) {
4866 RETURN_TYPE_ERROR(zone, exception, Instance);
4867 }
4868 const Instance& stk = Api::UnwrapInstanceHandle(zone, stacktrace);
4869 if (stk.IsNull()) {
4870 RETURN_TYPE_ERROR(zone, stacktrace, Instance);
4871 }
4872 }
4873 if (thread->top_exit_frame_info() == 0) {
4874 // There are no dart frames on the stack so it would be illegal to
4875 // throw an exception here.
4876 return Api::NewError("No Dart frames on stack, cannot throw exception");
4877 }
4878 // Unwind all the API scopes till the exit frame before throwing an
4879 // exception.
4880 const Instance* saved_exception;
4881 const StackTrace* saved_stacktrace;
4882 {
4883 NoSafepointScope no_safepoint;
4884 InstancePtr raw_exception =
4885 Api::UnwrapInstanceHandle(zone, exception).ptr();
4886 StackTracePtr raw_stacktrace =
4887 Api::UnwrapStackTraceHandle(zone, stacktrace).ptr();
4888 thread->UnwindScopes(thread->top_exit_frame_info());
4889 saved_exception = &Instance::Handle(raw_exception);
4890 saved_stacktrace = &StackTrace::Handle(raw_stacktrace);
4891 }
4892 Exceptions::ReThrow(thread, *saved_exception, *saved_stacktrace);
4893 return Api::NewError("Exception was not re thrown, internal error");
4894}
4895
4896// --- Native fields and functions ---
4897
4899 int* count) {
4900 Thread* thread = Thread::Current();
4901 CHECK_ISOLATE(thread->isolate());
4902 TransitionNativeToVM transition(thread);
4903 {
4904 ReusableObjectHandleScope reused_obj_handle(thread);
4905 const Instance& instance =
4906 Api::UnwrapInstanceHandle(reused_obj_handle, obj);
4907 if (!instance.IsNull()) {
4908 *count = instance.NumNativeFields();
4909 return Api::Success();
4910 }
4911 }
4912 RETURN_TYPE_ERROR(thread->zone(), obj, Instance);
4913}
4914
4916 int index,
4917 intptr_t* value) {
4918 Thread* thread = Thread::Current();
4919 CHECK_ISOLATE(thread->isolate());
4920 TransitionNativeToVM transition(thread);
4921 bool is_null = false;
4922 {
4923 ReusableObjectHandleScope reused_obj_handle(thread);
4924 const Instance& instance =
4925 Api::UnwrapInstanceHandle(reused_obj_handle, obj);
4926 if (!instance.IsNull()) {
4927 if (instance.IsValidNativeIndex(index)) {
4928 *value = instance.GetNativeField(index);
4929 return Api::Success();
4930 }
4931 } else {
4932 is_null = true;
4933 }
4934 }
4935 if (is_null) {
4936 RETURN_TYPE_ERROR(thread->zone(), obj, Instance);
4937 }
4938 return Api::NewError(
4939 "%s: invalid index %d passed into access native instance field",
4940 CURRENT_FUNC, index);
4941}
4942
4944 int index,
4945 intptr_t value) {
4948 if (instance.IsNull()) {
4950 }
4951 if (!instance.IsValidNativeIndex(index)) {
4952 return Api::NewError(
4953 "%s: invalid index %d passed into set native instance field",
4954 CURRENT_FUNC, index);
4955 }
4956 instance.SetNativeField(index, value);
4957 return Api::Success();
4958}
4959
4961 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
4962 Isolate* isolate = arguments->thread()->isolate();
4963 ASSERT(isolate == Isolate::Current());
4964 return isolate->init_callback_data();
4965}
4966
4969 int num_arguments,
4970 const Dart_NativeArgument_Descriptor* argument_descriptors,
4971 Dart_NativeArgument_Value* arg_values) {
4972 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
4973 TransitionNativeToVM transition(arguments->thread());
4974 ASSERT(arguments->thread()->isolate() == Isolate::Current());
4975 if (arg_values == nullptr) {
4976 RETURN_NULL_ERROR(arg_values);
4977 }
4978 for (int i = 0; i < num_arguments; i++) {
4979 Dart_NativeArgument_Descriptor desc = argument_descriptors[i];
4980 Dart_NativeArgument_Type arg_type =
4981 static_cast<Dart_NativeArgument_Type>(desc.type);
4982 int arg_index = desc.index;
4983 ASSERT(arg_index >= 0 && arg_index < arguments->NativeArgCount());
4984 Dart_NativeArgument_Value* native_value = &(arg_values[i]);
4985 switch (arg_type) {
4987 if (!Api::GetNativeBooleanArgument(arguments, arg_index,
4988 &(native_value->as_bool))) {
4989 return Api::NewArgumentError(
4990 "%s: expects argument at index %d to be of"
4991 " type Boolean.",
4992 CURRENT_FUNC, i);
4993 }
4994 break;
4995
4997 int64_t value = 0;
4998 if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
4999 return Api::NewArgumentError(
5000 "%s: expects argument at index %d to be of"
5001 " type Integer.",
5002 CURRENT_FUNC, i);
5003 }
5004 if (value < INT32_MIN || value > INT32_MAX) {
5005 return Api::NewArgumentError(
5006 "%s: argument value at index %d is out of range", CURRENT_FUNC,
5007 i);
5008 }
5009 native_value->as_int32 = static_cast<int32_t>(value);
5010 break;
5011 }
5012
5014 int64_t value = 0;
5015 if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
5016 return Api::NewArgumentError(
5017 "%s: expects argument at index %d to be of"
5018 " type Integer.",
5019 CURRENT_FUNC, i);
5020 }
5021 if (value < 0 || value > UINT32_MAX) {
5022 return Api::NewArgumentError(
5023 "%s: argument value at index %d is out of range", CURRENT_FUNC,
5024 i);
5025 }
5026 native_value->as_uint32 = static_cast<uint32_t>(value);
5027 break;
5028 }
5029
5031 int64_t value = 0;
5032 if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
5033 return Api::NewArgumentError(
5034 "%s: expects argument at index %d to be of"
5035 " type Integer.",
5036 CURRENT_FUNC, i);
5037 }
5038 native_value->as_int64 = value;
5039 break;
5040 }
5041
5043 uint64_t value = 0;
5044 if (!GetNativeUnsignedIntegerArgument(arguments, arg_index, &value)) {
5045 return Api::NewArgumentError(
5046 "%s: expects argument at index %d to be of"
5047 " type Integer.",
5048 CURRENT_FUNC, i);
5049 }
5050 native_value->as_uint64 = value;
5051 break;
5052 }
5053
5055 if (!GetNativeDoubleArgument(arguments, arg_index,
5056 &(native_value->as_double))) {
5057 return Api::NewArgumentError(
5058 "%s: expects argument at index %d to be of"
5059 " type Double.",
5060 CURRENT_FUNC, i);
5061 }
5062 break;
5063
5065 if (!GetNativeStringArgument(arguments, arg_index,
5066 &(native_value->as_string.dart_str),
5067 &(native_value->as_string.peer))) {
5068 return Api::NewArgumentError(
5069 "%s: expects argument at index %d to be of"
5070 " type String.",
5071 CURRENT_FUNC, i);
5072 }
5073 break;
5074
5077 arguments, arg_index, native_value->as_native_fields.num_fields,
5078 native_value->as_native_fields.values, CURRENT_FUNC);
5079 if (result != Api::Success()) {
5080 return result;
5081 }
5082 break;
5083 }
5084
5086 ASSERT(arguments->thread() == Thread::Current());
5087 ASSERT(arguments->thread()->api_top_scope() != nullptr);
5088 native_value->as_instance = Api::NewHandle(
5089 arguments->thread(), arguments->NativeArgAt(arg_index));
5090 break;
5091 }
5092
5093 default:
5094 return Api::NewArgumentError("%s: invalid argument type %d.",
5095 CURRENT_FUNC, arg_type);
5096 }
5097 }
5098 return Api::Success();
5099}
5100
5102 int index) {
5103 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5104 if ((index < 0) || (index >= arguments->NativeArgCount())) {
5105 return Api::NewError(
5106 "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
5107 CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
5108 }
5109 TransitionNativeToVM transition(arguments->thread());
5110 return Api::NewHandle(arguments->thread(), arguments->NativeArgAt(index));
5111}
5112
5114 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5115 return arguments->NativeArgCount();
5116}
5117
5120 int arg_index,
5121 int num_fields,
5122 intptr_t* field_values) {
5123 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5124 if ((arg_index < 0) || (arg_index >= arguments->NativeArgCount())) {
5125 return Api::NewError(
5126 "%s: argument 'arg_index' out of range. Expected 0..%d but saw %d.",
5127 CURRENT_FUNC, arguments->NativeArgCount() - 1, arg_index);
5128 }
5129 if (field_values == nullptr) {
5130 RETURN_NULL_ERROR(field_values);
5131 }
5132 return GetNativeFieldsOfArgument(arguments, arg_index, num_fields,
5133 field_values, CURRENT_FUNC);
5134}
5135
5137 intptr_t* value) {
5138 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5139 TransitionNativeToVM transition(arguments->thread());
5140 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5141 if (value == nullptr) {
5143 }
5144 if (Api::GetNativeReceiver(arguments, value)) {
5145 return Api::Success();
5146 }
5147 return Api::NewError(
5148 "%s expects receiver argument to be non-null and of"
5149 " type Instance.",
5150 CURRENT_FUNC);
5151}
5152
5154 int arg_index,
5155 void** peer) {
5156 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5157 TransitionNativeToVM transition(arguments->thread());
5159 if (!GetNativeStringArgument(arguments, arg_index, &result, peer)) {
5160 return Api::NewArgumentError(
5161 "%s expects argument at %d to be of"
5162 " type String.",
5163 CURRENT_FUNC, arg_index);
5164 }
5165 return result;
5166}
5167
5169 int index,
5170 int64_t* value) {
5171 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5172 if ((index < 0) || (index >= arguments->NativeArgCount())) {
5173 return Api::NewError(
5174 "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
5175 CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
5176 }
5177 if (!GetNativeIntegerArgument(arguments, index, value)) {
5178 return Api::NewArgumentError(
5179 "%s: expects argument at %d to be of"
5180 " type Integer.",
5181 CURRENT_FUNC, index);
5182 }
5183 return Api::Success();
5184}
5185
5187 int index,
5188 bool* value) {
5189 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5190 if ((index < 0) || (index >= arguments->NativeArgCount())) {
5191 return Api::NewError(
5192 "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
5193 CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
5194 }
5195 if (!Api::GetNativeBooleanArgument(arguments, index, value)) {
5196 return Api::NewArgumentError(
5197 "%s: expects argument at %d to be of type Boolean.", CURRENT_FUNC,
5198 index);
5199 }
5200 return Api::Success();
5201}
5202
5204 int index,
5205 double* value) {
5206 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5207 if ((index < 0) || (index >= arguments->NativeArgCount())) {
5208 return Api::NewError(
5209 "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
5210 CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
5211 }
5212 if (!GetNativeDoubleArgument(arguments, index, value)) {
5213 return Api::NewArgumentError(
5214 "%s: expects argument at %d to be of"
5215 " type Double.",
5216 CURRENT_FUNC, index);
5217 }
5218 return Api::Success();
5219}
5220
5222 Dart_Handle retval) {
5223 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5224 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5225 ASSERT_CALLBACK_STATE(arguments->thread());
5226 TransitionNativeToVM transition(arguments->thread());
5227 if ((retval != Api::Null()) && !Api::IsInstance(retval) &&
5228 !Api::IsError(retval)) {
5229 // Print the current stack trace to make the problematic caller
5230 // easier to find.
5231 const StackTrace& stacktrace = GetCurrentStackTrace(0);
5232 OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());
5233
5234 const Object& ret_obj = Object::Handle(Api::UnwrapHandle(retval));
5235 FATAL(
5236 "Return value check failed: saw '%s' expected a dart Instance or "
5237 "an Error.",
5238 ret_obj.ToCString());
5239 }
5240 ASSERT(retval != nullptr);
5241 Api::SetReturnValue(arguments, retval);
5242}
5243
5246 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5247 TransitionNativeToVM transition(arguments->thread());
5248#if defined(DEBUG)
5249 Isolate* isolate = arguments->thread()->isolate();
5250 ASSERT(isolate == Isolate::Current());
5251 ASSERT(isolate->group()->api_state() != nullptr &&
5252 (isolate->group()->api_state()->IsValidWeakPersistentHandle(rval)));
5253#endif
5254 Api::SetWeakHandleReturnValue(arguments, rval);
5255}
5256
5257// --- Environment ---
5258StringPtr Api::GetEnvironmentValue(Thread* thread, const String& name) {
5259 String& result = String::Handle(CallEnvironmentCallback(thread, name));
5260 if (result.IsNull()) {
5261 // Every 'dart:X' library introduces an environment variable
5262 // 'dart.library.X' that is set to 'true'.
5263 // We just need to make sure to hide private libraries (starting with
5264 // "_", and the mirrors library, if it is not supported.
5265
5266 if (!FLAG_enable_mirrors && name.Equals(Symbols::DartLibraryMirrors())) {
5267 return Symbols::False().ptr();
5268 }
5269
5270 if (!Api::IsFfiEnabled() && name.Equals(Symbols::DartLibraryFfi())) {
5271 return Symbols::False().ptr();
5272 }
5273
5274 if (name.Equals(Symbols::DartVMProduct())) {
5275#ifdef PRODUCT
5276 return Symbols::True().ptr();
5277#else
5278 return Symbols::False().ptr();
5279#endif
5280 }
5281
5282 if (name.Equals(Symbols::DartDeveloperTimeline())) {
5283#ifdef SUPPORT_TIMELINE
5284 return Symbols::True().ptr();
5285#else
5286 return Symbols::False().ptr();
5287#endif
5288 }
5289
5290 const String& prefix = Symbols::DartLibrary();
5291 if (name.StartsWith(prefix)) {
5292 const String& library_name =
5293 String::Handle(String::SubString(name, prefix.Length()));
5294
5295 // Private libraries (starting with "_") are not exposed to the user.
5296 if (!library_name.IsNull() && library_name.CharAt(0) != '_') {
5297 const String& dart_library_name =
5298 String::Handle(String::Concat(Symbols::DartScheme(), library_name));
5299 const Library& library =
5300 Library::Handle(Library::LookupLibrary(thread, dart_library_name));
5301 if (!library.IsNull()) {
5302 return Symbols::True().ptr();
5303 }
5304 }
5305 }
5306 // Check for default VM provided values. If it was not overridden on the
5307 // command line.
5308 if (Symbols::DartIsVM().Equals(name)) {
5309 return Symbols::True().ptr();
5310 }
5311 }
5312 return result.ptr();
5313}
5314
5315StringPtr Api::CallEnvironmentCallback(Thread* thread, const String& name) {
5316 Isolate* isolate = thread->isolate();
5318 if (callback != nullptr) {
5319 Scope api_scope(thread);
5320 Dart_Handle api_name = Api::NewHandle(thread, name.ptr());
5321 Dart_Handle api_response;
5322 {
5323 TransitionVMToNative transition(thread);
5324 api_response = callback(api_name);
5325 }
5326 const Object& response =
5327 Object::Handle(thread->zone(), Api::UnwrapHandle(api_response));
5328 if (response.IsString()) {
5329 return String::Cast(response).ptr();
5330 } else if (response.IsError()) {
5332 String::Handle(String::New(Error::Cast(response).ToErrorCString())));
5333 } else if (!response.IsNull()) {
5334 // At this point everything except null are invalid environment values.
5336 String::Handle(String::New("Illegal environment value")));
5337 }
5338 }
5339 return String::null();
5340}
5341
5349
5350// --- Scripts and Libraries ---
5352 bool retval) {
5353 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5354 TransitionNativeToVM transition(arguments->thread());
5355 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5356 ASSERT_CALLBACK_STATE(arguments->thread());
5357 arguments->SetReturn(Bool::Get(retval));
5358}
5359
5361 int64_t retval) {
5362 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5363 TransitionNativeToVM transition(arguments->thread());
5364 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5365 ASSERT_CALLBACK_STATE(arguments->thread());
5366 if (Smi::IsValid(retval)) {
5367 Api::SetSmiReturnValue(arguments, static_cast<intptr_t>(retval));
5368 } else {
5369 // Slow path for Mints.
5370 Api::SetIntegerReturnValue(arguments, retval);
5371 }
5372}
5373
5375 double retval) {
5376 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5377 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5378 ASSERT_CALLBACK_STATE(arguments->thread());
5379 TransitionNativeToVM transition(arguments->thread());
5380 Api::SetDoubleReturnValue(arguments, retval);
5381}
5382
5383// --- Scripts and Libraries ---
5384
5387 Isolate* isolate = Isolate::Current();
5388 CHECK_ISOLATE(isolate);
5389 isolate->group()->set_library_tag_handler(handler);
5390 return Api::Success();
5391}
5392
5394 Dart_Handle url) {
5398
5399 const String& base_uri = Api::UnwrapStringHandle(Z, base_url);
5400 if (base_uri.IsNull()) {
5401 RETURN_TYPE_ERROR(Z, base_url, String);
5402 }
5403 const String& uri = Api::UnwrapStringHandle(Z, url);
5404 if (uri.IsNull()) {
5405 RETURN_TYPE_ERROR(Z, url, String);
5406 }
5407
5408 const char* resolved_uri;
5409 if (!ResolveUri(uri.ToCString(), base_uri.ToCString(), &resolved_uri)) {
5410 return Api::NewError("%s: Unable to canonicalize uri '%s'.", CURRENT_FUNC,
5411 uri.ToCString());
5412 }
5413 return Api::NewHandle(T, String::New(resolved_uri));
5414}
5415
5418 Isolate* isolate = Isolate::Current();
5419 CHECK_ISOLATE(isolate);
5420 isolate->group()->set_deferred_load_handler(handler);
5421 return Api::Success();
5422}
5423
5425 intptr_t buffer_size) {
5426#if defined(DART_PRECOMPILED_RUNTIME)
5427 return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
5428#else
5431 StackZone zone(T);
5432 IsolateGroup* IG = T->isolate_group();
5433
5434 Library& library = Library::Handle(Z, IG->object_store()->root_library());
5435 if (!library.IsNull()) {
5436 const String& library_url = String::Handle(Z, library.url());
5437 return Api::NewError("%s: A script has already been loaded from '%s'.",
5438 CURRENT_FUNC, library_url.ToCString());
5439 }
5441
5442 // NOTE: We do not attach a finalizer for this object, because the embedder
5443 // will free it once the isolate group has shutdown.
5445 kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
5447
5448 const char* error = nullptr;
5449 std::unique_ptr<kernel::Program> program =
5450 kernel::Program::ReadFromTypedData(td, &error);
5451 if (program == nullptr) {
5452 return Api::NewError("Can't load Kernel binary: %s.", error);
5453 }
5454 const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
5455 program.reset();
5456
5457 if (tmp.IsError()) {
5458 return Api::NewHandle(T, tmp.ptr());
5459 }
5460
5461 IG->source()->script_kernel_size = buffer_size;
5462 IG->source()->script_kernel_buffer = buffer;
5463
5464 // TODO(32618): Setting root library based on whether it has 'main' or not
5465 // is not correct because main can be in the exported namespace of a library
5466 // or it could be a getter.
5467 if (tmp.IsNull()) {
5468 return Api::NewError(
5469 "Invoked Dart programs must have a 'main' function defined:\n"
5470 "https://dart.dev/guides/language/"
5471 "language-tour#a-basic-dart-program");
5472 }
5473 library ^= tmp.ptr();
5474 IG->object_store()->set_root_library(library);
5475 return Api::NewHandle(T, library.ptr());
5476#endif // defined(DART_PRECOMPILED_RUNTIME)
5477}
5478
5480 Thread* thread = Thread::Current();
5481 Isolate* isolate = thread->isolate();
5482 CHECK_ISOLATE(isolate);
5483 TransitionNativeToVM transition(thread);
5484 return Api::NewHandle(thread,
5485 isolate->group()->object_store()->root_library());
5486}
5487
5490 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(library));
5491 if (obj.IsNull() || obj.IsLibrary()) {
5492 Library& lib = Library::Handle(Z);
5493 lib ^= obj.ptr();
5494 T->isolate_group()->object_store()->set_root_library(lib);
5495 return library;
5496 }
5497 RETURN_TYPE_ERROR(Z, library, Library);
5498}
5499
5503 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5504 if (lib.IsNull()) {
5505 RETURN_TYPE_ERROR(Z, library, Library);
5506 }
5507 const String& cls_name = Api::UnwrapStringHandle(Z, class_name);
5508 if (cls_name.IsNull()) {
5510 }
5511 const Class& cls = Class::Handle(Z, lib.LookupClassAllowPrivate(cls_name));
5512 if (cls.IsNull()) {
5513 // TODO(turnidge): Return null or error in this case?
5514 const String& lib_name = String::Handle(Z, lib.name());
5515 return Api::NewError("Class '%s' not found in library '%s'.",
5516 cls_name.ToCString(), lib_name.ToCString());
5517 }
5520 return Api::NewHandle(T, cls.RareType());
5521}
5522
5525 intptr_t number_of_type_arguments,
5526 Dart_Handle* type_arguments,
5527 Nullability nullability) {
5529 // Validate the input arguments.
5530 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5531 if (lib.IsNull()) {
5532 RETURN_TYPE_ERROR(Z, library, Library);
5533 }
5534 if (!lib.Loaded()) {
5535 return Api::NewError("%s expects library argument 'library' to be loaded.",
5536 CURRENT_FUNC);
5537 }
5538 const String& name_str = Api::UnwrapStringHandle(Z, class_name);
5539 if (name_str.IsNull()) {
5541 }
5542 const Class& cls = Class::Handle(Z, lib.LookupClassAllowPrivate(name_str));
5543 if (cls.IsNull()) {
5544 const String& lib_name = String::Handle(Z, lib.name());
5545 return Api::NewError("Type '%s' not found in library '%s'.",
5546 name_str.ToCString(), lib_name.ToCString());
5547 }
5550
5551 Type& type = Type::Handle();
5552 if (cls.NumTypeArguments() == 0) {
5553 if (number_of_type_arguments != 0) {
5554 return Api::NewError(
5555 "Invalid number of type arguments specified, "
5556 "got %" Pd " expected 0",
5557 number_of_type_arguments);
5558 }
5560 type ^= type.ToNullability(nullability, Heap::kOld);
5561 } else {
5562 intptr_t num_expected_type_arguments = cls.NumTypeParameters();
5563 TypeArguments& type_args_obj = TypeArguments::Handle();
5564 if (number_of_type_arguments > 0) {
5565 if (type_arguments == nullptr) {
5566 RETURN_NULL_ERROR(type_arguments);
5567 }
5568 if (num_expected_type_arguments != number_of_type_arguments) {
5569 return Api::NewError(
5570 "Invalid number of type arguments specified, "
5571 "got %" Pd " expected %" Pd,
5572 number_of_type_arguments, num_expected_type_arguments);
5573 }
5574 const Array& array = Api::UnwrapArrayHandle(Z, *type_arguments);
5575 if (array.IsNull()) {
5576 RETURN_TYPE_ERROR(Z, *type_arguments, Array);
5577 }
5578 if (array.Length() != num_expected_type_arguments) {
5579 return Api::NewError(
5580 "Invalid type arguments specified, expected an "
5581 "array of len %" Pd " but got an array of len %" Pd,
5582 number_of_type_arguments, array.Length());
5583 }
5584 // Set up the type arguments array.
5585 type_args_obj = TypeArguments::New(num_expected_type_arguments);
5586 AbstractType& type_arg = AbstractType::Handle();
5587 for (intptr_t i = 0; i < number_of_type_arguments; i++) {
5588 type_arg ^= array.At(i);
5589 type_args_obj.SetTypeAt(i, type_arg);
5590 }
5591 }
5592
5593 // Construct the type object, canonicalize it and return.
5594 type ^= Type::New(cls, type_args_obj, nullability);
5595 }
5597 return Api::NewHandle(T, type.ptr());
5598}
5599
5602 intptr_t number_of_type_arguments,
5603 Dart_Handle* type_arguments) {
5604 return Api::NewError(
5605 "Cannot use legacy types with --sound-null-safety enabled. "
5606 "Use Dart_GetNullableType or Dart_GetNonNullableType instead.");
5607}
5608
5611 intptr_t number_of_type_arguments,
5612 Dart_Handle* type_arguments) {
5613 return GetTypeCommon(library, class_name, number_of_type_arguments,
5614 type_arguments, Nullability::kNullable);
5615}
5616
5620 intptr_t number_of_type_arguments,
5621 Dart_Handle* type_arguments) {
5622 return GetTypeCommon(library, class_name, number_of_type_arguments,
5623 type_arguments, Nullability::kNonNullable);
5624}
5625
5628 const Type& ty = Api::UnwrapTypeHandle(Z, type);
5629 if (ty.IsNull()) {
5631 }
5632 if (ty.nullability() == nullability) {
5633 return type;
5634 }
5635 return Api::NewHandle(T, ty.ToNullability(nullability, Heap::kOld));
5636}
5637
5641
5645
5647 Nullability nullability,
5648 bool* result) {
5650 const Type& ty = Api::UnwrapTypeHandle(Z, type);
5651 if (ty.IsNull()) {
5652 *result = false;
5654 }
5655 *result = (ty.nullability() == nullability);
5656 return Api::Success();
5657}
5658
5662
5666
5670
5673 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5674 if (lib.IsNull()) {
5675 RETURN_TYPE_ERROR(Z, library, Library);
5676 }
5677 const String& url = String::Handle(Z, lib.url());
5678 ASSERT(!url.IsNull());
5679 return Api::NewHandle(T, url.ptr());
5680}
5681
5684 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5685 if (lib.IsNull()) {
5686 RETURN_TYPE_ERROR(Z, library, Library);
5687 }
5688 const Class& toplevel = Class::Handle(lib.toplevel_class());
5689 ASSERT(!toplevel.IsNull());
5690 const Script& script = Script::Handle(toplevel.script());
5691 ASSERT(!script.IsNull());
5692 const String& url = String::Handle(script.resolved_url());
5693 ASSERT(!url.IsNull());
5694 return Api::NewHandle(T, url.ptr());
5695}
5696
5699 auto IG = T->isolate_group();
5700
5701 const GrowableObjectArray& libs =
5702 GrowableObjectArray::Handle(Z, IG->object_store()->libraries());
5703 int num_libs = libs.Length();
5704
5705 // Create new list and populate with the loaded libraries.
5706 Library& lib = Library::Handle();
5707 const Array& library_list = Array::Handle(Z, Array::New(num_libs));
5708 for (int i = 0; i < num_libs; i++) {
5709 lib ^= libs.At(i);
5710 ASSERT(!lib.IsNull());
5711 library_list.SetAt(i, lib);
5712 }
5713 return Api::NewHandle(T, library_list.ptr());
5714}
5715
5718 const String& url_str = Api::UnwrapStringHandle(Z, url);
5719 if (url_str.IsNull()) {
5720 RETURN_TYPE_ERROR(Z, url, String);
5721 }
5722 const Library& library =
5724 if (library.IsNull()) {
5725 return Api::NewError("%s: library '%s' not found.", CURRENT_FUNC,
5726 url_str.ToCString());
5727 } else {
5728 return Api::NewHandle(T, library.ptr());
5729 }
5730}
5731
5733 Dart_Handle error_in) {
5735
5736 const Library& lib = Api::UnwrapLibraryHandle(Z, library_in);
5737 if (lib.IsNull()) {
5738 RETURN_TYPE_ERROR(Z, library_in, Library);
5739 }
5740 const Instance& err = Api::UnwrapInstanceHandle(Z, error_in);
5741 if (err.IsNull()) {
5742 RETURN_TYPE_ERROR(Z, error_in, Instance);
5743 }
5745
5746 return error_in;
5747}
5748
5749#if !defined(DART_PRECOMPILED_RUNTIME)
5751 const char* error = nullptr;
5752 std::unique_ptr<kernel::Program> program =
5753 kernel::Program::ReadFromTypedData(td, &error);
5754 if (program == nullptr) {
5755 return Api::NewError("Can't load Kernel binary: %s.", error);
5756 }
5757 const Object& result =
5758 kernel::KernelLoader::LoadEntireProgram(program.get(), false);
5759 program.reset();
5760
5762 source->add_loaded_blob(Z, td);
5763
5764 return Api::NewHandle(T, result.ptr());
5765}
5766#endif // !defined(DART_PRECOMPILED_RUNTIME)
5767
5769 intptr_t buffer_size) {
5770#if defined(DART_PRECOMPILED_RUNTIME)
5771 return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
5772#else
5775 StackZone zone(T);
5776
5778
5779 // NOTE: We do not attach a finalizer for this object, because the embedder
5780 // will/should free it once the isolate group has shutdown.
5782 kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
5784 return LoadLibrary(T, td);
5785#endif // defined(DART_PRECOMPILED_RUNTIME)
5786}
5787
5789#if defined(DART_PRECOMPILED_RUNTIME)
5790 return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
5791#else
5793 const ExternalTypedData& td =
5794 Api::UnwrapExternalTypedDataHandle(Z, kernel_buffer);
5795 if (td.IsNull()) {
5796 RETURN_TYPE_ERROR(Z, kernel_buffer, ExternalTypedData);
5797 }
5798 return LoadLibrary(T, td);
5799#endif // defined(DART_PRECOMPILED_RUNTIME)
5800}
5801
5802// Finalizes classes and invokes Dart core library function that completes
5803// futures of loadLibrary calls (deferred library loading).
5807 Isolate* I = T->isolate();
5809
5810 // Finalize all classes if needed.
5812 if (Api::IsError(state)) {
5813 return state;
5814 }
5815
5816#if !defined(PRODUCT)
5817 // Now that the newly loaded classes are finalized, notify the debugger
5818 // that new code has been loaded. If there are latent breakpoints in
5819 // the new code, the debugger convert them to unresolved source breakpoints.
5820 // The code that completes the futures (invoked below) may call into the
5821 // newly loaded code and trigger one of these breakpoints.
5822 I->debugger()->NotifyDoneLoading();
5823#endif
5824
5825 // After having loaded all the code, we can let the GC set reasonable limits
5826 // for the heap growth.
5827 // If this is an auxiliary isolate inside a larger isolate group, we will not
5828 // re-initialize the growth policy.
5829 if (I->group()->ContainsOnlyOneIsolate()) {
5830 I->group()->heap()->old_space()->EvaluateAfterLoading();
5831 }
5832
5833#if !defined(DART_PRECOMPILED_RUNTIME)
5834 if (FLAG_enable_mirrors) {
5835 // Notify mirrors that MirrorSystem.libraries needs to be recomputed.
5836 const Library& libmirrors = Library::Handle(Z, Library::MirrorsLibrary());
5837 const Field& dirty_bit =
5839 String::Handle(String::New("_dirty"))));
5840 ASSERT(!dirty_bit.IsNull() && dirty_bit.is_static());
5841 dirty_bit.SetStaticValue(Bool::True());
5842 }
5843#endif
5844
5845 return Api::Success();
5846}
5847
5848static Dart_Handle DeferredLoadComplete(intptr_t loading_unit_id,
5849 bool error,
5850 const uint8_t* snapshot_data,
5851 const uint8_t* snapshot_instructions,
5852 const char* error_message,
5853 bool transient_error) {
5856 auto IG = T->isolate_group();
5858
5859 const Array& loading_units =
5860 Array::Handle(IG->object_store()->loading_units());
5861 if (loading_units.IsNull() || (loading_unit_id < LoadingUnit::kRootId) ||
5862 (loading_unit_id >= loading_units.Length())) {
5863 return Api::NewError("Invalid loading unit");
5864 }
5866 unit ^= loading_units.At(loading_unit_id);
5867 if (unit.loaded()) {
5868 return Api::NewError("Unit already loaded");
5869 }
5870
5871 if (error) {
5872 CHECK_NULL(error_message);
5873 return Api::NewHandle(
5874 T, unit.CompleteLoad(String::Handle(String::New(error_message)),
5875 transient_error));
5876 } else {
5877#if defined(SUPPORT_TIMELINE)
5878 TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
5879 "ReadUnitSnapshot");
5880#endif // defined(SUPPORT_TIMELINE)
5881 const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
5882 if (snapshot == nullptr) {
5883 return Api::NewError("Invalid snapshot");
5884 }
5885 if (!IsSnapshotCompatible(Dart::vm_snapshot_kind(), snapshot->kind())) {
5887 "Incompatible snapshot kinds: vm '%s', isolate '%s'",
5889 Snapshot::KindToCString(snapshot->kind())));
5890 return Api::NewHandle(T, ApiError::New(message));
5891 }
5892
5893 FullSnapshotReader reader(snapshot, snapshot_instructions, T);
5894 const Error& error = Error::Handle(reader.ReadUnitSnapshot(unit));
5895 if (!error.IsNull()) {
5896 return Api::NewHandle(T, error.ptr());
5897 }
5898
5899 return Api::NewHandle(T, unit.CompleteLoad(String::Handle(), false));
5900 }
5901}
5902
5904Dart_DeferredLoadComplete(intptr_t loading_unit_id,
5905 const uint8_t* snapshot_data,
5906 const uint8_t* snapshot_instructions) {
5907 return DeferredLoadComplete(loading_unit_id, false, snapshot_data,
5908 snapshot_instructions, nullptr, false);
5909}
5910
5912Dart_DeferredLoadCompleteError(intptr_t loading_unit_id,
5913 const char* error_message,
5914 bool transient) {
5915 return DeferredLoadComplete(loading_unit_id, true, nullptr, nullptr,
5916 error_message, transient);
5917}
5918
5921 Dart_NativeEntryResolver resolver,
5922 Dart_NativeEntrySymbol symbol) {
5924 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5925 if (lib.IsNull()) {
5926 RETURN_TYPE_ERROR(Z, library, Library);
5927 }
5928 lib.set_native_entry_resolver(resolver);
5930 return Api::Success();
5931}
5932
5935 Dart_NativeEntryResolver* resolver) {
5936 if (resolver == nullptr) {
5937 RETURN_NULL_ERROR(resolver);
5938 }
5939 *resolver = nullptr;
5941 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5942 if (lib.IsNull()) {
5943 RETURN_TYPE_ERROR(Z, library, Library);
5944 }
5945 *resolver = lib.native_entry_resolver();
5946 return Api::Success();
5947}
5948
5950 Dart_NativeEntrySymbol* resolver) {
5951 if (resolver == nullptr) {
5952 RETURN_NULL_ERROR(resolver);
5953 }
5954 *resolver = nullptr;
5956 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5957 if (lib.IsNull()) {
5958 RETURN_TYPE_ERROR(Z, library, Library);
5959 }
5960 *resolver = lib.native_entry_symbol_resolver();
5961 return Api::Success();
5962}
5963
5966 Dart_FfiNativeResolver resolver) {
5968 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5969 if (lib.IsNull()) {
5970 RETURN_TYPE_ERROR(Z, library, Library);
5971 }
5972 lib.set_ffi_native_resolver(resolver);
5973 return Api::Success();
5974}
5975
5976// --- Peer support ---
5977
5979 if (peer == nullptr) {
5980 RETURN_NULL_ERROR(peer);
5981 }
5982 Thread* thread = Thread::Current();
5983 CHECK_ISOLATE(thread->isolate());
5984 TransitionNativeToVM transition(thread);
5986 Object& obj = thread->ObjectHandle();
5987 obj = Api::UnwrapHandle(object);
5988 if (obj.IsNull() || obj.IsNumber() || obj.IsBool()) {
5989 const char* msg =
5990 "%s: argument 'object' cannot be a subtype of Null, num, or bool";
5991 return Api::NewError(msg, CURRENT_FUNC);
5992 }
5993 {
5994 NoSafepointScope no_safepoint;
5995 ObjectPtr raw_obj = obj.ptr();
5996 *peer = thread->heap()->GetPeer(raw_obj);
5997 }
5998 return Api::Success();
5999}
6000
6002 Thread* thread = Thread::Current();
6003 CHECK_ISOLATE(thread->isolate());
6004 TransitionNativeToVM transition(thread);
6006 Object& obj = thread->ObjectHandle();
6007 obj = Api::UnwrapHandle(object);
6008 if (obj.IsNull() || obj.IsNumber() || obj.IsBool()) {
6009 const char* msg =
6010 "%s: argument 'object' cannot be a subtype of Null, num, or bool";
6011 return Api::NewError(msg, CURRENT_FUNC);
6012 }
6013 {
6014 NoSafepointScope no_safepoint;
6015 ObjectPtr raw_obj = obj.ptr();
6016 thread->heap()->SetPeer(raw_obj, peer);
6017 }
6018 return Api::Success();
6019}
6020
6021// --- Dart Front-End (Kernel) support ---
6022
6024#if defined(DART_PRECOMPILED_RUNTIME)
6025 return false;
6026#else
6027 Isolate* iso = reinterpret_cast<Isolate*>(isolate);
6028 return iso->is_kernel_isolate();
6029#endif
6030}
6031
6033#if defined(DART_PRECOMPILED_RUNTIME)
6034 return false;
6035#else
6036 return KernelIsolate::IsRunning();
6037#endif
6038}
6039
6041#if defined(DART_PRECOMPILED_RUNTIME)
6042 return false;
6043#else
6045#endif
6046}
6047
6049Dart_CompileToKernel(const char* script_uri,
6050 const uint8_t* platform_kernel,
6051 intptr_t platform_kernel_size,
6052 bool incremental_compile,
6053 bool for_snapshot,
6054 bool embed_sources,
6055 const char* package_config,
6058
6060#if defined(DART_PRECOMPILED_RUNTIME)
6062 result.error = Utils::StrDup("Dart_CompileToKernel is unsupported.");
6063#else
6065 script_uri, platform_kernel, platform_kernel_size, 0, nullptr,
6066 incremental_compile, for_snapshot, embed_sources, package_config, nullptr,
6067 nullptr, verbosity);
6068 if (incremental_compile) {
6069 Dart_KernelCompilationResult ack_result =
6073 if (ack_result.status != Dart_KernelCompilationStatus_Ok) {
6074 FATAL(
6075 "An error occurred in the CFE while acking the most recent"
6076 " compilation results: %s",
6077 ack_result.error);
6078 }
6079 }
6080#endif
6081 return result;
6082}
6083
6086#if defined(DART_PRECOMPILED_RUNTIME)
6088 result.error = Utils::StrDup("Dart_KernelListDependencies is unsupported.");
6089#else
6091#endif
6092 return result;
6093}
6094
6096 const uint8_t* platform_kernel,
6097 const intptr_t platform_kernel_size) {
6098#if !defined(PRODUCT)
6100 platform_kernel_size);
6101#endif
6102}
6103
6104DART_EXPORT bool Dart_DetectNullSafety(const char* script_uri,
6105 const char* package_config,
6106 const char* original_working_directory,
6107 const uint8_t* snapshot_data,
6108 const uint8_t* snapshot_instructions,
6109 const uint8_t* kernel_buffer,
6110 intptr_t kernel_buffer_size) {
6111 return true;
6112}
6113
6114// --- Service support ---
6115
6117 Isolate* iso = reinterpret_cast<Isolate*>(isolate);
6118 return iso->is_service_isolate();
6119}
6120
6129
6138
6145
6147 Dart_ServiceStreamListenCallback listen_callback,
6148 Dart_ServiceStreamCancelCallback cancel_callback) {
6149#if defined(PRODUCT)
6150 return nullptr;
6151#else
6152 if (listen_callback != nullptr) {
6153 if (Service::stream_listen_callback() != nullptr) {
6154 return Utils::StrDup(
6155 "Dart_SetServiceStreamCallbacks "
6156 "permits only one listen callback to be registered, please "
6157 "remove the existing callback and then add this callback");
6158 }
6159 } else {
6160 if (Service::stream_listen_callback() == nullptr) {
6161 return Utils::StrDup(
6162 "Dart_SetServiceStreamCallbacks "
6163 "expects 'listen_callback' to be present in the callback set.");
6164 }
6165 }
6166 if (cancel_callback != nullptr) {
6167 if (Service::stream_cancel_callback() != nullptr) {
6168 return Utils::StrDup(
6169 "Dart_SetServiceStreamCallbacks "
6170 "permits only one cancel callback to be registered, please "
6171 "remove the existing callback and then add this callback");
6172 }
6173 } else {
6174 if (Service::stream_cancel_callback() == nullptr) {
6175 return Utils::StrDup(
6176 "Dart_SetServiceStreamCallbacks "
6177 "expects 'cancel_callback' to be present in the callback set.");
6178 }
6179 }
6180 Service::SetEmbedderStreamCallbacks(listen_callback, cancel_callback);
6181 return nullptr;
6182#endif
6183}
6184
6185DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
6186 const char* event_kind,
6187 const uint8_t* bytes,
6188 intptr_t bytes_length) {
6189#if !defined(PRODUCT)
6190 if (stream_id == nullptr) {
6191 return Utils::StrDup(
6192 "Dart_ServiceSendDataEvent expects argument 'stream_id' to be "
6193 "non-null.");
6194 }
6195 if (event_kind == nullptr) {
6196 return Utils::StrDup(
6197 "Dart_ServiceSendDataEvent expects argument 'event_kind' to be "
6198 "non-null.");
6199 }
6200 if (bytes == nullptr) {
6201 return Utils::StrDup(
6202 "Dart_ServiceSendDataEvent expects argument 'bytes' to be non-null.");
6203 }
6204 if (bytes_length < 0) {
6205 return Utils::StrDup(
6206 "Dart_ServiceSendDataEvent expects argument 'bytes_length' to be >= "
6207 "0.");
6208 }
6209 Service::SendEmbedderEvent(Isolate::Current(), // May be nullptr
6210 stream_id, event_kind, bytes, bytes_length);
6211#endif
6212 return nullptr;
6213}
6214
6219
6221 Dart_FileModifiedCallback file_modified_callback) {
6222#if !defined(PRODUCT)
6223#if !defined(DART_PRECOMPILED_RUNTIME)
6224 if (file_modified_callback != nullptr) {
6226 return Utils::StrDup(
6227 "Dart_SetFileModifiedCallback permits only one callback to be"
6228 " registered, please remove the existing callback and then add"
6229 " this callback");
6230 }
6231 } else {
6233 return Utils::StrDup(
6234 "Dart_SetFileModifiedCallback expects 'file_modified_callback' to"
6235 " be set before it is cleared.");
6236 }
6237 }
6239#endif // !defined(DART_PRECOMPILED_RUNTIME)
6240#endif // !defined(PRODUCT)
6241 return nullptr;
6242}
6243
6245#if defined(PRODUCT) || defined(DART_PRECOMPILED_RUNTIME)
6246 return false;
6247#else
6248 Thread* thread = Thread::Current();
6249 Isolate* isolate = thread->isolate();
6250 CHECK_ISOLATE(isolate);
6251 return isolate->group()->IsReloading();
6252#endif
6253}
6254
6255DART_EXPORT bool Dart_SetEnabledTimelineCategory(const char* categories) {
6256#if defined(SUPPORT_TIMELINE)
6257 bool result = false;
6258 if (categories != nullptr) {
6259 char* carray = Utils::SCreate("[%s]", categories);
6261 free(carray);
6262 }
6263 return result;
6264#else
6265 return false;
6266#endif
6267}
6268
6272
6276
6280
6282 int64_t timestamp0,
6283 int64_t timestamp1_or_id,
6284 intptr_t flow_id_count,
6285 const int64_t* flow_ids,
6287 intptr_t argument_count,
6288 const char** argument_names,
6289 const char** argument_values) {
6290#if defined(SUPPORT_TIMELINE)
6292 return;
6293 }
6295 return;
6296 }
6297 if (!Dart::SetActiveApiCall()) {
6298 return;
6299 }
6300 TimelineStream* stream = Timeline::GetEmbedderStream();
6301 ASSERT(stream != nullptr);
6302 TimelineEvent* event = stream->StartEvent();
6303 if (event != nullptr) {
6304 switch (type) {
6306 event->Begin(label, timestamp1_or_id, timestamp0);
6307 break;
6309 event->End(label, timestamp1_or_id, timestamp0);
6310 break;
6312 event->Instant(label, timestamp0);
6313 break;
6315 event->Duration(label, timestamp0, timestamp1_or_id);
6316 break;
6318 event->AsyncBegin(label, timestamp1_or_id, timestamp0);
6319 break;
6321 event->AsyncEnd(label, timestamp1_or_id, timestamp0);
6322 break;
6324 event->AsyncInstant(label, timestamp1_or_id, timestamp0);
6325 break;
6327 event->Counter(label, timestamp0);
6328 break;
6330 event->FlowBegin(label, timestamp1_or_id, timestamp0);
6331 break;
6333 event->FlowStep(label, timestamp1_or_id, timestamp0);
6334 break;
6336 event->FlowEnd(label, timestamp1_or_id, timestamp0);
6337 break;
6338 default:
6339 FATAL("Unknown Dart_Timeline_Event_Type");
6340 }
6341 if (flow_id_count > 0 && flow_ids != nullptr) {
6342 std::unique_ptr<const int64_t[]> flow_ids_copy;
6343 int64_t* flow_ids_internal = new int64_t[flow_id_count];
6344 for (intptr_t i = 0; i < flow_id_count; ++i) {
6345 flow_ids_internal[i] = flow_ids[i];
6346 }
6347 flow_ids_copy = std::unique_ptr<const int64_t[]>(flow_ids_internal);
6348 event->SetFlowIds(flow_id_count, flow_ids_copy);
6349 }
6350 event->SetNumArguments(argument_count);
6351 for (intptr_t i = 0; i < argument_count; i++) {
6352 event->CopyArgument(i, argument_names[i], argument_values[i]);
6353 }
6354 event->Complete();
6355 }
6357#endif
6358}
6359
6362#if defined(SUPPORT_TIMELINE)
6363 Timeline::set_callback(callback);
6364#endif
6365}
6366
6368 OSThread* thread = OSThread::Current();
6369 if (thread == nullptr) {
6370 // VM is shutting down.
6371 return;
6372 }
6373 thread->SetName(name);
6374}
6375
6377#if defined(DART_PRECOMPILED_RUNTIME)
6378 return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
6379#else
6381
6382 // Prevent background compiler from running while code is being cleared and
6383 // adding new code.
6384 NoBackgroundCompilerScope no_bg_compiler(T);
6385
6386 // We don't have mechanisms to change class-ids that are embedded in code and
6387 // ICData.
6389 // Make sure that ICData etc. that have been cleared are also removed from
6390 // the heap so that they are not found by the heap verifier.
6393 return Api::Success();
6394#endif // defined(DART_PRECOMPILED_RUNTIME)
6395}
6396
6398#if defined(TARGET_ARCH_IA32)
6399 return Api::NewError("AOT compilation is not supported on IA32.");
6400#elif !defined(DART_PRECOMPILER)
6401 return Api::NewError(
6402 "This VM was built without support for AOT compilation.");
6403#else
6406 if (!FLAG_precompiled_mode) {
6407 return Api::NewError("Flag --precompilation was not specified.");
6408 }
6410 if (Api::IsError(result)) {
6411 return result;
6412 }
6414 CompilerState state(Thread::Current(), /*is_aot=*/true,
6415 /*is_optimizing=*/true);
6417 return Api::Success();
6418#endif
6419}
6420
6421// Used for StreamingWriteStream/BlobImageWriter sizes for ELF and blobs.
6422#if !defined(TARGET_ARCH_IA32) && defined(DART_PRECOMPILER)
6423static constexpr intptr_t kAssemblyInitialSize = 512 * KB;
6424static constexpr intptr_t kInitialSize = 2 * MB;
6425static constexpr intptr_t kInitialDebugSize = 1 * MB;
6426
6427static void CreateAppAOTSnapshot(
6429 void* callback_data,
6430 bool strip,
6431 bool as_elf,
6432 void* debug_callback_data,
6433 GrowableArray<LoadingUnitSerializationData*>* units,
6434 LoadingUnitSerializationData* unit,
6435 uint32_t program_hash) {
6436 Thread* T = Thread::Current();
6437
6438 NOT_IN_PRODUCT(TimelineBeginEndScope tbes2(T, Timeline::GetIsolateStream(),
6439 "WriteAppAOTSnapshot"));
6440
6441 ZoneWriteStream vm_snapshot_data(T->zone(), FullSnapshotWriter::kInitialSize);
6442 ZoneWriteStream vm_snapshot_instructions(T->zone(), kInitialSize);
6443 ZoneWriteStream isolate_snapshot_data(T->zone(),
6445 ZoneWriteStream isolate_snapshot_instructions(T->zone(), kInitialSize);
6446
6447 const bool generate_debug = debug_callback_data != nullptr;
6448
6449 auto* const deobfuscation_trie =
6450 (strip && !generate_debug) ? nullptr
6451 : ImageWriter::CreateReverseObfuscationTrie(T);
6452
6453 if (as_elf) {
6454 StreamingWriteStream elf_stream(kInitialSize, callback, callback_data);
6455 StreamingWriteStream debug_stream(generate_debug ? kInitialDebugSize : 0,
6456 callback, debug_callback_data);
6457
6458 auto const dwarf = strip ? nullptr : new (Z) Dwarf(Z, deobfuscation_trie);
6459 auto const elf = new (Z) Elf(Z, &elf_stream, Elf::Type::Snapshot, dwarf);
6460 // Re-use the same DWARF object if the snapshot is unstripped.
6461 auto const debug_elf =
6462 generate_debug
6463 ? new (Z) Elf(Z, &debug_stream, Elf::Type::DebugInfo,
6464 strip ? new (Z) Dwarf(Z, deobfuscation_trie) : dwarf)
6465 : nullptr;
6466
6467 BlobImageWriter image_writer(T, &vm_snapshot_instructions,
6468 &isolate_snapshot_instructions,
6469 deobfuscation_trie, debug_elf, elf);
6470 FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data,
6471 &isolate_snapshot_data, &image_writer,
6472 &image_writer);
6473
6474 if (unit == nullptr || unit->id() == LoadingUnit::kRootId) {
6475 writer.WriteFullSnapshot(units);
6476 } else {
6477 writer.WriteUnitSnapshot(units, unit, program_hash);
6478 }
6479
6480 elf->Finalize();
6481 if (debug_elf != nullptr) {
6482 debug_elf->Finalize();
6483 }
6484 } else {
6485 StreamingWriteStream assembly_stream(kAssemblyInitialSize, callback,
6486 callback_data);
6487 StreamingWriteStream debug_stream(generate_debug ? kInitialDebugSize : 0,
6488 callback, debug_callback_data);
6489
6490 auto const elf = generate_debug
6491 ? new (Z) Elf(Z, &debug_stream, Elf::Type::DebugInfo,
6492 new (Z) Dwarf(Z, deobfuscation_trie))
6493 : nullptr;
6494
6495 AssemblyImageWriter image_writer(T, &assembly_stream, deobfuscation_trie,
6496 strip, elf);
6497 FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data,
6498 &isolate_snapshot_data, &image_writer,
6499 &image_writer);
6500
6501 if (unit == nullptr || unit->id() == LoadingUnit::kRootId) {
6502 writer.WriteFullSnapshot(units);
6503 } else {
6504 writer.WriteUnitSnapshot(units, unit, program_hash);
6505 }
6506 image_writer.Finalize();
6507 }
6508}
6509
6510static void Split(Dart_CreateLoadingUnitCallback next_callback,
6511 void* next_callback_data,
6512 bool strip,
6513 bool as_elf,
6514 Dart_StreamingWriteCallback write_callback,
6515 Dart_StreamingCloseCallback close_callback) {
6516 Thread* T = Thread::Current();
6517 ProgramVisitor::AssignUnits(T);
6518
6519 const Array& loading_units =
6520 Array::Handle(T->isolate_group()->object_store()->loading_units());
6521 const uint32_t program_hash = ProgramVisitor::Hash(T);
6522 loading_units.SetAt(0, Smi::Handle(Z, Smi::New(program_hash)));
6523 GrowableArray<LoadingUnitSerializationData*> data;
6524 data.SetLength(loading_units.Length());
6525 data[0] = nullptr;
6526
6527 LoadingUnit& loading_unit = LoadingUnit::Handle();
6528 LoadingUnit& parent = LoadingUnit::Handle();
6529 for (intptr_t id = 1; id < loading_units.Length(); id++) {
6530 loading_unit ^= loading_units.At(id);
6531 parent = loading_unit.parent();
6532 LoadingUnitSerializationData* parent_data =
6533 parent.IsNull() ? nullptr : data[parent.id()];
6534 data[id] = new LoadingUnitSerializationData(id, parent_data);
6535 }
6536
6537 for (intptr_t id = 1; id < loading_units.Length(); id++) {
6538 void* write_callback_data = nullptr;
6539 void* write_debug_callback_data = nullptr;
6540 {
6541 TransitionVMToNative transition(T);
6542 next_callback(next_callback_data, id, &write_callback_data,
6543 &write_debug_callback_data);
6544 }
6545 CreateAppAOTSnapshot(write_callback, write_callback_data, strip, as_elf,
6546 write_debug_callback_data, &data, data[id],
6547 program_hash);
6548 {
6549 TransitionVMToNative transition(T);
6550 close_callback(write_callback_data);
6551 if (write_debug_callback_data != nullptr) {
6552 close_callback(write_debug_callback_data);
6553 }
6554 }
6555 }
6556}
6557#endif
6558
6561 void* callback_data,
6562 bool strip,
6563 void* debug_callback_data) {
6564#if defined(TARGET_ARCH_IA32)
6565 return Api::NewError("AOT compilation is not supported on IA32.");
6566#elif defined(DART_TARGET_OS_WINDOWS)
6567 return Api::NewError("Assembly generation is not implemented for Windows.");
6568#elif !defined(DART_PRECOMPILER)
6569 return Api::NewError(
6570 "This VM was built without support for AOT compilation.");
6571#else
6575
6576 // Mark as not split.
6577 T->isolate_group()->object_store()->set_loading_units(Object::null_array());
6578
6579 CreateAppAOTSnapshot(callback, callback_data, strip, /*as_elf*/ false,
6580 debug_callback_data, nullptr, nullptr, 0);
6581
6582 return Api::Success();
6583#endif
6584}
6585
6587 Dart_CreateLoadingUnitCallback next_callback,
6588 void* next_callback_data,
6589 bool strip,
6590 Dart_StreamingWriteCallback write_callback,
6591 Dart_StreamingCloseCallback close_callback) {
6592#if defined(TARGET_ARCH_IA32)
6593 return Api::NewError("AOT compilation is not supported on IA32.");
6594#elif defined(DART_TARGET_OS_WINDOWS)
6595 return Api::NewError("Assembly generation is not implemented for Windows.");
6596#elif !defined(DART_PRECOMPILER)
6597 return Api::NewError(
6598 "This VM was built without support for AOT compilation.");
6599#else
6602 CHECK_NULL(next_callback);
6603 CHECK_NULL(write_callback);
6604 CHECK_NULL(close_callback);
6605
6606 Split(next_callback, next_callback_data, strip, /*as_elf*/ false,
6607 write_callback, close_callback);
6608
6609 return Api::Success();
6610#endif
6611}
6612
6615 void* callback_data) {
6616#if defined(TARGET_ARCH_IA32)
6617 return Api::NewError("AOT compilation is not supported on IA32.");
6618#elif defined(DART_TARGET_OS_WINDOWS)
6619 return Api::NewError("Assembly generation is not implemented for Windows.");
6620#elif !defined(DART_PRECOMPILER)
6621 return Api::NewError(
6622 "This VM was built without support for AOT compilation.");
6623#else
6627
6628 TIMELINE_DURATION(T, Isolate, "WriteVMAOTSnapshot");
6629 StreamingWriteStream assembly_stream(kAssemblyInitialSize, callback,
6630 callback_data);
6631 AssemblyImageWriter image_writer(T, &assembly_stream);
6632 ZoneWriteStream vm_snapshot_data(T->zone(), FullSnapshotWriter::kInitialSize);
6633 FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data, nullptr,
6634 &image_writer, nullptr);
6635
6636 writer.WriteFullSnapshot();
6637
6638 return Api::Success();
6639#endif
6640}
6641
6644 void* callback_data,
6645 bool strip,
6646 void* debug_callback_data) {
6647#if defined(TARGET_ARCH_IA32)
6648 return Api::NewError("AOT compilation is not supported on IA32.");
6649#elif !defined(DART_PRECOMPILER)
6650 return Api::NewError(
6651 "This VM was built without support for AOT compilation.");
6652#else
6656
6657 // Mark as not split.
6658 T->isolate_group()->object_store()->set_loading_units(Object::null_array());
6659
6660 CreateAppAOTSnapshot(callback, callback_data, strip, /*as_elf*/ true,
6661 debug_callback_data, nullptr, nullptr, 0);
6662
6663 return Api::Success();
6664#endif
6665}
6666
6669 void* next_callback_data,
6670 bool strip,
6671 Dart_StreamingWriteCallback write_callback,
6672 Dart_StreamingCloseCallback close_callback) {
6673#if defined(TARGET_ARCH_IA32)
6674 return Api::NewError("AOT compilation is not supported on IA32.");
6675#elif !defined(DART_PRECOMPILER)
6676 return Api::NewError(
6677 "This VM was built without support for AOT compilation.");
6678#else
6681 CHECK_NULL(next_callback);
6682 CHECK_NULL(write_callback);
6683 CHECK_NULL(close_callback);
6684
6685 Split(next_callback, next_callback_data, strip, /*as_elf*/ true,
6686 write_callback, close_callback);
6687
6688 return Api::Success();
6689#endif
6690}
6691
6693#if defined(TARGET_ARCH_IA32)
6694 return Api::NewError("AOT compilation is not supported on IA32.");
6695#elif !defined(DART_PRECOMPILER)
6696 return Api::NewError(
6697 "This VM was built without support for AOT compilation.");
6698#else
6701
6702 const Array& loading_units =
6703 Array::Handle(Z, T->isolate_group()->object_store()->loading_unit_uris());
6704 if (loading_unit_id >= 0 && loading_unit_id < loading_units.Length()) {
6705 return Api::NewHandle(T, loading_units.At(loading_unit_id));
6706 }
6707 return Api::NewError("Invalid loading_unit_id");
6708#endif
6709}
6710
6711#if (!defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME))
6712
6713// Any flag that affects how we compile code might cause a problem when the
6714// snapshot writer generates code with one value of the flag and the snapshot
6715// reader expects code to behave according to another value of the flag.
6716// Normally, we add these flags to Dart::FeaturesString and refuse to run the
6717// snapshot it they don't match, but since --interpret-irregexp affects only
6718// 2 functions we choose to remove the code instead. See issue #34422.
6719static void DropRegExpMatchCode(Zone* zone) {
6720 const String& execute_match_name =
6721 String::Handle(zone, String::New("_ExecuteMatch"));
6722 const String& execute_match_sticky_name =
6723 String::Handle(zone, String::New("_ExecuteMatchSticky"));
6724
6725 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
6726 const Class& reg_exp_class =
6727 Class::Handle(zone, core_lib.LookupClassAllowPrivate(Symbols::_RegExp()));
6728 ASSERT(!reg_exp_class.IsNull());
6729
6730 auto thread = Thread::Current();
6731 Function& func = Function::Handle(
6732 zone, reg_exp_class.LookupFunctionAllowPrivate(execute_match_name));
6733 ASSERT(!func.IsNull());
6734 Code& code = Code::Handle(zone);
6735 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
6736 if (func.HasCode()) {
6737 code = func.CurrentCode();
6738 ASSERT(!code.IsNull());
6739 code.DisableDartCode();
6740 }
6741 func.ClearCode();
6742 func.ClearICDataArray();
6743 ASSERT(!func.HasCode());
6744
6745 func = reg_exp_class.LookupFunctionAllowPrivate(execute_match_sticky_name);
6746 ASSERT(!func.IsNull());
6747 if (func.HasCode()) {
6748 code = func.CurrentCode();
6749 ASSERT(!code.IsNull());
6750 code.DisableDartCode();
6751 }
6752 func.ClearCode();
6753 func.ClearICDataArray();
6754 ASSERT(!func.HasCode());
6755}
6756
6757#endif // (!defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME))
6758
6759#if !defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
6760static void KillNonMainIsolatesSlow(Thread* thread, Isolate* main_isolate) {
6761 auto group = main_isolate->group();
6762 while (true) {
6763 bool non_main_isolates_alive = false;
6764 {
6765 DeoptSafepointOperationScope safepoint(thread);
6766 group->ForEachIsolate(
6767 [&](Isolate* isolate) {
6768 if (isolate != main_isolate) {
6770 non_main_isolates_alive = true;
6771 }
6772 },
6773 /*at_safepoint=*/true);
6774 if (!non_main_isolates_alive) {
6775 break;
6776 }
6777 }
6778 OS::SleepMicros(10 * 1000);
6779 }
6780}
6781#endif // !defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
6782
6784Dart_CreateAppJITSnapshotAsBlobs(uint8_t** isolate_snapshot_data_buffer,
6785 intptr_t* isolate_snapshot_data_size,
6786 uint8_t** isolate_snapshot_instructions_buffer,
6787 intptr_t* isolate_snapshot_instructions_size) {
6788#if defined(TARGET_ARCH_IA32)
6789 return Api::NewError("Snapshots with code are not supported on IA32.");
6790#elif defined(DART_PRECOMPILED_RUNTIME)
6791 return Api::NewError("JIT app snapshots cannot be taken from an AOT runtime");
6792#else
6795 auto I = T->isolate();
6796 auto IG = T->isolate_group();
6797 CHECK_NULL(isolate_snapshot_data_buffer);
6798 CHECK_NULL(isolate_snapshot_data_size);
6799 CHECK_NULL(isolate_snapshot_instructions_buffer);
6800 CHECK_NULL(isolate_snapshot_instructions_size);
6801
6802 // Finalize all classes if needed.
6804 if (Api::IsError(state)) {
6805 return state;
6806 }
6807
6808 // Kill off any auxiliary isolates before starting with deduping.
6810
6811 NoBackgroundCompilerScope no_bg_compiler(T);
6813
6815
6816 if (FLAG_dump_tables) {
6821 }
6822
6823 TIMELINE_DURATION(T, Isolate, "WriteAppJITSnapshot");
6824 ZoneWriteStream isolate_snapshot_data(Api::TopScope(T)->zone(),
6826 ZoneWriteStream isolate_snapshot_instructions(
6828 BlobImageWriter image_writer(T, /*vm_instructions=*/nullptr,
6829 &isolate_snapshot_instructions);
6830 FullSnapshotWriter writer(Snapshot::kFullJIT, nullptr, &isolate_snapshot_data,
6831 nullptr, &image_writer);
6832 writer.WriteFullSnapshot();
6833
6834 *isolate_snapshot_data_buffer = isolate_snapshot_data.buffer();
6835 *isolate_snapshot_data_size = isolate_snapshot_data.bytes_written();
6836 *isolate_snapshot_instructions_buffer =
6837 isolate_snapshot_instructions.buffer();
6838 *isolate_snapshot_instructions_size =
6839 isolate_snapshot_instructions.bytes_written();
6840
6841 return Api::Success();
6842#endif
6843}
6844
6846 intptr_t* buffer_length) {
6847#if defined(DART_PRECOMPILED_RUNTIME)
6848 return Api::NewError("No obfuscation map to save on an AOT runtime.");
6849#elif !defined(DART_PRECOMPILER)
6850 return Api::NewError("Obfuscation is only supported for AOT compiler.");
6851#else
6852 Thread* thread = Thread::Current();
6853 DARTSCOPE(thread);
6854 auto isolate_group = thread->isolate_group();
6855
6856 if (buffer == nullptr) {
6858 }
6859 if (buffer_length == nullptr) {
6860 RETURN_NULL_ERROR(buffer_length);
6861 }
6862
6863 // Note: can't use JSONStream in PRODUCT builds.
6864 const intptr_t kInitialBufferSize = 1 * MB;
6865 ZoneTextBuffer text_buffer(Api::TopScope(T)->zone(), kInitialBufferSize);
6866
6867 text_buffer.AddChar('[');
6868 if (isolate_group->obfuscation_map() != nullptr) {
6869 for (intptr_t i = 0; isolate_group->obfuscation_map()[i] != nullptr; i++) {
6870 if (i > 0) {
6871 text_buffer.AddChar(',');
6872 }
6873 text_buffer.AddChar('"');
6874 text_buffer.AddEscapedString(isolate_group->obfuscation_map()[i]);
6875 text_buffer.AddChar('"');
6876 }
6877 }
6878 text_buffer.AddChar(']');
6879
6880 *buffer_length = text_buffer.length();
6881 *reinterpret_cast<char**>(buffer) = text_buffer.buffer();
6882 return Api::Success();
6883#endif
6884}
6885
6887#if defined(DART_PRECOMPILED_RUNTIME)
6888 return true;
6889#else
6890 return false;
6891#endif
6892}
6893
6894DART_EXPORT void Dart_DumpNativeStackTrace(void* context) {
6895#if !defined(PRODUCT) || defined(DART_PRECOMPILER)
6896 Profiler::DumpStackTrace(context);
6897#endif
6898}
6899
6902}
6903
6905 Thread* thread = Thread::Current();
6906 CHECK_ISOLATE(thread->isolate());
6907 DARTSCOPE(thread);
6908 Isolate* isolate = thread->isolate();
6909 return Api::NewHandle(thread, isolate->current_tag());
6910}
6911
6913 Thread* thread = Thread::Current();
6914 CHECK_ISOLATE(thread->isolate());
6915 DARTSCOPE(thread);
6916 Isolate* isolate = thread->isolate();
6917 return Api::NewHandle(thread, isolate->default_tag());
6918}
6919
6921 Thread* thread = Thread::Current();
6922 CHECK_ISOLATE(thread->isolate());
6923 DARTSCOPE(thread);
6924 if (label == nullptr) {
6925 return Api::NewError(
6926 "Dart_NewUserTag expects argument 'label' to be non-null");
6927 }
6928 const String& value = String::Handle(String::New(label));
6929 return Api::NewHandle(thread, UserTag::New(value));
6930}
6931
6933 Thread* thread = Thread::Current();
6934 CHECK_ISOLATE(thread->isolate());
6935 DARTSCOPE(thread);
6936 const UserTag& tag = Api::UnwrapUserTagHandle(Z, user_tag);
6937 if (tag.IsNull()) {
6938 RETURN_TYPE_ERROR(Z, user_tag, UserTag);
6939 }
6940 return Api::NewHandle(thread, tag.MakeActive());
6941}
6942
6945 const UserTag& tag = Api::UnwrapUserTagHandle(Z, user_tag);
6946 if (tag.IsNull()) {
6947 return nullptr;
6948 }
6949 const String& label = String::Handle(Z, tag.label());
6950 return Utils::StrDup(label.ToCString());
6951}
6952
6955 void* context) {
6956#if defined(DART_ENABLE_HEAP_SNAPSHOT_WRITER)
6958 CallbackHeapSnapshotWriter callback_writer(T, write, context);
6959 HeapSnapshotWriter writer(T, &callback_writer);
6960 writer.Write();
6961 return nullptr;
6962#else
6963 return Utils::StrDup("VM is built without the heap snapshot writer.");
6964#endif
6965}
6966
6967} // namespace dart
int count
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
SI void store(P *ptr, const T &val)
SI F table(const skcms_Curve *curve, F v)
#define IG
#define UNREACHABLE()
Definition assert.h:248
#define Z
#define CLASS_LIST_FOR_HANDLES(V)
Definition class_id.h:193
bool IsFinalized() const
Definition object.h:9030
Nullability nullability() const
Definition object.h:9037
virtual ClassPtr type_class() const
Definition object.cc:21083
AcquiredData(void *data, intptr_t size_in_bytes, bool copy)
void * GetData() const
LocalHandles * local_handles()
ApiLocalScope * previous() const
static ApiNativeScope * Current()
bool IsActivePersistentHandle(Dart_PersistentHandle object)
bool IsValidWeakPersistentHandle(Dart_WeakPersistentHandle object)
bool IsActiveWeakPersistentHandle(Dart_WeakPersistentHandle object)
static Dart_Handle Success()
static void SetDoubleReturnValue(NativeArguments *args, double retval)
static bool IsInstance(Dart_Handle handle)
static Dart_Handle NewHandle(Thread *thread, ObjectPtr raw)
static void SetReturnValue(NativeArguments *args, Dart_Handle retval)
static bool GetNativeFieldsOfArgument(NativeArguments *args, int arg_index, int num_fields, intptr_t *field_values)
static Dart_Isolate CastIsolate(Isolate *isolate)
static ApiLocalScope * TopScope(Thread *thread)
static ObjectPtr UnwrapHandle(Dart_Handle object)
static bool GetNativeBooleanArgument(NativeArguments *args, int arg_index, bool *value)
static StringPtr GetEnvironmentValue(Thread *thread, const String &name)
static Dart_Handle False()
static intptr_t ClassId(Dart_Handle handle)
static Dart_Handle static Dart_Handle NewArgumentError(const char *format,...) PRINTF_ATTRIBUTE(1
static Dart_IsolateGroup CastIsolateGroup(IsolateGroup *isolate_group)
static bool StringGetPeerHelper(NativeArguments *args, int arg_index, void **peer)
static void Init()
static Dart_Handle static Dart_Handle static Dart_Handle Null()
static void InitHandles()
static bool GetNativeDoubleArgument(NativeArguments *args, int arg_index, double *value)
static const Instance & UnwrapInstanceHandle(const ReusableObjectHandleScope &reused, Dart_Handle object)
static bool IsFfiEnabled()
static Dart_Handle EmptyString()
static bool IsProtectedHandle(Dart_Handle object)
static bool GetNativeIntegerArgument(NativeArguments *args, int arg_index, int64_t *value)
static const String & UnwrapStringHandle(const ReusableObjectHandleScope &reused, Dart_Handle object)
static void SetWeakHandleReturnValue(NativeArguments *args, Dart_WeakPersistentHandle retval)
static void SetSmiReturnValue(NativeArguments *args, intptr_t retval)
static Dart_Handle True()
static bool IsValid(Dart_Handle handle)
static intptr_t SmiValue(Dart_Handle handle)
static bool GetNativeReceiver(NativeArguments *args, intptr_t *value)
static bool IsSmi(Dart_Handle handle)
static void Cleanup()
static void SetIntegerReturnValue(NativeArguments *args, int64_t retval)
static bool IsError(Dart_Handle handle)
static Dart_Handle NewError(const char *format,...) PRINTF_ATTRIBUTE(1
static Dart_Handle CheckAndFinalizePendingClasses(Thread *thread)
static ArrayPtr NewBoxed(intptr_t type_args_len, intptr_t num_arguments, const Array &optional_arguments_names, Heap::Space space=Heap::kOld)
Definition dart_entry.h:83
static constexpr intptr_t kMaxElements
Definition object.h:10898
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
virtual void SetTypeArguments(const TypeArguments &value) const
Definition object.h:10882
ObjectPtr At(intptr_t index) const
Definition object.h:10854
intptr_t Length() const
Definition object.h:10808
void SetAt(intptr_t index, const Object &value) const
Definition object.h:10858
char * buffer() const
Definition text_buffer.h:35
intptr_t length() const
Definition text_buffer.h:36
void AddEscapedString(const char *s)
void AddChar(char ch)
static const Bool & False()
Definition object.h:10778
static const Bool & Get(bool value)
Definition object.h:10780
static const Bool & True()
Definition object.h:10776
bool value() const
Definition object.h:10770
static InstancePtr Data(const Instance &view_obj)
Definition object.h:11837
static AbstractTypePtr FinalizeType(const AbstractType &type, FinalizationKind finalization=kCanonicalize)
static bool ProcessPendingClasses()
static bool AllClassesFinalized()
static void ClearAllCode(bool including_nonchanging_cids=false)
ClassPtr At(intptr_t cid) const
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition object.cc:6222
ObjectPtr InvokeSetter(const String &selector, const Instance &argument, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition object.cc:4632
LibraryPtr library() const
Definition object.h:1335
ObjectPtr Invoke(const String &selector, const Array &arguments, const Array &argument_names, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition object.cc:4739
ObjectPtr InvokeGetter(const String &selector, bool throw_nsm_if_absent, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition object.cc:4572
intptr_t id() const
Definition object.h:1235
void set_is_fields_marked_nullable() const
Definition object.cc:5750
intptr_t NumTypeArguments() const
Definition object.cc:3690
TypePtr RareType() const
Definition object.cc:3097
ArrayPtr fields() const
Definition object.h:1617
static bool IsSubtypeOf(const Class &cls, const TypeArguments &type_arguments, Nullability nullability, const AbstractType &other, Heap::Space space, FunctionTypeMapping *function_type_equivalence=nullptr)
Definition object.cc:5975
uint16_t num_native_fields() const
Definition object.h:1790
bool IsDynamicClass() const
Definition object.h:1558
StringPtr Name() const
Definition object.cc:3038
FunctionPtr LookupStaticFunctionAllowPrivate(const String &name) const
Definition object.cc:6198
ErrorPtr EnsureIsFinalized(Thread *thread) const
Definition object.cc:4979
bool IsVoidClass() const
Definition object.h:1561
bool is_future_subtype() const
Definition object.h:2172
ErrorPtr EnsureIsAllocateFinalized(Thread *thread) const
Definition object.cc:5009
bool is_fields_marked_nullable() const
Definition object.h:1778
ClassPtr SuperClass(ClassTable *class_table=nullptr) const
Definition object.cc:3715
StringPtr UserVisibleName() const
Definition object.cc:3050
bool IsTopLevel() const
Definition object.cc:6176
bool IsNeverClass() const
Definition object.h:1564
bool is_allocated() const
Definition object.h:1783
DART_WARN_UNUSED_RESULT ErrorPtr VerifyEntryPoint() const
Definition object.cc:27446
intptr_t NumTypeParameters(Thread *thread) const
Definition object.cc:3605
bool is_finalized() const
Definition object.h:1725
ScriptPtr script() const
Definition object.h:1274
void EnsureDeclarationLoaded() const
Definition object.cc:4968
static ObjectPtr InvokeClosure(Thread *thread, const Array &arguments)
static ObjectPtr InvokeFunction(const Function &function, const Array &arguments)
Definition dart_entry.cc:31
static ObjectPtr InstanceCreate(const Library &library, const String &exception_name, const String &constructor_name, const Array &arguments)
static ObjectPtr Equals(const Instance &left, const Instance &right)
static ObjectPtr ToString(const Instance &receiver)
static ErrorPtr InitializeIsolateGroup(Thread *T, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions, const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
Definition dart.cc:908
static bool IsReadOnlyHandle(uword address)
Definition dart.cc:1139
static char * Cleanup()
Definition dart.cc:629
static void ShutdownIsolate(Thread *T)
Definition dart.cc:1115
static bool SetActiveApiCall()
Definition dart.cc:803
static Isolate * vm_isolate()
Definition dart.h:68
static char * Init(const Dart_InitializeParams *params)
Definition dart.cc:526
static Isolate * CreateIsolate(const char *name_prefix, const Dart_IsolateFlags &api_flags, IsolateGroup *isolate_group)
Definition dart.cc:811
static bool IsReadOnlyApiHandle(Dart_Handle handle)
Definition dart.cc:1144
static void ResetActiveApiCall()
Definition dart.cc:807
static Snapshot::Kind vm_snapshot_kind()
Definition dart.h:95
static void RunShutdownCallback()
Definition dart.cc:1102
static LocalHandle * AllocateReadOnlyApiHandle()
Definition dart.cc:1133
static ErrorPtr InitializeIsolate(Thread *T, bool is_first_isolate_in_group, void *isolate_data)
Definition dart.cc:944
static void set_dwarf_stacktrace_footnote_callback(Dart_DwarfStackTraceFootnoteCallback cb)
Definition dart.h:139
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
Definition object.cc:23481
double value() const
Definition object.h:10094
static DART_NORETURN void Throw(Thread *thread, const Instance &exception)
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
static DART_NORETURN void ReThrow(Thread *thread, const Instance &exception, const Instance &stacktrace, bool bypass_debugger=false)
static DART_NORETURN void PropagateError(const Error &error)
static ExternalTypedDataPtr New(intptr_t class_id, uint8_t *data, intptr_t len, Heap::Space space=Heap::kNew, bool perform_eager_msan_initialization_check=true)
Definition object.cc:25705
static bool IsExternalTypedData(const Instance &obj)
Definition object.h:11732
static intptr_t MaxElements(intptr_t class_id)
Definition object.h:11718
bool is_static() const
Definition object.h:4418
void SetStaticValue(const Object &value) const
Definition object.cc:12818
void RecordStore(const Object &value) const
Definition object.cc:13074
static FinalizablePersistentHandle * New(IsolateGroup *isolate_group, const Object &object, void *peer, Dart_HandleFinalizer callback, intptr_t external_size, bool auto_delete)
Dart_HandleFinalizer callback() const
Dart_FinalizableHandle ApiFinalizableHandle()
Dart_WeakPersistentHandle ApiWeakPersistentHandle()
static FinalizablePersistentHandle * Cast(Dart_WeakPersistentHandle handle)
static char * ProcessCommandLineFlags(int argc, const char **argv)
Definition flags.cc:433
static bool IsSet(const char *name)
Definition flags.cc:179
ApiErrorPtr ReadUnitSnapshot(const LoadingUnit &unit)
intptr_t VmIsolateSnapshotSize() const
void WriteFullSnapshot(GrowableArray< LoadingUnitSerializationData * > *data=nullptr)
intptr_t IsolateSnapshotSize() const
static constexpr intptr_t kInitialSize
CodePtr CurrentCode() const
Definition object.h:3157
StringPtr UserVisibleName() const
Definition object.cc:11057
ObjectPtr DoArgumentTypesMatch(const Array &args, const ArgumentsDescriptor &arg_names) const
Definition object.cc:9563
bool IsImplicitClosureFunction() const
Definition object.h:3883
bool HasCode() const
Definition object.cc:7994
FunctionPtr parent_function() const
Definition object.cc:8225
bool AreValidArgumentCounts(intptr_t num_type_arguments, intptr_t num_arguments, intptr_t num_named_arguments, String *error_message) const
Definition object.cc:9308
DART_WARN_UNUSED_RESULT ErrorPtr VerifyCallEntryPoint() const
Definition object.cc:27386
FunctionPtr ImplicitClosureFunction() const
Definition object.cc:10443
bool IsNonImplicitClosureFunction() const
Definition object.h:3891
bool IsFactory() const
Definition object.h:3347
void ClearCode() const
Definition object.cc:8006
bool IsGenerativeConstructor() const
Definition object.h:3343
ClassPtr Owner() const
Definition object.cc:10899
UntaggedFunction::Kind kind() const
Definition object.h:3329
ClosurePtr ImplicitStaticClosure() const
Definition object.cc:10758
void ClearICDataArray() const
Definition object.cc:11334
void IterateObjects(ObjectVisitor *visitor) const
Definition heap.cc:334
static void SetSamplingCallback(Dart_HeapSamplingCreateCallback create_callback, Dart_HeapSamplingDeleteCallback delete_callback)
Definition sampler.cc:81
static void SetSamplingInterval(intptr_t bytes_interval)
Definition sampler.cc:60
static void Enable(bool enabled)
Definition sampler.cc:47
@ kNew
Definition heap.h:38
@ kOld
Definition heap.h:39
void * GetPeer(ObjectPtr raw_obj) const
Definition heap.h:167
void SetPeer(ObjectPtr raw_obj, void *peer)
Definition heap.h:164
void CollectAllGarbage(GCReason reason=GCReason::kFull, bool compact=false)
Definition heap.cc:562
Space SpaceForExternal(intptr_t size) const
Definition heap.cc:1130
bool IsCallable(Function *function) const
Definition object.cc:20954
virtual void SetTypeArguments(const TypeArguments &value) const
Definition object.cc:20622
static InstancePtr New(const Class &cls, Heap::Space space=Heap::kNew)
Definition object.cc:20976
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition object.cc:23063
const char * ToHexCString(Zone *zone) const
Definition object.cc:23179
virtual bool IsNegative() const
Definition object.cc:23125
static IntegerPtr NewFromUint64(uint64_t value, Heap::Space space=Heap::kNew)
Definition object.cc:23105
virtual int64_t AsInt64Value() const
Definition object.cc:23137
static bool IsValueInRange(uint64_t value)
Definition object.cc:23109
static Dart_FileModifiedCallback file_modified_callback()
static void SetFileModifiedCallback(Dart_FileModifiedCallback callback)
const char ** obfuscation_map() const
Definition isolate.h:408
void * embedder_data() const
Definition isolate.h:290
Heap * heap() const
Definition isolate.h:295
ObjectStore * object_store() const
Definition isolate.h:505
SafepointRwLock * program_lock()
Definition isolate.h:532
static IsolateGroup * Current()
Definition isolate.h:534
ClassTable * class_table() const
Definition isolate.h:491
uint64_t id() const
Definition isolate.h:673
ApiState * api_state() const
Definition isolate.h:693
void set_library_tag_handler(Dart_LibraryTagHandler handler)
Definition isolate.h:553
bool IsReloading() const
Definition isolate.h:662
static void RegisterIsolateGroup(IsolateGroup *isolate_group)
Definition isolate.cc:698
static void ForEach(std::function< void(IsolateGroup *)> action)
Definition isolate.cc:677
void set_deferred_load_handler(Dart_DeferredLoadHandler handler)
Definition isolate.h:559
IsolateGroupSource * source() const
Definition isolate.h:989
bool HasLivePorts()
Definition isolate.cc:3706
Thread * scheduled_mutator_thread() const
Definition isolate.h:945
Dart_EnvironmentCallback environment_callback() const
Definition isolate.h:1028
ErrorPtr sticky_error() const
Definition isolate.h:1310
UserTagPtr current_tag() const
Definition isolate.h:1301
static Isolate * Current()
Definition isolate.h:939
void set_on_shutdown_callback(Dart_IsolateShutdownCallback value)
Definition isolate.h:972
static void KillIfExists(Isolate *isolate, LibMsgId msg_id)
Definition isolate.cc:3660
UserTagPtr default_tag() const
Definition isolate.h:1304
MessageHandler * message_handler() const
Definition isolate.cc:2380
static void FlagsInitialize(Dart_IsolateFlags *api_flags)
Definition isolate.cc:1612
void set_on_cleanup_callback(Dart_IsolateCleanupCallback value)
Definition isolate.h:978
bool HasPendingMessages()
Definition isolate.cc:1320
void * init_callback_data() const
Definition isolate.h:1021
void set_environment_callback(Dart_EnvironmentCallback value)
Definition isolate.h:1031
IsolateGroup * group() const
Definition isolate.h:990
void set_init_callback_data(void *value)
Definition isolate.h:1020
Dart_MessageNotifyCallback message_notify_callback() const
Definition isolate.h:964
bool AllowClassFinalization()
Definition isolate.h:1248
void set_origin_id(Dart_Port id)
Definition isolate.cc:1959
bool IsScheduled()
Definition isolate.h:944
bool is_runnable() const
Definition isolate.h:1048
void set_message_notify_callback(Dart_MessageNotifyCallback value)
Definition isolate.h:968
Dart_Port main_port() const
Definition isolate.h:1001
void SetStickyError(ErrorPtr sticky_error)
Definition isolate.cc:2368
const char * name() const
Definition isolate.h:996
static Dart_KernelCompilationResult ListDependencies()
static Dart_KernelCompilationResult CompileToKernel(const char *script_uri, const uint8_t *platform_kernel, intptr_t platform_kernel_size, int source_files_count=0, Dart_SourceFile source_files[]=nullptr, bool incremental_compile=true, bool for_snapshot=false, bool embed_sources=true, const char *package_config=nullptr, const char *multiroot_filepaths=nullptr, const char *multiroot_scheme=nullptr, Dart_KernelCompilationVerbosityLevel verbosity=Dart_KernelCompilationVerbosityLevel_All)
static bool IsRunning()
static Dart_KernelCompilationResult RejectCompilation()
static Dart_KernelCompilationResult AcceptCompilation()
static Dart_Port KernelPort()
static LibraryPtr CoreLibrary()
Definition object.cc:14834
StringPtr PrivateName(const String &name) const
Definition object.cc:14751
void set_native_entry_symbol_resolver(Dart_NativeEntrySymbol native_symbol_resolver) const
Definition object.h:5213
static LibraryPtr MirrorsLibrary()
Definition object.cc:14863
bool Loaded() const
Definition object.h:5082
static bool IsPrivate(const String &name)
Definition object.cc:14666
ObjectPtr InvokeGetter(const String &selector, bool throw_nsm_if_absent, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition object.cc:14389
void set_native_entry_resolver(Dart_NativeEntryResolver value) const
Definition object.h:5204
ObjectPtr InvokeSetter(const String &selector, const Instance &argument, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition object.cc:14457
void set_ffi_native_resolver(Dart_FfiNativeResolver value) const
Definition object.h:5225
ClassPtr LookupClassAllowPrivate(const String &name) const
Definition object.cc:14160
ObjectPtr Invoke(const String &selector, const Array &arguments, const Array &argument_names, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition object.cc:14520
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition object.cc:14131
ClassPtr toplevel_class() const
Definition object.h:5179
StringPtr name() const
Definition object.h:5065
Dart_NativeEntrySymbol native_entry_symbol_resolver() const
Definition object.h:5209
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition object.cc:14646
Dart_NativeEntryResolver native_entry_resolver() const
Definition object.h:5200
FieldPtr LookupFieldAllowPrivate(const String &name) const
Definition object.cc:14122
StringPtr url() const
Definition object.h:5068
bool loaded() const
Definition object.h:7961
ObjectPtr CompleteLoad(const String &error_message, bool transient_error) const
Definition object.cc:19763
static constexpr intptr_t kRootId
Definition object.h:7940
void set_ptr(ObjectPtr ptr)
static intptr_t ptr_offset()
Dart_Handle apiHandle()
void PausedOnStart(bool paused)
void PausedOnExit(bool paused)
bool is_paused_on_start() const
void set_should_pause_on_start(bool should_pause_on_start)
void set_should_pause_on_exit(bool should_pause_on_exit)
bool is_paused_on_exit() const
bool should_pause_on_start() const
bool should_pause_on_exit() const
@ kNormalPriority
Definition message.h:28
Monitor::WaitResult Wait(int64_t millis=Monitor::kNoTimeout)
Definition lockers.h:172
Thread * thread() const
void SetReturn(const Object &value) const
ObjectPtr NativeArgAt(int index) const
ObjectPtr NativeArg0() const
static void AddSymbols(const char *dso_name, void *buffer, size_t size)
void DisableThreadInterrupts()
Definition os_thread.cc:143
void SetName(const char *name)
Definition os_thread.cc:115
static ThreadId GetCurrentThreadId()
static ThreadLocalKey CreateThreadLocal(ThreadDestructor destructor=nullptr)
static OSThread * Current()
Definition os_thread.h:175
void EnableThreadInterrupts()
Definition os_thread.cc:148
static intptr_t ThreadIdToIntPtr(ThreadId id)
static void SleepMicros(int64_t micros)
static int64_t GetCurrentMonotonicMicros()
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static char static char * VSCreate(Zone *zone, const char *format, va_list args)
static void PrepareToAbort()
static int64_t GetCurrentMonotonicFrequency()
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2
static int64_t GetCurrentMonotonicTicks()
UntaggedObject * untag() const
uword heap_base() const
intptr_t GetClassId() const
Definition raw_object.h:864
intptr_t GetClassIdMayBeSmi() const
bool IsImmutable() const
Definition object.h:338
static ObjectPtr null()
Definition object.h:433
intptr_t GetClassId() const
Definition object.h:341
ObjectPtr ptr() const
Definition object.h:332
void SetImmutable() const
Definition object.h:339
virtual const char * ToCString() const
Definition object.h:366
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
ClassPtr clazz() const
Definition object.h:13192
Monitor * tasks_lock() const
Definition pages.h:309
Phase phase() const
Definition pages.h:336
static void ClearCache()
Definition page.cc:36
Dart_PersistentHandle apiHandle()
static intptr_t ptr_offset()
void set_ptr(ObjectPtr ref)
static PersistentHandle * Cast(Dart_PersistentHandle handle)
ObjectPtr ptr() const
static Dart_Port GetOriginId(Dart_Port id)
Definition port.cc:196
static bool PostMessage(std::unique_ptr< Message > message, bool before_events=false)
Definition port.cc:152
static ErrorPtr CompileAll()
static void DumpStackTrace(void *context)
Definition profiler.cc:409
static void Cleanup()
Definition profiler.cc:599
static void Init()
Definition profiler.cc:567
static void Dedup(Thread *thread)
static SendPortPtr New(Dart_Port id, Heap::Space space=Heap::kNew)
Definition object.cc:25891
Dart_Port Id() const
Definition object.h:12464
static void SendEmbedderEvent(Isolate *isolate, const char *stream_id, const char *event_kind, const uint8_t *bytes, intptr_t bytes_len)
Definition service.cc:4838
static void SetDartLibraryKernelForSources(const uint8_t *kernel_bytes, intptr_t kernel_length)
Definition service.cc:1481
static void SetEmbedderStreamCallbacks(Dart_ServiceStreamListenCallback listen_callback, Dart_ServiceStreamCancelCallback cancel_callback)
Definition service.cc:1434
static void RegisterRootEmbedderCallback(const char *name, Dart_ServiceRequestCallback callback, void *user_data)
Definition service.cc:1411
static void RegisterIsolateEmbedderCallback(const char *name, Dart_ServiceRequestCallback callback, void *user_data)
Definition service.cc:1376
static Dart_ServiceStreamCancelCallback stream_cancel_callback()
Definition service.h:198
static Dart_ServiceStreamListenCallback stream_listen_callback()
Definition service.h:195
static void SetEmbedderInformationCallback(Dart_EmbedderInformationCallback callback)
Definition service.cc:1446
static bool EnableTimelineStreams(char *categories_list)
static SmiPtr New(intptr_t value)
Definition object.h:9985
intptr_t Value() const
Definition object.h:9969
static bool IsValid(int64_t value)
Definition object.h:10005
Kind kind() const
Definition snapshot.h:60
static const Snapshot * SetupFromBuffer(const void *raw_memory)
Definition snapshot.cc:30
static const char * KindToCString(Kind kind)
Definition snapshot.cc:12
static constexpr intptr_t kMaxElements
Definition object.h:10152
static StringPtr NewFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition object.cc:24083
bool IsOneByteString() const
Definition object.h:10290
intptr_t Length() const
Definition object.h:10189
static StringPtr ConcatAll(const Array &strings, Heap::Space space=Heap::kNew)
Definition object.cc:24127
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
intptr_t CharSize() const
Definition object.cc:23601
void ToUTF8(uint8_t *utf8_array, intptr_t array_len) const
Definition object.cc:24225
uint16_t CharAt(intptr_t index) const
Definition object.h:10238
static StringPtr SubString(const String &str, intptr_t begin_index, Heap::Space space=Heap::kNew)
Definition object.cc:24159
static StringPtr Concat(const String &str1, const String &str2, Heap::Space space=Heap::kNew)
Definition object.cc:24116
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition object.cc:24205
static StringPtr FromUTF16(const uint16_t *utf16_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition object.cc:23818
static StringPtr FromUTF32(const int32_t *utf32_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition object.cc:23834
static StringPtr FromUTF8(const uint8_t *utf8_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition object.cc:23784
static const String & True()
Definition symbols.h:692
static const String & False()
Definition symbols.h:688
static const String & Empty()
Definition symbols.h:687
static const String & Dot()
Definition symbols.h:612
static void DumpTable(IsolateGroup *isolate_group)
Definition symbols.cc:496
Zone * zone() const
void UnwindScopes(uword stack_marker)
Definition thread.cc:1262
ApiLocalScope * api_top_scope() const
Definition thread.h:512
static Thread * Current()
Definition thread.h:361
bool IsValidHandle(Dart_Handle object) const
Definition thread.cc:1199
Heap * heap() const
Definition thread.cc:876
void EnterApiScope()
Definition thread.cc:1235
void ExitApiScope()
Definition thread.cc:1248
static void ExitIsolateGroupAsHelper(bool bypass_safepoint)
Definition thread.cc:494
uword top_exit_frame_info() const
Definition thread.h:678
bool IsDartMutatorThread() const
Definition thread.h:546
ExecutionState execution_state() const
Definition thread.h:1027
Isolate * isolate() const
Definition thread.h:533
@ kThreadInNative
Definition thread.h:1023
IsolateGroup * isolate_group() const
Definition thread.h:540
static void EnterIsolate(Isolate *isolate)
Definition thread.cc:366
static void ExitIsolate(bool isolate_shutdown=false)
Definition thread.cc:423
ErrorPtr sticky_error() const
Definition thread.cc:230
static bool EnterIsolateGroupAsHelper(IsolateGroup *isolate_group, TaskKind kind, bool bypass_safepoint)
Definition thread.cc:476
void SetTypeAt(intptr_t index, const AbstractType &value) const
Definition object.cc:7381
static TypeArgumentsPtr New(intptr_t len, Heap::Space space=Heap::kOld)
Definition object.cc:7733
TypeArgumentsPtr GetInstanceTypeArguments(Thread *thread, bool canonicalize=true) const
Definition object.cc:22480
static TypePtr VoidType()
Definition object.cc:21870
TypePtr ToNullability(Nullability value, Heap::Space space) const
Definition object.cc:21971
static TypePtr New(const Class &clazz, const TypeArguments &arguments, Nullability nullability=Nullability::kLegacy, Heap::Space space=Heap::kOld)
Definition object.cc:22492
static TypePtr NeverType()
Definition object.cc:21874
static TypePtr DynamicType()
Definition object.cc:21866
virtual ClassPtr type_class() const
Definition object.cc:22028
static TypePtr NewNonParameterizedType(const Class &type_class)
Definition object.cc:21946
intptr_t Length() const
Definition object.h:11492
intptr_t ElementSizeInBytes() const
Definition object.h:11505
void * DataAddr(intptr_t byte_offset) const
Definition object.h:11545
static TypedDataViewPtr New(intptr_t class_id, Heap::Space space=Heap::kNew)
Definition object.cc:25737
static bool IsTypedData(const Instance &obj)
Definition object.h:11677
static intptr_t MaxElements(intptr_t class_id)
Definition object.h:11658
static TypedDataPtr New(intptr_t class_id, intptr_t len, Heap::Space space=Heap::kNew)
Definition object.cc:25666
static UnhandledExceptionPtr New(const Instance &exception, const Instance &stacktrace, Heap::Space space=Heap::kNew)
Definition object.cc:19989
static uword ToAddr(const UntaggedObject *raw_obj)
Definition raw_object.h:501
bool InVMIsolateHeap() const
Definition raw_object.cc:20
static UserTagPtr New(const String &label, Heap::Space space=Heap::kOld)
Definition object.cc:27028
UserTagPtr MakeActive() const
Definition object.cc:27007
StringPtr label() const
Definition object.h:13142
static intptr_t Length(int32_t ch)
Definition unicode.cc:98
static bool IsValid(const uint8_t *utf8_array, intptr_t array_len)
Definition unicode.cc:70
static char * StrDup(const char *s)
static bool RangeCheck(intptr_t offset, intptr_t count, intptr_t length)
Definition utils.h:396
static char * SCreate(const char *format,...) PRINTF_ATTRIBUTE(1
Definition utils.cc:231
static const char * String()
Definition version_in.cc:11
static void ClearCache()
Definition zone.cc:69
void * AllocUnsafe(intptr_t size)
ElementType * Alloc(intptr_t length)
static Object & LoadEntireProgram(Program *program, bool process_pending_classes=true)
Dart_CoreType_Id
Definition dart_api.h:2423
@ Dart_CoreType_Dynamic
Definition dart_api.h:2424
@ Dart_CoreType_Int
Definition dart_api.h:2425
@ Dart_CoreType_String
Definition dart_api.h:2426
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
Definition dart_api.h:839
Dart_Handle(* Dart_EnvironmentCallback)(Dart_Handle name)
Definition dart_api.h:3269
void(* Dart_StreamingWriteCallback)(void *callback_data, const uint8_t *buffer, intptr_t size)
Definition dart_api.h:3878
@ Dart_KernelCompilationStatus_Unknown
Definition dart_api.h:3727
@ Dart_KernelCompilationStatus_Ok
Definition dart_api.h:3728
#define ILLEGAL_PORT
Definition dart_api.h:1530
void(* Dart_IsolateCleanupCallback)(void *isolate_group_data, void *isolate_data)
Definition dart_api.h:728
Dart_PerformanceMode
Definition dart_api.h:1368
int64_t Dart_Port
Definition dart_api.h:1524
void(* Dart_MessageNotifyCallback)(Dart_Isolate destination_isolate)
Definition dart_api.h:1541
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
struct _Dart_Isolate * Dart_Isolate
Definition dart_api.h:88
Dart_NativeFunction(* Dart_NativeEntryResolver)(Dart_Handle name, int num_of_arguments, bool *auto_setup_scope)
Definition dart_api.h:3225
void(* Dart_StreamingCloseCallback)(void *callback_data)
Definition dart_api.h:3881
void(* Dart_HandleFinalizer)(void *isolate_callback_data, void *peer)
Definition dart_api.h:265
struct _Dart_IsolateGroup * Dart_IsolateGroup
Definition dart_api.h:89
const uint8_t *(* Dart_NativeEntrySymbol)(Dart_NativeFunction nf)
Definition dart_api.h:3246
void *(* Dart_FfiNativeResolver)(const char *name, uintptr_t args_n)
Definition dart_api.h:3253
struct _Dart_NativeArguments * Dart_NativeArguments
Definition dart_api.h:3010
Dart_TypedData_Type
Definition dart_api.h:2603
@ Dart_TypedData_kFloat32x4
Definition dart_api.h:2617
@ Dart_TypedData_kInt32x4
Definition dart_api.h:2616
@ Dart_TypedData_kUint8
Definition dart_api.h:2606
@ Dart_TypedData_kUint32
Definition dart_api.h:2611
@ Dart_TypedData_kInt32
Definition dart_api.h:2610
@ Dart_TypedData_kUint16
Definition dart_api.h:2609
@ Dart_TypedData_kFloat64x2
Definition dart_api.h:2618
@ Dart_TypedData_kUint64
Definition dart_api.h:2613
@ Dart_TypedData_kFloat32
Definition dart_api.h:2614
@ Dart_TypedData_kInt16
Definition dart_api.h:2608
@ Dart_TypedData_kFloat64
Definition dart_api.h:2615
@ Dart_TypedData_kUint8Clamped
Definition dart_api.h:2607
@ Dart_TypedData_kByteData
Definition dart_api.h:2604
@ Dart_TypedData_kInt8
Definition dart_api.h:2605
@ Dart_TypedData_kInt64
Definition dart_api.h:2612
@ Dart_TypedData_kInvalid
Definition dart_api.h:2619
Dart_Handle Dart_PersistentHandle
Definition dart_api.h:259
struct _Dart_FinalizableHandle * Dart_FinalizableHandle
Definition dart_api.h:261
void(* Dart_CreateLoadingUnitCallback)(void *callback_data, intptr_t loading_unit_id, void **write_callback_data, void **write_debug_callback_data)
Definition dart_api.h:3873
void(* Dart_IsolateShutdownCallback)(void *isolate_group_data, void *isolate_data)
Definition dart_api.h:710
void *(* Dart_HeapSamplingCreateCallback)(Dart_Isolate isolate, Dart_IsolateGroup isolate_group, const char *cls_name, intptr_t allocation_size)
Definition dart_api.h:1282
Dart_Handle(* Dart_LibraryTagHandler)(Dart_LibraryTag tag, Dart_Handle library_or_package_map_url, Dart_Handle url)
Definition dart_api.h:3378
Dart_NativeArgument_Type
Definition dart_api.h:3017
@ Dart_NativeArgument_kString
Definition dart_api.h:3024
@ Dart_NativeArgument_kInt64
Definition dart_api.h:3021
@ Dart_NativeArgument_kNativeFields
Definition dart_api.h:3026
@ Dart_NativeArgument_kInstance
Definition dart_api.h:3025
@ Dart_NativeArgument_kInt32
Definition dart_api.h:3019
@ Dart_NativeArgument_kUint64
Definition dart_api.h:3022
@ Dart_NativeArgument_kUint32
Definition dart_api.h:3020
@ Dart_NativeArgument_kDouble
Definition dart_api.h:3023
@ Dart_NativeArgument_kBool
Definition dart_api.h:3018
int64_t Dart_IsolateGroupId
Definition dart_api.h:1208
char *(* Dart_DwarfStackTraceFootnoteCallback)(void *addresses[], intptr_t count)
Definition dart_api.h:4088
struct _Dart_WeakPersistentHandle * Dart_WeakPersistentHandle
Definition dart_api.h:260
Dart_KernelCompilationVerbosityLevel
Definition dart_api.h:3741
Dart_Handle(* Dart_DeferredLoadHandler)(intptr_t loading_unit_id)
Definition dart_api.h:3413
void(* Dart_HeapSamplingDeleteCallback)(void *data)
Definition dart_api.h:1287
void(* Dart_HeapSamplingReportCallback)(void *context, void *data)
Definition dart_api.h:1280
#define ISOLATE_GROUP_METRIC_API(type, variable, name, unit)
#define CHECK_ERROR_HANDLE(error)
#define GET_LIST_ELEMENT(thread, type, obj, index)
#define GET_LIST_RANGE(thread, type, obj, offset, length)
#define SET_LIST_ELEMENT_AS_BYTES(type, obj, native_array, offset, length)
#define GET_LIST_ELEMENT_AS_BYTES(type, obj, native_array, offset, length)
#define GET_LIST_LENGTH(zone, type, obj, len)
#define DEFINE_UNWRAP(type)
#define SET_LIST_ELEMENT(type, obj, index, value)
#define ISOLATE_METRIC_API(type, variable, name, unit)
#define API_TIMELINE_DURATION(thread)
#define CHECK_ISOLATE(isolate)
#define DARTSCOPE(thread)
#define CHECK_ISOLATE_GROUP(isolate_group)
#define RETURN_TYPE_ERROR(zone, dart_handle, type)
#define ASSERT_CALLBACK_STATE(thread)
#define CHECK_LENGTH(length, max_elements)
#define RETURN_NULL_ERROR(parameter)
#define CHECK_NO_ISOLATE(isolate)
#define START_NO_CALLBACK_SCOPE(thread)
#define API_TIMELINE_BEGIN_END(thread)
#define CHECK_API_SCOPE(thread)
#define CHECK_NULL(parameter)
#define END_NO_CALLBACK_SCOPE(thread)
#define CHECK_CALLBACK_STATE(thread)
#define CURRENT_FUNC
bool(* Dart_ServiceStreamListenCallback)(const char *stream_id)
void(* Dart_TimelineRecorderCallback)(Dart_TimelineRecorderEvent *event)
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
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)
void(* Dart_HeapSnapshotWriteChunkCallback)(void *context, uint8_t *buffer, intptr_t size, bool is_last)
bool(* Dart_FileModifiedCallback)(const char *url, int64_t since)
void(* Dart_ServiceStreamCancelCallback)(const char *stream_id)
void(* Dart_EmbedderInformationCallback)(Dart_EmbedderInformation *info)
const EmbeddedViewParams * params
#define ASSERT(E)
VkInstance instance
Definition main.cc:48
SkBitmap source
Definition examples.cpp:28
#define DART_EXPORT
#define FATAL(error)
AtkStateType state
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlKeyEvent * event
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
uint32_t uint32_t * format
uint32_t * target
#define DECLARE_FLAG(type, name)
Definition flags.h:14
#define DEFINE_FLAG(type, name, default_value, comment)
Definition flags.h:16
Dart_NativeFunction function
Definition fuchsia.cc:51
int argument_count
Definition fuchsia.cc:52
#define HANDLESCOPE(thread)
Definition handles.h:321
#define I
size_t length
Win32Message message
char ** argv
Definition library.h:9
#define DART_API_ISOLATE_GROUP_METRIC_LIST(V)
Definition metrics.h:29
#define ISOLATE_METRIC_LIST(V)
Definition metrics.h:49
Definition copy.py:1
DART_EXPORT bool Dart_HasServiceMessages()
DART_EXPORT Dart_Handle Dart_StringToUTF8(Dart_Handle str, uint8_t **utf8_array, intptr_t *length)
static bool GetNativeStringArgument(NativeArguments *arguments, int arg_index, Dart_Handle *str, void **peer)
DART_EXPORT bool Dart_IsLibrary(Dart_Handle object)
static bool Equals(const Object &expected, const Object &actual)
constexpr intptr_t MB
Definition globals.h:530
DART_EXPORT Dart_Handle Dart_SetFfiNativeResolver(Dart_Handle library, Dart_FfiNativeResolver resolver)
bool IsTypedDataViewClassId(intptr_t index)
Definition class_id.h:439
static FunctionPtr FindCoreLibPrivateFunction(Zone *zone, const String &name)
DART_EXPORT void Dart_PrepareToAbort()
bool IsTypedDataClassId(intptr_t index)
Definition class_id.h:433
DART_EXPORT void Dart_ReportSurvivingAllocations(Dart_HeapSamplingReportCallback callback, void *context, bool force_gc)
DART_EXPORT Dart_Handle Dart_ListGetAt(Dart_Handle list, intptr_t index)
DART_EXPORT Dart_WeakPersistentHandle Dart_NewWeakPersistentHandle(Dart_Handle object, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT Dart_Handle Dart_ClassLibrary(Dart_Handle cls_type)
static TypeArgumentsPtr TypeArgumentsForElementType(ObjectStore *store, Dart_CoreType_Id element_type_id)
static ObjectPtr ResolveConstructor(const char *current_func, const Class &cls, const String &class_name, const String &dotted_name, int num_args)
DART_EXPORT Dart_Handle Dart_SetPeer(Dart_Handle object, void *peer)
DART_EXPORT bool Dart_DetectNullSafety(const char *script_uri, const char *package_config, const char *original_working_directory, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions, const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
DART_EXPORT bool Dart_IsDouble(Dart_Handle object)
DART_EXPORT bool Dart_IsInstance(Dart_Handle object)
bool IsOneByteStringClassId(intptr_t index)
Definition class_id.h:354
DART_EXPORT void Dart_DisableHeapSampling()
DART_EXPORT Dart_Handle Dart_IsNonNullableType(Dart_Handle type, bool *result)
static bool GetNativeIntegerArgument(NativeArguments *arguments, int arg_index, int64_t *value)
DART_EXPORT Dart_Handle Dart_SetCurrentUserTag(Dart_Handle user_tag)
DART_EXPORT bool Dart_IsCompilationError(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsElfs(Dart_CreateLoadingUnitCallback next_callback, void *next_callback_data, bool strip, Dart_StreamingWriteCallback write_callback, Dart_StreamingCloseCallback close_callback)
DART_EXPORT Dart_Handle Dart_Allocate(Dart_Handle type)
DART_EXPORT Dart_Handle Dart_GetNativeStringArgument(Dart_NativeArguments args, int arg_index, void **peer)
DART_EXPORT bool Dart_IsBoolean(Dart_Handle object)
DART_EXPORT void Dart_EnterScope()
DART_EXPORT Dart_Handle Dart_GetObfuscationMap(uint8_t **buffer, intptr_t *buffer_length)
DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object)
DART_EXPORT void Dart_SetPersistentHandle(Dart_PersistentHandle obj1, Dart_Handle obj2)
const char *const name
DART_EXPORT Dart_Port Dart_GetMainPortId()
DART_EXPORT Dart_Handle Dart_FinalizeLoading(bool complete_futures)
DART_EXPORT Dart_Handle Dart_NewUserTag(const char *label)
static Dart_Handle GetNativeFieldsOfArgument(NativeArguments *arguments, int arg_index, int num_fields, intptr_t *field_values, const char *current_func)
DART_EXPORT Dart_Handle Dart_GetStickyError()
static InstancePtr GetMapInstance(Zone *zone, const Object &obj)
DART_EXPORT char * Dart_GetUserTagLabel(Dart_Handle user_tag)
DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception, Dart_Handle stacktrace)
const int kTypedDataCidRemainderUnmodifiable
Definition class_id.h:264
static bool GetNativeDoubleArgument(NativeArguments *arguments, int arg_index, double *value)
DART_EXPORT void Dart_StartProfiling()
static bool GetNativeUnsignedIntegerArgument(NativeArguments *arguments, int arg_index, uint64_t *value)
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_TypeNever()
DART_EXPORT Dart_Handle Dart_DebugName()
DART_EXPORT Dart_Handle Dart_False()
DART_EXPORT bool Dart_ErrorHasException(Dart_Handle handle)
DART_EXPORT Dart_IsolateGroupId Dart_CurrentIsolateGroupId()
DART_EXPORT char * Dart_SetServiceStreamCallbacks(Dart_ServiceStreamListenCallback listen_callback, Dart_ServiceStreamCancelCallback cancel_callback)
DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj, int index, intptr_t *value)
DART_EXPORT Dart_Handle Dart_NewStringFromUTF32(const int32_t *utf32_array, intptr_t length)
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT Dart_Handle Dart_NewDouble(double value)
DART_EXPORT const char * Dart_IsolateServiceId(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsAssemblies(Dart_CreateLoadingUnitCallback next_callback, void *next_callback_data, bool strip, Dart_StreamingWriteCallback write_callback, Dart_StreamingCloseCallback close_callback)
DART_EXPORT void Dart_ThreadEnableProfiling()
DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle cls_type)
DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void **peer)
static Dart_Handle NewExternalByteData(Thread *thread, void *data, intptr_t length, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback, bool unmodifiable)
DART_EXPORT void * Dart_GetNativeIsolateGroupData(Dart_NativeArguments args)
DART_EXPORT bool Dart_IsKernel(const uint8_t *buffer, intptr_t buffer_size)
bool ResolveUri(const char *ref_uri, const char *base_uri, const char **target_uri)
Definition uri.cc:424
DART_EXPORT bool Dart_HasStickyError()
DART_EXPORT Dart_Handle Dart_StringToLatin1(Dart_Handle str, uint8_t *latin1_array, intptr_t *length)
DART_EXPORT void Dart_NotifyLowMemory()
DART_EXPORT void Dart_SetThreadName(const char *name)
Nullability
Definition object.h:1112
DART_EXPORT Dart_Handle Dart_True()
DART_EXPORT Dart_Handle Dart_RootLibrary()
DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, Dart_Handle class_name)
DART_EXPORT bool Dart_IsNumber(Dart_Handle object)
static intptr_t kInitialSize
static Dart_Handle NewTypedData(Thread *thread, intptr_t cid, intptr_t length)
DART_EXPORT void Dart_SetBooleanReturnValue(Dart_NativeArguments args, bool retval)
DART_EXPORT void Dart_SetEmbedderInformationCallback(Dart_EmbedderInformationCallback callback)
const char * CanonicalFunction(const char *func)
bool IsNumberClassId(intptr_t index)
Definition class_id.h:333
DART_EXPORT Dart_Handle Dart_NewStringFromUTF16(const uint16_t *utf16_array, intptr_t length)
bool IsTypeClassId(intptr_t index)
Definition class_id.h:370
DART_EXPORT Dart_Handle Dart_IntegerFitsIntoUint64(Dart_Handle integer, bool *fits)
DART_EXPORT Dart_Handle Dart_GetNativeInstanceFieldCount(Dart_Handle obj, int *count)
DART_EXPORT Dart_MessageNotifyCallback Dart_GetMessageNotifyCallback()
void * malloc(size_t size)
Definition allocation.cc:19
static bool IsFfiCompound(Thread *T, const Object &obj)
static bool IsCompiletimeErrorObject(Zone *zone, const Object &obj)
DART_EXPORT Dart_Handle Dart_GetDefaultUserTag()
DART_EXPORT Dart_Handle Dart_TypeDynamic()
DART_EXPORT void Dart_SetShouldPauseOnExit(bool should_pause)
const char *const class_name
DART_EXPORT Dart_Handle Dart_Precompile()
DART_EXPORT void Dart_IsolateFlagsInitialize(Dart_IsolateFlags *flags)
DART_EXPORT Dart_Handle Dart_NewUnhandledExceptionError(Dart_Handle exception)
constexpr intptr_t kIntptrMin
Definition globals.h:556
DART_EXPORT Dart_Handle Dart_StringStorageSize(Dart_Handle str, intptr_t *size)
DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value)
DART_EXPORT bool Dart_IsUnhandledExceptionError(Dart_Handle object)
static Dart_Handle NewExternalTypedDataWithFinalizer(Dart_TypedData_Type type, void *data, intptr_t length, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback, bool unmodifiable)
DART_EXPORT Dart_Handle Dart_BooleanValue(Dart_Handle boolean_obj, bool *value)
DART_EXPORT Dart_Handle Dart_NewExternalTypedDataWithFinalizer(Dart_TypedData_Type type, void *data, intptr_t length, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
static Dart_Handle HandleFromFinalizable(Dart_FinalizableHandle object)
DART_EXPORT Dart_Handle Dart_NewStringFromUTF8(const uint8_t *utf8_array, intptr_t length)
DART_EXPORT void Dart_PropagateError(Dart_Handle handle)
static Dart_Handle InitNewReadOnlyApiHandle(ObjectPtr raw)
bool IsUnmodifiableTypedDataViewClassId(intptr_t index)
Definition class_id.h:453
DART_EXPORT Dart_Handle Dart_GetNativeSymbol(Dart_Handle library, Dart_NativeEntrySymbol *resolver)
static InstancePtr GetListInstance(Zone *zone, const Object &obj)
@ kNullCid
Definition class_id.h:252
@ kNumPredefinedCids
Definition class_id.h:257
@ kByteDataViewCid
Definition class_id.h:244
@ kByteBufferCid
Definition class_id.h:247
@ kUnmodifiableByteDataViewCid
Definition class_id.h:245
DART_EXPORT Dart_Handle Dart_SetDeferredLoadHandler(Dart_DeferredLoadHandler handler)
DART_EXPORT void Dart_SetWeakHandleReturnValue(Dart_NativeArguments args, Dart_WeakPersistentHandle rval)
static void DropRegExpMatchCode(Zone *zone)
DART_EXPORT void Dart_StopProfiling()
DART_EXPORT void * Dart_IsolateGroupData(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_GetNonNullableType(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle *type_arguments)
DART_EXPORT Dart_FinalizableHandle Dart_NewFinalizableHandle(Dart_Handle object, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)
DART_EXPORT bool Dart_IsPausedOnStart()
DART_EXPORT Dart_Handle Dart_NewTypedData(Dart_TypedData_Type type, intptr_t length)
DART_EXPORT bool Dart_WriteProfileToTimeline(Dart_Port main_port, char **error)
DART_EXPORT Dart_Handle Dart_HandleFromWeakPersistent(Dart_WeakPersistentHandle object)
DART_EXPORT Dart_IsolateGroup Dart_CurrentIsolateGroup()
DART_EXPORT uint8_t * Dart_ScopeAllocate(intptr_t size)
DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args, Dart_Handle retval)
DART_EXPORT Dart_Handle Dart_GetStaticMethodClosure(Dart_Handle library, Dart_Handle cls_type, Dart_Handle function_name)
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)
DART_EXPORT char * Dart_SetFileModifiedCallback(Dart_FileModifiedCallback file_modified_callback)
DART_EXPORT Dart_Handle Dart_CreateAppJITSnapshotAsBlobs(uint8_t **isolate_snapshot_data_buffer, intptr_t *isolate_snapshot_data_size, uint8_t **isolate_snapshot_instructions_buffer, intptr_t *isolate_snapshot_instructions_size)
DART_EXPORT void Dart_NotifyDestroyed()
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsElf(Dart_StreamingWriteCallback callback, void *callback_data, bool strip, void *debug_callback_data)
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT Dart_Handle Dart_GetNativeResolver(Dart_Handle library, Dart_NativeEntryResolver *resolver)
DART_EXPORT Dart_Handle Dart_IsNullableType(Dart_Handle type, bool *result)
DART_EXPORT Dart_Handle Dart_GetCurrentUserTag()
DART_EXPORT Dart_Handle Dart_MapGetAt(Dart_Handle map, Dart_Handle key)
DART_EXPORT Dart_Handle Dart_DeferredLoadCompleteError(intptr_t loading_unit_id, const char *error_message, bool transient)
DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function, bool *is_static)
constexpr intptr_t KB
Definition globals.h:528
uintptr_t uword
Definition globals.h:501
DART_EXPORT Dart_Handle Dart_NewIntegerFromHexCString(const char *str)
static Dart_Handle NewExternalTypedData(Thread *thread, intptr_t cid, void *data, intptr_t length, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback, bool unmodifiable)
DART_EXPORT void Dart_SetHeapSamplingPeriod(intptr_t bytes)
DART_EXPORT int64_t Dart_TimelineGetTicks()
DART_EXPORT bool Dart_IsFuture(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_ToString(Dart_Handle object)
static Dart_WeakPersistentHandle AllocateWeakPersistentHandle(Thread *thread, const Object &ref, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT Dart_Handle Dart_ClosureFunction(Dart_Handle closure)
DART_EXPORT Dart_Handle Dart_TypedDataAcquireData(Dart_Handle object, Dart_TypedData_Type *type, void **data, intptr_t *len)
DART_EXPORT Dart_Handle Dart_GetNullableType(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle *type_arguments)
DART_EXPORT Dart_Isolate Dart_CurrentIsolate()
DART_EXPORT Dart_Handle Dart_NewListOfTypeFilled(Dart_Handle element_type, Dart_Handle fill_object, intptr_t length)
DART_EXPORT void Dart_RegisterRootServiceRequestCallback(const char *name, Dart_ServiceRequestCallback callback, void *user_data)
DART_EXPORT void Dart_DumpNativeStackTrace(void *context)
DART_EXPORT const char * Dart_VersionString()
DART_EXPORT Dart_Handle Dart_InvokeConstructor(Dart_Handle object, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT Dart_Handle Dart_ListSetAt(Dart_Handle list, intptr_t index, Dart_Handle value)
DART_EXPORT char * Dart_WriteHeapSnapshot(Dart_HeapSnapshotWriteChunkCallback write, void *context)
DART_EXPORT Dart_Handle Dart_IntegerToHexCString(Dart_Handle integer, const char **value)
DART_EXPORT bool Dart_SetEnabledTimelineCategory(const char *categories)
DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function)
DART_EXPORT Dart_Handle Dart_StringToUTF16(Dart_Handle str, uint16_t *utf16_array, intptr_t *length)
DART_EXPORT bool Dart_IsKernelIsolate(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_NewBoolean(bool value)
DART_EXPORT char * Dart_Cleanup()
static Dart_Handle NewByteData(Thread *thread, intptr_t length)
static Dart_Handle DeferredLoadComplete(intptr_t loading_unit_id, bool error, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions, const char *error_message, bool transient_error)
static Dart_Handle GetTypeCommon(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle *type_arguments, Nullability nullability)
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT char * Dart_ServiceSendDataEvent(const char *stream_id, const char *event_kind, const uint8_t *bytes, intptr_t bytes_length)
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback, void *callback_data, bool strip, void *debug_callback_data)
DART_EXPORT Dart_Handle Dart_LibraryResolvedUrl(Dart_Handle library)
DART_EXPORT Dart_Handle Dart_SetNativeInstanceField(Dart_Handle obj, int index, intptr_t value)
DART_EXPORT void Dart_SetIntegerReturnValue(Dart_NativeArguments args, int64_t retval)
DART_EXPORT void Dart_DeleteWeakPersistentHandle(Dart_WeakPersistentHandle object)
DART_EXPORT Dart_KernelCompilationResult Dart_CompileToKernel(const char *script_uri, const uint8_t *platform_kernel, intptr_t platform_kernel_size, bool incremental_compile, bool for_snapshot, bool embed_sources, const char *package_config, Dart_KernelCompilationVerbosityLevel verbosity)
const int kTypedDataCidRemainderExternal
Definition class_id.h:263
DART_EXPORT Dart_Handle Dart_EmptyString()
DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id)
DART_EXPORT Dart_Handle Dart_ObjectIsType(Dart_Handle object, Dart_Handle type, bool *value)
DART_EXPORT Dart_Handle Dart_CopyUTF8EncodingOfString(Dart_Handle str, uint8_t *utf8_array, intptr_t length)
DART_EXPORT Dart_Handle Dart_ErrorGetStackTrace(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_TypeToNullableType(Dart_Handle type)
DART_EXPORT Dart_Handle Dart_GetNativeFieldsOfArgument(Dart_NativeArguments args, int arg_index, int num_fields, intptr_t *field_values)
DART_EXPORT Dart_PerformanceMode Dart_SetPerformanceMode(Dart_PerformanceMode mode)
static ObjectPtr CallStatic3Args(Zone *zone, const String &name, const Instance &arg0, const Instance &arg1, const Instance &arg2)
DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list, intptr_t offset, const uint8_t *native_array, intptr_t length)
DART_EXPORT Dart_Isolate Dart_CreateIsolateInGroup(Dart_Isolate group_member, const char *name, Dart_IsolateShutdownCallback shutdown_callback, Dart_IsolateCleanupCallback cleanup_callback, void *child_isolate_data, char **error)
DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal, Dart_Port on_error_port, Dart_Port on_exit_port, char **error)
DART_EXPORT Dart_Handle Dart_NewExternalTypedData(Dart_TypedData_Type type, void *data, intptr_t length)
DART_EXPORT Dart_Handle Dart_TypeToNonNullableType(Dart_Handle type)
DART_EXPORT Dart_Handle Dart_AllocateWithNativeFields(Dart_Handle type, intptr_t num_native_fields, const intptr_t *native_fields)
static bool CanTypeContainNull(const Type &type)
DART_EXPORT Dart_Handle Dart_IntegerToUint64(Dart_Handle integer, uint64_t *value)
DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfTypedData(Dart_Handle object)
DART_EXPORT bool Dart_IsPausedOnExit()
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 Dart_Handle Dart_FunctionOwner(Dart_Handle function)
DART_EXPORT Dart_Handle Dart_StringGetProperties(Dart_Handle object, intptr_t *char_size, intptr_t *str_len, void **peer)
DART_EXPORT Dart_Handle Dart_NewIntegerFromUint64(uint64_t value)
DART_EXPORT bool Dart_IsServiceIsolate(Dart_Isolate isolate)
DART_EXPORT bool Dart_IsMap(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_SetNativeResolver(Dart_Handle library, Dart_NativeEntryResolver resolver, Dart_NativeEntrySymbol symbol)
static Dart_Handle IsOfTypeNullabilityHelper(Dart_Handle type, Nullability nullability, bool *result)
DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj, double *value)
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
DART_EXPORT void Dart_ExitIsolate()
DART_EXPORT void Dart_SetPausedOnStart(bool paused)
DART_EXPORT bool Dart_IsFunction(Dart_Handle handle)
DART_EXPORT void * Dart_IsolateData(Dart_Isolate isolate)
DART_EXPORT void Dart_SetTimelineRecorderCallback(Dart_TimelineRecorderCallback callback)
DART_EXPORT char * Dart_IsolateMakeRunnable(Dart_Isolate isolate)
static const char * GetErrorString(Thread *thread, const Object &obj)
DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance)
const intptr_t cid
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroup(const char *script_uri, const char *name, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT Dart_Handle Dart_LibraryHandleError(Dart_Handle library_in, Dart_Handle error_in)
DART_EXPORT Dart_Handle Dart_NewByteBuffer(Dart_Handle typed_data)
DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container, Dart_Handle name, Dart_Handle value)
DART_EXPORT Dart_Handle Dart_StringLength(Dart_Handle str, intptr_t *len)
raw_obj untag() -> num_entries()) VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(TypedData, TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(Record, RecordShape(raw_obj->untag() ->shape()).num_fields()) VARIABLE_NULL_VISITOR(CompressedStackMaps, CompressedStackMaps::PayloadSizeOf(raw_obj)) VARIABLE_NULL_VISITOR(OneByteString, Smi::Value(raw_obj->untag() ->length())) VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->untag() ->length())) intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj, ObjectPointerVisitor *visitor)
DART_EXPORT bool Dart_IsTearOff(Dart_Handle object)
static Dart_Handle TypeToHelper(Dart_Handle type, Nullability nullability)
DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, intptr_t offset, uint8_t *native_array, intptr_t length)
DART_EXPORT Dart_Handle Dart_RunLoop()
DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle kernel_buffer)
DART_EXPORT void * Dart_CurrentIsolateGroupData()
DART_EXPORT Dart_Handle Dart_NewListOfType(Dart_Handle element_type, intptr_t length)
static bool InstanceIsType(const Thread *thread, const Instance &instance, const Type &type)
DART_EXPORT bool Dart_IsType(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_MapKeys(Dart_Handle map)
DART_EXPORT void Dart_ThreadDisableProfiling()
static void KillNonMainIsolatesSlow(Thread *thread, Isolate *main_isolate)
DART_EXPORT bool Dart_IsPrecompiledRuntime()
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroupFromKernel(const char *script_uri, const char *name, const uint8_t *kernel_buffer, intptr_t kernel_buffer_size, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT char * Dart_SetVMFlags(int argc, const char **argv)
DART_EXPORT void Dart_NotifyIdle(int64_t deadline)
DART_EXPORT Dart_Handle Dart_NewListOf(Dart_CoreType_Id element_type_id, intptr_t length)
DART_EXPORT Dart_KernelCompilationResult Dart_KernelListDependencies()
DART_EXPORT Dart_Handle Dart_CreateVMAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback, void *callback_data)
DART_EXPORT Dart_Handle Dart_DeferredLoadComplete(intptr_t loading_unit_id, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions)
DART_EXPORT void Dart_DeleteFinalizableHandle(Dart_FinalizableHandle object, Dart_Handle strong_ref_to_object)
void DumpTypeTable(Isolate *isolate)
Definition object.cc:27154
DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler(Dart_LibraryTagHandler handler)
DART_EXPORT Dart_Handle Dart_SortClasses()
DART_EXPORT Dart_Handle Dart_TypeVoid()
DART_EXPORT Dart_Handle Dart_MapContainsKey(Dart_Handle map, Dart_Handle key)
DART_EXPORT void Dart_SetPausedOnExit(bool paused)
DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_LoadingUnitLibraryUris(intptr_t loading_unit_id)
DART_EXPORT void Dart_ExitScope()
DART_EXPORT int64_t Dart_TimelineGetTicksFrequency()
DART_EXPORT void Dart_RegisterHeapSamplingCallback(Dart_HeapSamplingCreateCallback create_callback, Dart_HeapSamplingDeleteCallback delete_callback)
static void RunLoopDone(uword param)
DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfExternalTypedData(Dart_Handle object)
DART_EXPORT const char * Dart_DebugNameToCString()
std::unique_ptr< Message > WriteMessage(bool same_group, const Object &obj, Dart_Port dest_port, Message::Priority priority)
DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer, bool *fits)
DART_EXPORT Dart_Handle Dart_NewApiError(const char *error)
DART_EXPORT Dart_Handle Dart_ListGetRange(Dart_Handle list, intptr_t offset, intptr_t length, Dart_Handle *result)
DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t *len)
static InstancePtr AllocateObject(Thread *thread, const Class &cls)
DART_EXPORT void Dart_SetMessageNotifyCallback(Dart_MessageNotifyCallback message_notify_callback)
DART_EXPORT Dart_Handle Dart_NewList(intptr_t length)
static ObjectPtr CallStatic1Arg(Zone *zone, const String &name, const Instance &arg0)
const StackTrace & GetCurrentStackTrace(int skip_frames)
Definition stacktrace.cc:94
DART_EXPORT void Dart_KillIsolate(Dart_Isolate handle)
static bool IsSnapshotCompatible(Snapshot::Kind vm_kind, Snapshot::Kind isolate_kind)
Definition snapshot.h:108
DART_EXPORT Dart_Handle Dart_NewCompilationError(const char *error)
DART_EXPORT bool Dart_ShouldPauseOnStart()
DART_EXPORT void Dart_SetDartLibrarySourcesKernel(const uint8_t *platform_kernel, const intptr_t platform_kernel_size)
DART_EXPORT Dart_Handle Dart_GetNativeDoubleArgument(Dart_NativeArguments args, int index, double *value)
DART_EXPORT Dart_Handle Dart_ErrorGetException(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT bool Dart_IsList(Dart_Handle object)
DART_EXPORT bool Dart_IsApiError(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_DefaultCanonicalizeUrl(Dart_Handle base_url, Dart_Handle url)
DART_EXPORT Dart_Handle Dart_GetLoadedLibraries()
DART_EXPORT void * Dart_CurrentIsolateData()
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception)
DART_EXPORT Dart_Handle Dart_GetNativeIntegerArgument(Dart_NativeArguments args, int index, int64_t *value)
DART_EXPORT int Dart_GetNativeArgumentCount(Dart_NativeArguments args)
DART_EXPORT Dart_Port Dart_KernelPort()
DART_EXPORT void Dart_AddSymbols(const char *dso_name, void *buffer, intptr_t buffer_size)
DART_EXPORT Dart_Handle Dart_LoadScriptFromKernel(const uint8_t *buffer, intptr_t buffer_size)
DART_EXPORT bool Dart_IsInteger(Dart_Handle object)
DART_EXPORT int64_t Dart_TimelineGetMicros()
pthread_key_t ThreadLocalKey
DART_EXPORT Dart_Handle Dart_ObjectEquals(Dart_Handle obj1, Dart_Handle obj2, bool *value)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library)
DART_EXPORT Dart_Handle Dart_SetEnvironmentCallback(Dart_EnvironmentCallback callback)
static Dart_Handle LoadLibrary(Thread *T, const ExternalTypedData &td)
bool IsIntegerClassId(intptr_t index)
Definition class_id.h:340
DART_EXPORT bool Dart_IsVariable(Dart_Handle handle)
DART_EXPORT void Dart_SetDwarfStackTraceFootnoteCallback(Dart_DwarfStackTraceFootnoteCallback callback)
DART_EXPORT void Dart_SetDoubleReturnValue(Dart_NativeArguments args, double retval)
DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle)
DART_EXPORT bool Dart_IsVMFlagSet(const char *flag_name)
DART_EXPORT Dart_Handle Dart_Null()
static Dart_TypedData_Type GetType(intptr_t class_id)
static ObjectPtr GetByteBufferConstructor(Thread *thread, const String &class_name, const String &constructor_name, intptr_t num_args)
DART_EXPORT bool Dart_IsReloading()
DART_EXPORT void Dart_SetStickyError(Dart_Handle error)
DART_EXPORT bool Dart_IsString(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_New(Dart_Handle type, Dart_Handle constructor_name, int number_of_arguments, Dart_Handle *arguments)
void DumpTypeParameterTable(Isolate *isolate)
Definition object.cc:27177
Isolate * CreateWithinExistingIsolateGroup(IsolateGroup *group, const char *name, char **error)
const char *const function_name
static int8_t data[kExtLength]
DART_EXPORT bool Dart_ShouldPauseOnExit()
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library)
DART_EXPORT Dart_Handle Dart_GetNativeBooleanArgument(Dart_NativeArguments args, int index, bool *value)
DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle object, const char **cstr)
DART_EXPORT bool Dart_KernelIsolateIsRunning()
DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t **vm_snapshot_data_buffer, intptr_t *vm_snapshot_data_size, uint8_t **isolate_snapshot_data_buffer, intptr_t *isolate_snapshot_data_size, bool is_core)
DART_EXPORT Dart_Handle Dart_SendPortGetId(Dart_Handle port, Dart_Port *port_id)
static Dart_Isolate CreateIsolate(IsolateGroup *group, bool is_new_group, const char *name, void *isolate_data, char **error)
DART_EXPORT Dart_Handle Dart_HandleFromPersistent(Dart_PersistentHandle object)
DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle *type_arguments)
DART_EXPORT void Dart_ShutdownIsolate()
DART_EXPORT bool Dart_IsClosure(Dart_Handle object)
DART_EXPORT bool Dart_HasLivePorts()
DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(const char *name, Dart_ServiceRequestCallback callback, void *user_data)
DART_EXPORT Dart_Handle Dart_GetNativeReceiver(Dart_NativeArguments args, intptr_t *value)
DART_EXPORT bool Dart_HandleServiceMessages()
void DumpTypeArgumentsTable(Isolate *isolate)
Definition object.cc:27185
DART_EXPORT Dart_Handle Dart_NewUnmodifiableExternalTypedDataWithFinalizer(Dart_TypedData_Type type, const void *data, intptr_t length, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT Dart_Handle Dart_GetDataFromByteBuffer(Dart_Handle object)
static Dart_Handle SetupArguments(Thread *thread, int num_args, Dart_Handle *arguments, int extra_args, Array *args)
static Dart_FinalizableHandle AllocateFinalizableHandle(Thread *thread, const Object &ref, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
static ObjectPtr CallStatic2Args(Zone *zone, const String &name, const Instance &arg0, const Instance &arg1)
DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle)
static ObjectPtr ThrowArgumentError(const char *exception_message)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_GetNativeArguments(Dart_NativeArguments args, int num_arguments, const Dart_NativeArgument_Descriptor *argument_descriptors, Dart_NativeArgument_Value *arg_values)
static const ThreadLocalKey kUnsetThreadLocalKey
bool IsBuiltinListClassId(intptr_t index)
Definition class_id.h:364
DART_EXPORT bool Dart_IsByteBuffer(Dart_Handle handle)
bool IsExternalTypedDataClassId(intptr_t index)
Definition class_id.h:447
DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t *buffer, intptr_t buffer_size)
DART_EXPORT bool Dart_IdentityEquals(Dart_Handle obj1, Dart_Handle obj2)
DART_EXPORT bool Dart_IsFatalError(Dart_Handle object)
constexpr intptr_t kIntptrMax
Definition globals.h:557
bool IsStringClassId(intptr_t index)
Definition class_id.h:350
DART_EXPORT Dart_Handle Dart_IntegerToInt64(Dart_Handle integer, int64_t *value)
DART_EXPORT Dart_Handle Dart_StringUTF8Length(Dart_Handle str, intptr_t *len)
DART_EXPORT Dart_Handle Dart_IsLegacyType(Dart_Handle type, bool *result)
DART_EXPORT void Dart_EnableHeapSampling()
DART_EXPORT Dart_Handle Dart_HandleMessage()
DART_EXPORT void Dart_SetShouldPauseOnStart(bool should_pause)
static SkString fmt(SkColor4f c)
Definition p3.cpp:43
#define Px
Definition globals.h:410
#define Pd64
Definition globals.h:416
#define Pd
Definition globals.h:408
#define Pu64
Definition globals.h:417
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
#define T
#define REUSABLE_OBJECT_HANDLESCOPE(thread)
void write(SkWStream *wStream, const T &text)
Definition skqp.cpp:188
Point offset
Dart_KernelCompilationStatus status
Definition dart_api.h:3735
Definition SkMD5.cpp:134
const uintptr_t id
#define TIMELINE_DURATION(thread, stream, name)
Definition timeline.h:39
struct _Dart_NativeArgument_Value::@83 as_string
struct _Dart_NativeArgument_Value::@84 as_native_fields
#define NOT_IN_PRODUCT(code)
Definition globals.h:84