Flutter Engine
The Flutter Engine
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/version.h"
57#include "vm/zone_text_buffer.h"
58
59#if !defined(DART_PRECOMPILED_RUNTIME)
61#include "vm/kernel_loader.h"
62#endif // !defined(DART_PRECOMPILED_RUNTIME)
63
64namespace dart {
65
66// Facilitate quick access to the current zone once we have the current thread.
67#define Z (T->zone())
68
69DECLARE_FLAG(bool, print_class_table);
70#if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
71DEFINE_FLAG(bool,
72 check_function_fingerprints,
73 true,
74 "Check function fingerprints");
75#endif // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
77 verify_acquired_data,
78 false,
79 "Verify correct API acquire/release of typed data.");
81 dump_tables,
82 false,
83 "Dump common hash tables before snapshotting.");
85 enable_deprecated_wait_for,
86 false,
87 "Enable deprecated dart:cli waitFor. "
88 "This feature will be fully removed in Dart 3.4 release. "
89 "See https://dartbug.com/52121.");
90
91#define CHECK_ERROR_HANDLE(error) \
92 { \
93 ErrorPtr err = (error); \
94 if (err != Error::null()) { \
95 return Api::NewHandle(T, err); \
96 } \
97 }
98
99ThreadLocalKey Api::api_native_key_ = kUnsetThreadLocalKey;
100Dart_Handle Api::true_handle_ = nullptr;
101Dart_Handle Api::false_handle_ = nullptr;
102Dart_Handle Api::null_handle_ = nullptr;
103Dart_Handle Api::empty_string_handle_ = nullptr;
104Dart_Handle Api::no_callbacks_error_handle_ = nullptr;
105Dart_Handle Api::unwind_in_progress_error_handle_ = nullptr;
106
107const char* CanonicalFunction(const char* func) {
108 if (strncmp(func, "dart::", 6) == 0) {
109 return func + 6;
110 } else {
111 return func;
112 }
113}
114
115#if defined(DEBUG)
116// An object visitor which will iterate over all the function objects in the
117// heap and check if the result type and parameter types are canonicalized
118// or not. An assertion is raised if a type is not canonicalized.
119class CheckFunctionTypesVisitor : public ObjectVisitor {
120 public:
121 explicit CheckFunctionTypesVisitor(Thread* thread)
122 : classHandle_(Class::Handle(thread->zone())),
123 funcHandle_(Function::Handle(thread->zone())),
124 typeHandle_(AbstractType::Handle(thread->zone())) {}
125
126 void VisitObject(ObjectPtr obj) override {
127 if (obj->IsFunction()) {
128 funcHandle_ ^= obj;
129 classHandle_ ^= funcHandle_.Owner();
130 // Verify that the result type of a function is canonical or a
131 // TypeParameter.
132 typeHandle_ ^= funcHandle_.result_type();
133 ASSERT(typeHandle_.IsTypeParameter() || typeHandle_.IsCanonical());
134 // Verify that the types in the function signature are all canonical or
135 // a TypeParameter.
136 const intptr_t num_parameters = funcHandle_.NumParameters();
137 for (intptr_t i = 0; i < num_parameters; i++) {
138 typeHandle_ = funcHandle_.ParameterTypeAt(i);
139 ASSERT(typeHandle_.IsTypeParameter() || typeHandle_.IsCanonical());
140 }
141 }
142 }
143
144 private:
145 Class& classHandle_;
146 Function& funcHandle_;
147 AbstractType& typeHandle_;
148};
149#endif // #if defined(DEBUG).
150
151static InstancePtr GetListInstance(Zone* zone, const Object& obj) {
152 if (obj.IsInstance()) {
154 const Type& list_rare_type =
155 Type::Handle(zone, object_store->non_nullable_list_rare_type());
156 ASSERT(!list_rare_type.IsNull());
157 const Instance& instance = Instance::Cast(obj);
158 const Class& obj_class = Class::Handle(zone, obj.clazz());
159 if (Class::IsSubtypeOf(obj_class, Object::null_type_arguments(),
160 Nullability::kNonNullable, list_rare_type,
161 Heap::kNew)) {
162 return instance.ptr();
163 }
164 }
165 return Instance::null();
166}
167
168static InstancePtr GetMapInstance(Zone* zone, const Object& obj) {
169 if (obj.IsInstance()) {
171 const Type& map_rare_type =
172 Type::Handle(zone, object_store->non_nullable_map_rare_type());
173 ASSERT(!map_rare_type.IsNull());
174 const Instance& instance = Instance::Cast(obj);
175 const Class& obj_class = Class::Handle(zone, obj.clazz());
176 if (Class::IsSubtypeOf(obj_class, Object::null_type_arguments(),
177 Nullability::kNonNullable, map_rare_type,
178 Heap::kNew)) {
179 return instance.ptr();
180 }
181 }
182 return Instance::null();
183}
184
185static bool IsCompiletimeErrorObject(Zone* zone, const Object& obj) {
186#if defined(DART_PRECOMPILED_RUNTIME)
187 // All compile-time errors were handled at snapshot generation time and
188 // compiletime_error_class was removed.
189 return false;
190#else
191 auto isolate_group = Thread::Current()->isolate_group();
192 const Class& error_class = Class::Handle(
193 zone, isolate_group->object_store()->compiletime_error_class());
194 ASSERT(!error_class.IsNull());
195 return (obj.GetClassId() == error_class.id());
196#endif
197}
198
200 int arg_index,
201 Dart_Handle* str,
202 void** peer) {
203 ASSERT(peer != nullptr);
204 if (Api::StringGetPeerHelper(arguments, arg_index, peer)) {
205 *str = nullptr;
206 return true;
207 }
208 Thread* thread = arguments->thread();
209 ASSERT(thread == Thread::Current());
210 *peer = nullptr;
212 Object& obj = thread->ObjectHandle();
213 obj = arguments->NativeArgAt(arg_index);
214 if (IsStringClassId(obj.GetClassId())) {
215 ASSERT(thread->api_top_scope() != nullptr);
216 *str = Api::NewHandle(thread, obj.ptr());
217 return true;
218 }
219 if (obj.IsNull()) {
220 *str = Api::Null();
221 return true;
222 }
223 return false;
224}
225
227 int arg_index,
228 int64_t* value) {
229 ASSERT(value != nullptr);
230 return Api::GetNativeIntegerArgument(arguments, arg_index, value);
231}
232
234 int arg_index,
235 uint64_t* value) {
236 ASSERT(value != nullptr);
237 int64_t arg_value = 0;
238 if (Api::GetNativeIntegerArgument(arguments, arg_index, &arg_value)) {
239 *value = static_cast<uint64_t>(arg_value);
240 return true;
241 }
242 return false;
243}
244
246 int arg_index,
247 double* value) {
248 ASSERT(value != nullptr);
249 return Api::GetNativeDoubleArgument(arguments, arg_index, value);
250}
251
253 int arg_index,
254 int num_fields,
255 intptr_t* field_values,
256 const char* current_func) {
257 ASSERT(field_values != nullptr);
258 if (Api::GetNativeFieldsOfArgument(arguments, arg_index, num_fields,
259 field_values)) {
260 return Api::Success();
261 }
262 Thread* thread = arguments->thread();
263 ASSERT(thread == Thread::Current());
265 Object& obj = thread->ObjectHandle();
266 obj = arguments->NativeArgAt(arg_index);
267 if (obj.IsNull()) {
268 memset(field_values, 0, (num_fields * sizeof(field_values[0])));
269 return Api::Success();
270 }
271 // We did not succeed in extracting the native fields report the
272 // appropriate error.
273 if (!obj.IsInstance()) {
274 return Api::NewError(
275 "%s expects argument at index '%d' to be of"
276 " type Instance.",
277 current_func, arg_index);
278 }
279 const Instance& instance = Instance::Cast(obj);
280 int field_count = instance.NumNativeFields();
281 ASSERT(num_fields != field_count);
282 return Api::NewError("%s: expected %d 'num_fields' but was passed in %d.",
283 current_func, field_count, num_fields);
284}
285
286static FunctionPtr FindCoreLibPrivateFunction(Zone* zone, const String& name) {
287 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
288 ASSERT(!core_lib.IsNull());
289 const Function& function =
291 ASSERT(!function.IsNull());
292 return function.ptr();
293}
294
296 const String& name,
297 const Instance& arg0) {
298 const intptr_t kNumArgs = 1;
299 const Function& function =
301 const Array& args = Array::Handle(zone, Array::New(kNumArgs));
302 args.SetAt(0, arg0);
304}
305
307 const String& name,
308 const Instance& arg0,
309 const Instance& arg1) {
310 const intptr_t kNumArgs = 2;
311 const Function& function =
313 const Array& args = Array::Handle(zone, Array::New(kNumArgs));
314 args.SetAt(0, arg0);
315 args.SetAt(1, arg1);
317}
318
320 const String& name,
321 const Instance& arg0,
322 const Instance& arg1,
323 const Instance& arg2) {
324 const intptr_t kNumArgs = 3;
325 const Function& function =
327 const Array& args = Array::Handle(Array::New(kNumArgs));
328 args.SetAt(0, arg0);
329 args.SetAt(1, arg1);
330 args.SetAt(2, arg2);
332}
333
334static const char* GetErrorString(Thread* thread, const Object& obj) {
335 // This function requires an API scope to be present.
336 if (obj.IsError()) {
337 ASSERT(thread->api_top_scope() != nullptr);
338 const Error& error = Error::Cast(obj);
339 const char* str = error.ToErrorCString();
340 intptr_t len = strlen(str) + 1;
341 char* str_copy = Api::TopScope(thread)->zone()->Alloc<char>(len);
342 strncpy(str_copy, str, len);
343 // Strip a possible trailing '\n'.
344 if ((len > 1) && (str_copy[len - 2] == '\n')) {
345 str_copy[len - 2] = '\0';
346 }
347 return str_copy;
348 } else {
349 return "";
350 }
351}
352
353Dart_Handle Api::InitNewHandle(Thread* thread, ObjectPtr raw) {
354 LocalHandles* local_handles = Api::TopScope(thread)->local_handles();
355 ASSERT(local_handles != nullptr);
356 LocalHandle* ref = local_handles->AllocateHandle();
357 ref->set_ptr(raw);
358 return ref->apiHandle();
359}
360
362 if (raw == Object::null()) {
363 return Null();
364 }
365 if (raw == Bool::True().ptr()) {
366 return True();
367 }
368 if (raw == Bool::False().ptr()) {
369 return False();
370 }
372 return InitNewHandle(thread, raw);
373}
374
376#if defined(DEBUG)
377 Thread* thread = Thread::Current();
379 ASSERT(thread->IsDartMutatorThread());
380 ASSERT(thread->isolate() != nullptr);
383#endif
384 return (reinterpret_cast<LocalHandle*>(object))->ptr();
385}
386
387#define DEFINE_UNWRAP(type) \
388 const type& Api::Unwrap##type##Handle(Zone* zone, Dart_Handle dart_handle) { \
389 const Object& obj = Object::Handle(zone, Api::UnwrapHandle(dart_handle)); \
390 if (obj.Is##type()) { \
391 return type::Cast(obj); \
392 } \
393 return type::Handle(zone); \
394 }
396#undef DEFINE_UNWRAP
397
398const String& Api::UnwrapStringHandle(const ReusableObjectHandleScope& reuse,
399 Dart_Handle dart_handle) {
400 Object& ref = reuse.Handle();
401 ref = Api::UnwrapHandle(dart_handle);
402 if (ref.IsString()) {
403 return String::Cast(ref);
404 }
405 return Object::null_string();
406}
407
409 const ReusableObjectHandleScope& reuse,
410 Dart_Handle dart_handle) {
411 Object& ref = reuse.Handle();
412 ref = Api::UnwrapHandle(dart_handle);
413 if (ref.IsInstance()) {
414 return Instance::Cast(ref);
415 }
416 return Object::null_instance();
417}
418
420 Isolate* isolate = thread->isolate();
421 if (!isolate->AllowClassFinalization()) {
422 // Class finalization is blocked for the isolate. Do nothing.
423 return Api::Success();
424 }
426 return Api::Success();
427 }
428 ASSERT(thread->sticky_error() != Object::null());
429 return Api::NewHandle(thread, thread->sticky_error());
430}
431
433 return reinterpret_cast<Dart_Isolate>(isolate);
434}
435
437 return reinterpret_cast<Dart_IsolateGroup>(isolate_group);
438}
439
444 // Ensure we transition safepoint state to VM if we are not already in
445 // that state.
446 TransitionToVM transition(T);
447 HANDLESCOPE(T);
448
449 va_list args;
451 char* buffer = OS::VSCreate(Z, format, args);
452 va_end(args);
453
455 return Api::NewHandle(T, ApiError::New(message));
456}
457
462 // Ensure we transition safepoint state to VM if we are not already in
463 // that state.
464 TransitionToVM transition(T);
465 HANDLESCOPE(T);
466
467 va_list args;
469 char* buffer = OS::VSCreate(Z, format, args);
470 va_end(args);
471
473 const Array& arguments = Array::Handle(Z, Array::New(1));
474 arguments.SetAt(0, message);
478 Symbols::ArgumentError(), Symbols::Dot(), arguments));
479 if (!error.IsError()) {
481 }
482 return Api::NewHandle(T, error.ptr());
483}
484
486 Isolate* isolate = Isolate::Current();
487 Thread* thread = Thread::Current();
488 ASSERT(thread->IsDartMutatorThread());
489 CHECK_ISOLATE(isolate);
490
491 // Check against all of the handles in the current isolate as well as the
492 // read-only handles.
493 return thread->IsValidHandle(handle) ||
495 reinterpret_cast<Dart_PersistentHandle>(handle)) ||
497 reinterpret_cast<Dart_WeakPersistentHandle>(handle)) ||
499 Dart::IsReadOnlyHandle(reinterpret_cast<uword>(handle));
500}
501
503 ASSERT(thread != nullptr);
504 ApiLocalScope* scope = thread->api_top_scope();
505 ASSERT(scope != nullptr);
506 return scope;
507}
508
509void Api::Init() {
510 if (api_native_key_ == kUnsetThreadLocalKey) {
511 api_native_key_ = OSThread::CreateThreadLocal();
512 }
513 ASSERT(api_native_key_ != kUnsetThreadLocalKey);
514}
515
517 ASSERT(raw->untag()->InVMIsolateHeap());
519 ref->set_ptr(raw);
520 return ref->apiHandle();
521}
522
524 Isolate* isolate = Isolate::Current();
525 ASSERT(isolate != nullptr);
526 ASSERT(isolate == Dart::vm_isolate());
527 ApiState* state = isolate->group()->api_state();
528 ASSERT(state != nullptr);
529
530 ASSERT(true_handle_ == nullptr);
531 true_handle_ = InitNewReadOnlyApiHandle(Bool::True().ptr());
532
533 ASSERT(false_handle_ == nullptr);
534 false_handle_ = InitNewReadOnlyApiHandle(Bool::False().ptr());
535
536 ASSERT(null_handle_ == nullptr);
537 null_handle_ = InitNewReadOnlyApiHandle(Object::null());
538
539 ASSERT(empty_string_handle_ == nullptr);
540 empty_string_handle_ = InitNewReadOnlyApiHandle(Symbols::Empty().ptr());
541
542 ASSERT(no_callbacks_error_handle_ == nullptr);
543 no_callbacks_error_handle_ =
544 InitNewReadOnlyApiHandle(Object::no_callbacks_error().ptr());
545
546 ASSERT(unwind_in_progress_error_handle_ == nullptr);
547 unwind_in_progress_error_handle_ =
548 InitNewReadOnlyApiHandle(Object::unwind_in_progress_error().ptr());
549}
550
552 true_handle_ = nullptr;
553 false_handle_ = nullptr;
554 null_handle_ = nullptr;
555 empty_string_handle_ = nullptr;
556 no_callbacks_error_handle_ = nullptr;
557 unwind_in_progress_error_handle_ = nullptr;
558}
559
561 int arg_index,
562 void** peer) {
563 NoSafepointScope no_safepoint_scope;
564 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
565 if (!raw_obj->IsHeapObject()) {
566 return false;
567 }
568 intptr_t cid = raw_obj->GetClassId();
569 if (cid == kOneByteStringCid || cid == kTwoByteStringCid) {
570 auto isolate_group = arguments->thread()->isolate_group();
571 *peer = isolate_group->heap()->GetPeer(raw_obj);
572 return (*peer != nullptr);
573 }
574 return false;
575}
576
577bool Api::GetNativeReceiver(NativeArguments* arguments, intptr_t* value) {
578 NoSafepointScope no_safepoint_scope;
579 ObjectPtr raw_obj = arguments->NativeArg0();
580 if (raw_obj->IsHeapObject()) {
581 intptr_t cid = raw_obj->GetClassId();
582 if (cid >= kNumPredefinedCids) {
583 ASSERT(Instance::Cast(Object::Handle(raw_obj)).IsValidNativeIndex(0));
584 TypedDataPtr native_fields =
585 reinterpret_cast<CompressedTypedDataPtr*>(
586 UntaggedObject::ToAddr(raw_obj) + sizeof(UntaggedObject))
587 ->Decompress(raw_obj->heap_base());
588 if (native_fields == TypedData::null()) {
589 *value = 0;
590 } else {
591 *value = *bit_cast<intptr_t*, uint8_t*>(native_fields->untag()->data());
592 }
593 return true;
594 }
595 }
596 return false;
597}
598
600 int arg_index,
601 bool* value) {
602 NoSafepointScope no_safepoint_scope;
603 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
604 if (raw_obj->IsHeapObject()) {
605 intptr_t cid = raw_obj->GetClassId();
606 if (cid == kBoolCid) {
607 *value = (raw_obj == Object::bool_true().ptr());
608 return true;
609 }
610 if (cid == kNullCid) {
611 *value = false;
612 return true;
613 }
614 }
615 return false;
616}
617
619 int arg_index,
620 int64_t* value) {
621 NoSafepointScope no_safepoint_scope;
622 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
623 if (raw_obj->IsHeapObject()) {
624 intptr_t cid = raw_obj->GetClassId();
625 if (cid == kMintCid) {
626 *value = static_cast<MintPtr>(raw_obj)->untag()->value_;
627 return true;
628 }
629 return false;
630 }
631 *value = Smi::Value(static_cast<SmiPtr>(raw_obj));
632 return true;
633}
634
636 int arg_index,
637 double* value) {
638 NoSafepointScope no_safepoint_scope;
639 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
640 if (raw_obj->IsHeapObject()) {
641 intptr_t cid = raw_obj->GetClassId();
642 if (cid == kDoubleCid) {
643 *value = static_cast<DoublePtr>(raw_obj)->untag()->value_;
644 return true;
645 }
646 if (cid == kMintCid) {
647 *value =
648 static_cast<double>(static_cast<MintPtr>(raw_obj)->untag()->value_);
649 return true;
650 }
651 return false;
652 }
653 *value = static_cast<double>(Smi::Value(static_cast<SmiPtr>(raw_obj)));
654 return true;
655}
656
658 int arg_index,
659 int num_fields,
660 intptr_t* field_values) {
661 NoSafepointScope no_safepoint_scope;
662 ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
663 intptr_t cid = raw_obj->GetClassIdMayBeSmi();
664 int class_num_fields = arguments->thread()
665 ->isolate_group()
666 ->class_table()
667 ->At(cid)
668 ->untag()
669 ->num_native_fields_;
670 if (num_fields != class_num_fields) {
671 // No native fields or mismatched native field count.
672 return false;
673 }
674 TypedDataPtr native_fields =
675 reinterpret_cast<CompressedTypedDataPtr*>(
676 UntaggedObject::ToAddr(raw_obj) + sizeof(UntaggedObject))
677 ->Decompress(raw_obj->heap_base());
678 if (native_fields == TypedData::null()) {
679 // Native fields not initialized.
680 memset(field_values, 0, (num_fields * sizeof(field_values[0])));
681 return true;
682 }
683 ASSERT(class_num_fields == Smi::Value(native_fields->untag()->length()));
684 intptr_t* native_values =
685 reinterpret_cast<intptr_t*>(native_fields->untag()->data());
686 memmove(field_values, native_values, (num_fields * sizeof(field_values[0])));
687 return true;
688}
689
692 args->SetReturnUnsafe(FinalizablePersistentHandle::Cast(retval)->ptr());
693}
694
696 ASSERT(IsolateGroup::Current()->api_state()->IsValidPersistentHandle(handle));
697 return reinterpret_cast<PersistentHandle*>(handle);
698}
699
702#if defined(DEBUG)
704 ASSERT(state->IsValidWeakPersistentHandle(handle));
705#endif
706 return reinterpret_cast<FinalizablePersistentHandle*>(handle);
707}
709 Dart_FinalizableHandle handle) {
710#if defined(DEBUG)
712 ASSERT(state->IsValidFinalizableHandle(handle));
713#endif
714 return reinterpret_cast<FinalizablePersistentHandle*>(handle);
715}
716
717void FinalizablePersistentHandle::Finalize(
718 IsolateGroup* isolate_group,
720 if (!handle->ptr()->IsHeapObject()) {
721 return; // Free handle.
722 }
724 ASSERT(callback != nullptr);
725 void* peer = handle->peer();
726 ApiState* state = isolate_group->api_state();
727 ASSERT(state != nullptr);
728
729 if (!handle->auto_delete()) {
730 // Clear handle before running finalizer, finalizer can free the handle.
731 state->ClearWeakPersistentHandle(handle);
732 }
733
734 (*callback)(isolate_group->embedder_data(), peer);
735
736 if (handle->auto_delete()) {
737 state->FreeWeakPersistentHandle(handle);
738 }
739}
740
741// --- Handles ---
742
744 Thread* thread = Thread::Current();
745 TransitionNativeToVM transition(thread);
746 return Api::IsError(handle);
747}
748
750 Isolate* isolate = reinterpret_cast<Isolate*>(handle);
751 CHECK_ISOLATE(isolate);
753}
754
756 Thread* thread = Thread::Current();
757 TransitionNativeToVM transition(thread);
758 return Api::ClassId(object) == kApiErrorCid;
759}
760
762 Thread* thread = Thread::Current();
763 TransitionNativeToVM transition(thread);
764 return Api::ClassId(object) == kUnhandledExceptionCid;
765}
766
771 UnhandledException::Cast(Object::Handle(Z, Api::UnwrapHandle(object)));
772 const Instance& exc = Instance::Handle(Z, error.exception());
773 return IsCompiletimeErrorObject(Z, exc);
774 }
775
776 Thread* thread = Thread::Current();
777 TransitionNativeToVM transition(thread);
778 return Api::ClassId(object) == kLanguageErrorCid;
779}
780
782 Thread* thread = Thread::Current();
783 TransitionNativeToVM transition(thread);
784 return Api::ClassId(object) == kUnwindErrorCid;
785}
786
790 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
791 return GetErrorString(T, obj);
792}
793
796 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
797 return obj.IsUnhandledException();
798}
799
802 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
803 if (obj.IsUnhandledException()) {
804 const UnhandledException& error = UnhandledException::Cast(obj);
805 return Api::NewHandle(T, error.exception());
806 } else if (obj.IsError()) {
807 return Api::NewError("This error is not an unhandled exception error.");
808 } else {
809 return Api::NewError("Can only get exceptions from error handles.");
810 }
811}
812
815 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
816 if (obj.IsUnhandledException()) {
817 const UnhandledException& error = UnhandledException::Cast(obj);
818 return Api::NewHandle(T, error.stacktrace());
819 } else if (obj.IsError()) {
820 return Api::NewError("This error is not an unhandled exception error.");
821 } else {
822 return Api::NewError("Can only get stacktraces from error handles.");
823 }
824}
825
829
831 return Api::NewHandle(T, ApiError::New(message));
832}
833
837
839 return Api::NewHandle(T, LanguageError::New(message));
840}
841
845
847 intptr_t class_id = Api::ClassId(exception);
848 if ((class_id == kApiErrorCid) || (class_id == kLanguageErrorCid)) {
849 const Object& excp = Object::Handle(Z, Api::UnwrapHandle(exception));
850 obj = String::New(GetErrorString(T, excp));
851 } else {
852 obj = Api::UnwrapInstanceHandle(Z, exception).ptr();
853 if (obj.IsNull()) {
854 RETURN_TYPE_ERROR(Z, exception, Instance);
855 }
856 }
857 const StackTrace& stacktrace = StackTrace::Handle(Z);
858 return Api::NewHandle(T, UnhandledException::New(obj, stacktrace));
859}
860
862 Thread* thread = Thread::Current();
863 CHECK_ISOLATE(thread->isolate());
864 TransitionNativeToVM transition(thread);
865 const Object& obj = Object::Handle(thread->zone(), Api::UnwrapHandle(handle));
866 if (!obj.IsError()) {
867 FATAL(
868 "%s expects argument 'handle' to be an error handle. "
869 "Did you forget to check Dart_IsError first?",
871 }
872 if (thread->top_exit_frame_info() == 0) {
873 // There are no dart frames on the stack so it would be illegal to
874 // propagate an error here.
875 FATAL("No Dart frames on stack, cannot propagate error.");
876 }
877 // Unwind all the API scopes till the exit frame before propagating.
878 const Error* error;
879 {
880 // We need to preserve the error object across the destruction of zones
881 // when the ApiScopes are unwound. By using NoSafepointScope, we can ensure
882 // that GC won't touch the raw error object before creating a valid
883 // handle for it in the surviving zone.
884 NoSafepointScope no_safepoint;
885 ErrorPtr raw_error = Api::UnwrapErrorHandle(thread->zone(), handle).ptr();
886 thread->UnwindScopes(thread->top_exit_frame_info());
887 // Note that thread's zone is different here than at the beginning of this
888 // function.
889 error = &Error::Handle(thread->zone(), raw_error);
890 }
892 UNREACHABLE();
893}
894
897 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
898 if (obj.IsString()) {
899 return Api::NewHandle(T, obj.ptr());
900 } else if (obj.IsInstance()) {
902 const Instance& receiver = Instance::Cast(obj);
904 } else {
906 // This is a VM internal object. Call the C++ method of printing.
907 return Api::NewHandle(T, String::New(obj.ToCString()));
908 }
909}
910
913 {
914 NoSafepointScope no_safepoint_scope;
915 if (Api::UnwrapHandle(obj1) == Api::UnwrapHandle(obj2)) {
916 return true;
917 }
918 }
919 const Object& object1 = Object::Handle(Z, Api::UnwrapHandle(obj1));
920 const Object& object2 = Object::Handle(Z, Api::UnwrapHandle(obj2));
921 if (object1.IsInstance() && object2.IsInstance()) {
922 return Instance::Cast(object1).IsIdenticalTo(Instance::Cast(object2));
923 }
924 return false;
925}
926
929 Thread* thread = Thread::Current();
930 Isolate* isolate = thread->isolate();
931 CHECK_ISOLATE(isolate);
932 ApiState* state = isolate->group()->api_state();
933 ASSERT(state != nullptr);
934 TransitionNativeToVM transition(thread);
935 NoSafepointScope no_safepoint_scope;
937 return Api::NewHandle(thread, ref->ptr());
938}
939
942 Thread* thread = Thread::Current();
943 Isolate* isolate = thread->isolate();
944 CHECK_ISOLATE(isolate);
945 ApiState* state = isolate->group()->api_state();
946 ASSERT(state != nullptr);
947 TransitionNativeToVM transition(thread);
948 NoSafepointScope no_safepoint_scope;
951 if (weak_ref->IsFinalizedNotFreed()) {
952 return Dart_Null();
953 }
954 return Api::NewHandle(thread, weak_ref->ptr());
955}
956
958 Thread* thread = Thread::Current();
959 Isolate* isolate = thread->isolate();
960 CHECK_ISOLATE(isolate);
961 ApiState* state = isolate->group()->api_state();
962 ASSERT(state != nullptr);
963 TransitionNativeToVM transition(thread);
964 NoSafepointScope no_safepoint_scope;
967 return Api::NewHandle(thread, weak_ref->ptr());
968}
969
972 Isolate* I = T->isolate();
973 ApiState* state = I->group()->api_state();
974 ASSERT(state != nullptr);
975 const Object& old_ref = Object::Handle(Z, Api::UnwrapHandle(object));
976 PersistentHandle* new_ref = state->AllocatePersistentHandle();
977 new_ref->set_ptr(old_ref);
978 return new_ref->apiHandle();
979}
980
982 Dart_Handle obj2) {
984 Isolate* I = T->isolate();
985 ApiState* state = I->group()->api_state();
986 ASSERT(state != nullptr);
987 ASSERT(state->IsValidPersistentHandle(obj1));
988 const Object& obj2_ref = Object::Handle(Z, Api::UnwrapHandle(obj2));
990 obj1_ref->set_ptr(obj2_ref);
991}
992
993static bool IsFfiCompound(Thread* T, const Object& obj) {
994 if (obj.IsNull()) {
995 return false;
996 }
997
998 // CFE guarantees we can only have direct subclasses of `Struct` and `Union`
999 // (no implementations or indirect subclasses are allowed).
1000 const auto& klass = Class::Handle(Z, obj.clazz());
1001 const auto& super_klass = Class::Handle(Z, klass.SuperClass());
1002 if (super_klass.IsNull()) {
1003 // This means klass is Object.
1004 return false;
1005 }
1006 if (super_klass.Name() != Symbols::Struct().ptr() &&
1007 super_klass.Name() != Symbols::Union().ptr()) {
1008 return false;
1009 }
1010 const auto& library = Library::Handle(Z, super_klass.library());
1011 return library.url() == Symbols::DartFfi().ptr();
1012}
1013
1015 Thread* thread,
1016 const Object& ref,
1017 void* peer,
1018 intptr_t external_allocation_size,
1020 if (!ref.ptr()->IsHeapObject()) {
1021 return nullptr;
1022 }
1023 if (ref.IsPointer()) {
1024 return nullptr;
1025 }
1026 if (IsFfiCompound(thread, ref)) {
1027 return nullptr;
1028 }
1029
1030 FinalizablePersistentHandle* finalizable_ref =
1032 callback, external_allocation_size,
1033 /*auto_delete=*/false);
1034 return finalizable_ref == nullptr
1035 ? nullptr
1036 : finalizable_ref->ApiWeakPersistentHandle();
1037}
1038
1040 Thread* T,
1041 Dart_Handle object,
1042 void* peer,
1043 intptr_t external_allocation_size,
1045 const auto& ref = Object::Handle(Z, Api::UnwrapHandle(object));
1046 return AllocateWeakPersistentHandle(T, ref, peer, external_allocation_size,
1047 callback);
1048}
1049
1051 Thread* thread,
1052 const Object& ref,
1053 void* peer,
1054 intptr_t external_allocation_size,
1056 if (!ref.ptr()->IsHeapObject()) {
1057 return nullptr;
1058 }
1059 if (ref.IsPointer()) {
1060 return nullptr;
1061 }
1062 if (IsFfiCompound(thread, ref)) {
1063 return nullptr;
1064 }
1065
1066 FinalizablePersistentHandle* finalizable_ref =
1068 callback, external_allocation_size,
1069 /*auto_delete=*/true);
1070 return finalizable_ref == nullptr ? nullptr
1071 : finalizable_ref->ApiFinalizableHandle();
1072}
1073
1075 Thread* T,
1076 Dart_Handle object,
1077 void* peer,
1078 intptr_t external_allocation_size,
1080 const auto& ref = Object::Handle(Z, Api::UnwrapHandle(object));
1081 return AllocateFinalizableHandle(T, ref, peer, external_allocation_size,
1082 callback);
1083}
1084
1087 void* peer,
1088 intptr_t external_allocation_size,
1091 if (callback == nullptr) {
1092 return nullptr;
1093 }
1094
1095 return AllocateWeakPersistentHandle(T, object, peer, external_allocation_size,
1096 callback);
1097}
1098
1101 void* peer,
1102 intptr_t external_allocation_size,
1105 if (callback == nullptr) {
1106 return nullptr;
1107 }
1108
1109 return AllocateFinalizableHandle(T, object, peer, external_allocation_size,
1110 callback);
1111}
1112
1115 IsolateGroup* isolate_group = T->isolate_group();
1116 CHECK_ISOLATE_GROUP(isolate_group);
1117 TransitionToVM transition(T);
1118 ApiState* state = isolate_group->api_state();
1119 ASSERT(state != nullptr);
1120 ASSERT(state->IsActivePersistentHandle(object));
1122 if (!Api::IsProtectedHandle(object)) {
1124 state->FreePersistentHandle(ref);
1125 }
1126}
1127
1131 IsolateGroup* isolate_group = T->isolate_group();
1132 CHECK_ISOLATE_GROUP(isolate_group);
1133 TransitionToVM transition(T);
1134 ApiState* state = isolate_group->api_state();
1135 ASSERT(state != nullptr);
1136 ASSERT(state->IsActiveWeakPersistentHandle(object));
1137 auto weak_ref = FinalizablePersistentHandle::Cast(object);
1138 weak_ref->EnsureFreedExternal(isolate_group);
1139 state->FreeWeakPersistentHandle(weak_ref);
1140}
1141
1144 Dart_Handle strong_ref_to_object) {
1145 if (!::Dart_IdentityEquals(strong_ref_to_object,
1146 HandleFromFinalizable(object))) {
1147 FATAL(
1148 "%s expects arguments 'object' and 'strong_ref_to_object' to point to "
1149 "the same object.",
1150 CURRENT_FUNC);
1151 }
1152
1153 auto wph_object = reinterpret_cast<Dart_WeakPersistentHandle>(object);
1154
1156}
1157
1158// --- Initialization and Globals ---
1159
1161 return Version::String();
1162}
1163
1165 if (params == nullptr) {
1166 return Utils::StrDup(
1167 "Dart_Initialize: "
1168 "Dart_InitializeParams is null.");
1169 }
1170
1172 return Utils::StrDup(
1173 "Dart_Initialize: "
1174 "Invalid Dart_InitializeParams version.");
1175 }
1176
1177 return Dart::Init(params);
1178}
1179
1182 return Dart::Cleanup();
1183}
1184
1185DART_EXPORT char* Dart_SetVMFlags(int argc, const char** argv) {
1187}
1188
1189DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name) {
1190 return Flags::IsSet(flag_name);
1191}
1192
1193#define ISOLATE_GROUP_METRIC_API(type, variable, name, unit) \
1194 DART_EXPORT int64_t Dart_IsolateGroup##variable##Metric( \
1195 Dart_IsolateGroup isolate_group) { \
1196 if (isolate_group == nullptr) { \
1197 FATAL("%s expects argument 'isolate_group' to be non-null.", \
1198 CURRENT_FUNC); \
1199 } \
1200 IsolateGroup* group = reinterpret_cast<IsolateGroup*>(isolate_group); \
1201 return group->Get##variable##Metric()->Value(); \
1202 }
1204#undef ISOLATE_GROUP_METRIC_API
1205
1206#if !defined(PRODUCT)
1207#define ISOLATE_METRIC_API(type, variable, name, unit) \
1208 DART_EXPORT int64_t Dart_Isolate##variable##Metric(Dart_Isolate isolate) { \
1209 if (isolate == nullptr) { \
1210 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC); \
1211 } \
1212 Isolate* iso = reinterpret_cast<Isolate*>(isolate); \
1213 return iso->Get##variable##Metric()->Value(); \
1214 }
1216#undef ISOLATE_METRIC_API
1217#else // !defined(PRODUCT)
1218#define ISOLATE_METRIC_API(type, variable, name, unit) \
1219 DART_EXPORT int64_t Dart_Isolate##variable##Metric(Dart_Isolate isolate) { \
1220 return -1; \
1221 }
1223#undef ISOLATE_METRIC_API
1224#endif // !defined(PRODUCT)
1225
1226// --- Isolates ---
1227
1229 bool is_new_group,
1230 const char* name,
1231 void* isolate_data,
1232 char** error) {
1234
1235 auto source = group->source();
1237 if (I == nullptr) {
1238 if (error != nullptr) {
1239 *error = Utils::StrDup("Isolate creation failed");
1240 }
1241 return static_cast<Dart_Isolate>(nullptr);
1242 }
1243
1245 bool success = false;
1246 {
1247 StackZone zone(T);
1248 HandleScope handle_scope(T);
1249
1250#if defined(SUPPORT_TIMELINE)
1251 TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
1252 "InitializeIsolate");
1253 tbes.SetNumArguments(1);
1254 tbes.CopyArgument(0, "isolateName", I->name());
1255#endif
1256
1257 // We enter an API scope here as InitializeIsolate could compile some
1258 // bootstrap library files which call out to a tag handler that may create
1259 // Api Handles when an error is encountered.
1260 T->EnterApiScope();
1261 auto& error_obj = Error::Handle(Z);
1262 if (is_new_group) {
1263 error_obj = Dart::InitializeIsolateGroup(
1264 T, source->snapshot_data, source->snapshot_instructions,
1265 source->kernel_buffer, source->kernel_buffer_size);
1266 }
1267 if (error_obj.IsNull()) {
1268 error_obj = Dart::InitializeIsolate(T, is_new_group, isolate_data);
1269 }
1270 if (error_obj.IsNull()) {
1271#if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
1272 if (FLAG_check_function_fingerprints && !FLAG_precompiled_mode) {
1273 Library::CheckFunctionFingerprints();
1274 }
1275#endif // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
1276 success = true;
1277 } else if (error != nullptr) {
1278 *error = Utils::StrDup(error_obj.ToErrorCString());
1279 }
1280 // We exit the API scope entered above.
1281 T->ExitApiScope();
1282 }
1283
1284 if (success) {
1285 // A Thread structure has been associated to the thread, we do the
1286 // safepoint transition explicitly here instead of using the
1287 // TransitionXXX scope objects as the reverse transition happens
1288 // outside this scope in Dart_ShutdownIsolate/Dart_ExitIsolate.
1289 T->set_execution_state(Thread::kThreadInNative);
1290 T->EnterSafepoint();
1291 if (error != nullptr) {
1292 *error = nullptr;
1293 }
1294 return Api::CastIsolate(I);
1295 }
1296
1298 return static_cast<Dart_Isolate>(nullptr);
1299}
1300
1302 const char* name,
1303 char** error) {
1306
1307 auto spawning_group = group;
1308
1309 Isolate* isolate = reinterpret_cast<Isolate*>(
1310 CreateIsolate(spawning_group, /*is_new_group=*/false, name,
1311 /*isolate_data=*/nullptr, error));
1312 if (isolate == nullptr) return nullptr;
1313
1314 auto source = spawning_group->source();
1315 ASSERT(isolate->source() == source);
1316
1317 return isolate;
1318}
1319
1322}
1323
1325Dart_CreateIsolateGroup(const char* script_uri,
1326 const char* name,
1327 const uint8_t* snapshot_data,
1328 const uint8_t* snapshot_instructions,
1330 void* isolate_group_data,
1331 void* isolate_data,
1332 char** error) {
1334
1335 Dart_IsolateFlags api_flags;
1336 if (flags == nullptr) {
1337 Isolate::FlagsInitialize(&api_flags);
1338 flags = &api_flags;
1339 }
1340
1341 const char* non_null_name = name == nullptr ? "isolate" : name;
1342 std::unique_ptr<IsolateGroupSource> source(
1343 new IsolateGroupSource(script_uri, non_null_name, snapshot_data,
1344 snapshot_instructions, nullptr, -1, *flags));
1345 auto group = new IsolateGroup(std::move(source), isolate_group_data, *flags,
1346 /*is_vm_isolate=*/false);
1347 group->CreateHeap(
1348 /*is_vm_isolate=*/false,
1349 flags->is_service_isolate || flags->is_kernel_isolate);
1351 Dart_Isolate isolate = CreateIsolate(group, /*is_new_group=*/true,
1352 non_null_name, isolate_data, error);
1353 if (isolate != nullptr) {
1354 group->set_initial_spawn_successful();
1355 }
1356 return isolate;
1357}
1358
1361 const char* name,
1362 const uint8_t* kernel_buffer,
1363 intptr_t kernel_buffer_size,
1365 void* isolate_group_data,
1366 void* isolate_data,
1367 char** error) {
1369
1370 Dart_IsolateFlags api_flags;
1371 if (flags == nullptr) {
1372 Isolate::FlagsInitialize(&api_flags);
1373 flags = &api_flags;
1374 }
1375
1376 const char* non_null_name = name == nullptr ? "isolate" : name;
1377 std::shared_ptr<IsolateGroupSource> source(
1378 new IsolateGroupSource(script_uri, non_null_name, nullptr, nullptr,
1379 kernel_buffer, kernel_buffer_size, *flags));
1380 auto group = new IsolateGroup(source, isolate_group_data, *flags,
1381 /*is_vm_isolate=*/false);
1383 group->CreateHeap(
1384 /*is_vm_isolate=*/false,
1385 flags->is_service_isolate || flags->is_kernel_isolate);
1386 Dart_Isolate isolate = CreateIsolate(group, /*is_new_group=*/true,
1387 non_null_name, isolate_data, error);
1388 if (isolate != nullptr) {
1389 group->set_initial_spawn_successful();
1390 }
1391 return isolate;
1392}
1393
1396 const char* name,
1397 Dart_IsolateShutdownCallback shutdown_callback,
1398 Dart_IsolateCleanupCallback cleanup_callback,
1399 void* child_isolate_data,
1400 char** error) {
1402 auto member = reinterpret_cast<Isolate*>(group_member);
1403 if (member->IsScheduled()) {
1404 FATAL("The given member isolate (%s) must not have been entered.",
1405 member->name());
1406 }
1407
1408 *error = nullptr;
1409
1410 Isolate* isolate;
1411 isolate = CreateWithinExistingIsolateGroup(member->group(), name, error);
1412 if (isolate != nullptr) {
1413 isolate->set_origin_id(member->origin_id());
1414 isolate->set_init_callback_data(child_isolate_data);
1415 isolate->set_on_shutdown_callback(shutdown_callback);
1416 isolate->set_on_cleanup_callback(cleanup_callback);
1417 }
1418
1419 return Api::CastIsolate(isolate);
1420}
1421
1424 auto I = T->isolate();
1426
1427 // The Thread structure is disassociated from the isolate, we do the
1428 // safepoint transition explicitly here instead of using the TransitionXXX
1429 // scope objects as the original transition happened outside this scope in
1430 // Dart_EnterIsolate/Dart_CreateIsolateGroup.
1431 ASSERT(T->execution_state() == Thread::kThreadInNative);
1432 T->ExitSafepoint();
1433 T->set_execution_state(Thread::kThreadInVM);
1434
1435 I->WaitForOutstandingSpawns();
1436
1437 // Release any remaining API scopes.
1438 ApiLocalScope* scope = T->api_top_scope();
1439 while (scope != nullptr) {
1440 ApiLocalScope* previous = scope->previous();
1441 delete scope;
1442 scope = previous;
1443 }
1444 T->set_api_top_scope(nullptr);
1445
1446 {
1447 StackZone zone(T);
1448 HandleScope handle_scope(T);
1450 }
1452}
1453
1456}
1457
1459 Isolate* isolate = Isolate::Current();
1460 CHECK_ISOLATE(isolate);
1461 NoSafepointScope no_safepoint_scope;
1462 return isolate->init_callback_data();
1463}
1464
1466 if (isolate == nullptr) {
1467 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
1468 }
1469 // TODO(http://dartbug.com/16615): Validate isolate parameter.
1470 return reinterpret_cast<Isolate*>(isolate)->init_callback_data();
1471}
1472
1475}
1476
1478 IsolateGroup* isolate_group = IsolateGroup::Current();
1479 CHECK_ISOLATE_GROUP(isolate_group);
1480 NoSafepointScope no_safepoint_scope;
1481 return isolate_group->embedder_data();
1482}
1483
1485 IsolateGroup* isolate_group = IsolateGroup::Current();
1486 CHECK_ISOLATE_GROUP(isolate_group);
1487 return isolate_group->id();
1488}
1489
1491 if (isolate == nullptr) {
1492 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
1493 }
1494 // TODO(http://dartbug.com/16615): Validate isolate parameter.
1495 return reinterpret_cast<Isolate*>(isolate)->group()->embedder_data();
1496}
1497
1500 Isolate* I = T->isolate();
1501 return Api::NewHandle(
1502 T, String::NewFormatted("(%" Pd64 ") '%s'",
1503 static_cast<int64_t>(I->main_port()), I->name()));
1504}
1505
1507 Thread* thread = Thread::Current();
1508 if (thread == nullptr) {
1509 return nullptr;
1510 }
1511 Isolate* I = thread->isolate();
1512 if (I == nullptr) {
1513 return nullptr;
1514 }
1515 int64_t main_port = static_cast<int64_t>(I->main_port());
1516 const char* fmt = "%s (%" Pd64 ")";
1517 int length = snprintf(nullptr, 0, fmt, I->name(), main_port) + 1;
1518 char* res = Api::TopScope(thread)->zone()->Alloc<char>(length);
1519 snprintf(res, length, fmt, I->name(), main_port);
1520 return res;
1521}
1522
1524 if (isolate == nullptr) {
1525 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
1526 }
1527 // TODO(http://dartbug.com/16615): Validate isolate parameter.
1528 Isolate* I = reinterpret_cast<Isolate*>(isolate);
1529 int64_t main_port = static_cast<int64_t>(I->main_port());
1530 return OS::SCreate(nullptr, "isolates/%" Pd64, main_port);
1531}
1532
1535 // TODO(http://dartbug.com/16615): Validate isolate parameter.
1536 Isolate* iso = reinterpret_cast<Isolate*>(isolate);
1537 if (iso->IsScheduled()) {
1538 FATAL(
1539 "Isolate %s is already scheduled on mutator thread %p, "
1540 "failed to schedule from os thread 0x%" Px "\n",
1541 iso->name(), iso->scheduled_mutator_thread(),
1543 }
1545 // A Thread structure has been associated to the thread, we do the
1546 // safepoint transition explicitly here instead of using the
1547 // TransitionXXX scope objects as the reverse transition happens
1548 // outside this scope in Dart_ExitIsolate/Dart_ShutdownIsolate.
1550 T->set_execution_state(Thread::kThreadInNative);
1551 T->EnterSafepoint();
1552}
1553
1555#if !defined(PRODUCT)
1556 if (!FLAG_profiler) {
1557 FLAG_profiler = true;
1559 }
1560#endif // !defined(PRODUCT)
1561}
1562
1564#if !defined(PRODUCT)
1565 if (FLAG_profiler) {
1567 FLAG_profiler = false;
1568 }
1569#endif // !defined(PRODUCT)
1570}
1571
1573#if !defined(PRODUCT)
1574 OSThread* os_thread = OSThread::Current();
1575 if (os_thread == nullptr) {
1576 return;
1577 }
1578 os_thread->DisableThreadInterrupts();
1579#endif // !defined(PRODUCT)
1580}
1581
1583#if !defined(PRODUCT)
1584 OSThread* os_thread = OSThread::Current();
1585 if (os_thread == nullptr) {
1586 return;
1587 }
1588 os_thread->EnableThreadInterrupts();
1589#endif // !defined(PRODUCT)
1590}
1591
1592DART_EXPORT void Dart_AddSymbols(const char* dso_name,
1593 void* buffer,
1594 intptr_t buffer_size) {
1596}
1597
1599 char** error) {
1600#if defined(PRODUCT)
1601 return false;
1602#else
1603 if (!FLAG_profiler) {
1604 if (error != nullptr) {
1605 *error = Utils::StrDup("The profiler is not running.");
1606 }
1607 return false;
1608 }
1609
1610 const intptr_t kBufferLength = 512;
1611 char method[kBufferLength];
1612
1613 // clang-format off
1614 intptr_t method_length = snprintf(method, kBufferLength, "{"
1615 "\"jsonrpc\": \"2.0\","
1616 "\"method\": \"_writeCpuProfileTimeline\","
1617 "\"id\": \"\","
1618 "\"params\": {"
1619 " \"isolateId\": \"isolates/%" Pd64 "\","
1620 " \"tags\": \"None\""
1621 "}"
1622 "}", main_port);
1623 // clang-format on
1624 ASSERT(method_length <= kBufferLength);
1625
1626 char* response = nullptr;
1627 intptr_t response_length;
1628 bool success = Dart_InvokeVMServiceMethod(
1629 reinterpret_cast<uint8_t*>(method), method_length,
1630 reinterpret_cast<uint8_t**>(&response), &response_length, error);
1631 free(response);
1632 return success;
1633#endif
1634}
1635
1637#if defined(PRODUCT)
1638 return false;
1639#else
1640 Isolate* isolate = Isolate::Current();
1641 CHECK_ISOLATE(isolate);
1642 NoSafepointScope no_safepoint_scope;
1643 return isolate->message_handler()->should_pause_on_start();
1644#endif
1645}
1646
1648#if defined(PRODUCT)
1649 if (should_pause) {
1650 FATAL("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
1651 }
1652#else
1653 Isolate* isolate = Isolate::Current();
1654 CHECK_ISOLATE(isolate);
1655 NoSafepointScope no_safepoint_scope;
1656 if (isolate->is_runnable()) {
1657 FATAL("%s expects the current isolate to not be runnable yet.",
1658 CURRENT_FUNC);
1659 }
1660 isolate->message_handler()->set_should_pause_on_start(should_pause);
1661#endif
1662}
1663
1665#if defined(PRODUCT)
1666 return false;
1667#else
1668 Isolate* isolate = Isolate::Current();
1669 CHECK_ISOLATE(isolate);
1670 NoSafepointScope no_safepoint_scope;
1671 return isolate->message_handler()->is_paused_on_start();
1672#endif
1673}
1674
1676#if defined(PRODUCT)
1677 if (paused) {
1678 FATAL("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
1679 }
1680#else
1681 Isolate* isolate = Isolate::Current();
1682 CHECK_ISOLATE(isolate);
1683 NoSafepointScope no_safepoint_scope;
1684 if (isolate->message_handler()->is_paused_on_start() != paused) {
1685 isolate->message_handler()->PausedOnStart(paused);
1686 }
1687#endif
1688}
1689
1691#if defined(PRODUCT)
1692 return false;
1693#else
1694 Isolate* isolate = Isolate::Current();
1695 CHECK_ISOLATE(isolate);
1696 NoSafepointScope no_safepoint_scope;
1697 return isolate->message_handler()->should_pause_on_exit();
1698#endif
1699}
1700
1702#if defined(PRODUCT)
1703 if (should_pause) {
1704 FATAL("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
1705 }
1706#else
1707 Isolate* isolate = Isolate::Current();
1708 CHECK_ISOLATE(isolate);
1709 NoSafepointScope no_safepoint_scope;
1710 isolate->message_handler()->set_should_pause_on_exit(should_pause);
1711#endif
1712}
1713
1715#if defined(PRODUCT)
1716 return false;
1717#else
1718 Isolate* isolate = Isolate::Current();
1719 CHECK_ISOLATE(isolate);
1720 NoSafepointScope no_safepoint_scope;
1721 return isolate->message_handler()->is_paused_on_exit();
1722#endif
1723}
1724
1726#if defined(PRODUCT)
1727 if (paused) {
1728 FATAL("%s(true) is not supported in a PRODUCT build", CURRENT_FUNC);
1729 }
1730#else
1731 Isolate* isolate = Isolate::Current();
1732 CHECK_ISOLATE(isolate);
1733 NoSafepointScope no_safepoint_scope;
1734 if (isolate->message_handler()->is_paused_on_exit() != paused) {
1735 isolate->message_handler()->PausedOnExit(paused);
1736 }
1737#endif
1738}
1739
1741 Thread* thread = Thread::Current();
1742 DARTSCOPE(thread);
1743 Isolate* isolate = thread->isolate();
1744 CHECK_ISOLATE(isolate);
1745 NoSafepointScope no_safepoint_scope;
1746 const Error& error_handle = Api::UnwrapErrorHandle(Z, error);
1747 if ((isolate->sticky_error() != Error::null()) &&
1748 (error_handle.ptr() != Object::null())) {
1749 FATAL("%s expects there to be no sticky error.", CURRENT_FUNC);
1750 }
1751 if (!error_handle.IsUnhandledException() &&
1752 (error_handle.ptr() != Object::null())) {
1753 FATAL("%s expects the error to be an unhandled exception error or null.",
1754 CURRENT_FUNC);
1755 }
1756 isolate->SetStickyError(error_handle.ptr());
1757}
1758
1761 Isolate* isolate = T->isolate();
1762 CHECK_ISOLATE(isolate);
1763 NoSafepointScope no_safepoint_scope;
1764 return isolate->sticky_error() != Error::null();
1765}
1766
1769 Isolate* I = T->isolate();
1771 {
1772 NoSafepointScope no_safepoint_scope;
1773 if (I->sticky_error() == Error::null()) {
1774 return Api::Null();
1775 }
1776 }
1777 TransitionNativeToVM transition(T);
1778 return Api::NewHandle(T, I->sticky_error());
1779}
1780
1781DART_EXPORT void Dart_NotifyIdle(int64_t deadline) {
1783 CHECK_ISOLATE(T->isolate());
1785 TransitionNativeToVM transition(T);
1786 T->isolate()->group()->idle_time_handler()->NotifyIdle(deadline);
1787}
1788
1791 CHECK_ISOLATE(T->isolate());
1793 TransitionNativeToVM transition(T);
1794 T->heap()->NotifyDestroyed();
1795}
1796
1798#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1800#endif
1801}
1802
1804#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1806#endif
1807}
1808
1810 Dart_HeapSamplingCreateCallback create_callback,
1811 Dart_HeapSamplingDeleteCallback delete_callback) {
1812#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1813 HeapProfileSampler::SetSamplingCallback(create_callback, delete_callback);
1814#endif
1815}
1816
1819 void* context,
1820 bool force_gc) {
1821#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1825 /*bypass_safepoint=*/false);
1826 if (force_gc) {
1827 group->heap()->CollectAllGarbage(GCReason::kDebugging);
1828 }
1829 group->heap()->ReportSurvivingAllocations(callback, context);
1830 Thread::ExitIsolateGroupAsHelper(/*bypass_safepoint=*/false);
1831 });
1832#endif
1833}
1834
1836#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
1838#endif
1839}
1840
1845
1846 // For each isolate's global variables, we might also clear:
1847 // - RegExp backtracking stack (both bytecode and compiled versions)
1848 // - String -> RegExp cache
1849 // - BigInt division/remainder cache
1850 // - double.toString cache
1851 // But cache invalidation code might be larger than the expected size of some
1852 // caches.
1853}
1854
1858 CHECK_ISOLATE(T->isolate());
1859 TransitionNativeToVM transition(T);
1860 return T->heap()->SetMode(mode);
1861}
1862
1865 CHECK_ISOLATE(T->isolate());
1866 // The Thread structure is disassociated from the isolate, we do the
1867 // safepoint transition explicitly here instead of using the TransitionXXX
1868 // scope objects as the original transition happened outside this scope in
1869 // Dart_EnterIsolate/Dart_CreateIsolateGroup.
1870 ASSERT(T->execution_state() == Thread::kThreadInNative);
1871 T->ExitSafepoint();
1872 T->set_execution_state(Thread::kThreadInVM);
1874}
1875
1877Dart_CreateSnapshot(uint8_t** vm_snapshot_data_buffer,
1878 intptr_t* vm_snapshot_data_size,
1879 uint8_t** isolate_snapshot_data_buffer,
1880 intptr_t* isolate_snapshot_data_size,
1881 bool is_core) {
1882#if defined(DART_PRECOMPILED_RUNTIME)
1883 return Api::NewError("Cannot create snapshots on an AOT runtime.");
1884#else
1887 if (vm_snapshot_data_buffer != nullptr) {
1888 CHECK_NULL(vm_snapshot_data_size);
1889 }
1890 CHECK_NULL(isolate_snapshot_data_buffer);
1891 CHECK_NULL(isolate_snapshot_data_size);
1892 // Finalize all classes if needed.
1894 if (Api::IsError(state)) {
1895 return state;
1896 }
1897 NoBackgroundCompilerScope no_bg_compiler(T);
1898
1899#if defined(DEBUG)
1900 T->isolate_group()->heap()->CollectAllGarbage(GCReason::kDebugging);
1901 {
1902 HeapIterationScope iteration(T);
1903 CheckFunctionTypesVisitor check_canonical(T);
1904 iteration.IterateObjects(&check_canonical);
1905 }
1906#endif // #if defined(DEBUG)
1907
1914 FullSnapshotWriter writer(
1916 nullptr /* vm_image_writer */, nullptr /* isolate_image_writer */);
1917 writer.WriteFullSnapshot();
1918 if (vm_snapshot_data_buffer != nullptr) {
1919 *vm_snapshot_data_buffer = vm_snapshot_data.buffer();
1920 *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
1921 }
1922 *isolate_snapshot_data_buffer = isolate_snapshot_data.buffer();
1923 *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
1924 return Api::Success();
1925#endif
1926}
1927
1928DART_EXPORT bool Dart_IsKernel(const uint8_t* buffer, intptr_t buffer_size) {
1929 if (buffer_size < 4) {
1930 return false;
1931 }
1932 return (buffer[0] == 0x90) && (buffer[1] == 0xab) && (buffer[2] == 0xcd) &&
1933 (buffer[3] == 0xef);
1934}
1935
1939 if (isolate == nullptr) {
1940 FATAL("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
1941 }
1942 // TODO(16615): Validate isolate parameter.
1943 const char* error = reinterpret_cast<Isolate*>(isolate)->MakeRunnable();
1944 if (error != nullptr) {
1945 return Utils::StrDup(error);
1946 }
1947 return nullptr;
1948}
1949
1950// --- Messages and Ports ---
1951
1953 Dart_MessageNotifyCallback message_notify_callback) {
1954 Isolate* isolate = Isolate::Current();
1955 CHECK_ISOLATE(isolate);
1956
1957 {
1958 NoSafepointScope no_safepoint_scope;
1959 isolate->set_message_notify_callback(message_notify_callback);
1960 }
1961
1962 if (message_notify_callback != nullptr && isolate->HasPendingMessages()) {
1964
1965 // If a new handler gets installed and there are pending messages in the
1966 // queue (e.g. OOB messages for doing vm service work) we need to notify
1967 // the newly registered callback, otherwise the embedder might never get
1968 // notified about the pending messages.
1969 message_notify_callback(Api::CastIsolate(isolate));
1970
1972 }
1973}
1974
1976 Isolate* isolate = Isolate::Current();
1977 CHECK_ISOLATE(isolate);
1978 NoSafepointScope no_safepoint_scope;
1979 return isolate->message_notify_callback();
1980}
1981
1984 bool done;
1985};
1986
1987static void RunLoopDone(uword param) {
1988 RunLoopData* data = reinterpret_cast<RunLoopData*>(param);
1989 ASSERT(data->monitor != nullptr);
1990 MonitorLocker ml(data->monitor);
1991 data->done = true;
1992 ml.Notify();
1993}
1994
1996 Isolate* I;
1997 bool result;
1998 {
2000 I = T->isolate();
2003 }
2005 // The message handler run loop does not expect to have a current isolate
2006 // so we exit the isolate here and enter it again after the runloop is done.
2008 {
2009 Monitor monitor;
2010 MonitorLocker ml(&monitor);
2012 data.monitor = &monitor;
2013 data.done = false;
2014 result =
2015 I->message_handler()->Run(I->group()->thread_pool(), nullptr,
2016 RunLoopDone, reinterpret_cast<uword>(&data));
2017 if (result) {
2018 while (!data.done) {
2019 ml.Wait();
2020 }
2021 }
2022 }
2024 if (!result) {
2026 TransitionNativeToVM transition(T);
2027 return Api::NewError("Run method in isolate message handler failed");
2028 } else if (I->sticky_error() != Object::null()) {
2030 TransitionNativeToVM transition(T);
2031 return Api::NewHandle(T, I->StealStickyError());
2032 }
2033 if (FLAG_print_class_table) {
2035 I->group()->class_table()->Print();
2036 }
2037 return Api::Success();
2038}
2039
2040DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal,
2041 Dart_Port on_error_port,
2042 Dart_Port on_exit_port,
2043 char** error) {
2044 auto thread = Thread::Current();
2045 auto isolate = thread->isolate();
2046 CHECK_ISOLATE(isolate);
2047 *error = nullptr;
2048
2049 if (thread->api_top_scope() != nullptr) {
2050 *error = Utils::StrDup("There must not be an active api scope.");
2051 return false;
2052 }
2053
2054 if (!isolate->is_runnable()) {
2055 const char* error_msg = isolate->MakeRunnable();
2056 if (error_msg != nullptr) {
2057 *error = Utils::StrDup(error_msg);
2058 return false;
2059 }
2060 }
2061
2062 isolate->SetErrorsFatal(errors_are_fatal);
2063
2064 if (on_error_port != ILLEGAL_PORT || on_exit_port != ILLEGAL_PORT) {
2065 auto thread = Thread::Current();
2066 TransitionNativeToVM transition(thread);
2067 StackZone zone(thread);
2068
2069 if (on_error_port != ILLEGAL_PORT) {
2070 const auto& port =
2071 SendPort::Handle(thread->zone(), SendPort::New(on_error_port));
2072 isolate->AddErrorListener(port);
2073 }
2074 if (on_exit_port != ILLEGAL_PORT) {
2075 const auto& port =
2076 SendPort::Handle(thread->zone(), SendPort::New(on_exit_port));
2077 isolate->AddExitListener(port, Instance::null_instance());
2078 }
2079 }
2080
2082 isolate->Run();
2083 return true;
2084}
2085
2088 Isolate* I = T->isolate();
2092 TransitionNativeToVM transition(T);
2093 if (I->message_handler()->HandleNextMessage() != MessageHandler::kOK) {
2094 return Api::NewHandle(T, T->StealStickyError());
2095 }
2096 return Api::Success();
2097}
2098
2100#if defined(PRODUCT)
2101 return true;
2102#else
2104 Isolate* I = T->isolate();
2108 TransitionNativeToVM transition(T);
2109 ASSERT(I->GetAndClearResumeRequest() == false);
2111 I->message_handler()->HandleOOBMessages();
2112 bool resume = I->GetAndClearResumeRequest();
2113 return (status != MessageHandler::kOK) || resume;
2114#endif
2115}
2116
2118#if defined(PRODUCT)
2119 return false;
2120#else
2121 Isolate* isolate = Isolate::Current();
2122 ASSERT(isolate);
2123 NoSafepointScope no_safepoint_scope;
2124 return isolate->message_handler()->HasOOBMessages();
2125#endif
2126}
2127
2129 Isolate* isolate = Isolate::Current();
2130 ASSERT(isolate);
2131 NoSafepointScope no_safepoint_scope;
2132 return isolate->HasLivePorts();
2133}
2134
2138 NoSafepointScope no_safepoint_scope;
2139 if (port_id == ILLEGAL_PORT) {
2140 return false;
2141 }
2142
2143 const Object& object = Object::Handle(Z, Api::UnwrapHandle(handle));
2144 return PortMap::PostMessage(WriteMessage(/* same_group */ false, object,
2145 port_id, Message::kNormalPriority));
2146}
2147
2151 if (port_id == ILLEGAL_PORT) {
2152 return Api::NewError("%s: illegal port_id %" Pd64 ".", CURRENT_FUNC,
2153 port_id);
2154 }
2155 int64_t origin_id = PortMap::GetOriginId(port_id);
2156 return Api::NewHandle(T, SendPort::New(port_id, origin_id));
2157}
2158
2162 if (portex_id.port_id == ILLEGAL_PORT) {
2163 return Api::NewError("%s: illegal port_id %" Pd64 ".", CURRENT_FUNC,
2164 portex_id.port_id);
2165 }
2166 return Api::NewHandle(T,
2167 SendPort::New(portex_id.port_id, portex_id.origin_id));
2168}
2169
2171 Dart_Port* port_id) {
2175 const SendPort& send_port = Api::UnwrapSendPortHandle(Z, port);
2176 if (send_port.IsNull()) {
2178 }
2179 if (port_id == nullptr) {
2180 RETURN_NULL_ERROR(port_id);
2181 }
2182 *port_id = send_port.Id();
2183 return Api::Success();
2184}
2185
2187 Dart_PortEx* portex_id) {
2191 const SendPort& send_port = Api::UnwrapSendPortHandle(Z, port);
2192 if (send_port.IsNull()) {
2194 }
2195 if (portex_id == nullptr) {
2196 RETURN_NULL_ERROR(port_id);
2197 }
2198 portex_id->port_id = send_port.Id();
2199 portex_id->origin_id = send_port.origin_id();
2200 return Api::Success();
2201}
2202
2204 Isolate* isolate = Isolate::Current();
2205 CHECK_ISOLATE(isolate);
2206 return isolate->main_port();
2207}
2208
2209// --- Scopes ----
2210
2212 Thread* thread = Thread::Current();
2213 Isolate* isolate = thread->isolate();
2214 CHECK_ISOLATE(isolate);
2215 TransitionNativeToVM transition(thread);
2216 thread->EnterApiScope();
2217}
2218
2220 Thread* thread = Thread::Current();
2221 CHECK_API_SCOPE(thread);
2222 TransitionNativeToVM transition(thread);
2223 thread->ExitApiScope();
2224}
2225
2227 Zone* zone;
2228 Thread* thread = Thread::Current();
2229 if (thread != nullptr) {
2230 ApiLocalScope* scope = thread->api_top_scope();
2231 zone = scope->zone();
2232 } else {
2234 if (scope == nullptr) return nullptr;
2235 zone = scope->zone();
2236 }
2237 return reinterpret_cast<uint8_t*>(zone->AllocUnsafe(size));
2238}
2239
2240// --- Objects ----
2241
2243 ASSERT(Isolate::Current() != nullptr);
2244 return Api::Null();
2245}
2246
2249 return Api::UnwrapHandle(object) == Object::null();
2250}
2251
2253 ASSERT(Isolate::Current() != nullptr);
2254 return Api::EmptyString();
2255}
2256
2262}
2263
2268 return Api::NewHandle(T, Type::VoidType());
2269}
2270
2275 return Api::NewHandle(T, Type::NeverType());
2276}
2277
2279 Dart_Handle obj2,
2280 bool* value) {
2283 const Instance& expected =
2284 Instance::CheckedHandle(Z, Api::UnwrapHandle(obj1));
2285 const Instance& actual = Instance::CheckedHandle(Z, Api::UnwrapHandle(obj2));
2286 const Object& result =
2287 Object::Handle(Z, DartLibraryCalls::Equals(expected, actual));
2288 if (result.IsBool()) {
2289 *value = Bool::Cast(result).value();
2290 return Api::Success();
2291 } else if (result.IsError()) {
2292 return Api::NewHandle(T, result.ptr());
2293 } else {
2294 return Api::NewError("Expected boolean result from ==");
2295 }
2296}
2297
2298// Assumes type is non-null.
2299static bool InstanceIsType(const Thread* thread,
2300 const Instance& instance,
2301 const Type& type) {
2302 ASSERT(!type.IsNull());
2303 CHECK_CALLBACK_STATE(thread);
2304 return instance.IsInstanceOf(type, Object::null_type_arguments(),
2305 Object::null_type_arguments());
2306}
2307
2310 bool* value) {
2312
2313 const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
2314 if (type_obj.IsNull()) {
2315 *value = false;
2317 }
2318 if (!type_obj.IsFinalized()) {
2319 return Api::NewError(
2320 "%s expects argument 'type' to be a fully resolved type.",
2321 CURRENT_FUNC);
2322 }
2323 if (object == Api::Null()) {
2324 *value = false;
2325 return Api::Success();
2326 }
2327 const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
2328 if (instance.IsNull()) {
2329 *value = false;
2330 RETURN_TYPE_ERROR(Z, object, Instance);
2331 }
2332 *value = InstanceIsType(T, instance, type_obj);
2333 return Api::Success();
2334}
2335
2337 Thread* thread = Thread::Current();
2338 CHECK_ISOLATE(thread->isolate());
2339 TransitionNativeToVM transition(thread);
2341 Object& ref = thread->ObjectHandle();
2342 ref = Api::UnwrapHandle(object);
2343 return ref.IsInstance();
2344}
2345
2347 Thread* thread = Thread::Current();
2348 CHECK_ISOLATE(thread->isolate());
2349 TransitionNativeToVM transition(thread);
2350 return IsNumberClassId(Api::ClassId(object));
2351}
2352
2354 Thread* thread = Thread::Current();
2355 CHECK_ISOLATE(thread->isolate());
2356 TransitionNativeToVM transition(thread);
2357 return IsIntegerClassId(Api::ClassId(object));
2358}
2359
2361 Thread* thread = Thread::Current();
2362 CHECK_ISOLATE(thread->isolate());
2363 TransitionNativeToVM transition(thread);
2364 return Api::ClassId(object) == kDoubleCid;
2365}
2366
2368 Thread* thread = Thread::Current();
2369 CHECK_ISOLATE(thread->isolate());
2370 TransitionNativeToVM transition(thread);
2371 return Api::ClassId(object) == kBoolCid;
2372}
2373
2375 Thread* thread = Thread::Current();
2376 CHECK_ISOLATE(thread->isolate());
2377 TransitionNativeToVM transition(thread);
2378 return IsStringClassId(Api::ClassId(object));
2379}
2380
2382 Thread* thread = Thread::Current();
2383 CHECK_ISOLATE(thread->isolate());
2384 TransitionNativeToVM transition(thread);
2385 return IsOneByteStringClassId(Api::ClassId(object));
2386}
2387
2390 if (IsBuiltinListClassId(Api::ClassId(object))) {
2391 return true;
2392 }
2393
2394 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
2395 return GetListInstance(Z, obj) != Instance::null();
2396}
2397
2400 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
2401 return GetMapInstance(Z, obj) != Instance::null();
2402}
2403
2405 Thread* thread = Thread::Current();
2406 CHECK_ISOLATE(thread->isolate());
2407 TransitionNativeToVM transition(thread);
2408 return Api::ClassId(object) == kLibraryCid;
2409}
2410
2412 Thread* thread = Thread::Current();
2413 CHECK_ISOLATE(thread->isolate());
2414 TransitionNativeToVM transition(thread);
2415 return IsTypeClassId(Api::ClassId(handle));
2416}
2417
2419 Thread* thread = Thread::Current();
2420 CHECK_ISOLATE(thread->isolate());
2421 TransitionNativeToVM transition(thread);
2422 return Api::ClassId(handle) == kFunctionCid;
2423}
2424
2426 Thread* thread = Thread::Current();
2427 CHECK_ISOLATE(thread->isolate());
2428 TransitionNativeToVM transition(thread);
2429 return Api::ClassId(handle) == kFieldCid;
2430}
2431
2433 Thread* thread = Thread::Current();
2434 CHECK_ISOLATE(thread->isolate());
2435 TransitionNativeToVM transition(thread);
2436 return Api::ClassId(handle) == kTypeParameterCid;
2437}
2438
2440 Thread* thread = Thread::Current();
2441 CHECK_ISOLATE(thread->isolate());
2442 TransitionNativeToVM transition(thread);
2443 return Api::ClassId(object) == kClosureCid;
2444}
2445
2449 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
2450 if (obj.IsClosure()) {
2451 const Closure& closure = Closure::Cast(obj);
2452 const Function& func = Function::Handle(Z, closure.function());
2453 return func.IsImplicitClosureFunction();
2454 }
2455 return false;
2456}
2457
2459 Thread* thread = Thread::Current();
2460 CHECK_ISOLATE(thread->isolate());
2461 TransitionNativeToVM transition(thread);
2462 intptr_t cid = Api::ClassId(handle);
2465}
2466
2468 Thread* thread = Thread::Current();
2469 CHECK_ISOLATE(thread->isolate());
2470 TransitionNativeToVM transition(thread);
2471 return Api::ClassId(handle) == kByteBufferCid;
2472}
2473
2477 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
2478 if (obj.IsInstance()) {
2479 const Class& obj_class = Class::Handle(Z, obj.clazz());
2480 return obj_class.is_future_subtype();
2481 }
2482 return false;
2483}
2484
2485// --- Instances ----
2486
2490 auto isolate_group = T->isolate_group();
2492 if (obj.IsNull()) {
2493 return Api::NewHandle(T, isolate_group->object_store()->null_type());
2494 }
2495 if (!obj.IsInstance()) {
2497 }
2498 const AbstractType& type =
2499 AbstractType::Handle(Instance::Cast(obj).GetType(Heap::kNew));
2500 return Api::NewHandle(T, type.Canonicalize(T));
2501}
2502
2505 const Function& func = Api::UnwrapFunctionHandle(Z, function);
2506 if (func.IsNull()) {
2508 }
2509 return Api::NewHandle(T, func.UserVisibleName());
2510}
2511
2514 const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
2515 if (type_obj.IsNull()) {
2516 RETURN_TYPE_ERROR(Z, cls_type, Type);
2517 }
2518 const Class& klass = Class::Handle(Z, type_obj.type_class());
2519 if (klass.IsNull()) {
2520 return Api::NewError(
2521 "cls_type must be a Type object which represents a Class.");
2522 }
2523 return Api::NewHandle(T, klass.UserVisibleName());
2524}
2525
2528 const Function& func = Api::UnwrapFunctionHandle(Z, function);
2529 if (func.IsNull()) {
2531 }
2532 if (func.IsNonImplicitClosureFunction()) {
2533 FunctionPtr parent_function = func.parent_function();
2534 return Api::NewHandle(T, parent_function);
2535 }
2536 const Class& owner = Class::Handle(Z, func.Owner());
2537 ASSERT(!owner.IsNull());
2538 if (owner.IsTopLevel()) {
2539// Top-level functions are implemented as members of a hidden class. We hide
2540// that class here and instead answer the library.
2541#if defined(DEBUG)
2542 const Library& lib = Library::Handle(Z, owner.library());
2543 if (lib.IsNull()) {
2544 ASSERT(owner.IsDynamicClass() || owner.IsVoidClass() ||
2545 owner.IsNeverClass());
2546 }
2547#endif
2548 return Api::NewHandle(T, owner.library());
2549 } else {
2550 return Api::NewHandle(T, owner.RareType());
2551 }
2552}
2553
2555 bool* is_static) {
2557 if (is_static == nullptr) {
2558 RETURN_NULL_ERROR(is_static);
2559 }
2560 const Function& func = Api::UnwrapFunctionHandle(Z, function);
2561 if (func.IsNull()) {
2563 }
2564 *is_static = func.is_static();
2565 return Api::Success();
2566}
2567
2570 const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure);
2571 if (closure_obj.IsNull() || !closure_obj.IsClosure()) {
2573 }
2574
2576
2577 FunctionPtr rf = Closure::Cast(closure_obj).function();
2578 return Api::NewHandle(T, rf);
2579}
2580
2583 const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
2584 const Class& klass = Class::Handle(Z, type_obj.type_class());
2585 if (klass.IsNull()) {
2586 return Api::NewError(
2587 "cls_type must be a Type object which represents a Class.");
2588 }
2589 const Library& library = Library::Handle(klass.library());
2590 if (library.IsNull()) {
2591 return Dart_Null();
2592 }
2593 return Api::NewHandle(Thread::Current(), library.ptr());
2594}
2595
2596// --- Numbers, Integers and Doubles ----
2597
2599 bool* fits) {
2600 // Fast path for Smis and Mints.
2601 Thread* thread = Thread::Current();
2602 API_TIMELINE_DURATION(thread);
2603 Isolate* isolate = thread->isolate();
2604 CHECK_ISOLATE(isolate);
2605 if (Api::IsSmi(integer)) {
2606 *fits = true;
2607 return Api::Success();
2608 }
2609 // Slow path for mints and type error.
2610 DARTSCOPE(thread);
2611 if (Api::ClassId(integer) == kMintCid) {
2612 *fits = true;
2613 return Api::Success();
2614 }
2615 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2616 ASSERT(int_obj.IsNull());
2617 RETURN_TYPE_ERROR(Z, integer, Integer);
2618}
2619
2621 bool* fits) {
2622 // Fast path for Smis.
2623 Thread* thread = Thread::Current();
2624 Isolate* isolate = thread->isolate();
2625 CHECK_ISOLATE(isolate);
2626 API_TIMELINE_DURATION(thread);
2627 if (Api::IsSmi(integer)) {
2628 *fits = (Api::SmiValue(integer) >= 0);
2629 return Api::Success();
2630 }
2631 // Slow path for Mints.
2632 DARTSCOPE(thread);
2633 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2634 if (int_obj.IsNull()) {
2635 RETURN_TYPE_ERROR(Z, integer, Integer);
2636 }
2637 ASSERT(int_obj.IsMint());
2638 *fits = !int_obj.IsNegative();
2639 return Api::Success();
2640}
2641
2643 // Fast path for Smis.
2644 Thread* thread = Thread::Current();
2645 Isolate* isolate = thread->isolate();
2646 CHECK_ISOLATE(isolate);
2647 API_TIMELINE_DURATION(thread);
2648 DARTSCOPE(thread);
2649 CHECK_CALLBACK_STATE(thread);
2650 return Api::NewHandle(thread, Integer::New(value));
2651}
2652
2659 }
2660 return Api::NewError("%s: Cannot create Dart integer from value %" Pu64,
2662}
2663
2668 const String& str_obj = String::Handle(Z, String::New(str));
2669 IntegerPtr integer = Integer::New(str_obj);
2670 if (integer == Integer::null()) {
2671 return Api::NewError("%s: Cannot create Dart integer from string %s",
2672 CURRENT_FUNC, str);
2673 }
2674 return Api::NewHandle(T, integer);
2675}
2676
2678 int64_t* value) {
2679 // Fast path for Smis.
2680 Thread* thread = Thread::Current();
2681 Isolate* isolate = thread->isolate();
2682 CHECK_ISOLATE(isolate);
2683 if (Api::IsSmi(integer)) {
2684 *value = Api::SmiValue(integer);
2685 return Api::Success();
2686 }
2687 // Slow path for Mints.
2688 DARTSCOPE(thread);
2689 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2690 if (int_obj.IsNull()) {
2691 RETURN_TYPE_ERROR(Z, integer, Integer);
2692 }
2693 ASSERT(int_obj.IsMint());
2694 *value = int_obj.AsInt64Value();
2695 return Api::Success();
2696}
2697
2699 uint64_t* value) {
2700 // Fast path for Smis.
2701 Thread* thread = Thread::Current();
2702 Isolate* isolate = thread->isolate();
2703 CHECK_ISOLATE(isolate);
2704 if (Api::IsSmi(integer)) {
2705 intptr_t smi_value = Api::SmiValue(integer);
2706 if (smi_value >= 0) {
2707 *value = smi_value;
2708 return Api::Success();
2709 }
2710 }
2711 // Slow path for Mints.
2712 DARTSCOPE(thread);
2713 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2714 if (int_obj.IsNull()) {
2715 RETURN_TYPE_ERROR(Z, integer, Integer);
2716 }
2717 if (int_obj.IsSmi()) {
2718 ASSERT(int_obj.IsNegative());
2719 } else {
2720 ASSERT(int_obj.IsMint());
2721 if (!int_obj.IsNegative()) {
2722 *value = int_obj.AsInt64Value();
2723 return Api::Success();
2724 }
2725 }
2726 return Api::NewError("%s: Integer %s cannot be represented as a uint64_t.",
2727 CURRENT_FUNC, int_obj.ToCString());
2728}
2729
2731 const char** value) {
2734 const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
2735 if (int_obj.IsNull()) {
2736 RETURN_TYPE_ERROR(Z, integer, Integer);
2737 }
2738 Zone* scope_zone = Api::TopScope(Thread::Current())->zone();
2739 *value = int_obj.ToHexCString(scope_zone);
2740 return Api::Success();
2741}
2742
2747}
2748
2750 double* value) {
2752 const Double& obj = Api::UnwrapDoubleHandle(Z, double_obj);
2753 if (obj.IsNull()) {
2754 RETURN_TYPE_ERROR(Z, double_obj, Double);
2755 }
2756 *value = obj.value();
2757 return Api::Success();
2758}
2759
2761 Dart_Handle cls_type,
2764 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
2765 if (lib.IsNull()) {
2766 RETURN_TYPE_ERROR(Z, library, Library);
2767 }
2768
2769 const Type& type_obj = Api::UnwrapTypeHandle(Z, cls_type);
2770 if (type_obj.IsNull()) {
2771 RETURN_TYPE_ERROR(Z, cls_type, Type);
2772 }
2773
2774 const Class& klass = Class::Handle(Z, type_obj.type_class());
2775 if (klass.IsNull()) {
2776 return Api::NewError(
2777 "cls_type must be a Type object which represents a Class");
2778 }
2779
2780 const auto& error = klass.EnsureIsFinalized(Thread::Current());
2781 if (error != Error::null()) {
2782 return Api::NewHandle(T, error);
2783 }
2784
2785 const String& func_name = Api::UnwrapStringHandle(Z, function_name);
2786 if (func_name.IsNull()) {
2788 }
2789
2790 Function& func =
2792 if (func.IsNull()) {
2793 return Dart_Null();
2794 }
2795
2796 if (!func.is_static()) {
2797 return Api::NewError("function_name must refer to a static method.");
2798 }
2799
2800 if (func.kind() != UntaggedFunction::kRegularFunction) {
2801 return Api::NewError(
2802 "function_name must be the name of a regular function.");
2803 }
2804 func = func.ImplicitClosureFunction();
2805 if (func.IsNull()) {
2806 return Dart_Null();
2807 }
2808
2809 return Api::NewHandle(T, func.ImplicitStaticClosure());
2810}
2811
2812// --- Booleans ----
2813
2815 ASSERT(Isolate::Current() != nullptr);
2816 return Api::True();
2817}
2818
2820 ASSERT(Isolate::Current() != nullptr);
2821 return Api::False();
2822}
2823
2825 Isolate* isolate = Isolate::Current();
2826 CHECK_ISOLATE(isolate);
2827 return value ? Api::True() : Api::False();
2828}
2829
2831 bool* value) {
2833 const Bool& obj = Api::UnwrapBoolHandle(Z, boolean_obj);
2834 if (obj.IsNull()) {
2835 RETURN_TYPE_ERROR(Z, boolean_obj, Bool);
2836 }
2837 *value = obj.value();
2838 return Api::Success();
2839}
2840
2841// --- Strings ---
2842
2844 Thread* thread = Thread::Current();
2845 DARTSCOPE(thread);
2846 {
2847 ReusableObjectHandleScope reused_obj_handle(thread);
2848 const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
2849 if (!str_obj.IsNull()) {
2850 *len = str_obj.Length();
2851 return Api::Success();
2852 }
2853 }
2854 RETURN_TYPE_ERROR(thread->zone(), str, String);
2855}
2856
2858 Thread* thread = Thread::Current();
2859 DARTSCOPE(thread);
2860 {
2861 ReusableObjectHandleScope reused_obj_handle(thread);
2862 const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
2863 if (!str_obj.IsNull()) {
2864 *len = Utf8::Length(str_obj);
2865 return Api::Success();
2866 }
2867 }
2868 RETURN_TYPE_ERROR(thread->zone(), str, String);
2869}
2870
2874 if (str == nullptr) {
2875 RETURN_NULL_ERROR(str);
2876 }
2878 return Api::NewHandle(T, String::New(str));
2879}
2880
2882 intptr_t length) {
2885 if (utf8_array == nullptr && length != 0) {
2886 RETURN_NULL_ERROR(utf8_array);
2887 }
2889 if (!Utf8::IsValid(utf8_array, length)) {
2890 return Api::NewError("%s expects argument 'str' to be valid UTF-8.",
2891 CURRENT_FUNC);
2892 }
2894 return Api::NewHandle(T, String::FromUTF8(utf8_array, length));
2895}
2896
2898 intptr_t length) {
2900 if (utf16_array == nullptr && length != 0) {
2901 RETURN_NULL_ERROR(utf16_array);
2902 }
2905 return Api::NewHandle(T, String::FromUTF16(utf16_array, length));
2906}
2907
2909 intptr_t length) {
2912 if (utf32_array == nullptr && length != 0) {
2913 RETURN_NULL_ERROR(utf32_array);
2914 }
2917 return Api::NewHandle(T, String::FromUTF32(utf32_array, length));
2918}
2919
2921 const char** cstr) {
2924 if (cstr == nullptr) {
2925 RETURN_NULL_ERROR(cstr);
2926 }
2927 const String& str_obj = Api::UnwrapStringHandle(Z, object);
2928 if (str_obj.IsNull()) {
2929 RETURN_TYPE_ERROR(Z, object, String);
2930 }
2931 intptr_t string_length = Utf8::Length(str_obj);
2932 char* res = Api::TopScope(T)->zone()->Alloc<char>(string_length + 1);
2933 if (res == nullptr) {
2934 return Api::NewError("Unable to allocate memory");
2935 }
2936 const char* string_value = str_obj.ToCString();
2937 memmove(res, string_value, string_length + 1);
2938 ASSERT(res[string_length] == '\0');
2939 *cstr = res;
2940 return Api::Success();
2941}
2942
2944 uint8_t** utf8_array,
2945 intptr_t* length) {
2948 if (utf8_array == nullptr) {
2949 RETURN_NULL_ERROR(utf8_array);
2950 }
2951 if (length == nullptr) {
2953 }
2954 const String& str_obj = Api::UnwrapStringHandle(Z, str);
2955 if (str_obj.IsNull()) {
2956 RETURN_TYPE_ERROR(Z, str, String);
2957 }
2958 intptr_t str_len = Utf8::Length(str_obj);
2959 *utf8_array = Api::TopScope(T)->zone()->Alloc<uint8_t>(str_len);
2960 if (*utf8_array == nullptr) {
2961 return Api::NewError("Unable to allocate memory");
2962 }
2963 str_obj.ToUTF8(*utf8_array, str_len);
2964 *length = str_len;
2965 return Api::Success();
2966}
2967
2969 uint8_t* utf8_array,
2970 intptr_t length) {
2973 if (utf8_array == nullptr) {
2974 RETURN_NULL_ERROR(utf8_array);
2975 }
2976 const String& str_obj = Api::UnwrapStringHandle(Z, str);
2977 if (str_obj.IsNull()) {
2978 RETURN_TYPE_ERROR(Z, str, String);
2979 }
2980 intptr_t str_len = Utf8::Length(str_obj);
2981 if (length < str_len) {
2982 return Api::NewError(
2983 "Provided buffer is not large enough to hold "
2984 "the UTF-8 representation of the string");
2985 }
2986 str_obj.ToUTF8(utf8_array, str_len);
2987 return Api::Success();
2988}
2989
2991 uint8_t* latin1_array,
2992 intptr_t* length) {
2995 if (latin1_array == nullptr) {
2996 RETURN_NULL_ERROR(latin1_array);
2997 }
2998 if (length == nullptr) {
3000 }
3001 const String& str_obj = Api::UnwrapStringHandle(Z, str);
3002 if (str_obj.IsNull() || !str_obj.IsOneByteString()) {
3003 RETURN_TYPE_ERROR(Z, str, String);
3004 }
3005 intptr_t str_len = str_obj.Length();
3006 intptr_t copy_len = (str_len > *length) ? *length : str_len;
3007
3008 // We have already asserted that the string object is a Latin-1 string
3009 // so we can copy the characters over using a simple loop.
3010 for (intptr_t i = 0; i < copy_len; i++) {
3011 latin1_array[i] = str_obj.CharAt(i);
3012 }
3013 *length = copy_len;
3014 return Api::Success();
3015}
3016
3018 uint16_t* utf16_array,
3019 intptr_t* length) {
3022 const String& str_obj = Api::UnwrapStringHandle(Z, str);
3023 if (str_obj.IsNull()) {
3024 RETURN_TYPE_ERROR(Z, str, String);
3025 }
3026 intptr_t str_len = str_obj.Length();
3027 intptr_t copy_len = (str_len > *length) ? *length : str_len;
3028 for (intptr_t i = 0; i < copy_len; i++) {
3029 utf16_array[i] = str_obj.CharAt(i);
3030 }
3031 *length = copy_len;
3032 return Api::Success();
3033}
3034
3036 intptr_t* size) {
3037 Thread* thread = Thread::Current();
3038 CHECK_ISOLATE(thread->isolate());
3039 TransitionNativeToVM transition(thread);
3040 if (size == nullptr) {
3042 }
3043 {
3044 ReusableObjectHandleScope reused_obj_handle(thread);
3045 const String& str_obj = Api::UnwrapStringHandle(reused_obj_handle, str);
3046 if (!str_obj.IsNull()) {
3047 *size = (str_obj.Length() * str_obj.CharSize());
3048 return Api::Success();
3049 }
3050 }
3051 RETURN_TYPE_ERROR(thread->zone(), str, String);
3052}
3053
3055 intptr_t* char_size,
3056 intptr_t* str_len,
3057 void** peer) {
3058 Thread* thread = Thread::Current();
3059 CHECK_ISOLATE(thread->isolate());
3060 TransitionNativeToVM transition(thread);
3061 {
3062 ReusableObjectHandleScope reused_obj_handle(thread);
3063 const String& str = Api::UnwrapStringHandle(reused_obj_handle, object);
3064 if (!str.IsNull()) {
3065 NoSafepointScope no_safepoint_scope;
3066 *peer = thread->heap()->GetPeer(str.ptr());
3067 *char_size = str.CharSize();
3068 *str_len = str.Length();
3069 return Api::Success();
3070 }
3071 }
3072 RETURN_TYPE_ERROR(thread->zone(), object, String);
3073}
3074
3075// --- Lists ---
3076
3081 const Array& arr = Array::Handle(Z, Array::New(length));
3082 return Api::NewHandle(T, arr.ptr());
3083}
3084
3085static bool CanTypeContainNull(const Type& type) {
3086 return (type.nullability() == Nullability::kNullable);
3087}
3088
3090 intptr_t length) {
3094 const Type& type = Api::UnwrapTypeHandle(Z, element_type);
3095 if (type.IsNull()) {
3096 RETURN_TYPE_ERROR(Z, element_type, Type);
3097 }
3098 if (!type.IsFinalized()) {
3099 return Api::NewError(
3100 "%s expects argument 'type' to be a fully resolved type.",
3101 CURRENT_FUNC);
3102 }
3103 if ((length > 0) && !CanTypeContainNull(type)) {
3104 return Api::NewError("%s expects argument 'type' to be a nullable type.",
3105 CURRENT_FUNC);
3106 }
3108}
3109
3111 Dart_Handle fill_object,
3112 intptr_t length) {
3116 const Type& type = Api::UnwrapTypeHandle(Z, element_type);
3117 if (type.IsNull()) {
3118 RETURN_TYPE_ERROR(Z, element_type, Type);
3119 }
3120 if (!type.IsFinalized()) {
3121 return Api::NewError(
3122 "%s expects argument 'type' to be a fully resolved type.",
3123 CURRENT_FUNC);
3124 }
3125 const Instance& instance = Api::UnwrapInstanceHandle(Z, fill_object);
3126 if (!instance.IsNull() && !InstanceIsType(T, instance, type)) {
3127 return Api::NewError(
3128 "%s expects argument 'fill_object' to have the same type as "
3129 "'element_type'.",
3130 CURRENT_FUNC);
3131 }
3132 if ((length > 0) && instance.IsNull() && !CanTypeContainNull(type)) {
3133 return Api::NewError(
3134 "%s expects argument 'fill_object' to be non-null for a non-nullable "
3135 "'element_type'.",
3136 CURRENT_FUNC);
3137 }
3139 for (intptr_t i = 0; i < arr.Length(); ++i) {
3140 arr.SetAt(i, instance);
3141 }
3142 return Api::NewHandle(T, arr.ptr());
3143}
3144
3145#define GET_LIST_LENGTH(zone, type, obj, len) \
3146 type& array = type::Handle(zone); \
3147 array ^= obj.ptr(); \
3148 *len = array.Length(); \
3149 return Api::Success();
3150
3153 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3154 if (obj.IsError()) {
3155 // Pass through errors.
3156 return list;
3157 }
3158 if (obj.IsTypedDataBase()) {
3160 }
3161 if (obj.IsArray()) {
3162 GET_LIST_LENGTH(Z, Array, obj, len);
3163 }
3164 if (obj.IsGrowableObjectArray()) {
3166 }
3168
3169 // Now check and handle a dart object that implements the List interface.
3171 if (instance.IsNull()) {
3172 return Api::NewArgumentError(
3173 "Object does not implement the List interface");
3174 }
3175 const Object& retval =
3176 Object::Handle(Z, CallStatic1Arg(Z, Symbols::_listLength(), instance));
3177 if (retval.IsSmi()) {
3178 *len = Smi::Cast(retval).Value();
3179 return Api::Success();
3180 } else if (retval.IsMint()) {
3181 int64_t mint_value = Mint::Cast(retval).value();
3182 if (mint_value >= kIntptrMin && mint_value <= kIntptrMax) {
3183 *len = static_cast<intptr_t>(mint_value);
3184 return Api::Success();
3185 }
3186 return Api::NewError(
3187 "Length of List object is greater than the "
3188 "maximum value that 'len' parameter can hold");
3189 } else if (retval.IsError()) {
3190 return Api::NewHandle(T, retval.ptr());
3191 } else {
3192 return Api::NewError("Length of List object is not an integer");
3193 }
3194}
3195
3196#define GET_LIST_ELEMENT(thread, type, obj, index) \
3197 const type& array_obj = type::Cast(obj); \
3198 if ((index >= 0) && (index < array_obj.Length())) { \
3199 return Api::NewHandle(thread, array_obj.At(index)); \
3200 } \
3201 return Api::NewError("Invalid index passed into access list element");
3202
3205 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3206 if (obj.IsArray()) {
3207 GET_LIST_ELEMENT(T, Array, obj, index);
3208 } else if (obj.IsGrowableObjectArray()) {
3210 } else if (obj.IsError()) {
3211 return list;
3212 } else {
3214 // Check and handle a dart object that implements the List interface.
3216 if (!instance.IsNull()) {
3217 return Api::NewHandle(
3218 T, CallStatic2Args(Z, Symbols::_listGetAt(), instance,
3219 Instance::Handle(Z, Integer::New(index))));
3220 }
3221 return Api::NewArgumentError(
3222 "Object does not implement the 'List' interface");
3223 }
3224}
3225
3226#define GET_LIST_RANGE(thread, type, obj, offset, length) \
3227 const type& array_obj = type::Cast(obj); \
3228 if ((offset >= 0) && (offset + length <= array_obj.Length())) { \
3229 for (intptr_t index = 0; index < length; ++index) { \
3230 result[index] = Api::NewHandle(thread, array_obj.At(index + offset)); \
3231 } \
3232 return Api::Success(); \
3233 } \
3234 return Api::NewError("Invalid offset/length passed into access list");
3235
3237 intptr_t offset,
3238 intptr_t length,
3241 if (result == nullptr) {
3243 }
3244 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3245 if (obj.IsArray()) {
3247 } else if (obj.IsGrowableObjectArray()) {
3249 } else if (obj.IsError()) {
3250 return list;
3251 } else {
3253 // Check and handle a dart object that implements the List interface.
3255 if (!instance.IsNull()) {
3256 const intptr_t kNumArgs = 2;
3258 Z, FindCoreLibPrivateFunction(Z, Symbols::_listGetAt()));
3259 const Array& args = Array::Handle(Z, Array::New(kNumArgs));
3260 args.SetAt(0, instance);
3261 Instance& index = Instance::Handle(Z);
3262 for (intptr_t i = 0; i < length; ++i) {
3263 index = Integer::New(i);
3264 args.SetAt(1, index);
3267 if (Api::IsError(value)) return value;
3268 result[i] = value;
3269 }
3270 return Api::Success();
3271 }
3272 return Api::NewArgumentError(
3273 "Object does not implement the 'List' interface");
3274 }
3275}
3276
3277#define SET_LIST_ELEMENT(type, obj, index, value) \
3278 const type& array = type::Cast(obj); \
3279 const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value)); \
3280 if (!value_obj.IsNull() && !value_obj.IsInstance()) { \
3281 RETURN_TYPE_ERROR(Z, value, Instance); \
3282 } \
3283 if ((index >= 0) && (index < array.Length())) { \
3284 array.SetAt(index, value_obj); \
3285 return Api::Success(); \
3286 } \
3287 return Api::NewError("Invalid index passed into set list element");
3288
3290 intptr_t index,
3293 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3294 // If the list is immutable we call into Dart for the indexed setter to
3295 // get the unsupported operation exception as the result.
3296 if (obj.IsArray() && !Array::Cast(obj).IsImmutable()) {
3297 SET_LIST_ELEMENT(Array, obj, index, value);
3298 } else if (obj.IsGrowableObjectArray()) {
3300 } else if (obj.IsError()) {
3301 return list;
3302 } else {
3304
3305 // Check and handle a dart object that implements the List interface.
3307 if (!instance.IsNull()) {
3308 const Integer& index_obj = Integer::Handle(Z, Integer::New(index));
3309 const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));
3310 if (!value_obj.IsNull() && !value_obj.IsInstance()) {
3312 }
3313 return Api::NewHandle(
3314 T, CallStatic3Args(Z, Symbols::_listSetAt(), instance, index_obj,
3315 Instance::Cast(value_obj)));
3316 }
3317 return Api::NewArgumentError(
3318 "Object does not implement the 'List' interface");
3319 }
3320}
3321
3322static ObjectPtr ResolveConstructor(const char* current_func,
3323 const Class& cls,
3324 const String& class_name,
3325 const String& dotted_name,
3326 int num_args);
3327
3328static ObjectPtr ThrowArgumentError(const char* exception_message) {
3329 Thread* thread = Thread::Current();
3330 Zone* zone = thread->zone();
3331 // Lookup the class ArgumentError in dart:core.
3332 const String& lib_url = String::Handle(String::New("dart:core"));
3333 const String& class_name = String::Handle(String::New("ArgumentError"));
3334 const Library& lib =
3335 Library::Handle(zone, Library::LookupLibrary(thread, lib_url));
3336 if (lib.IsNull()) {
3338 "%s: library '%s' not found.", CURRENT_FUNC, lib_url.ToCString()));
3339 return ApiError::New(message);
3340 }
3341 const Class& cls =
3343 ASSERT(!cls.IsNull());
3344 Object& result = Object::Handle(zone);
3345 String& dot_name = String::Handle(String::New("."));
3346 String& constr_name = String::Handle(String::Concat(class_name, dot_name));
3347 result = ResolveConstructor(CURRENT_FUNC, cls, class_name, constr_name, 1);
3348 if (result.IsError()) return result.ptr();
3349 ASSERT(result.IsFunction());
3350 Function& constructor = Function::Handle(zone);
3351 constructor ^= result.ptr();
3352 if (!constructor.IsGenerativeConstructor()) {
3353 const String& message = String::Handle(
3354 String::NewFormatted("%s: class '%s' is not a constructor.",
3355 CURRENT_FUNC, class_name.ToCString()));
3356 return ApiError::New(message);
3357 }
3358 Instance& exception = Instance::Handle(zone);
3359 exception = Instance::New(cls);
3360 const Array& args = Array::Handle(zone, Array::New(2));
3361 args.SetAt(0, exception);
3362 args.SetAt(1, String::Handle(String::New(exception_message)));
3363 result = DartEntry::InvokeFunction(constructor, args);
3364 if (result.IsError()) return result.ptr();
3365 ASSERT(result.IsNull());
3366
3367 if (thread->top_exit_frame_info() == 0) {
3368 // There are no dart frames on the stack so it would be illegal to
3369 // throw an exception here.
3370 const String& message = String::Handle(
3371 String::New("No Dart frames on stack, cannot throw exception"));
3372 return ApiError::New(message);
3373 }
3374 // Unwind all the API scopes till the exit frame before throwing an
3375 // exception.
3376 const Instance* saved_exception;
3377 {
3378 NoSafepointScope no_safepoint;
3379 InstancePtr raw_exception = exception.ptr();
3380 thread->UnwindScopes(thread->top_exit_frame_info());
3381 saved_exception = &Instance::Handle(raw_exception);
3382 }
3383 Exceptions::Throw(thread, *saved_exception);
3384 const String& message =
3385 String::Handle(String::New("Exception was not thrown, internal error"));
3386 return ApiError::New(message);
3387}
3388
3389// TODO(sgjesse): value should always be smaller then 0xff. Add error handling.
3390#define GET_LIST_ELEMENT_AS_BYTES(type, obj, native_array, offset, length) \
3391 const type& array = type::Cast(obj); \
3392 if (Utils::RangeCheck(offset, length, array.Length())) { \
3393 Object& element = Object::Handle(Z); \
3394 for (int i = 0; i < length; i++) { \
3395 element = array.At(offset + i); \
3396 if (!element.IsInteger()) { \
3397 return Api::NewHandle( \
3398 T, ThrowArgumentError("List contains non-int elements")); \
3399 } \
3400 const Integer& integer = Integer::Cast(element); \
3401 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \
3402 ASSERT(integer.AsInt64Value() <= 0xff); \
3403 } \
3404 return Api::Success(); \
3405 } \
3406 return Api::NewError("Invalid length passed into access array elements");
3407
3409 intptr_t offset,
3410 uint8_t* native_array,
3411 intptr_t length) {
3413 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3414 if (obj.IsTypedDataBase()) {
3415 const TypedDataBase& array = TypedDataBase::Cast(obj);
3416 if (array.ElementSizeInBytes() == 1) {
3417 if (Utils::RangeCheck(offset, length, array.Length())) {
3418 NoSafepointScope no_safepoint;
3419 memmove(native_array,
3420 reinterpret_cast<uint8_t*>(array.DataAddr(offset)), length);
3421 return Api::Success();
3422 }
3423 return Api::NewError("Invalid length passed into access list elements");
3424 }
3425 }
3426 if (obj.IsArray()) {
3427 GET_LIST_ELEMENT_AS_BYTES(Array, obj, native_array, offset, length);
3428 }
3429 if (obj.IsGrowableObjectArray()) {
3431 length);
3432 }
3433 if (obj.IsError()) {
3434 return list;
3435 }
3437
3438 // Check and handle a dart object that implements the List interface.
3440 if (!instance.IsNull()) {
3441 const int kNumArgs = 2;
3443 Z, FindCoreLibPrivateFunction(Z, Symbols::_listGetAt()));
3445 Integer& intobj = Integer::Handle(Z);
3446 const Array& args = Array::Handle(Z, Array::New(kNumArgs));
3447 args.SetAt(0, instance); // Set up the receiver as the first argument.
3448 for (int i = 0; i < length; i++) {
3449 HANDLESCOPE(T);
3450 intobj = Integer::New(offset + i);
3451 args.SetAt(1, intobj);
3453 if (result.IsError()) {
3454 return Api::NewHandle(T, result.ptr());
3455 }
3456 if (!result.IsInteger()) {
3457 return Api::NewError(
3458 "%s expects the argument 'list' to be "
3459 "a List of int",
3460 CURRENT_FUNC);
3461 }
3462 const Integer& integer_result = Integer::Cast(result);
3463 ASSERT(integer_result.AsInt64Value() <= 0xff);
3464 // TODO(hpayer): value should always be smaller then 0xff. Add error
3465 // handling.
3466 native_array[i] =
3467 static_cast<uint8_t>(integer_result.AsInt64Value() & 0xff);
3468 }
3469 return Api::Success();
3470 }
3471 return Api::NewArgumentError(
3472 "Object does not implement the 'List' interface");
3473}
3474
3475#define SET_LIST_ELEMENT_AS_BYTES(type, obj, native_array, offset, length) \
3476 const type& array = type::Cast(obj); \
3477 Integer& integer = Integer::Handle(Z); \
3478 if (Utils::RangeCheck(offset, length, array.Length())) { \
3479 for (int i = 0; i < length; i++) { \
3480 integer = Integer::New(native_array[i]); \
3481 array.SetAt(offset + i, integer); \
3482 } \
3483 return Api::Success(); \
3484 } \
3485 return Api::NewError("Invalid length passed into set array elements");
3486
3488 intptr_t offset,
3489 const uint8_t* native_array,
3490 intptr_t length) {
3492 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
3493 if (obj.IsTypedDataBase()) {
3494 const TypedDataBase& array = TypedDataBase::Cast(obj);
3495 if (array.ElementSizeInBytes() == 1) {
3496 if (Utils::RangeCheck(offset, length, array.Length())) {
3497 NoSafepointScope no_safepoint;
3498 memmove(reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
3499 native_array, length);
3500 return Api::Success();
3501 }
3502 return Api::NewError("Invalid length passed into access list elements");
3503 }
3504 }
3505 if (obj.IsArray() && !Array::Cast(obj).IsImmutable()) {
3506 // If the list is immutable we call into Dart for the indexed setter to
3507 // get the unsupported operation exception as the result.
3508 SET_LIST_ELEMENT_AS_BYTES(Array, obj, native_array, offset, length);
3509 }
3510 if (obj.IsGrowableObjectArray()) {
3512 length);
3513 }
3514 if (obj.IsError()) {
3515 return list;
3516 }
3518
3519 // Check and handle a dart object that implements the List interface.
3521 if (!instance.IsNull()) {
3522 const int kNumArgs = 3;
3524 Z, FindCoreLibPrivateFunction(Z, Symbols::_listSetAt()));
3525 Integer& indexobj = Integer::Handle(Z);
3526 Integer& valueobj = Integer::Handle(Z);
3527 const Array& args = Array::Handle(Z, Array::New(kNumArgs));
3528 args.SetAt(0, instance); // Set up the receiver as the first argument.
3529 for (int i = 0; i < length; i++) {
3530 indexobj = Integer::New(offset + i);
3531 valueobj = Integer::New(native_array[i]);
3532 args.SetAt(1, indexobj);
3533 args.SetAt(2, valueobj);
3534 const Object& result =
3536 if (result.IsError()) {
3537 return Api::NewHandle(T, result.ptr());
3538 }
3539 }
3540 return Api::Success();
3541 }
3542 return Api::NewArgumentError(
3543 "Object does not implement the 'List' interface");
3544}
3545
3546// --- Maps ---
3547
3553 if (!instance.IsNull()) {
3554 const Object& key_obj = Object::Handle(Api::UnwrapHandle(key));
3555 if (!(key_obj.IsInstance() || key_obj.IsNull())) {
3556 return Api::NewError("Key is not an instance");
3557 }
3558 return Api::NewHandle(T, CallStatic2Args(Z, Symbols::_mapGet(), instance,
3559 Instance::Cast(key_obj)));
3560 }
3561 return Api::NewArgumentError("Object does not implement the 'Map' interface");
3562}
3563
3569 if (!instance.IsNull()) {
3570 const Object& key_obj = Object::Handle(Z, Api::UnwrapHandle(key));
3571 if (!(key_obj.IsInstance() || key_obj.IsNull())) {
3572 return Api::NewError("Key is not an instance");
3573 }
3574 return Api::NewHandle(
3575 T, CallStatic2Args(Z, Symbols::_mapContainsKey(), instance,
3576 Instance::Cast(key_obj)));
3577 }
3578 return Api::NewArgumentError("Object does not implement the 'Map' interface");
3579}
3580
3586 if (!instance.IsNull()) {
3587 return Api::NewHandle(T, CallStatic1Arg(Z, Symbols::_mapKeys(), instance));
3588 }
3589 return Api::NewArgumentError("Object does not implement the 'Map' interface");
3590}
3591
3592// --- Typed Data ---
3593
3594// Helper method to get the type of a TypedData object.
3595static Dart_TypedData_Type GetType(intptr_t class_id) {
3597 switch (class_id) {
3598 case kByteDataViewCid:
3601 break;
3602 case kTypedDataInt8ArrayCid:
3603 case kTypedDataInt8ArrayViewCid:
3604 case kUnmodifiableTypedDataInt8ArrayViewCid:
3605 case kExternalTypedDataInt8ArrayCid:
3607 break;
3608 case kTypedDataUint8ArrayCid:
3609 case kTypedDataUint8ArrayViewCid:
3610 case kUnmodifiableTypedDataUint8ArrayViewCid:
3611 case kExternalTypedDataUint8ArrayCid:
3613 break;
3614 case kTypedDataUint8ClampedArrayCid:
3615 case kTypedDataUint8ClampedArrayViewCid:
3616 case kUnmodifiableTypedDataUint8ClampedArrayViewCid:
3617 case kExternalTypedDataUint8ClampedArrayCid:
3619 break;
3620 case kTypedDataInt16ArrayCid:
3621 case kTypedDataInt16ArrayViewCid:
3622 case kUnmodifiableTypedDataInt16ArrayViewCid:
3623 case kExternalTypedDataInt16ArrayCid:
3625 break;
3626 case kTypedDataUint16ArrayCid:
3627 case kTypedDataUint16ArrayViewCid:
3628 case kUnmodifiableTypedDataUint16ArrayViewCid:
3629 case kExternalTypedDataUint16ArrayCid:
3631 break;
3632 case kTypedDataInt32ArrayCid:
3633 case kTypedDataInt32ArrayViewCid:
3634 case kUnmodifiableTypedDataInt32ArrayViewCid:
3635 case kExternalTypedDataInt32ArrayCid:
3637 break;
3638 case kTypedDataUint32ArrayCid:
3639 case kTypedDataUint32ArrayViewCid:
3640 case kUnmodifiableTypedDataUint32ArrayViewCid:
3641 case kExternalTypedDataUint32ArrayCid:
3643 break;
3644 case kTypedDataInt64ArrayCid:
3645 case kTypedDataInt64ArrayViewCid:
3646 case kUnmodifiableTypedDataInt64ArrayViewCid:
3647 case kExternalTypedDataInt64ArrayCid:
3649 break;
3650 case kTypedDataUint64ArrayCid:
3651 case kTypedDataUint64ArrayViewCid:
3652 case kUnmodifiableTypedDataUint64ArrayViewCid:
3653 case kExternalTypedDataUint64ArrayCid:
3655 break;
3656 case kTypedDataFloat32ArrayCid:
3657 case kTypedDataFloat32ArrayViewCid:
3658 case kUnmodifiableTypedDataFloat32ArrayViewCid:
3659 case kExternalTypedDataFloat32ArrayCid:
3661 break;
3662 case kTypedDataFloat64ArrayCid:
3663 case kTypedDataFloat64ArrayViewCid:
3664 case kUnmodifiableTypedDataFloat64ArrayViewCid:
3665 case kExternalTypedDataFloat64ArrayCid:
3667 break;
3668 case kTypedDataInt32x4ArrayCid:
3669 case kTypedDataInt32x4ArrayViewCid:
3670 case kUnmodifiableTypedDataInt32x4ArrayViewCid:
3671 case kExternalTypedDataInt32x4ArrayCid:
3673 break;
3674 case kTypedDataFloat32x4ArrayCid:
3675 case kTypedDataFloat32x4ArrayViewCid:
3676 case kUnmodifiableTypedDataFloat32x4ArrayViewCid:
3677 case kExternalTypedDataFloat32x4ArrayCid:
3679 break;
3680 case kTypedDataFloat64x2ArrayCid:
3681 case kTypedDataFloat64x2ArrayViewCid:
3682 case kUnmodifiableTypedDataFloat64x2ArrayViewCid:
3683 case kExternalTypedDataFloat64x2ArrayCid:
3685 break;
3686 default:
3688 break;
3689 }
3690 return type;
3691}
3692
3694 Thread* thread = Thread::Current();
3695 API_TIMELINE_DURATION(thread);
3696 TransitionNativeToVM transition(thread);
3697 intptr_t class_id = Api::ClassId(object);
3698 if (IsTypedDataClassId(class_id) || IsTypedDataViewClassId(class_id) ||
3700 return GetType(class_id);
3701 }
3703}
3704
3707 Thread* thread = Thread::Current();
3708 API_TIMELINE_DURATION(thread);
3709 TransitionNativeToVM transition(thread);
3710 intptr_t class_id = Api::ClassId(object);
3711 if (IsExternalTypedDataClassId(class_id)) {
3712 return GetType(class_id);
3713 }
3714 if (IsTypedDataViewClassId(class_id) ||
3716 // Check if data object of the view is external.
3717 Zone* zone = thread->zone();
3718 const auto& view_obj = Api::UnwrapTypedDataViewHandle(zone, object);
3719 ASSERT(!view_obj.IsNull());
3720 const auto& data_obj = Instance::Handle(zone, view_obj.typed_data());
3722 return GetType(class_id);
3723 }
3724 }
3726}
3727
3728static Dart_Handle NewByteData(Thread* thread, intptr_t length) {
3729 CHECK_LENGTH(length, TypedData::MaxElements(kTypedDataUint8ArrayCid));
3730 const TypedData& array =
3731 TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, length));
3732 return Api::NewHandle(thread,
3734}
3735
3736static Dart_Handle NewTypedData(Thread* thread, intptr_t cid, intptr_t length) {
3738 return Api::NewHandle(thread, TypedData::New(cid, length));
3739}
3740
3742 intptr_t cid,
3743 void* data,
3744 intptr_t length,
3745 void* peer,
3746 intptr_t external_allocation_size,
3748 bool unmodifiable) {
3750 Zone* zone = thread->zone();
3753 zone,
3754 ExternalTypedData::New(cid, reinterpret_cast<uint8_t*>(data), length,
3755 thread->heap()->SpaceForExternal(bytes)));
3756 if (callback != nullptr) {
3757 AllocateFinalizableHandle(thread, result, peer, external_allocation_size,
3758 callback);
3759 }
3760 if (unmodifiable) {
3761 result.SetImmutable(); // Can pass by reference.
3762 const intptr_t view_cid = cid - kTypedDataCidRemainderExternal +
3764 result = TypedDataView::New(view_cid, ExternalTypedData::Cast(result), 0,
3765 length);
3766 }
3767 return Api::NewHandle(thread, result.ptr());
3768}
3769
3771 void* data,
3772 intptr_t length,
3773 void* peer,
3774 intptr_t external_allocation_size,
3776 bool unmodifiable) {
3777 Zone* zone = thread->zone();
3779 thread, kExternalTypedDataUint8ArrayCid, data, length, peer,
3780 external_allocation_size, callback, false);
3781 if (Api::IsError(ext_data)) {
3782 return ext_data;
3783 }
3784 const ExternalTypedData& array =
3785 Api::UnwrapExternalTypedDataHandle(zone, ext_data);
3786 if (unmodifiable) {
3787 array.SetImmutable(); // Can pass by reference.
3788 }
3789 return Api::NewHandle(
3792 array, 0, length));
3793}
3794
3796 intptr_t length) {
3799 switch (type) {
3801 return NewByteData(T, length);
3803 return NewTypedData(T, kTypedDataInt8ArrayCid, length);
3805 return NewTypedData(T, kTypedDataUint8ArrayCid, length);
3807 return NewTypedData(T, kTypedDataUint8ClampedArrayCid, length);
3809 return NewTypedData(T, kTypedDataInt16ArrayCid, length);
3811 return NewTypedData(T, kTypedDataUint16ArrayCid, length);
3813 return NewTypedData(T, kTypedDataInt32ArrayCid, length);
3815 return NewTypedData(T, kTypedDataUint32ArrayCid, length);
3817 return NewTypedData(T, kTypedDataInt64ArrayCid, length);
3819 return NewTypedData(T, kTypedDataUint64ArrayCid, length);
3821 return NewTypedData(T, kTypedDataFloat32ArrayCid, length);
3823 return NewTypedData(T, kTypedDataFloat64ArrayCid, length);
3825 return NewTypedData(T, kTypedDataInt32x4ArrayCid, length);
3827 return NewTypedData(T, kTypedDataFloat32x4ArrayCid, length);
3829 return NewTypedData(T, kTypedDataFloat64x2ArrayCid, length);
3830 default:
3831 return Api::NewError("%s expects argument 'type' to be of 'TypedData'",
3832 CURRENT_FUNC);
3833 }
3834 UNREACHABLE();
3835 return Api::Null();
3836}
3837
3840 void* data,
3841 intptr_t length,
3842 void* peer,
3843 intptr_t external_allocation_size,
3845 bool unmodifiable) {
3847 if (data == nullptr && length != 0) {
3849 }
3851 switch (type) {
3853 return NewExternalByteData(T, data, length, peer,
3854 external_allocation_size, callback,
3855 unmodifiable);
3857 return NewExternalTypedData(T, kExternalTypedDataInt8ArrayCid, data,
3858 length, peer, external_allocation_size,
3859 callback, unmodifiable);
3861 return NewExternalTypedData(T, kExternalTypedDataUint8ArrayCid, data,
3862 length, peer, external_allocation_size,
3863 callback, unmodifiable);
3865 return NewExternalTypedData(T, kExternalTypedDataUint8ClampedArrayCid,
3866 data, length, peer, external_allocation_size,
3867 callback, unmodifiable);
3869 return NewExternalTypedData(T, kExternalTypedDataInt16ArrayCid, data,
3870 length, peer, external_allocation_size,
3871 callback, unmodifiable);
3873 return NewExternalTypedData(T, kExternalTypedDataUint16ArrayCid, data,
3874 length, peer, external_allocation_size,
3875 callback, unmodifiable);
3877 return NewExternalTypedData(T, kExternalTypedDataInt32ArrayCid, data,
3878 length, peer, external_allocation_size,
3879 callback, unmodifiable);
3881 return NewExternalTypedData(T, kExternalTypedDataUint32ArrayCid, data,
3882 length, peer, external_allocation_size,
3883 callback, unmodifiable);
3885 return NewExternalTypedData(T, kExternalTypedDataInt64ArrayCid, data,
3886 length, peer, external_allocation_size,
3887 callback, unmodifiable);
3889 return NewExternalTypedData(T, kExternalTypedDataUint64ArrayCid, data,
3890 length, peer, external_allocation_size,
3891 callback, unmodifiable);
3893 return NewExternalTypedData(T, kExternalTypedDataFloat32ArrayCid, data,
3894 length, peer, external_allocation_size,
3895 callback, unmodifiable);
3897 return NewExternalTypedData(T, kExternalTypedDataFloat64ArrayCid, data,
3898 length, peer, external_allocation_size,
3899 callback, unmodifiable);
3901 return NewExternalTypedData(T, kExternalTypedDataInt32x4ArrayCid, data,
3902 length, peer, external_allocation_size,
3903 callback, unmodifiable);
3905 return NewExternalTypedData(T, kExternalTypedDataFloat32x4ArrayCid, data,
3906 length, peer, external_allocation_size,
3907 callback, unmodifiable);
3909 return NewExternalTypedData(T, kExternalTypedDataFloat64x2ArrayCid, data,
3910 length, peer, external_allocation_size,
3911 callback, unmodifiable);
3912 default:
3913 return Api::NewError(
3914 "%s expects argument 'type' to be of"
3915 " 'external TypedData'",
3916 CURRENT_FUNC);
3917 }
3918 UNREACHABLE();
3919 return Api::Null();
3920}
3921
3923 void* data,
3924 intptr_t length) {
3926 nullptr, false);
3927}
3928
3931 void* data,
3932 intptr_t length,
3933 void* peer,
3934 intptr_t external_allocation_size,
3937 type, data, length, peer, external_allocation_size, callback, false);
3938}
3939
3942 const void* data,
3943 intptr_t length,
3944 void* peer,
3945 intptr_t external_allocation_size,
3948 type, const_cast<void*>(data), length, peer, external_allocation_size,
3949 callback, true);
3950}
3951
3953 const String& class_name,
3954 const String& constructor_name,
3955 intptr_t num_args) {
3956 const Library& lib = Library::Handle(
3957 thread->isolate_group()->object_store()->typed_data_library());
3958 ASSERT(!lib.IsNull());
3959 const Class& cls =
3961 ASSERT(!cls.IsNull());
3962 return ResolveConstructor(CURRENT_FUNC, cls, class_name, constructor_name,
3963 num_args);
3964}
3965
3968 intptr_t class_id = Api::ClassId(typed_data);
3969 if (!IsExternalTypedDataClassId(class_id) &&
3970 !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id)) {
3971 RETURN_TYPE_ERROR(Z, typed_data, 'TypedData');
3972 }
3974 result = GetByteBufferConstructor(T, Symbols::_ByteBuffer(),
3975 Symbols::_ByteBufferDot_New(), 1);
3976 ASSERT(!result.IsNull());
3977 ASSERT(result.IsFunction());
3978 const Function& factory = Function::Cast(result);
3979 ASSERT(!factory.IsGenerativeConstructor());
3980
3981 // Create the argument list.
3982 const Array& args = Array::Handle(Z, Array::New(2));
3983 // Factories get type arguments.
3984 args.SetAt(0, Object::null_type_arguments());
3985 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(typed_data));
3986 args.SetAt(1, obj);
3987
3988 // Invoke the factory constructor and return the new object.
3990 ASSERT(result.IsInstance() || result.IsNull() || result.IsError());
3991 return Api::NewHandle(T, result.ptr());
3992}
3993
3994// Structure to record acquired typed data for verification purposes.
3996 public:
3997 AcquiredData(void* data, intptr_t size_in_bytes, bool copy)
3998 : size_in_bytes_(size_in_bytes), data_(data), data_copy_(nullptr) {
3999 if (copy) {
4000 data_copy_ = malloc(size_in_bytes_);
4001 memmove(data_copy_, data_, size_in_bytes_);
4002 }
4003 }
4004
4005 // The pointer to hand out via the API.
4006 void* GetData() const { return data_copy_ != nullptr ? data_copy_ : data_; }
4007
4008 // Writes back and deletes/zaps, if a copy was made.
4010 if (data_copy_ != nullptr) {
4011 memmove(data_, data_copy_, size_in_bytes_);
4012 memset(data_copy_, kZapReleasedByte, size_in_bytes_);
4013 free(data_copy_);
4014 }
4015 }
4016
4017 private:
4018 static constexpr uint8_t kZapReleasedByte = 0xda;
4019 intptr_t size_in_bytes_;
4020 void* data_;
4021 void* data_copy_;
4022
4023 DISALLOW_COPY_AND_ASSIGN(AcquiredData);
4024};
4025
4028 void** data,
4029 intptr_t* len) {
4031 Isolate* I = T->isolate();
4032 intptr_t class_id = Api::ClassId(object);
4033 if (!IsExternalTypedDataClassId(class_id) &&
4034 !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id) &&
4036 RETURN_TYPE_ERROR(Z, object, 'TypedData');
4037 }
4038 if (type == nullptr) {
4040 }
4041 if (data == nullptr) {
4043 }
4044 if (len == nullptr) {
4046 }
4047 // Get the type of typed data object.
4048 *type = GetType(class_id);
4049 intptr_t length = 0;
4050 intptr_t size_in_bytes = 0;
4051 void* data_tmp = nullptr;
4052 bool external = false;
4053 T->IncrementNoSafepointScopeDepth();
4055 if (IsExternalTypedDataClassId(class_id)) {
4056 const ExternalTypedData& obj =
4057 Api::UnwrapExternalTypedDataHandle(Z, object);
4058 ASSERT(!obj.IsNull());
4059 length = obj.Length();
4060 size_in_bytes = length * ExternalTypedData::ElementSizeInBytes(class_id);
4061 data_tmp = obj.DataAddr(0);
4062 external = true;
4063 } else if (IsTypedDataClassId(class_id)) {
4064 const TypedData& obj = Api::UnwrapTypedDataHandle(Z, object);
4065 ASSERT(!obj.IsNull());
4066 length = obj.Length();
4067 size_in_bytes = length * TypedData::ElementSizeInBytes(class_id);
4068 data_tmp = obj.DataAddr(0);
4069 } else {
4070 ASSERT(IsTypedDataViewClassId(class_id) ||
4072 const auto& view_obj = Api::UnwrapTypedDataViewHandle(Z, object);
4073 ASSERT(!view_obj.IsNull());
4074 Smi& val = Smi::Handle();
4075 val = view_obj.length();
4076 length = val.Value();
4077 size_in_bytes = length * TypedDataView::ElementSizeInBytes(class_id);
4078 val = view_obj.offset_in_bytes();
4079 intptr_t offset_in_bytes = val.Value();
4080 const auto& obj = Instance::Handle(view_obj.typed_data());
4081 if (TypedData::IsTypedData(obj)) {
4082 const TypedData& data_obj = TypedData::Cast(obj);
4083 data_tmp = data_obj.DataAddr(offset_in_bytes);
4084 } else {
4086 const ExternalTypedData& data_obj = ExternalTypedData::Cast(obj);
4087 data_tmp = data_obj.DataAddr(offset_in_bytes);
4088 external = true;
4089 }
4090 }
4091 if (FLAG_verify_acquired_data) {
4092 {
4093 NoSafepointScope no_safepoint(T);
4094 bool sweep_in_progress;
4095 {
4096 PageSpace* old_space = T->heap()->old_space();
4097 MonitorLocker ml(old_space->tasks_lock());
4098 sweep_in_progress = (old_space->phase() == PageSpace::kSweepingLarge) ||
4099 (old_space->phase() == PageSpace::kSweepingRegular);
4100 }
4101 if (!sweep_in_progress) {
4102 if (external) {
4103 ASSERT(!T->heap()->Contains(reinterpret_cast<uword>(data_tmp)));
4104 } else {
4105 ASSERT(T->heap()->Contains(reinterpret_cast<uword>(data_tmp)));
4106 }
4107 }
4108 }
4109 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
4110 WeakTable* table = I->group()->api_state()->acquired_table();
4111 intptr_t current = table->GetValue(obj.ptr());
4112 if (current != 0) {
4113 return Api::NewError("Data was already acquired for this object.");
4114 }
4115 // Do not make a copy if the data is external. Some callers expect external
4116 // data to remain in place, even though the API spec doesn't guarantee it.
4117 // TODO(koda/asiva): Make final decision and document it.
4118 AcquiredData* ad = new AcquiredData(data_tmp, size_in_bytes, !external);
4119 table->SetValue(obj.ptr(), reinterpret_cast<intptr_t>(ad));
4120 data_tmp = ad->GetData();
4121 }
4122 *data = data_tmp;
4123 *len = length;
4124 return Api::Success();
4125}
4126
4129 Isolate* I = T->isolate();
4130 intptr_t class_id = Api::ClassId(object);
4131 if (!IsExternalTypedDataClassId(class_id) &&
4132 !IsTypedDataViewClassId(class_id) && !IsTypedDataClassId(class_id) &&
4134 RETURN_TYPE_ERROR(Z, object, 'TypedData');
4135 }
4136 if (FLAG_verify_acquired_data) {
4137 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object));
4138 WeakTable* table = I->group()->api_state()->acquired_table();
4139 intptr_t current = table->GetValue(obj.ptr());
4140 if (current == 0) {
4141 return Api::NewError("Data was not acquired for this object.");
4142 }
4143 AcquiredData* ad = reinterpret_cast<AcquiredData*>(current);
4144 table->SetValue(obj.ptr(), 0); // Delete entry from table.
4145 delete ad;
4146 }
4147 T->DecrementNoSafepointScopeDepth();
4149 return Api::Success();
4150}
4151
4153 Thread* thread = Thread::Current();
4154 Zone* zone = thread->zone();
4155 Isolate* isolate = thread->isolate();
4156 CHECK_ISOLATE(isolate);
4157 TransitionNativeToVM transition(thread);
4158 intptr_t class_id = Api::ClassId(object);
4159 if (class_id != kByteBufferCid) {
4160 RETURN_TYPE_ERROR(zone, object, 'ByteBuffer');
4161 }
4162 const Instance& instance = Api::UnwrapInstanceHandle(zone, object);
4163 ASSERT(!instance.IsNull());
4164 return Api::NewHandle(thread, ByteBuffer::Data(instance));
4165}
4166
4167// --- Invoking Constructors, Methods, and Field accessors ---
4168
4169static ObjectPtr ResolveConstructor(const char* current_func,
4170 const Class& cls,
4171 const String& class_name,
4172 const String& constr_name,
4173 int num_args) {
4174 // The constructor must be present in the interface.
4175 Function& constructor = Function::Handle();
4177 constructor = cls.LookupFunctionAllowPrivate(constr_name);
4178 }
4179 if (constructor.IsNull() ||
4180 (!constructor.IsGenerativeConstructor() && !constructor.IsFactory())) {
4181 const String& lookup_class_name = String::Handle(cls.Name());
4182 if (!class_name.Equals(lookup_class_name)) {
4183 // When the class name used to build the constructor name is
4184 // different than the name of the class in which we are doing
4185 // the lookup, it can be confusing to the user to figure out
4186 // what's going on. Be a little more explicit for these error
4187 // messages.
4189 "%s: could not find factory '%s' in class '%s'.", current_func,
4190 constr_name.ToCString(), lookup_class_name.ToCString()));
4191 return ApiError::New(message);
4192 } else {
4193 const String& message = String::Handle(
4194 String::NewFormatted("%s: could not find constructor '%s'.",
4195 current_func, constr_name.ToCString()));
4196 return ApiError::New(message);
4197 }
4198 }
4199 const int kTypeArgsLen = 0;
4200 const int extra_args = 1;
4201 String& error_message = String::Handle();
4202 if (!constructor.AreValidArgumentCounts(kTypeArgsLen, num_args + extra_args,
4203 0, &error_message)) {
4205 "%s: wrong argument count for "
4206 "constructor '%s': %s.",
4207 current_func, constr_name.ToCString(), error_message.ToCString()));
4208 return ApiError::New(message);
4209 }
4210 ErrorPtr error = constructor.VerifyCallEntryPoint();
4211 if (error != Error::null()) return error;
4212 return constructor.ptr();
4213}
4214
4216 Dart_Handle constructor_name,
4217 int number_of_arguments,
4218 Dart_Handle* arguments) {
4222
4223 if (number_of_arguments < 0) {
4224 return Api::NewError(
4225 "%s expects argument 'number_of_arguments' to be non-negative.",
4226 CURRENT_FUNC);
4227 }
4228
4229 // Get the class to instantiate.
4230 Object& unchecked_type = Object::Handle(Api::UnwrapHandle(type));
4231 if (unchecked_type.IsNull() || !unchecked_type.IsType()) {
4233 }
4234 Type& type_obj = Type::Handle();
4235 type_obj ^= unchecked_type.ptr();
4236 if (!type_obj.IsFinalized()) {
4237 return Api::NewError(
4238 "%s expects argument 'type' to be a fully resolved type.",
4239 CURRENT_FUNC);
4240 }
4241 Class& cls = Class::Handle(Z, type_obj.type_class());
4243
4244 TypeArguments& type_arguments =
4246
4247 const String& base_constructor_name = String::Handle(Z, cls.Name());
4248
4249 // And get the name of the constructor to invoke.
4250 String& dot_name = String::Handle(Z);
4251 result = Api::UnwrapHandle(constructor_name);
4252 if (result.IsNull()) {
4253 dot_name = Symbols::Dot().ptr();
4254 } else if (result.IsString()) {
4255 dot_name = String::Concat(Symbols::Dot(), String::Cast(result));
4256 } else {
4257 RETURN_TYPE_ERROR(Z, constructor_name, String);
4258 }
4259
4260 // Resolve the constructor.
4261 String& constr_name =
4262 String::Handle(String::Concat(base_constructor_name, dot_name));
4263 result = ResolveConstructor("Dart_New", cls, base_constructor_name,
4264 constr_name, number_of_arguments);
4265 if (result.IsError()) {
4266 return Api::NewHandle(T, result.ptr());
4267 }
4268 ASSERT(result.IsFunction());
4269 Function& constructor = Function::Handle(Z);
4270 constructor ^= result.ptr();
4271
4272 Instance& new_object = Instance::Handle(Z);
4273 if (constructor.IsGenerativeConstructor()) {
4275#if defined(DEBUG)
4276 if (!cls.is_allocated() &&
4278 return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
4279 }
4280#endif
4281 // Create the new object.
4282 new_object = Instance::New(cls);
4283 }
4284
4285 // Create the argument list.
4286 intptr_t arg_index = 0;
4287 int extra_args = 1;
4288 const Array& args =
4289 Array::Handle(Z, Array::New(number_of_arguments + extra_args));
4290 if (constructor.IsGenerativeConstructor()) {
4291 // Constructors get the uninitialized object.
4292 if (!type_arguments.IsNull()) {
4293 // The type arguments will be null if the class has no type parameters, in
4294 // which case the following call would fail because there is no slot
4295 // reserved in the object for the type vector.
4296 new_object.SetTypeArguments(type_arguments);
4297 }
4298 args.SetAt(arg_index++, new_object);
4299 } else {
4300 // Factories get type arguments.
4301 args.SetAt(arg_index++, type_arguments);
4302 }
4303 Object& argument = Object::Handle(Z);
4304 for (int i = 0; i < number_of_arguments; i++) {
4305 argument = Api::UnwrapHandle(arguments[i]);
4306 if (!argument.IsNull() && !argument.IsInstance()) {
4307 if (argument.IsError()) {
4308 return Api::NewHandle(T, argument.ptr());
4309 } else {
4310 return Api::NewError(
4311 "%s expects arguments[%d] to be an Instance handle.", CURRENT_FUNC,
4312 i);
4313 }
4314 }
4315 args.SetAt(arg_index++, argument);
4316 }
4317
4318 const int kTypeArgsLen = 0;
4319 Array& args_descriptor_array = Array::Handle(
4320 Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length()));
4321
4322 ArgumentsDescriptor args_descriptor(args_descriptor_array);
4323 ObjectPtr type_error = constructor.DoArgumentTypesMatch(
4324 args, args_descriptor, type_arguments, Object::empty_type_arguments());
4325 if (type_error != Error::null()) {
4326 return Api::NewHandle(T, type_error);
4327 }
4328
4329 // Invoke the constructor and return the new object.
4330 result = DartEntry::InvokeFunction(constructor, args);
4331 if (result.IsError()) {
4332 return Api::NewHandle(T, result.ptr());
4333 }
4334
4335 if (constructor.IsGenerativeConstructor()) {
4336 ASSERT(result.IsNull());
4337 } else {
4338 ASSERT(result.IsNull() || result.IsInstance());
4339 new_object ^= result.ptr();
4340 }
4341 return Api::NewHandle(T, new_object.ptr());
4342}
4343
4344static InstancePtr AllocateObject(Thread* thread, const Class& cls) {
4345 if (!cls.is_fields_marked_nullable()) {
4346 // Mark all fields as nullable.
4347 Zone* zone = thread->zone();
4348 Class& iterate_cls = Class::Handle(zone, cls.ptr());
4349 Field& field = Field::Handle(zone);
4350 Array& fields = Array::Handle(zone);
4351 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
4352 if (!cls.is_fields_marked_nullable()) {
4353 while (!iterate_cls.IsNull()) {
4354 ASSERT(iterate_cls.is_finalized());
4355 iterate_cls.set_is_fields_marked_nullable();
4356 fields = iterate_cls.fields();
4357 iterate_cls = iterate_cls.SuperClass();
4358 for (int field_num = 0; field_num < fields.Length(); field_num++) {
4359 field ^= fields.At(field_num);
4360 if (field.is_static()) {
4361 continue;
4362 }
4363 field.RecordStore(Object::null_object());
4364 }
4365 }
4366 }
4367 }
4368
4369 // Allocate an object for the given class.
4370 return Instance::New(cls);
4371}
4372
4376
4377 const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
4378 // Get the class to instantiate.
4379 if (type_obj.IsNull()) {
4381 }
4382
4383 if (!type_obj.IsFinalized()) {
4384 return Api::NewError(
4385 "%s expects argument 'type' to be a fully resolved type.",
4386 CURRENT_FUNC);
4387 }
4388
4389 const Class& cls = Class::Handle(Z, type_obj.type_class());
4390 const TypeArguments& type_arguments =
4392
4394#if defined(DEBUG)
4396 return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
4397 }
4398#endif
4400 const Instance& new_obj = Instance::Handle(Z, AllocateObject(T, cls));
4401 if (!type_arguments.IsNull()) {
4402 new_obj.SetTypeArguments(type_arguments);
4403 }
4404 return Api::NewHandle(T, new_obj.ptr());
4405}
4406
4409 intptr_t num_native_fields,
4410 const intptr_t* native_fields) {
4413
4414 const Type& type_obj = Api::UnwrapTypeHandle(Z, type);
4415 // Get the class to instantiate.
4416 if (type_obj.IsNull()) {
4418 }
4419 if (native_fields == nullptr) {
4420 RETURN_NULL_ERROR(native_fields);
4421 }
4422 const Class& cls = Class::Handle(Z, type_obj.type_class());
4424#if defined(DEBUG)
4426 return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
4427 }
4428#endif
4430 if (num_native_fields != cls.num_native_fields()) {
4431 return Api::NewError(
4432 "%s: invalid number of native fields %" Pd " passed in, expected %d",
4433 CURRENT_FUNC, num_native_fields, cls.num_native_fields());
4434 }
4436 instance.SetNativeFields(num_native_fields, native_fields);
4437 return Api::NewHandle(T, instance.ptr());
4438}
4439
4441 int num_args,
4442 Dart_Handle* arguments,
4443 int extra_args,
4444 Array* args) {
4445 Zone* zone = thread->zone();
4446 // Check for malformed arguments in the arguments list.
4447 *args = Array::New(num_args + extra_args);
4448 Object& arg = Object::Handle(zone);
4449 for (int i = 0; i < num_args; i++) {
4450 arg = Api::UnwrapHandle(arguments[i]);
4451 if (!arg.IsNull() && !arg.IsInstance()) {
4452 *args = Array::null();
4453 if (arg.IsError()) {
4454 return Api::NewHandle(thread, arg.ptr());
4455 } else {
4456 return Api::NewError(
4457 "%s expects arguments[%d] to be an Instance handle.", "Dart_Invoke",
4458 i);
4459 }
4460 }
4461 args->SetAt((i + extra_args), arg);
4462 }
4463 return Api::Success();
4464}
4465
4468 int number_of_arguments,
4469 Dart_Handle* arguments) {
4473
4474 if (number_of_arguments < 0) {
4475 return Api::NewError(
4476 "%s expects argument 'number_of_arguments' to be non-negative.",
4477 CURRENT_FUNC);
4478 }
4479 const Instance& instance = Api::UnwrapInstanceHandle(Z, object);
4480 if (instance.IsNull()) {
4481 RETURN_TYPE_ERROR(Z, object, Instance);
4482 }
4483
4484 // Since we have allocated an object it would mean that the type
4485 // is finalized.
4486 // TODO(asiva): How do we ensure that a constructor is not called more than
4487 // once for the same object.
4488
4489 // Construct name of the constructor to invoke.
4490 const String& constructor_name = Api::UnwrapStringHandle(Z, name);
4491 AbstractType& type_obj =
4493 const Class& cls = Class::Handle(Z, type_obj.type_class());
4494 const String& class_name = String::Handle(Z, cls.Name());
4495 const Array& strings = Array::Handle(Z, Array::New(3));
4496 strings.SetAt(0, class_name);
4497 strings.SetAt(1, Symbols::Dot());
4498 if (constructor_name.IsNull()) {
4499 strings.SetAt(2, Symbols::Empty());
4500 } else {
4501 strings.SetAt(2, constructor_name);
4502 }
4503 const String& dot_name = String::Handle(Z, String::ConcatAll(strings));
4504 TypeArguments& type_arguments = TypeArguments::Handle(Z);
4505 if (type_obj.IsType()) {
4506 type_arguments = Type::Cast(type_obj).GetInstanceTypeArguments(T);
4507 }
4508 const Function& constructor =
4510 const int kTypeArgsLen = 0;
4511 const int extra_args = 1;
4512 if (!constructor.IsNull() && constructor.IsGenerativeConstructor() &&
4513 constructor.AreValidArgumentCounts(
4514 kTypeArgsLen, number_of_arguments + extra_args, 0, nullptr)) {
4516 // Create the argument list.
4519 result =
4520 SetupArguments(T, number_of_arguments, arguments, extra_args, &args);
4521 if (!Api::IsError(result)) {
4522 args.SetAt(0, instance);
4523
4524 const int kTypeArgsLen = 0;
4525 const Array& args_descriptor_array = Array::Handle(
4526 Z, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, args.Length()));
4527 ArgumentsDescriptor args_descriptor(args_descriptor_array);
4528 ObjectPtr type_error = constructor.DoArgumentTypesMatch(
4529 args, args_descriptor, type_arguments);
4530 if (type_error != Error::null()) {
4531 return Api::NewHandle(T, type_error);
4532 }
4533
4534 const Object& retval =
4536 if (retval.IsError()) {
4537 result = Api::NewHandle(T, retval.ptr());
4538 } else {
4539 result = Api::NewHandle(T, instance.ptr());
4540 }
4541 }
4542 return result;
4543 }
4544 return Api::NewError("%s expects argument 'name' to be a valid constructor.",
4545 CURRENT_FUNC);
4546}
4547
4550 int number_of_arguments,
4551 Dart_Handle* arguments) {
4555
4558 if (function_name.IsNull()) {
4560 }
4561 if (number_of_arguments < 0) {
4562 return Api::NewError(
4563 "%s expects argument 'number_of_arguments' to be non-negative.",
4564 CURRENT_FUNC);
4565 }
4567 if (obj.IsError()) {
4568 return target;
4569 }
4572 // This API does not provide a way to pass named parameters.
4573 const Array& arg_names = Object::empty_array();
4574 const bool respect_reflectable = false;
4575 const bool check_is_entrypoint = FLAG_verify_entry_points;
4576 if (obj.IsType()) {
4577 if (!Type::Cast(obj).IsFinalized()) {
4578 return Api::NewError(
4579 "%s expects argument 'target' to be a fully resolved type.",
4580 CURRENT_FUNC);
4581 }
4582
4583 const Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
4585 const Library& lib = Library::Handle(Z, cls.library());
4587 }
4588
4589 // Setup args and check for malformed arguments in the arguments list.
4590 result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
4591 if (Api::IsError(result)) {
4592 return result;
4593 }
4594 return Api::NewHandle(
4595 T, cls.Invoke(function_name, args, arg_names, respect_reflectable,
4596 check_is_entrypoint));
4597 } else if (obj.IsNull() || obj.IsInstance()) {
4598 // Since we have allocated an object it would mean that the type of the
4599 // receiver is already resolved and finalized, hence it is not necessary
4600 // to check here.
4602 instance ^= obj.ptr();
4603
4604 // Setup args and check for malformed arguments in the arguments list.
4605 result = SetupArguments(T, number_of_arguments, arguments, 1, &args);
4606 if (Api::IsError(result)) {
4607 return result;
4608 }
4609 args.SetAt(0, instance);
4610 return Api::NewHandle(
4611 T, instance.Invoke(function_name, args, arg_names, respect_reflectable,
4612 check_is_entrypoint));
4613 } else if (obj.IsLibrary()) {
4614 // Check whether class finalization is needed.
4615 const Library& lib = Library::Cast(obj);
4616
4617 // Check that the library is loaded.
4618 if (!lib.Loaded()) {
4619 return Api::NewError("%s expects library argument 'target' to be loaded.",
4620 CURRENT_FUNC);
4621 }
4622
4625 }
4626
4627 // Setup args and check for malformed arguments in the arguments list.
4628 result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
4629 if (Api::IsError(result)) {
4630 return result;
4631 }
4632
4633 return Api::NewHandle(
4634 T, lib.Invoke(function_name, args, arg_names, respect_reflectable,
4635 check_is_entrypoint));
4636 } else {
4637 return Api::NewError(
4638 "%s expects argument 'target' to be an object, type, or library.",
4639 CURRENT_FUNC);
4640 }
4641}
4642
4644 int number_of_arguments,
4645 Dart_Handle* arguments) {
4649 const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure);
4650 if (closure_obj.IsNull() || !closure_obj.IsCallable(nullptr)) {
4652 }
4653 if (number_of_arguments < 0) {
4654 return Api::NewError(
4655 "%s expects argument 'number_of_arguments' to be non-negative.",
4656 CURRENT_FUNC);
4657 }
4658
4659 // Set up arguments to include the closure as the first argument.
4660 const Array& args = Array::Handle(Z, Array::New(number_of_arguments + 1));
4661 Object& obj = Object::Handle(Z);
4662 args.SetAt(0, closure_obj);
4663 for (int i = 0; i < number_of_arguments; i++) {
4664 obj = Api::UnwrapHandle(arguments[i]);
4665 if (!obj.IsNull() && !obj.IsInstance()) {
4666 RETURN_TYPE_ERROR(Z, arguments[i], Instance);
4667 }
4668 args.SetAt(i + 1, obj);
4669 }
4670 // Now try to invoke the closure.
4672}
4673
4678
4679 String& field_name =
4681 if (field_name.IsNull()) {
4683 }
4684 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
4685 const bool throw_nsm_if_absent = true;
4686 const bool respect_reflectable = false;
4687 const bool check_is_entrypoint = FLAG_verify_entry_points;
4688
4689 if (obj.IsType()) {
4690 if (!Type::Cast(obj).IsFinalized()) {
4691 return Api::NewError(
4692 "%s expects argument 'container' to be a fully resolved type.",
4693 CURRENT_FUNC);
4694 }
4695 Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
4696 if (Library::IsPrivate(field_name)) {
4697 const Library& lib = Library::Handle(Z, cls.library());
4698 field_name = lib.PrivateName(field_name);
4699 }
4700 return Api::NewHandle(
4701 T, cls.InvokeGetter(field_name, throw_nsm_if_absent,
4702 respect_reflectable, check_is_entrypoint));
4703 } else if (obj.IsNull() || obj.IsInstance()) {
4705 instance ^= obj.ptr();
4706 if (Library::IsPrivate(field_name)) {
4707 const Class& cls = Class::Handle(Z, instance.clazz());
4708 const Library& lib = Library::Handle(Z, cls.library());
4709 field_name = lib.PrivateName(field_name);
4710 }
4711 return Api::NewHandle(T,
4712 instance.InvokeGetter(field_name, respect_reflectable,
4713 check_is_entrypoint));
4714 } else if (obj.IsLibrary()) {
4715 const Library& lib = Library::Cast(obj);
4716 // Check that the library is loaded.
4717 if (!lib.Loaded()) {
4718 return Api::NewError(
4719 "%s expects library argument 'container' to be loaded.",
4720 CURRENT_FUNC);
4721 }
4722 if (Library::IsPrivate(field_name)) {
4723 field_name = lib.PrivateName(field_name);
4724 }
4725 return Api::NewHandle(
4726 T, lib.InvokeGetter(field_name, throw_nsm_if_absent,
4727 respect_reflectable, check_is_entrypoint));
4728 } else if (obj.IsError()) {
4729 return container;
4730 } else {
4731 return Api::NewError(
4732 "%s expects argument 'container' to be an object, type, or library.",
4733 CURRENT_FUNC);
4734 }
4735}
4736
4743
4744 String& field_name =
4746 if (field_name.IsNull()) {
4748 }
4749
4750 // Since null is allowed for value, we don't use UnwrapInstanceHandle.
4751 const Object& value_obj = Object::Handle(Z, Api::UnwrapHandle(value));
4752 if (!value_obj.IsNull() && !value_obj.IsInstance()) {
4754 }
4755 Instance& value_instance = Instance::Handle(Z);
4756 value_instance ^= value_obj.ptr();
4757
4758 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
4759 const bool respect_reflectable = false;
4760 const bool check_is_entrypoint = FLAG_verify_entry_points;
4761
4762 if (obj.IsType()) {
4763 if (!Type::Cast(obj).IsFinalized()) {
4764 return Api::NewError(
4765 "%s expects argument 'container' to be a fully resolved type.",
4766 CURRENT_FUNC);
4767 }
4768
4769 // To access a static field we may need to use the Field or the
4770 // setter Function.
4771 Class& cls = Class::Handle(Z, Type::Cast(obj).type_class());
4772 if (Library::IsPrivate(field_name)) {
4773 const Library& lib = Library::Handle(Z, cls.library());
4774 field_name = lib.PrivateName(field_name);
4775 }
4776 return Api::NewHandle(
4777 T, cls.InvokeSetter(field_name, value_instance, respect_reflectable,
4778 check_is_entrypoint));
4779 } else if (obj.IsNull() || obj.IsInstance()) {
4781 instance ^= obj.ptr();
4782 if (Library::IsPrivate(field_name)) {
4783 const Class& cls = Class::Handle(Z, instance.clazz());
4784 const Library& lib = Library::Handle(Z, cls.library());
4785 field_name = lib.PrivateName(field_name);
4786 }
4787 return Api::NewHandle(
4788 T, instance.InvokeSetter(field_name, value_instance,
4789 respect_reflectable, check_is_entrypoint));
4790 } else if (obj.IsLibrary()) {
4791 // To access a top-level we may need to use the Field or the
4792 // setter Function. The setter function may either be in the
4793 // library or in the field's owner class, depending.
4794 const Library& lib = Library::Cast(obj);
4795 // Check that the library is loaded.
4796 if (!lib.Loaded()) {
4797 return Api::NewError(
4798 "%s expects library argument 'container' to be loaded.",
4799 CURRENT_FUNC);
4800 }
4801
4802 if (Library::IsPrivate(field_name)) {
4803 field_name = lib.PrivateName(field_name);
4804 }
4805 return Api::NewHandle(
4806 T, lib.InvokeSetter(field_name, value_instance, respect_reflectable,
4807 check_is_entrypoint));
4808 } else if (obj.IsError()) {
4809 return container;
4810 }
4811 return Api::NewError(
4812 "%s expects argument 'container' to be an object, type, or library.",
4813 CURRENT_FUNC);
4814}
4815
4816// --- Exceptions ----
4817
4819 Thread* thread = Thread::Current();
4820 Zone* zone = thread->zone();
4821 Isolate* isolate = thread->isolate();
4822 CHECK_ISOLATE(isolate);
4823 CHECK_CALLBACK_STATE(thread);
4824 if (::Dart_IsError(exception)) {
4825 ::Dart_PropagateError(exception);
4826 }
4827 TransitionNativeToVM transition(thread);
4828 const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
4829 if (excp.IsNull()) {
4830 RETURN_TYPE_ERROR(zone, exception, Instance);
4831 }
4832 if (thread->top_exit_frame_info() == 0) {
4833 // There are no dart frames on the stack so it would be illegal to
4834 // throw an exception here.
4835 return Api::NewError("No Dart frames on stack, cannot throw exception");
4836 }
4837 // Unwind all the API scopes till the exit frame before throwing an
4838 // exception.
4839 const Instance* saved_exception;
4840 {
4841 NoSafepointScope no_safepoint;
4842 InstancePtr raw_exception =
4843 Api::UnwrapInstanceHandle(zone, exception).ptr();
4844 thread->UnwindScopes(thread->top_exit_frame_info());
4845 saved_exception = &Instance::Handle(raw_exception);
4846 }
4847 Exceptions::Throw(thread, *saved_exception);
4848 return Api::NewError("Exception was not thrown, internal error");
4849}
4850
4852 Dart_Handle stacktrace) {
4853 Thread* thread = Thread::Current();
4854 Zone* zone = thread->zone();
4855 Isolate* isolate = thread->isolate();
4856 CHECK_ISOLATE(isolate);
4857 CHECK_CALLBACK_STATE(thread);
4858 TransitionNativeToVM transition(thread);
4859 {
4860 const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
4861 if (excp.IsNull()) {
4862 RETURN_TYPE_ERROR(zone, exception, Instance);
4863 }
4864 const Instance& stk = Api::UnwrapInstanceHandle(zone, stacktrace);
4865 if (stk.IsNull()) {
4866 RETURN_TYPE_ERROR(zone, stacktrace, Instance);
4867 }
4868 }
4869 if (thread->top_exit_frame_info() == 0) {
4870 // There are no dart frames on the stack so it would be illegal to
4871 // throw an exception here.
4872 return Api::NewError("No Dart frames on stack, cannot throw exception");
4873 }
4874 // Unwind all the API scopes till the exit frame before throwing an
4875 // exception.
4876 const Instance* saved_exception;
4877 const StackTrace* saved_stacktrace;
4878 {
4879 NoSafepointScope no_safepoint;
4880 InstancePtr raw_exception =
4881 Api::UnwrapInstanceHandle(zone, exception).ptr();
4882 StackTracePtr raw_stacktrace =
4883 Api::UnwrapStackTraceHandle(zone, stacktrace).ptr();
4884 thread->UnwindScopes(thread->top_exit_frame_info());
4885 saved_exception = &Instance::Handle(raw_exception);
4886 saved_stacktrace = &StackTrace::Handle(raw_stacktrace);
4887 }
4888 Exceptions::ReThrow(thread, *saved_exception, *saved_stacktrace);
4889 return Api::NewError("Exception was not re thrown, internal error");
4890}
4891
4892// --- Native fields and functions ---
4893
4895 int* count) {
4896 Thread* thread = Thread::Current();
4897 CHECK_ISOLATE(thread->isolate());
4898 TransitionNativeToVM transition(thread);
4899 {
4900 ReusableObjectHandleScope reused_obj_handle(thread);
4901 const Instance& instance =
4902 Api::UnwrapInstanceHandle(reused_obj_handle, obj);
4903 if (!instance.IsNull()) {
4904 *count = instance.NumNativeFields();
4905 return Api::Success();
4906 }
4907 }
4908 RETURN_TYPE_ERROR(thread->zone(), obj, Instance);
4909}
4910
4912 int index,
4913 intptr_t* value) {
4914 Thread* thread = Thread::Current();
4915 CHECK_ISOLATE(thread->isolate());
4916 TransitionNativeToVM transition(thread);
4917 bool is_null = false;
4918 {
4919 ReusableObjectHandleScope reused_obj_handle(thread);
4920 const Instance& instance =
4921 Api::UnwrapInstanceHandle(reused_obj_handle, obj);
4922 if (!instance.IsNull()) {
4923 if (instance.IsValidNativeIndex(index)) {
4924 *value = instance.GetNativeField(index);
4925 return Api::Success();
4926 }
4927 } else {
4928 is_null = true;
4929 }
4930 }
4931 if (is_null) {
4932 RETURN_TYPE_ERROR(thread->zone(), obj, Instance);
4933 }
4934 return Api::NewError(
4935 "%s: invalid index %d passed into access native instance field",
4936 CURRENT_FUNC, index);
4937}
4938
4940 int index,
4941 intptr_t value) {
4944 if (instance.IsNull()) {
4946 }
4947 if (!instance.IsValidNativeIndex(index)) {
4948 return Api::NewError(
4949 "%s: invalid index %d passed into set native instance field",
4950 CURRENT_FUNC, index);
4951 }
4952 instance.SetNativeField(index, value);
4953 return Api::Success();
4954}
4955
4957 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
4958 Isolate* isolate = arguments->thread()->isolate();
4959 ASSERT(isolate == Isolate::Current());
4960 return isolate->init_callback_data();
4961}
4962
4965 int num_arguments,
4966 const Dart_NativeArgument_Descriptor* argument_descriptors,
4967 Dart_NativeArgument_Value* arg_values) {
4968 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
4969 TransitionNativeToVM transition(arguments->thread());
4970 ASSERT(arguments->thread()->isolate() == Isolate::Current());
4971 if (arg_values == nullptr) {
4972 RETURN_NULL_ERROR(arg_values);
4973 }
4974 for (int i = 0; i < num_arguments; i++) {
4975 Dart_NativeArgument_Descriptor desc = argument_descriptors[i];
4976 Dart_NativeArgument_Type arg_type =
4977 static_cast<Dart_NativeArgument_Type>(desc.type);
4978 int arg_index = desc.index;
4979 ASSERT(arg_index >= 0 && arg_index < arguments->NativeArgCount());
4980 Dart_NativeArgument_Value* native_value = &(arg_values[i]);
4981 switch (arg_type) {
4983 if (!Api::GetNativeBooleanArgument(arguments, arg_index,
4984 &(native_value->as_bool))) {
4985 return Api::NewArgumentError(
4986 "%s: expects argument at index %d to be of"
4987 " type Boolean.",
4988 CURRENT_FUNC, i);
4989 }
4990 break;
4991
4993 int64_t value = 0;
4994 if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
4995 return Api::NewArgumentError(
4996 "%s: expects argument at index %d to be of"
4997 " type Integer.",
4998 CURRENT_FUNC, i);
4999 }
5000 if (value < INT32_MIN || value > INT32_MAX) {
5001 return Api::NewArgumentError(
5002 "%s: argument value at index %d is out of range", CURRENT_FUNC,
5003 i);
5004 }
5005 native_value->as_int32 = static_cast<int32_t>(value);
5006 break;
5007 }
5008
5010 int64_t value = 0;
5011 if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
5012 return Api::NewArgumentError(
5013 "%s: expects argument at index %d to be of"
5014 " type Integer.",
5015 CURRENT_FUNC, i);
5016 }
5017 if (value < 0 || value > UINT32_MAX) {
5018 return Api::NewArgumentError(
5019 "%s: argument value at index %d is out of range", CURRENT_FUNC,
5020 i);
5021 }
5022 native_value->as_uint32 = static_cast<uint32_t>(value);
5023 break;
5024 }
5025
5027 int64_t value = 0;
5028 if (!GetNativeIntegerArgument(arguments, arg_index, &value)) {
5029 return Api::NewArgumentError(
5030 "%s: expects argument at index %d to be of"
5031 " type Integer.",
5032 CURRENT_FUNC, i);
5033 }
5034 native_value->as_int64 = value;
5035 break;
5036 }
5037
5039 uint64_t value = 0;
5040 if (!GetNativeUnsignedIntegerArgument(arguments, arg_index, &value)) {
5041 return Api::NewArgumentError(
5042 "%s: expects argument at index %d to be of"
5043 " type Integer.",
5044 CURRENT_FUNC, i);
5045 }
5046 native_value->as_uint64 = value;
5047 break;
5048 }
5049
5051 if (!GetNativeDoubleArgument(arguments, arg_index,
5052 &(native_value->as_double))) {
5053 return Api::NewArgumentError(
5054 "%s: expects argument at index %d to be of"
5055 " type Double.",
5056 CURRENT_FUNC, i);
5057 }
5058 break;
5059
5061 if (!GetNativeStringArgument(arguments, arg_index,
5062 &(native_value->as_string.dart_str),
5063 &(native_value->as_string.peer))) {
5064 return Api::NewArgumentError(
5065 "%s: expects argument at index %d to be of"
5066 " type String.",
5067 CURRENT_FUNC, i);
5068 }
5069 break;
5070
5073 arguments, arg_index, native_value->as_native_fields.num_fields,
5074 native_value->as_native_fields.values, CURRENT_FUNC);
5075 if (result != Api::Success()) {
5076 return result;
5077 }
5078 break;
5079 }
5080
5082 ASSERT(arguments->thread() == Thread::Current());
5083 ASSERT(arguments->thread()->api_top_scope() != nullptr);
5084 native_value->as_instance = Api::NewHandle(
5085 arguments->thread(), arguments->NativeArgAt(arg_index));
5086 break;
5087 }
5088
5089 default:
5090 return Api::NewArgumentError("%s: invalid argument type %d.",
5091 CURRENT_FUNC, arg_type);
5092 }
5093 }
5094 return Api::Success();
5095}
5096
5098 int index) {
5099 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5100 if ((index < 0) || (index >= arguments->NativeArgCount())) {
5101 return Api::NewError(
5102 "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
5103 CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
5104 }
5105 TransitionNativeToVM transition(arguments->thread());
5106 return Api::NewHandle(arguments->thread(), arguments->NativeArgAt(index));
5107}
5108
5110 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5111 return arguments->NativeArgCount();
5112}
5113
5116 int arg_index,
5117 int num_fields,
5118 intptr_t* field_values) {
5119 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5120 if ((arg_index < 0) || (arg_index >= arguments->NativeArgCount())) {
5121 return Api::NewError(
5122 "%s: argument 'arg_index' out of range. Expected 0..%d but saw %d.",
5123 CURRENT_FUNC, arguments->NativeArgCount() - 1, arg_index);
5124 }
5125 if (field_values == nullptr) {
5126 RETURN_NULL_ERROR(field_values);
5127 }
5128 return GetNativeFieldsOfArgument(arguments, arg_index, num_fields,
5129 field_values, CURRENT_FUNC);
5130}
5131
5133 intptr_t* value) {
5134 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5135 TransitionNativeToVM transition(arguments->thread());
5136 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5137 if (value == nullptr) {
5139 }
5140 if (Api::GetNativeReceiver(arguments, value)) {
5141 return Api::Success();
5142 }
5143 return Api::NewError(
5144 "%s expects receiver argument to be non-null and of"
5145 " type Instance.",
5146 CURRENT_FUNC);
5147}
5148
5150 int arg_index,
5151 void** peer) {
5152 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5153 TransitionNativeToVM transition(arguments->thread());
5155 if (!GetNativeStringArgument(arguments, arg_index, &result, peer)) {
5156 return Api::NewArgumentError(
5157 "%s expects argument at %d to be of"
5158 " type String.",
5159 CURRENT_FUNC, arg_index);
5160 }
5161 return result;
5162}
5163
5165 int index,
5166 int64_t* value) {
5167 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5168 if ((index < 0) || (index >= arguments->NativeArgCount())) {
5169 return Api::NewError(
5170 "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
5171 CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
5172 }
5173 if (!GetNativeIntegerArgument(arguments, index, value)) {
5174 return Api::NewArgumentError(
5175 "%s: expects argument at %d to be of"
5176 " type Integer.",
5177 CURRENT_FUNC, index);
5178 }
5179 return Api::Success();
5180}
5181
5183 int index,
5184 bool* value) {
5185 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5186 if ((index < 0) || (index >= arguments->NativeArgCount())) {
5187 return Api::NewError(
5188 "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
5189 CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
5190 }
5191 if (!Api::GetNativeBooleanArgument(arguments, index, value)) {
5192 return Api::NewArgumentError(
5193 "%s: expects argument at %d to be of type Boolean.", CURRENT_FUNC,
5194 index);
5195 }
5196 return Api::Success();
5197}
5198
5200 int index,
5201 double* value) {
5202 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5203 if ((index < 0) || (index >= arguments->NativeArgCount())) {
5204 return Api::NewError(
5205 "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
5206 CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
5207 }
5208 if (!GetNativeDoubleArgument(arguments, index, value)) {
5209 return Api::NewArgumentError(
5210 "%s: expects argument at %d to be of"
5211 " type Double.",
5212 CURRENT_FUNC, index);
5213 }
5214 return Api::Success();
5215}
5216
5218 Dart_Handle retval) {
5219 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5220 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5221 ASSERT_CALLBACK_STATE(arguments->thread());
5222 TransitionNativeToVM transition(arguments->thread());
5223 if ((retval != Api::Null()) && !Api::IsInstance(retval) &&
5224 !Api::IsError(retval)) {
5225 // Print the current stack trace to make the problematic caller
5226 // easier to find.
5227 const StackTrace& stacktrace = GetCurrentStackTrace(0);
5228 OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());
5229
5230 const Object& ret_obj = Object::Handle(Api::UnwrapHandle(retval));
5231 FATAL(
5232 "Return value check failed: saw '%s' expected a dart Instance or "
5233 "an Error.",
5234 ret_obj.ToCString());
5235 }
5236 ASSERT(retval != nullptr);
5237 Api::SetReturnValue(arguments, retval);
5238}
5239
5242 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5243 TransitionNativeToVM transition(arguments->thread());
5244#if defined(DEBUG)
5245 Isolate* isolate = arguments->thread()->isolate();
5246 ASSERT(isolate == Isolate::Current());
5247 ASSERT(isolate->group()->api_state() != nullptr &&
5248 (isolate->group()->api_state()->IsValidWeakPersistentHandle(rval)));
5249#endif
5250 Api::SetWeakHandleReturnValue(arguments, rval);
5251}
5252
5253// --- Environment ---
5254StringPtr Api::GetEnvironmentValue(Thread* thread, const String& name) {
5255 String& result = String::Handle(CallEnvironmentCallback(thread, name));
5256 if (result.IsNull()) {
5257 // Every 'dart:X' library introduces an environment variable
5258 // 'dart.library.X' that is set to 'true'.
5259 // We just need to make sure to hide private libraries (starting with
5260 // "_", and the mirrors library, if it is not supported.
5261
5262 if (!FLAG_enable_mirrors && name.Equals(Symbols::DartLibraryMirrors())) {
5263 return Symbols::False().ptr();
5264 }
5265
5266 if (!Api::IsFfiEnabled() && name.Equals(Symbols::DartLibraryFfi())) {
5267 return Symbols::False().ptr();
5268 }
5269
5270 if (name.Equals(Symbols::DartVMProduct())) {
5271#ifdef PRODUCT
5272 return Symbols::True().ptr();
5273#else
5274 return Symbols::False().ptr();
5275#endif
5276 }
5277
5278 if (name.Equals(Symbols::DartDeveloperTimeline())) {
5279#ifdef SUPPORT_TIMELINE
5280 return Symbols::True().ptr();
5281#else
5282 return Symbols::False().ptr();
5283#endif
5284 }
5285
5286 const String& prefix = Symbols::DartLibrary();
5287 if (name.StartsWith(prefix)) {
5288 const String& library_name =
5290
5291 // Private libraries (starting with "_") are not exposed to the user.
5292 if (!library_name.IsNull() && library_name.CharAt(0) != '_') {
5293 const String& dart_library_name =
5294 String::Handle(String::Concat(Symbols::DartScheme(), library_name));
5295 const Library& library =
5296 Library::Handle(Library::LookupLibrary(thread, dart_library_name));
5297 if (!library.IsNull()) {
5298 return Symbols::True().ptr();
5299 }
5300 }
5301 }
5302 // Check for default VM provided values. If it was not overridden on the
5303 // command line.
5304 if (Symbols::DartIsVM().Equals(name)) {
5305 return Symbols::True().ptr();
5306 }
5307 }
5308 return result.ptr();
5309}
5310
5311StringPtr Api::CallEnvironmentCallback(Thread* thread, const String& name) {
5312 Isolate* isolate = thread->isolate();
5314 if (callback != nullptr) {
5315 Scope api_scope(thread);
5316 Dart_Handle api_name = Api::NewHandle(thread, name.ptr());
5317 Dart_Handle api_response;
5318 {
5319 TransitionVMToNative transition(thread);
5320 api_response = callback(api_name);
5321 }
5322 const Object& response =
5323 Object::Handle(thread->zone(), Api::UnwrapHandle(api_response));
5324 if (response.IsString()) {
5325 return String::Cast(response).ptr();
5326 } else if (response.IsError()) {
5328 String::Handle(String::New(Error::Cast(response).ToErrorCString())));
5329 } else if (!response.IsNull()) {
5330 // At this point everything except null are invalid environment values.
5332 String::Handle(String::New("Illegal environment value")));
5333 }
5334 }
5335 return String::null();
5336}
5337
5340 Isolate* isolate = Isolate::Current();
5341 CHECK_ISOLATE(isolate);
5343 return Api::Success();
5344}
5345
5346// --- Scripts and Libraries ---
5348 bool retval) {
5349 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5350 TransitionNativeToVM transition(arguments->thread());
5351 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5352 ASSERT_CALLBACK_STATE(arguments->thread());
5353 arguments->SetReturn(Bool::Get(retval));
5354}
5355
5357 int64_t retval) {
5358 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5359 TransitionNativeToVM transition(arguments->thread());
5360 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5361 ASSERT_CALLBACK_STATE(arguments->thread());
5362 if (Smi::IsValid(retval)) {
5363 Api::SetSmiReturnValue(arguments, static_cast<intptr_t>(retval));
5364 } else {
5365 // Slow path for Mints.
5366 Api::SetIntegerReturnValue(arguments, retval);
5367 }
5368}
5369
5371 double retval) {
5372 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
5373 ASSERT(arguments->thread()->isolate() == Isolate::Current());
5374 ASSERT_CALLBACK_STATE(arguments->thread());
5375 TransitionNativeToVM transition(arguments->thread());
5376 Api::SetDoubleReturnValue(arguments, retval);
5377}
5378
5379// --- Scripts and Libraries ---
5380
5383 Isolate* isolate = Isolate::Current();
5384 CHECK_ISOLATE(isolate);
5385 isolate->group()->set_library_tag_handler(handler);
5386 return Api::Success();
5387}
5388
5391 Isolate* isolate = Isolate::Current();
5392 CHECK_ISOLATE(isolate);
5393 isolate->group()->set_deferred_load_handler(handler);
5394 return Api::Success();
5395}
5396
5398 intptr_t buffer_size) {
5399#if defined(DART_PRECOMPILED_RUNTIME)
5400 return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
5401#else
5404 StackZone zone(T);
5405 IsolateGroup* IG = T->isolate_group();
5406
5407 Library& library = Library::Handle(Z, IG->object_store()->root_library());
5408 if (!library.IsNull()) {
5409 const String& library_url = String::Handle(Z, library.url());
5410 return Api::NewError("%s: A script has already been loaded from '%s'.",
5411 CURRENT_FUNC, library_url.ToCString());
5412 }
5414
5415 // NOTE: We do not attach a finalizer for this object, because the embedder
5416 // will free it once the isolate group has shutdown.
5418 kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
5420
5421 const char* error = nullptr;
5422 std::unique_ptr<kernel::Program> program =
5424 if (program == nullptr) {
5425 return Api::NewError("Can't load Kernel binary: %s.", error);
5426 }
5427 const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
5428 program.reset();
5429
5430 if (tmp.IsError()) {
5431 return Api::NewHandle(T, tmp.ptr());
5432 }
5433
5434 IG->source()->script_kernel_size = buffer_size;
5435 IG->source()->script_kernel_buffer = buffer;
5436
5437 // TODO(32618): Setting root library based on whether it has 'main' or not
5438 // is not correct because main can be in the exported namespace of a library
5439 // or it could be a getter.
5440 if (tmp.IsNull()) {
5441 return Api::NewError(
5442 "Invoked Dart programs must have a 'main' function defined:\n"
5443 "https://dart.dev/guides/language/"
5444 "language-tour#a-basic-dart-program");
5445 }
5446 library ^= tmp.ptr();
5447 IG->object_store()->set_root_library(library);
5448 return Api::NewHandle(T, library.ptr());
5449#endif // defined(DART_PRECOMPILED_RUNTIME)
5450}
5451
5453 Thread* thread = Thread::Current();
5454 Isolate* isolate = thread->isolate();
5455 CHECK_ISOLATE(isolate);
5456 TransitionNativeToVM transition(thread);
5457 return Api::NewHandle(thread,
5458 isolate->group()->object_store()->root_library());
5459}
5460
5463 const Object& obj = Object::Handle(Z, Api::UnwrapHandle(library));
5464 if (obj.IsNull() || obj.IsLibrary()) {
5465 Library& lib = Library::Handle(Z);
5466 lib ^= obj.ptr();
5467 T->isolate_group()->object_store()->set_root_library(lib);
5468 return library;
5469 }
5470 RETURN_TYPE_ERROR(Z, library, Library);
5471}
5472
5476 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5477 if (lib.IsNull()) {
5478 RETURN_TYPE_ERROR(Z, library, Library);
5479 }
5480 const String& cls_name = Api::UnwrapStringHandle(Z, class_name);
5481 if (cls_name.IsNull()) {
5483 }
5484 const Class& cls = Class::Handle(Z, lib.LookupClassAllowPrivate(cls_name));
5485 if (cls.IsNull()) {
5486 // TODO(turnidge): Return null or error in this case?
5487 const String& lib_name = String::Handle(Z, lib.name());
5488 return Api::NewError("Class '%s' not found in library '%s'.",
5489 cls_name.ToCString(), lib_name.ToCString());
5490 }
5493 return Api::NewHandle(T, cls.RareType());
5494}
5495
5498 intptr_t number_of_type_arguments,
5499 Dart_Handle* type_arguments,
5500 Nullability nullability) {
5502 // Validate the input arguments.
5503 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5504 if (lib.IsNull()) {
5505 RETURN_TYPE_ERROR(Z, library, Library);
5506 }
5507 if (!lib.Loaded()) {
5508 return Api::NewError("%s expects library argument 'library' to be loaded.",
5509 CURRENT_FUNC);
5510 }
5511 const String& name_str = Api::UnwrapStringHandle(Z, class_name);
5512 if (name_str.IsNull()) {
5514 }
5515 const Class& cls = Class::Handle(Z, lib.LookupClassAllowPrivate(name_str));
5516 if (cls.IsNull()) {
5517 const String& lib_name = String::Handle(Z, lib.name());
5518 return Api::NewError("Type '%s' not found in library '%s'.",
5519 name_str.ToCString(), lib_name.ToCString());
5520 }
5523
5524 Type& type = Type::Handle();
5525 if (cls.NumTypeArguments() == 0) {
5526 if (number_of_type_arguments != 0) {
5527 return Api::NewError(
5528 "Invalid number of type arguments specified, "
5529 "got %" Pd " expected 0",
5530 number_of_type_arguments);
5531 }
5533 type ^= type.ToNullability(nullability, Heap::kOld);
5534 } else {
5535 intptr_t num_expected_type_arguments = cls.NumTypeParameters();
5536 TypeArguments& type_args_obj = TypeArguments::Handle();
5537 if (number_of_type_arguments > 0) {
5538 if (type_arguments == nullptr) {
5539 RETURN_NULL_ERROR(type_arguments);
5540 }
5541 if (num_expected_type_arguments != number_of_type_arguments) {
5542 return Api::NewError(
5543 "Invalid number of type arguments specified, "
5544 "got %" Pd " expected %" Pd,
5545 number_of_type_arguments, num_expected_type_arguments);
5546 }
5547 const Array& array = Api::UnwrapArrayHandle(Z, *type_arguments);
5548 if (array.IsNull()) {
5549 RETURN_TYPE_ERROR(Z, *type_arguments, Array);
5550 }
5551 if (array.Length() != num_expected_type_arguments) {
5552 return Api::NewError(
5553 "Invalid type arguments specified, expected an "
5554 "array of len %" Pd " but got an array of len %" Pd,
5555 number_of_type_arguments, array.Length());
5556 }
5557 // Set up the type arguments array.
5558 type_args_obj = TypeArguments::New(num_expected_type_arguments);
5559 AbstractType& type_arg = AbstractType::Handle();
5560 for (intptr_t i = 0; i < number_of_type_arguments; i++) {
5561 type_arg ^= array.At(i);
5562 type_args_obj.SetTypeAt(i, type_arg);
5563 }
5564 }
5565
5566 // Construct the type object, canonicalize it and return.
5567 type ^= Type::New(cls, type_args_obj, nullability);
5568 }
5570 return Api::NewHandle(T, type.ptr());
5571}
5572
5575 intptr_t number_of_type_arguments,
5576 Dart_Handle* type_arguments) {
5577 return Api::NewError(
5578 "Cannot use legacy types with --sound-null-safety enabled. "
5579 "Use Dart_GetNullableType or Dart_GetNonNullableType instead.");
5580}
5581
5584 intptr_t number_of_type_arguments,
5585 Dart_Handle* type_arguments) {
5586 return GetTypeCommon(library, class_name, number_of_type_arguments,
5587 type_arguments, Nullability::kNullable);
5588}
5589
5593 intptr_t number_of_type_arguments,
5594 Dart_Handle* type_arguments) {
5595 return GetTypeCommon(library, class_name, number_of_type_arguments,
5596 type_arguments, Nullability::kNonNullable);
5597}
5598
5601 const Type& ty = Api::UnwrapTypeHandle(Z, type);
5602 if (ty.IsNull()) {
5604 }
5605 if (ty.nullability() == nullability) {
5606 return type;
5607 }
5608 return Api::NewHandle(T, ty.ToNullability(nullability, Heap::kOld));
5609}
5610
5613}
5614
5617}
5618
5620 Nullability nullability,
5621 bool* result) {
5623 const Type& ty = Api::UnwrapTypeHandle(Z, type);
5624 if (ty.IsNull()) {
5625 *result = false;
5627 }
5628 *result = (ty.nullability() == nullability);
5629 return Api::Success();
5630}
5631
5634}
5635
5638}
5639
5642 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5643 if (lib.IsNull()) {
5644 RETURN_TYPE_ERROR(Z, library, Library);
5645 }
5646 const String& url = String::Handle(Z, lib.url());
5647 ASSERT(!url.IsNull());
5648 return Api::NewHandle(T, url.ptr());
5649}
5650
5653 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5654 if (lib.IsNull()) {
5655 RETURN_TYPE_ERROR(Z, library, Library);
5656 }
5657 const Class& toplevel = Class::Handle(lib.toplevel_class());
5658 ASSERT(!toplevel.IsNull());
5659 const Script& script = Script::Handle(toplevel.script());
5660 ASSERT(!script.IsNull());
5661 const String& url = String::Handle(script.resolved_url());
5662 ASSERT(!url.IsNull());
5663 return Api::NewHandle(T, url.ptr());
5664}
5665
5668 auto IG = T->isolate_group();
5669
5670 const GrowableObjectArray& libs =
5671 GrowableObjectArray::Handle(Z, IG->object_store()->libraries());
5672 int num_libs = libs.Length();
5673
5674 // Create new list and populate with the loaded libraries.
5675 Library& lib = Library::Handle();
5676 const Array& library_list = Array::Handle(Z, Array::New(num_libs));
5677 for (int i = 0; i < num_libs; i++) {
5678 lib ^= libs.At(i);
5679 ASSERT(!lib.IsNull());
5680 library_list.SetAt(i, lib);
5681 }
5682 return Api::NewHandle(T, library_list.ptr());
5683}
5684
5687 const String& url_str = Api::UnwrapStringHandle(Z, url);
5688 if (url_str.IsNull()) {
5689 RETURN_TYPE_ERROR(Z, url, String);
5690 }
5691 const Library& library =
5693 if (library.IsNull()) {
5694 return Api::NewError("%s: library '%s' not found.", CURRENT_FUNC,
5695 url_str.ToCString());
5696 } else {
5697 return Api::NewHandle(T, library.ptr());
5698 }
5699}
5700
5702 Dart_Handle error_in) {
5704
5705 const Library& lib = Api::UnwrapLibraryHandle(Z, library_in);
5706 if (lib.IsNull()) {
5707 RETURN_TYPE_ERROR(Z, library_in, Library);
5708 }
5709 const Instance& err = Api::UnwrapInstanceHandle(Z, error_in);
5710 if (err.IsNull()) {
5711 RETURN_TYPE_ERROR(Z, error_in, Instance);
5712 }
5714
5715 return error_in;
5716}
5717
5718#if !defined(DART_PRECOMPILED_RUNTIME)
5720 const char* error = nullptr;
5721 std::unique_ptr<kernel::Program> program =
5723 if (program == nullptr) {
5724 return Api::NewError("Can't load Kernel binary: %s.", error);
5725 }
5726 const Object& result =
5727 kernel::KernelLoader::LoadEntireProgram(program.get(), false);
5728 program.reset();
5729
5731 source->add_loaded_blob(Z, td);
5732
5733 return Api::NewHandle(T, result.ptr());
5734}
5735#endif // !defined(DART_PRECOMPILED_RUNTIME)
5736
5738 intptr_t buffer_size) {
5739#if defined(DART_PRECOMPILED_RUNTIME)
5740 return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
5741#else
5744 StackZone zone(T);
5745
5747
5748 // NOTE: We do not attach a finalizer for this object, because the embedder
5749 // will/should free it once the isolate group has shutdown.
5751 kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
5753 return LoadLibrary(T, td);
5754#endif // defined(DART_PRECOMPILED_RUNTIME)
5755}
5756
5758#if defined(DART_PRECOMPILED_RUNTIME)
5759 return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
5760#else
5762 const ExternalTypedData& td =
5763 Api::UnwrapExternalTypedDataHandle(Z, kernel_buffer);
5764 if (td.IsNull()) {
5765 RETURN_TYPE_ERROR(Z, kernel_buffer, ExternalTypedData);
5766 }
5767 return LoadLibrary(T, td);
5768#endif // defined(DART_PRECOMPILED_RUNTIME)
5769}
5770
5771// Finalizes classes and invokes Dart core library function that completes
5772// futures of loadLibrary calls (deferred library loading).
5776 Isolate* I = T->isolate();
5778
5779 // Finalize all classes if needed.
5781 if (Api::IsError(state)) {
5782 return state;
5783 }
5784
5785#if !defined(PRODUCT)
5786 // Now that the newly loaded classes are finalized, notify the debugger
5787 // that new code has been loaded. If there are latent breakpoints in
5788 // the new code, the debugger convert them to unresolved source breakpoints.
5789 // The code that completes the futures (invoked below) may call into the
5790 // newly loaded code and trigger one of these breakpoints.
5791 I->debugger()->NotifyDoneLoading();
5792#endif
5793
5794 // After having loaded all the code, we can let the GC set reasonable limits
5795 // for the heap growth.
5796 // If this is an auxiliary isolate inside a larger isolate group, we will not
5797 // re-initialize the growth policy.
5798 if (I->group()->ContainsOnlyOneIsolate()) {
5799 I->group()->heap()->old_space()->EvaluateAfterLoading();
5800 }
5801
5802#if !defined(DART_PRECOMPILED_RUNTIME)
5803 if (FLAG_enable_mirrors) {
5804 // Notify mirrors that MirrorSystem.libraries needs to be recomputed.
5805 const Library& libmirrors = Library::Handle(Z, Library::MirrorsLibrary());
5806 const Field& dirty_bit =
5808 String::Handle(String::New("_dirty"))));
5809 ASSERT(!dirty_bit.IsNull() && dirty_bit.is_static());
5810 dirty_bit.SetStaticValue(Bool::True());
5811 }
5812#endif
5813
5814 return Api::Success();
5815}
5816
5817static Dart_Handle DeferredLoadComplete(intptr_t loading_unit_id,
5818 bool error,
5819 const uint8_t* snapshot_data,
5820 const uint8_t* snapshot_instructions,
5821 const char* error_message,
5822 bool transient_error) {
5825 auto IG = T->isolate_group();
5827
5828 const Array& loading_units =
5829 Array::Handle(IG->object_store()->loading_units());
5830 if (loading_units.IsNull() || (loading_unit_id < LoadingUnit::kRootId) ||
5831 (loading_unit_id >= loading_units.Length())) {
5832 return Api::NewError("Invalid loading unit");
5833 }
5835 unit ^= loading_units.At(loading_unit_id);
5836 if (unit.loaded()) {
5837 return Api::NewError("Unit already loaded");
5838 }
5839
5840 if (error) {
5841 CHECK_NULL(error_message);
5842 return Api::NewHandle(
5843 T, unit.CompleteLoad(String::Handle(String::New(error_message)),
5844 transient_error));
5845 } else {
5846#if defined(SUPPORT_TIMELINE)
5847 TimelineBeginEndScope tbes(T, Timeline::GetIsolateStream(),
5848 "ReadUnitSnapshot");
5849#endif // defined(SUPPORT_TIMELINE)
5850 const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
5851 if (snapshot == nullptr) {
5852 return Api::NewError("Invalid snapshot");
5853 }
5854 if (!IsSnapshotCompatible(Dart::vm_snapshot_kind(), snapshot->kind())) {
5856 "Incompatible snapshot kinds: vm '%s', isolate '%s'",
5858 Snapshot::KindToCString(snapshot->kind())));
5859 return Api::NewHandle(T, ApiError::New(message));
5860 }
5861
5862 FullSnapshotReader reader(snapshot, snapshot_instructions, T);
5863 const Error& error = Error::Handle(reader.ReadUnitSnapshot(unit));
5864 if (!error.IsNull()) {
5865 return Api::NewHandle(T, error.ptr());
5866 }
5867
5868 return Api::NewHandle(T, unit.CompleteLoad(String::Handle(), false));
5869 }
5870}
5871
5873Dart_DeferredLoadComplete(intptr_t loading_unit_id,
5874 const uint8_t* snapshot_data,
5875 const uint8_t* snapshot_instructions) {
5876 return DeferredLoadComplete(loading_unit_id, false, snapshot_data,
5877 snapshot_instructions, nullptr, false);
5878}
5879
5881Dart_DeferredLoadCompleteError(intptr_t loading_unit_id,
5882 const char* error_message,
5883 bool transient) {
5884 return DeferredLoadComplete(loading_unit_id, true, nullptr, nullptr,
5885 error_message, transient);
5886}
5887
5890 Dart_NativeEntryResolver resolver,
5891 Dart_NativeEntrySymbol symbol) {
5893 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5894 if (lib.IsNull()) {
5895 RETURN_TYPE_ERROR(Z, library, Library);
5896 }
5897 lib.set_native_entry_resolver(resolver);
5899 return Api::Success();
5900}
5901
5904 Dart_NativeEntryResolver* resolver) {
5905 if (resolver == nullptr) {
5906 RETURN_NULL_ERROR(resolver);
5907 }
5908 *resolver = nullptr;
5910 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5911 if (lib.IsNull()) {
5912 RETURN_TYPE_ERROR(Z, library, Library);
5913 }
5914 *resolver = lib.native_entry_resolver();
5915 return Api::Success();
5916}
5917
5919 Dart_NativeEntrySymbol* resolver) {
5920 if (resolver == nullptr) {
5921 RETURN_NULL_ERROR(resolver);
5922 }
5923 *resolver = nullptr;
5925 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5926 if (lib.IsNull()) {
5927 RETURN_TYPE_ERROR(Z, library, Library);
5928 }
5929 *resolver = lib.native_entry_symbol_resolver();
5930 return Api::Success();
5931}
5932
5935 Dart_FfiNativeResolver resolver) {
5937 const Library& lib = Api::UnwrapLibraryHandle(Z, library);
5938 if (lib.IsNull()) {
5939 RETURN_TYPE_ERROR(Z, library, Library);
5940 }
5941 lib.set_ffi_native_resolver(resolver);
5942 return Api::Success();
5943}
5944
5948 IsolateGroup* isolate_group = T->isolate_group();
5949 CHECK_ISOLATE_GROUP(isolate_group);
5950 isolate_group->SetNativeAssetsCallbacks(native_assets_api);
5951}
5952
5953// --- Peer support ---
5954
5956 if (peer == nullptr) {
5957 RETURN_NULL_ERROR(peer);
5958 }
5959 Thread* thread = Thread::Current();
5960 CHECK_ISOLATE(thread->isolate());
5961 TransitionNativeToVM transition(thread);
5963 Object& obj = thread->ObjectHandle();
5964 obj = Api::UnwrapHandle(object);
5965 if (obj.IsNull() || obj.IsNumber() || obj.IsBool()) {
5966 const char* msg =
5967 "%s: argument 'object' cannot be a subtype of Null, num, or bool";
5968 return Api::NewError(msg, CURRENT_FUNC);
5969 }
5970 {
5971 NoSafepointScope no_safepoint;
5972 ObjectPtr raw_obj = obj.ptr();
5973 *peer = thread->heap()->GetPeer(raw_obj);
5974 }
5975 return Api::Success();
5976}
5977
5979 Thread* thread = Thread::Current();
5980 CHECK_ISOLATE(thread->isolate());
5981 TransitionNativeToVM transition(thread);
5983 Object& obj = thread->ObjectHandle();
5984 obj = Api::UnwrapHandle(object);
5985 if (obj.IsNull() || obj.IsNumber() || obj.IsBool()) {
5986 const char* msg =
5987 "%s: argument 'object' cannot be a subtype of Null, num, or bool";
5988 return Api::NewError(msg, CURRENT_FUNC);
5989 }
5990 {
5991 NoSafepointScope no_safepoint;
5992 ObjectPtr raw_obj = obj.ptr();
5993 thread->heap()->SetPeer(raw_obj, peer);
5994 }
5995 return Api::Success();
5996}
5997
5998// --- Dart Front-End (Kernel) support ---
5999
6001#if defined(DART_PRECOMPILED_RUNTIME)
6002 return false;
6003#else
6004 Isolate* iso = reinterpret_cast<Isolate*>(isolate);
6005 return iso->is_kernel_isolate();
6006#endif
6007}
6008
6010#if defined(DART_PRECOMPILED_RUNTIME)
6011 return false;
6012#else
6013 return KernelIsolate::IsRunning();
6014#endif
6015}
6016
6018#if defined(DART_PRECOMPILED_RUNTIME)
6019 return false;
6020#else
6022#endif
6023}
6024
6026Dart_CompileToKernel(const char* script_uri,
6027 const uint8_t* platform_kernel,
6028 intptr_t platform_kernel_size,
6029 bool incremental_compile,
6030 bool for_snapshot,
6031 bool embed_sources,
6032 const char* package_config,
6035
6037#if defined(DART_PRECOMPILED_RUNTIME)
6039 result.error = Utils::StrDup("Dart_CompileToKernel is unsupported.");
6040#else
6042 script_uri, platform_kernel, platform_kernel_size, 0, nullptr,
6043 incremental_compile, for_snapshot, embed_sources, package_config, nullptr,
6044 nullptr, verbosity);
6045 if (incremental_compile) {
6046 Dart_KernelCompilationResult ack_result =
6050 if (ack_result.status != Dart_KernelCompilationStatus_Ok) {
6051 FATAL(
6052 "An error occurred in the CFE while acking the most recent"
6053 " compilation results: %s",
6054 ack_result.error);
6055 }
6056 }
6057#endif
6058 return result;
6059}
6060
6063#if defined(DART_PRECOMPILED_RUNTIME)
6065 result.error = Utils::StrDup("Dart_KernelListDependencies is unsupported.");
6066#else
6068#endif
6069 return result;
6070}
6071
6073 const uint8_t* platform_kernel,
6074 const intptr_t platform_kernel_size) {
6075#if !defined(PRODUCT)
6077 platform_kernel_size);
6078#endif
6079}
6080
6081DART_EXPORT bool Dart_DetectNullSafety(const char* script_uri,
6082 const char* package_config,
6083 const char* original_working_directory,
6084 const uint8_t* snapshot_data,
6085 const uint8_t* snapshot_instructions,
6086 const uint8_t* kernel_buffer,
6087 intptr_t kernel_buffer_size) {
6088 return true;
6089}
6090
6091// --- Service support ---
6092
6094 Isolate* iso = reinterpret_cast<Isolate*>(isolate);
6095 return iso->is_service_isolate();
6096}
6097
6099 const char* name,
6101 void* user_data) {
6102#if !defined(PRODUCT)
6104#endif
6105}
6106
6108 const char* name,
6110 void* user_data) {
6111#if !defined(PRODUCT)
6113#endif
6114}
6115
6118#if !defined(PRODUCT)
6120#endif
6121}
6122
6124 Dart_ServiceStreamListenCallback listen_callback,
6125 Dart_ServiceStreamCancelCallback cancel_callback) {
6126#if defined(PRODUCT)
6127 return nullptr;
6128#else
6129 if (listen_callback != nullptr) {
6130 if (Service::stream_listen_callback() != nullptr) {
6131 return Utils::StrDup(
6132 "Dart_SetServiceStreamCallbacks "
6133 "permits only one listen callback to be registered, please "
6134 "remove the existing callback and then add this callback");
6135 }
6136 } else {
6137 if (Service::stream_listen_callback() == nullptr) {
6138 return Utils::StrDup(
6139 "Dart_SetServiceStreamCallbacks "
6140 "expects 'listen_callback' to be present in the callback set.");
6141 }
6142 }
6143 if (cancel_callback != nullptr) {
6144 if (Service::stream_cancel_callback() != nullptr) {
6145 return Utils::StrDup(
6146 "Dart_SetServiceStreamCallbacks "
6147 "permits only one cancel callback to be registered, please "
6148 "remove the existing callback and then add this callback");
6149 }
6150 } else {
6151 if (Service::stream_cancel_callback() == nullptr) {
6152 return Utils::StrDup(
6153 "Dart_SetServiceStreamCallbacks "
6154 "expects 'cancel_callback' to be present in the callback set.");
6155 }
6156 }
6157 Service::SetEmbedderStreamCallbacks(listen_callback, cancel_callback);
6158 return nullptr;
6159#endif
6160}
6161
6162DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
6163 const char* event_kind,
6164 const uint8_t* bytes,
6165 intptr_t bytes_length) {
6166#if !defined(PRODUCT)
6167 if (stream_id == nullptr) {
6168 return Utils::StrDup(
6169 "Dart_ServiceSendDataEvent expects argument 'stream_id' to be "
6170 "non-null.");
6171 }
6172 if (event_kind == nullptr) {
6173 return Utils::StrDup(
6174 "Dart_ServiceSendDataEvent expects argument 'event_kind' to be "
6175 "non-null.");
6176 }
6177 if (bytes == nullptr) {
6178 return Utils::StrDup(
6179 "Dart_ServiceSendDataEvent expects argument 'bytes' to be non-null.");
6180 }
6181 if (bytes_length < 0) {
6182 return Utils::StrDup(
6183 "Dart_ServiceSendDataEvent expects argument 'bytes_length' to be >= "
6184 "0.");
6185 }
6186 Service::SendEmbedderEvent(Isolate::Current(), // May be nullptr
6187 stream_id, event_kind, bytes, bytes_length);
6188#endif
6189 return nullptr;
6190}
6191
6195}
6196
6198 Dart_FileModifiedCallback file_modified_callback) {
6199#if !defined(PRODUCT)
6200#if !defined(DART_PRECOMPILED_RUNTIME)
6201 if (file_modified_callback != nullptr) {
6203 return Utils::StrDup(
6204 "Dart_SetFileModifiedCallback permits only one callback to be"
6205 " registered, please remove the existing callback and then add"
6206 " this callback");
6207 }
6208 } else {
6210 return Utils::StrDup(
6211 "Dart_SetFileModifiedCallback expects 'file_modified_callback' to"
6212 " be set before it is cleared.");
6213 }
6214 }
6216#endif // !defined(DART_PRECOMPILED_RUNTIME)
6217#endif // !defined(PRODUCT)
6218 return nullptr;
6219}
6220
6222#if defined(PRODUCT) || defined(DART_PRECOMPILED_RUNTIME)
6223 return false;
6224#else
6225 Thread* thread = Thread::Current();
6226 Isolate* isolate = thread->isolate();
6227 CHECK_ISOLATE(isolate);
6228 return isolate->group()->IsReloading();
6229#endif
6230}
6231
6232DART_EXPORT bool Dart_SetEnabledTimelineCategory(const char* categories) {
6233#if defined(SUPPORT_TIMELINE)
6234 bool result = false;
6235 if (categories != nullptr) {
6236 char* carray = Utils::SCreate("[%s]", categories);
6238 free(carray);
6239 }
6240 return result;
6241#else
6242 return false;
6243#endif
6244}
6245
6248}
6249
6252}
6253
6256}
6257
6259 int64_t timestamp0,
6260 int64_t timestamp1_or_id,
6261 intptr_t flow_id_count,
6262 const int64_t* flow_ids,
6264 intptr_t argument_count,
6265 const char** argument_names,
6266 const char** argument_values) {
6267#if defined(SUPPORT_TIMELINE)
6269 return;
6270 }
6272 return;
6273 }
6274 if (!Dart::SetActiveApiCall()) {
6275 return;
6276 }
6277 TimelineStream* stream = Timeline::GetEmbedderStream();
6278 ASSERT(stream != nullptr);
6279 TimelineEvent* event = stream->StartEvent();
6280 if (event != nullptr) {
6281 switch (type) {
6283 event->Begin(label, timestamp1_or_id, timestamp0);
6284 break;
6286 event->End(label, timestamp1_or_id, timestamp0);
6287 break;
6289 event->Instant(label, timestamp0);
6290 break;
6292 event->Duration(label, timestamp0, timestamp1_or_id);
6293 break;
6295 event->AsyncBegin(label, timestamp1_or_id, timestamp0);
6296 break;
6298 event->AsyncEnd(label, timestamp1_or_id, timestamp0);
6299 break;
6301 event->AsyncInstant(label, timestamp1_or_id, timestamp0);
6302 break;
6304 event->Counter(label, timestamp0);
6305 break;
6307 event->FlowBegin(label, timestamp1_or_id, timestamp0);
6308 break;
6310 event->FlowStep(label, timestamp1_or_id, timestamp0);
6311 break;
6313 event->FlowEnd(label, timestamp1_or_id, timestamp0);
6314 break;
6315 default:
6316 FATAL("Unknown Dart_Timeline_Event_Type");
6317 }
6318 if (flow_id_count > 0 && flow_ids != nullptr) {
6319 std::unique_ptr<const int64_t[]> flow_ids_copy;
6320 int64_t* flow_ids_internal = new int64_t[flow_id_count];
6321 for (intptr_t i = 0; i < flow_id_count; ++i) {
6322 flow_ids_internal[i] = flow_ids[i];
6323 }
6324 flow_ids_copy = std::unique_ptr<const int64_t[]>(flow_ids_internal);
6325 event->SetFlowIds(flow_id_count, flow_ids_copy);
6326 }
6327 event->SetNumArguments(argument_count);
6328 for (intptr_t i = 0; i < argument_count; i++) {
6329 event->CopyArgument(i, argument_names[i], argument_values[i]);
6330 }
6331 event->Complete();
6332 }
6334#endif
6335}
6336
6339#if defined(SUPPORT_TIMELINE)
6340 Timeline::set_callback(callback);
6341#endif
6342}
6343
6345 OSThread* thread = OSThread::Current();
6346 if (thread == nullptr) {
6347 // VM is shutting down.
6348 return;
6349 }
6350 thread->SetName(name);
6351}
6352
6354#if defined(DART_PRECOMPILED_RUNTIME)
6355 return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
6356#else
6358
6359 // Prevent background compiler from running while code is being cleared and
6360 // adding new code.
6361 NoBackgroundCompilerScope no_bg_compiler(T);
6362
6363 // We don't have mechanisms to change class-ids that are embedded in code and
6364 // ICData.
6366 // Make sure that ICData etc. that have been cleared are also removed from
6367 // the heap so that they are not found by the heap verifier.
6370 return Api::Success();
6371#endif // defined(DART_PRECOMPILED_RUNTIME)
6372}
6373
6375#if defined(TARGET_ARCH_IA32)
6376 return Api::NewError("AOT compilation is not supported on IA32.");
6377#elif !defined(DART_PRECOMPILER)
6378 return Api::NewError(
6379 "This VM was built without support for AOT compilation.");
6380#else
6383 if (!FLAG_precompiled_mode) {
6384 return Api::NewError("Flag --precompilation was not specified.");
6385 }
6387 if (Api::IsError(result)) {
6388 return result;
6389 }
6391 CompilerState state(Thread::Current(), /*is_aot=*/true,
6392 /*is_optimizing=*/true);
6394 return Api::Success();
6395#endif
6396}
6397
6398// Used for StreamingWriteStream/BlobImageWriter sizes for ELF and blobs.
6399#if !defined(TARGET_ARCH_IA32) && defined(DART_PRECOMPILER)
6400static constexpr intptr_t kAssemblyInitialSize = 512 * KB;
6401static constexpr intptr_t kInitialSize = 2 * MB;
6402static constexpr intptr_t kInitialDebugSize = 1 * MB;
6403
6404static void CreateAppAOTSnapshot(
6406 void* callback_data,
6407 bool strip,
6408 bool as_elf,
6409 void* debug_callback_data,
6410 GrowableArray<LoadingUnitSerializationData*>* units,
6411 LoadingUnitSerializationData* unit,
6412 uint32_t program_hash) {
6413 Thread* T = Thread::Current();
6414
6415 NOT_IN_PRODUCT(TimelineBeginEndScope tbes2(T, Timeline::GetIsolateStream(),
6416 "WriteAppAOTSnapshot"));
6417
6418 ZoneWriteStream vm_snapshot_data(T->zone(), FullSnapshotWriter::kInitialSize);
6419 ZoneWriteStream vm_snapshot_instructions(T->zone(), kInitialSize);
6420 ZoneWriteStream isolate_snapshot_data(T->zone(),
6422 ZoneWriteStream isolate_snapshot_instructions(T->zone(), kInitialSize);
6423
6424 const bool generate_debug = debug_callback_data != nullptr;
6425
6426 auto* const deobfuscation_trie =
6427 (strip && !generate_debug) ? nullptr
6428 : ImageWriter::CreateReverseObfuscationTrie(T);
6429
6430 if (as_elf) {
6431 StreamingWriteStream elf_stream(kInitialSize, callback, callback_data);
6432 StreamingWriteStream debug_stream(generate_debug ? kInitialDebugSize : 0,
6433 callback, debug_callback_data);
6434
6435 auto const dwarf = strip ? nullptr : new (Z) Dwarf(Z, deobfuscation_trie);
6436 auto const elf = new (Z) Elf(Z, &elf_stream, Elf::Type::Snapshot, dwarf);
6437 // Re-use the same DWARF object if the snapshot is unstripped.
6438 auto const debug_elf =
6439 generate_debug
6440 ? new (Z) Elf(Z, &debug_stream, Elf::Type::DebugInfo,
6441 strip ? new (Z) Dwarf(Z, deobfuscation_trie) : dwarf)
6442 : nullptr;
6443
6444 BlobImageWriter image_writer(T, &vm_snapshot_instructions,
6446 deobfuscation_trie, debug_elf, elf);
6447 FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data,
6448 &isolate_snapshot_data, &image_writer,
6449 &image_writer);
6450
6451 if (unit == nullptr || unit->id() == LoadingUnit::kRootId) {
6452 writer.WriteFullSnapshot(units);
6453 } else {
6454 writer.WriteUnitSnapshot(units, unit, program_hash);
6455 }
6456
6457 elf->Finalize();
6458 if (debug_elf != nullptr) {
6459 debug_elf->Finalize();
6460 }
6461 } else {
6462 StreamingWriteStream assembly_stream(kAssemblyInitialSize, callback,
6463 callback_data);
6464 StreamingWriteStream debug_stream(generate_debug ? kInitialDebugSize : 0,
6465 callback, debug_callback_data);
6466
6467 auto const elf = generate_debug
6468 ? new (Z) Elf(Z, &debug_stream, Elf::Type::DebugInfo,
6469 new (Z) Dwarf(Z, deobfuscation_trie))
6470 : nullptr;
6471
6472 AssemblyImageWriter image_writer(T, &assembly_stream, deobfuscation_trie,
6473 strip, elf);
6474 FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data,
6475 &isolate_snapshot_data, &image_writer,
6476 &image_writer);
6477
6478 if (unit == nullptr || unit->id() == LoadingUnit::kRootId) {
6479 writer.WriteFullSnapshot(units);
6480 } else {
6481 writer.WriteUnitSnapshot(units, unit, program_hash);
6482 }
6483 image_writer.Finalize();
6484 }
6485}
6486
6487static void Split(Dart_CreateLoadingUnitCallback next_callback,
6488 void* next_callback_data,
6489 bool strip,
6490 bool as_elf,
6491 Dart_StreamingWriteCallback write_callback,
6492 Dart_StreamingCloseCallback close_callback) {
6493 Thread* T = Thread::Current();
6494 ProgramVisitor::AssignUnits(T);
6495
6496 const Array& loading_units =
6497 Array::Handle(T->isolate_group()->object_store()->loading_units());
6498 const uint32_t program_hash = ProgramVisitor::Hash(T);
6499 loading_units.SetAt(0, Smi::Handle(Z, Smi::New(program_hash)));
6500 GrowableArray<LoadingUnitSerializationData*> data;
6501 data.SetLength(loading_units.Length());
6502 data[0] = nullptr;
6503
6504 LoadingUnit& loading_unit = LoadingUnit::Handle();
6505 LoadingUnit& parent = LoadingUnit::Handle();
6506 for (intptr_t id = 1; id < loading_units.Length(); id++) {
6507 loading_unit ^= loading_units.At(id);
6508 parent = loading_unit.parent();
6509 LoadingUnitSerializationData* parent_data =
6510 parent.IsNull() ? nullptr : data[parent.id()];
6511 data[id] = new LoadingUnitSerializationData(id, parent_data);
6512 }
6513
6514 for (intptr_t id = 1; id < loading_units.Length(); id++) {
6515 void* write_callback_data = nullptr;
6516 void* write_debug_callback_data = nullptr;
6517 {
6518 TransitionVMToNative transition(T);
6519 next_callback(next_callback_data, id, &write_callback_data,
6520 &write_debug_callback_data);
6521 }
6522 CreateAppAOTSnapshot(write_callback, write_callback_data, strip, as_elf,
6523 write_debug_callback_data, &data, data[id],
6524 program_hash);
6525 {
6526 TransitionVMToNative transition(T);
6527 close_callback(write_callback_data);
6528 if (write_debug_callback_data != nullptr) {
6529 close_callback(write_debug_callback_data);
6530 }
6531 }
6532 }
6533}
6534#endif
6535
6538 void* callback_data,
6539 bool strip,
6540 void* debug_callback_data) {
6541#if defined(TARGET_ARCH_IA32)
6542 return Api::NewError("AOT compilation is not supported on IA32.");
6543#elif defined(DART_TARGET_OS_WINDOWS)
6544 return Api::NewError("Assembly generation is not implemented for Windows.");
6545#elif !defined(DART_PRECOMPILER)
6546 return Api::NewError(
6547 "This VM was built without support for AOT compilation.");
6548#else
6552
6553 // Mark as not split.
6554 T->isolate_group()->object_store()->set_loading_units(Object::null_array());
6555
6556 CreateAppAOTSnapshot(callback, callback_data, strip, /*as_elf*/ false,
6557 debug_callback_data, nullptr, nullptr, 0);
6558
6559 return Api::Success();
6560#endif
6561}
6562
6564 Dart_CreateLoadingUnitCallback next_callback,
6565 void* next_callback_data,
6566 bool strip,
6567 Dart_StreamingWriteCallback write_callback,
6568 Dart_StreamingCloseCallback close_callback) {
6569#if defined(TARGET_ARCH_IA32)
6570 return Api::NewError("AOT compilation is not supported on IA32.");
6571#elif defined(DART_TARGET_OS_WINDOWS)
6572 return Api::NewError("Assembly generation is not implemented for Windows.");
6573#elif !defined(DART_PRECOMPILER)
6574 return Api::NewError(
6575 "This VM was built without support for AOT compilation.");
6576#else
6579 CHECK_NULL(next_callback);
6580 CHECK_NULL(write_callback);
6581 CHECK_NULL(close_callback);
6582
6583 Split(next_callback, next_callback_data, strip, /*as_elf*/ false,
6584 write_callback, close_callback);
6585
6586 return Api::Success();
6587#endif
6588}
6589
6592 void* callback_data) {
6593#if defined(TARGET_ARCH_IA32)
6594 return Api::NewError("AOT compilation is not supported on IA32.");
6595#elif defined(DART_TARGET_OS_WINDOWS)
6596 return Api::NewError("Assembly generation is not implemented for Windows.");
6597#elif !defined(DART_PRECOMPILER)
6598 return Api::NewError(
6599 "This VM was built without support for AOT compilation.");
6600#else
6604
6605 TIMELINE_DURATION(T, Isolate, "WriteVMAOTSnapshot");
6606 StreamingWriteStream assembly_stream(kAssemblyInitialSize, callback,
6607 callback_data);
6608 AssemblyImageWriter image_writer(T, &assembly_stream);
6611 &image_writer, nullptr);
6612
6613 writer.WriteFullSnapshot();
6614
6615 return Api::Success();
6616#endif
6617}
6618
6621 void* callback_data,
6622 bool strip,
6623 void* debug_callback_data) {
6624#if defined(TARGET_ARCH_IA32)
6625 return Api::NewError("AOT compilation is not supported on IA32.");
6626#elif !defined(DART_PRECOMPILER)
6627 return Api::NewError(
6628 "This VM was built without support for AOT compilation.");
6629#else
6633
6634 // Mark as not split.
6635 T->isolate_group()->object_store()->set_loading_units(Object::null_array());
6636
6637 CreateAppAOTSnapshot(callback, callback_data, strip, /*as_elf*/ true,
6638 debug_callback_data, nullptr, nullptr, 0);
6639
6640 return Api::Success();
6641#endif
6642}
6643
6646 void* next_callback_data,
6647 bool strip,
6648 Dart_StreamingWriteCallback write_callback,
6649 Dart_StreamingCloseCallback close_callback) {
6650#if defined(TARGET_ARCH_IA32)
6651 return Api::NewError("AOT compilation is not supported on IA32.");
6652#elif !defined(DART_PRECOMPILER)
6653 return Api::NewError(
6654 "This VM was built without support for AOT compilation.");
6655#else
6658 CHECK_NULL(next_callback);
6659 CHECK_NULL(write_callback);
6660 CHECK_NULL(close_callback);
6661
6662 Split(next_callback, next_callback_data, strip, /*as_elf*/ true,
6663 write_callback, close_callback);
6664
6665 return Api::Success();
6666#endif
6667}
6668
6670#if defined(TARGET_ARCH_IA32)
6671 return Api::NewError("AOT compilation is not supported on IA32.");
6672#elif !defined(DART_PRECOMPILER)
6673 return Api::NewError(
6674 "This VM was built without support for AOT compilation.");
6675#else
6678
6679 const Array& loading_units =
6680 Array::Handle(Z, T->isolate_group()->object_store()->loading_unit_uris());
6681 if (loading_unit_id >= 0 && loading_unit_id < loading_units.Length()) {
6682 return Api::NewHandle(T, loading_units.At(loading_unit_id));
6683 }
6684 return Api::NewError("Invalid loading_unit_id");
6685#endif
6686}
6687
6688#if (!defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME))
6689
6690// Any flag that affects how we compile code might cause a problem when the
6691// snapshot writer generates code with one value of the flag and the snapshot
6692// reader expects code to behave according to another value of the flag.
6693// Normally, we add these flags to Dart::FeaturesString and refuse to run the
6694// snapshot it they don't match, but since --interpret-irregexp affects only
6695// 2 functions we choose to remove the code instead. See issue #34422.
6696static void DropRegExpMatchCode(Zone* zone) {
6697 const String& execute_match_name =
6698 String::Handle(zone, String::New("_ExecuteMatch"));
6699 const String& execute_match_sticky_name =
6700 String::Handle(zone, String::New("_ExecuteMatchSticky"));
6701
6702 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
6703 const Class& reg_exp_class =
6704 Class::Handle(zone, core_lib.LookupClassAllowPrivate(Symbols::_RegExp()));
6705 ASSERT(!reg_exp_class.IsNull());
6706
6707 auto thread = Thread::Current();
6708 Function& func = Function::Handle(
6709 zone, reg_exp_class.LookupFunctionAllowPrivate(execute_match_name));
6710 ASSERT(!func.IsNull());
6711 Code& code = Code::Handle(zone);
6712 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
6713 if (func.HasCode()) {
6714 code = func.CurrentCode();
6715 ASSERT(!code.IsNull());
6716 code.DisableDartCode();
6717 }
6718 func.ClearCode();
6719 func.ClearICDataArray();
6720 ASSERT(!func.HasCode());
6721
6722 func = reg_exp_class.LookupFunctionAllowPrivate(execute_match_sticky_name);
6723 ASSERT(!func.IsNull());
6724 if (func.HasCode()) {
6725 code = func.CurrentCode();
6726 ASSERT(!code.IsNull());
6727 code.DisableDartCode();
6728 }
6729 func.ClearCode();
6730 func.ClearICDataArray();
6731 ASSERT(!func.HasCode());
6732}
6733
6734#endif // (!defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME))
6735
6736#if !defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
6738 auto group = main_isolate->group();
6739 while (true) {
6740 bool non_main_isolates_alive = false;
6741 {
6742 DeoptSafepointOperationScope safepoint(thread);
6743 group->ForEachIsolate(
6744 [&](Isolate* isolate) {
6745 if (isolate != main_isolate) {
6747 non_main_isolates_alive = true;
6748 }
6749 },
6750 /*at_safepoint=*/true);
6751 if (!non_main_isolates_alive) {
6752 break;
6753 }
6754 }
6755 OS::SleepMicros(10 * 1000);
6756 }
6757}
6758#endif // !defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
6759
6761Dart_CreateAppJITSnapshotAsBlobs(uint8_t** isolate_snapshot_data_buffer,
6762 intptr_t* isolate_snapshot_data_size,
6763 uint8_t** isolate_snapshot_instructions_buffer,
6764 intptr_t* isolate_snapshot_instructions_size) {
6765#if defined(TARGET_ARCH_IA32)
6766 return Api::NewError("Snapshots with code are not supported on IA32.");
6767#elif defined(DART_PRECOMPILED_RUNTIME)
6768 return Api::NewError("JIT app snapshots cannot be taken from an AOT runtime");
6769#else
6772 auto I = T->isolate();
6773 auto IG = T->isolate_group();
6774 CHECK_NULL(isolate_snapshot_data_buffer);
6775 CHECK_NULL(isolate_snapshot_data_size);
6776 CHECK_NULL(isolate_snapshot_instructions_buffer);
6777 CHECK_NULL(isolate_snapshot_instructions_size);
6778
6779 // Finalize all classes if needed.
6781 if (Api::IsError(state)) {
6782 return state;
6783 }
6784
6785 // Kill off any auxiliary isolates before starting with deduping.
6787
6788 NoBackgroundCompilerScope no_bg_compiler(T);
6790
6792
6793 if (FLAG_dump_tables) {
6798 }
6799
6800 TIMELINE_DURATION(T, Isolate, "WriteAppJITSnapshot");
6805 BlobImageWriter image_writer(T, /*vm_instructions=*/nullptr,
6808 nullptr, &image_writer);
6809 writer.WriteFullSnapshot();
6810
6811 *isolate_snapshot_data_buffer = isolate_snapshot_data.buffer();
6812 *isolate_snapshot_data_size = isolate_snapshot_data.bytes_written();
6813 *isolate_snapshot_instructions_buffer =
6815 *isolate_snapshot_instructions_size =
6816 isolate_snapshot_instructions.bytes_written();
6817
6818 return Api::Success();
6819#endif
6820}
6821
6823 intptr_t* buffer_length) {
6824#if defined(DART_PRECOMPILED_RUNTIME)
6825 return Api::NewError("No obfuscation map to save on an AOT runtime.");
6826#elif !defined(DART_PRECOMPILER)
6827 return Api::NewError("Obfuscation is only supported for AOT compiler.");
6828#else
6829 Thread* thread = Thread::Current();
6830 DARTSCOPE(thread);
6831 auto isolate_group = thread->isolate_group();
6832
6833 if (buffer == nullptr) {
6835 }
6836 if (buffer_length == nullptr) {
6837 RETURN_NULL_ERROR(buffer_length);
6838 }
6839
6840 // Note: can't use JSONStream in PRODUCT builds.
6841 const intptr_t kInitialBufferSize = 1 * MB;
6842 ZoneTextBuffer text_buffer(Api::TopScope(T)->zone(), kInitialBufferSize);
6843
6844 text_buffer.AddChar('[');
6845 if (isolate_group->obfuscation_map() != nullptr) {
6846 for (intptr_t i = 0; isolate_group->obfuscation_map()[i] != nullptr; i++) {
6847 if (i > 0) {
6848 text_buffer.AddChar(',');
6849 }
6850 text_buffer.AddChar('"');
6851 text_buffer.AddEscapedString(isolate_group->obfuscation_map()[i]);
6852 text_buffer.AddChar('"');
6853 }
6854 }
6855 text_buffer.AddChar(']');
6856
6857 *buffer_length = text_buffer.length();
6858 *reinterpret_cast<char**>(buffer) = text_buffer.buffer();
6859 return Api::Success();
6860#endif
6861}
6862
6864#if defined(DART_PRECOMPILED_RUNTIME)
6865 return true;
6866#else
6867 return false;
6868#endif
6869}
6870
6871DART_EXPORT void Dart_DumpNativeStackTrace(void* context) {
6872#if !defined(PRODUCT) || defined(DART_PRECOMPILER)
6873 Profiler::DumpStackTrace(context);
6874#endif
6875}
6876
6879}
6880
6882 Thread* thread = Thread::Current();
6883 CHECK_ISOLATE(thread->isolate());
6884 DARTSCOPE(thread);
6885 Isolate* isolate = thread->isolate();
6886 return Api::NewHandle(thread, isolate->current_tag());
6887}
6888
6890 Thread* thread = Thread::Current();
6891 CHECK_ISOLATE(thread->isolate());
6892 DARTSCOPE(thread);
6893 Isolate* isolate = thread->isolate();
6894 return Api::NewHandle(thread, isolate->default_tag());
6895}
6896
6898 Thread* thread = Thread::Current();
6899 CHECK_ISOLATE(thread->isolate());
6900 DARTSCOPE(thread);
6901 if (label == nullptr) {
6902 return Api::NewError(
6903 "Dart_NewUserTag expects argument 'label' to be non-null");
6904 }
6905 const String& value = String::Handle(String::New(label));
6906 return Api::NewHandle(thread, UserTag::New(value));
6907}
6908
6910 Thread* thread = Thread::Current();
6911 CHECK_ISOLATE(thread->isolate());
6912 DARTSCOPE(thread);
6913 const UserTag& tag = Api::UnwrapUserTagHandle(Z, user_tag);
6914 if (tag.IsNull()) {
6915 RETURN_TYPE_ERROR(Z, user_tag, UserTag);
6916 }
6917 return Api::NewHandle(thread, tag.MakeActive());
6918}
6919
6922 const UserTag& tag = Api::UnwrapUserTagHandle(Z, user_tag);
6923 if (tag.IsNull()) {
6924 return nullptr;
6925 }
6926 const String& label = String::Handle(Z, tag.label());
6927 return Utils::StrDup(label.ToCString());
6928}
6929
6932 void* context) {
6933#if defined(DART_ENABLE_HEAP_SNAPSHOT_WRITER)
6935 CallbackHeapSnapshotWriter callback_writer(T, write, context);
6936 HeapSnapshotWriter writer(T, &callback_writer);
6937 writer.Write();
6938 return nullptr;
6939#else
6940 return Utils::StrDup("VM is built without the heap snapshot writer.");
6941#endif
6942}
6943
6944} // namespace dart
int count
Definition: FontMgrTest.cpp:50
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static void Union(SkRegion *rgn, const SkIRect &rect)
Definition: RegionTest.cpp:27
SI F table(const skcms_Curve *curve, F v)
#define IG
#define UNREACHABLE()
Definition: assert.h:248
GLenum type
#define CLASS_LIST_FOR_HANDLES(V)
Definition: class_id.h:193
bool IsFinalized() const
Definition: object.h:9053
Nullability nullability() const
Definition: object.h:9060
virtual ClassPtr type_class() const
Definition: object.cc:21042
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:10924
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
ObjectPtr At(intptr_t index) const
Definition: object.h:10875
intptr_t Length() const
Definition: object.h:10829
void SetAt(intptr_t index, const Object &value) const
Definition: object.h:10880
char * buffer() const
Definition: text_buffer.h:35
intptr_t length() const
Definition: text_buffer.h:36
void AddEscapedString(const char *s)
Definition: text_buffer.cc:267
void AddChar(char ch)
Definition: text_buffer.cc:49
static const Bool & False()
Definition: object.h:10799
static const Bool & Get(bool value)
Definition: object.h:10801
static const Bool & True()
Definition: object.h:10797
bool value() const
Definition: object.h:10791
static InstancePtr Data(const Instance &view_obj)
Definition: object.h:11863
static AbstractTypePtr FinalizeType(const AbstractType &type, FinalizationKind finalization=kCanonicalize)
static bool ProcessPendingClasses()
static bool AllClassesFinalized()
static void ClearAllCode(bool including_nonchanging_cids=false)
static void SortClasses()
ClassPtr At(intptr_t cid) const
Definition: class_table.h:362
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition: object.cc:6167
ObjectPtr InvokeSetter(const String &selector, const Instance &argument, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition: object.cc:4577
LibraryPtr library() const
Definition: object.h:1333
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:4684
ObjectPtr InvokeGetter(const String &selector, bool throw_nsm_if_absent, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition: object.cc:4517
intptr_t id() const
Definition: object.h:1233
void set_is_fields_marked_nullable() const
Definition: object.cc:5695
intptr_t NumTypeArguments() const
Definition: object.cc:3640
TypePtr RareType() const
Definition: object.cc:3036
ArrayPtr fields() const
Definition: object.h:1615
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:5920
uint16_t num_native_fields() const
Definition: object.h:1788
bool IsDynamicClass() const
Definition: object.h:1556
StringPtr Name() const
Definition: object.cc:2977
FunctionPtr LookupStaticFunctionAllowPrivate(const String &name) const
Definition: object.cc:6143
ErrorPtr EnsureIsFinalized(Thread *thread) const
Definition: object.cc:4924
bool IsVoidClass() const
Definition: object.h:1559
bool is_future_subtype() const
Definition: object.h:2182
ErrorPtr EnsureIsAllocateFinalized(Thread *thread) const
Definition: object.cc:4954
bool is_fields_marked_nullable() const
Definition: object.h:1776
ClassPtr SuperClass(ClassTable *class_table=nullptr) const
Definition: object.cc:3665
StringPtr UserVisibleName() const
Definition: object.cc:2989
bool IsTopLevel() const
Definition: object.cc:6121
bool IsNeverClass() const
Definition: object.h:1562
bool is_allocated() const
Definition: object.h:1781
DART_WARN_UNUSED_RESULT ErrorPtr VerifyEntryPoint() const
Definition: object.cc:27370
intptr_t NumTypeParameters(Thread *thread) const
Definition: object.cc:3555
bool is_finalized() const
Definition: object.h:1723
ScriptPtr script() const
Definition: object.h:1272
void EnsureDeclarationLoaded() const
Definition: object.cc:4913
static ObjectPtr InvokeClosure(Thread *thread, const Array &arguments)
Definition: dart_entry.cc:282
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)
Definition: dart_entry.cc:583
static ObjectPtr Equals(const Instance &left, const Instance &right)
Definition: dart_entry.cc:647
static ObjectPtr ToString(const Instance &receiver)
Definition: dart_entry.cc:615
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:1147
static char * Cleanup()
Definition: dart.cc:629
static void ShutdownIsolate(Thread *T)
Definition: dart.cc:1123
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:1152
static void ResetActiveApiCall()
Definition: dart.cc:807
static Snapshot::Kind vm_snapshot_kind()
Definition: dart.h:95
static void RunShutdownCallback()
Definition: dart.cc:1110
static LocalHandle * AllocateReadOnlyApiHandle()
Definition: dart.cc:1141
static ErrorPtr InitializeIsolate(Thread *T, bool is_first_isolate_in_group, void *isolate_data)
Definition: dart.cc:950
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:23402
double value() const
Definition: object.h:10115
static DART_NORETURN void Throw(Thread *thread, const Instance &exception)
Definition: exceptions.cc:979
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
Definition: exceptions.cc:1082
static DART_NORETURN void ReThrow(Thread *thread, const Instance &exception, const Instance &stacktrace, bool bypass_debugger=false)
Definition: exceptions.cc:986
static DART_NORETURN void PropagateError(const Error &error)
Definition: exceptions.cc:1003
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:25626
static bool IsExternalTypedData(const Instance &obj)
Definition: object.h:11758
static intptr_t MaxElements(intptr_t class_id)
Definition: object.h:11744
bool is_static() const
Definition: object.h:4440
void SetStaticValue(const Object &value) const
Definition: object.cc:12770
void RecordStore(const Object &value) const
Definition: object.cc:13027
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 bool IsSet(const char *name)
static char * ProcessCommandLineFlags(int argc, const char **argv)
ApiErrorPtr ReadUnitSnapshot(const LoadingUnit &unit)
intptr_t VmIsolateSnapshotSize() const
Definition: app_snapshot.h:125
void WriteFullSnapshot(GrowableArray< LoadingUnitSerializationData * > *data=nullptr)
intptr_t IsolateSnapshotSize() const
Definition: app_snapshot.h:126
static constexpr intptr_t kInitialSize
Definition: app_snapshot.h:110
CodePtr CurrentCode() const
Definition: object.h:3177
StringPtr UserVisibleName() const
Definition: object.cc:10999
ObjectPtr DoArgumentTypesMatch(const Array &args, const ArgumentsDescriptor &arg_names) const
Definition: object.cc:9505
bool IsImplicitClosureFunction() const
Definition: object.h:3903
bool HasCode() const
Definition: object.cc:7936
FunctionPtr parent_function() const
Definition: object.cc:8167
bool AreValidArgumentCounts(intptr_t num_type_arguments, intptr_t num_arguments, intptr_t num_named_arguments, String *error_message) const
Definition: object.cc:9250
DART_WARN_UNUSED_RESULT ErrorPtr VerifyCallEntryPoint() const
Definition: object.cc:27310
FunctionPtr ImplicitClosureFunction() const
Definition: object.cc:10385
bool IsNonImplicitClosureFunction() const
Definition: object.h:3911
bool IsFactory() const
Definition: object.h:3367
void ClearCode() const
Definition: object.cc:7948
bool IsGenerativeConstructor() const
Definition: object.h:3363
ClassPtr Owner() const
Definition: object.cc:10841
UntaggedFunction::Kind kind() const
Definition: object.h:3349
ClosurePtr ImplicitStaticClosure() const
Definition: object.cc:10700
void ClearICDataArray() const
Definition: object.cc:11276
void IterateObjects(ObjectVisitor *visitor) const
Definition: heap.cc:335
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:573
Space SpaceForExternal(intptr_t size) const
Definition: heap.cc:1141
bool IsCallable(Function *function) const
Definition: object.cc:20913
virtual void SetTypeArguments(const TypeArguments &value) const
Definition: object.cc:20581
static InstancePtr New(const Class &cls, Heap::Space space=Heap::kNew)
Definition: object.cc:20935
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition: object.cc:22984
const char * ToHexCString(Zone *zone) const
Definition: object.cc:23100
virtual bool IsNegative() const
Definition: object.cc:23046
static IntegerPtr NewFromUint64(uint64_t value, Heap::Space space=Heap::kNew)
Definition: object.cc:23026
virtual int64_t AsInt64Value() const
Definition: object.cc:23058
static bool IsValueInRange(uint64_t value)
Definition: object.cc:23030
static Dart_FileModifiedCallback file_modified_callback()
static void SetFileModifiedCallback(Dart_FileModifiedCallback callback)
const char ** obfuscation_map() const
Definition: isolate.h:409
void * embedder_data() const
Definition: isolate.h:291
Heap * heap() const
Definition: isolate.h:296
ObjectStore * object_store() const
Definition: isolate.h:510
SafepointRwLock * program_lock()
Definition: isolate.h:537
static IsolateGroup * Current()
Definition: isolate.h:539
ClassTable * class_table() const
Definition: isolate.h:496
uint64_t id() const
Definition: isolate.h:680
void SetNativeAssetsCallbacks(NativeAssetsApi *native_assets_api)
Definition: isolate.h:780
ApiState * api_state() const
Definition: isolate.h:700
void set_library_tag_handler(Dart_LibraryTagHandler handler)
Definition: isolate.h:558
bool IsReloading() const
Definition: isolate.h:669
static void RegisterIsolateGroup(IsolateGroup *isolate_group)
Definition: isolate.cc:704
static void ForEach(std::function< void(IsolateGroup *)> action)
Definition: isolate.cc:683
void set_deferred_load_handler(Dart_DeferredLoadHandler handler)
Definition: isolate.h:564
IsolateGroupSource * source() const
Definition: isolate.h:1036
bool HasLivePorts()
Definition: isolate.cc:3752
Thread * scheduled_mutator_thread() const
Definition: isolate.h:992
Dart_EnvironmentCallback environment_callback() const
Definition: isolate.h:1075
ErrorPtr sticky_error() const
Definition: isolate.h:1357
UserTagPtr current_tag() const
Definition: isolate.h:1348
static Isolate * Current()
Definition: isolate.h:986
void set_on_shutdown_callback(Dart_IsolateShutdownCallback value)
Definition: isolate.h:1019
static void KillIfExists(Isolate *isolate, LibMsgId msg_id)
Definition: isolate.cc:3706
UserTagPtr default_tag() const
Definition: isolate.h:1351
MessageHandler * message_handler() const
Definition: isolate.cc:2416
static void FlagsInitialize(Dart_IsolateFlags *api_flags)
Definition: isolate.cc:1648
void set_on_cleanup_callback(Dart_IsolateCleanupCallback value)
Definition: isolate.h:1025
bool HasPendingMessages()
Definition: isolate.cc:1356
void * init_callback_data() const
Definition: isolate.h:1068
void set_environment_callback(Dart_EnvironmentCallback value)
Definition: isolate.h:1078
IsolateGroup * group() const
Definition: isolate.h:1037
void set_init_callback_data(void *value)
Definition: isolate.h:1067
Dart_MessageNotifyCallback message_notify_callback() const
Definition: isolate.h:1011
bool AllowClassFinalization()
Definition: isolate.h:1295
void set_origin_id(Dart_Port id)
Definition: isolate.cc:1995
bool IsScheduled()
Definition: isolate.h:991
bool is_runnable() const
Definition: isolate.h:1095
void set_message_notify_callback(Dart_MessageNotifyCallback value)
Definition: isolate.h:1015
Dart_Port main_port() const
Definition: isolate.h:1048
void SetStickyError(ErrorPtr sticky_error)
Definition: isolate.cc:2404
const char * name() const
Definition: isolate.h:1043
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:14787
StringPtr PrivateName(const String &name) const
Definition: object.cc:14704
void set_native_entry_symbol_resolver(Dart_NativeEntrySymbol native_symbol_resolver) const
Definition: object.h:5242
static LibraryPtr MirrorsLibrary()
Definition: object.cc:14816
bool Loaded() const
Definition: object.h:5111
static bool IsPrivate(const String &name)
Definition: object.cc:14619
ObjectPtr InvokeGetter(const String &selector, bool throw_nsm_if_absent, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition: object.cc:14342
void set_native_entry_resolver(Dart_NativeEntryResolver value) const
Definition: object.h:5233
ObjectPtr InvokeSetter(const String &selector, const Instance &argument, bool respect_reflectable=true, bool check_is_entrypoint=false) const
Definition: object.cc:14410
void set_ffi_native_resolver(Dart_FfiNativeResolver value) const
Definition: object.h:5254
ClassPtr LookupClassAllowPrivate(const String &name) const
Definition: object.cc:14113
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:14473
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition: object.cc:14084
ClassPtr toplevel_class() const
Definition: object.h:5208
StringPtr name() const
Definition: object.h:5094
Dart_NativeEntrySymbol native_entry_symbol_resolver() const
Definition: object.h:5238
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition: object.cc:14599
Dart_NativeEntryResolver native_entry_resolver() const
Definition: object.h:5229
FieldPtr LookupFieldAllowPrivate(const String &name) const
Definition: object.cc:14075
StringPtr url() const
Definition: object.h:5097
bool loaded() const
Definition: object.h:7990
ObjectPtr CompleteLoad(const String &error_message, bool transient_error) const
Definition: object.cc:19713
static constexpr intptr_t kRootId
Definition: object.h:7969
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:179
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:885
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:13218
@ kSweepingRegular
Definition: pages.h:135
@ kSweepingLarge
Definition: pages.h:134
Monitor * tasks_lock() const
Definition: pages.h:314
Phase phase() const
Definition: pages.h:341
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:417
static void Cleanup()
Definition: profiler.cc:605
static void Init()
Definition: profiler.cc:573
static void Dedup(Thread *thread)
static SendPortPtr New(Dart_Port id, Heap::Space space=Heap::kNew)
Definition: object.cc:25812
Dart_Port Id() const
Definition: object.h:12490
Dart_Port origin_id() const
Definition: object.h:12492
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:10006
intptr_t Value() const
Definition: object.h:9990
static bool IsValid(int64_t value)
Definition: object.h:10026
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:10173
static StringPtr NewFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition: object.cc:24004
bool IsOneByteString() const
Definition: object.h:10311
intptr_t Length() const
Definition: object.h:10210
static StringPtr ConcatAll(const Array &strings, Heap::Space space=Heap::kNew)
Definition: object.cc:24048
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
intptr_t CharSize() const
Definition: object.cc:23522
void ToUTF8(uint8_t *utf8_array, intptr_t array_len) const
Definition: object.cc:24146
uint16_t CharAt(intptr_t index) const
Definition: object.h:10259
static StringPtr SubString(const String &str, intptr_t begin_index, Heap::Space space=Heap::kNew)
Definition: object.cc:24080
static StringPtr Concat(const String &str1, const String &str2, Heap::Space space=Heap::kNew)
Definition: object.cc:24037
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition: object.cc:24126
static StringPtr FromUTF16(const uint16_t *utf16_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition: object.cc:23739
static StringPtr FromUTF32(const int32_t *utf32_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition: object.cc:23755
static StringPtr FromUTF8(const uint8_t *utf8_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition: object.cc:23705
static const String & True()
Definition: symbols.h:693
static const String & False()
Definition: symbols.h:689
static const String & Empty()
Definition: symbols.h:688
static const String & Dot()
Definition: symbols.h:613
static void DumpTable(IsolateGroup *isolate_group)
Definition: symbols.cc:496
Zone * zone() const
Definition: thread_state.h:37
void UnwindScopes(uword stack_marker)
Definition: thread.cc:1328
ApiLocalScope * api_top_scope() const
Definition: thread.h:513
@ kUnknownTask
Definition: thread.h:346
static Thread * Current()
Definition: thread.h:362
bool IsValidHandle(Dart_Handle object) const
Definition: thread.cc:1265
Heap * heap() const
Definition: thread.cc:943
void EnterApiScope()
Definition: thread.cc:1301
void ExitApiScope()
Definition: thread.cc:1314
static void ExitIsolateGroupAsHelper(bool bypass_safepoint)
Definition: thread.cc:499
uword top_exit_frame_info() const
Definition: thread.h:691
bool IsDartMutatorThread() const
Definition: thread.h:551
ExecutionState execution_state() const
Definition: thread.h:1040
Isolate * isolate() const
Definition: thread.h:534
@ kThreadInNative
Definition: thread.h:1036
IsolateGroup * isolate_group() const
Definition: thread.h:541
static void EnterIsolate(Isolate *isolate)
Definition: thread.cc:371
static void ExitIsolate(bool isolate_shutdown=false)
Definition: thread.cc:428
ErrorPtr sticky_error() const
Definition: thread.cc:232
static bool EnterIsolateGroupAsHelper(IsolateGroup *isolate_group, TaskKind kind, bool bypass_safepoint)
Definition: thread.cc:481
void SetTypeAt(intptr_t index, const AbstractType &value) const
Definition: object.cc:7323
static TypeArgumentsPtr New(intptr_t len, Heap::Space space=Heap::kOld)
Definition: object.cc:7675
TypeArgumentsPtr GetInstanceTypeArguments(Thread *thread, bool canonicalize=true) const
static TypePtr VoidType()
TypePtr ToNullability(Nullability value, Heap::Space space) const
virtual ClassPtr type_class() const
static TypePtr NeverType()
static TypePtr DynamicType()
static TypePtr New(const Class &clazz, const TypeArguments &arguments, Nullability nullability=Nullability::kNonNullable, Heap::Space space=Heap::kOld)
static TypePtr NewNonParameterizedType(const Class &type_class)
intptr_t Length() const
Definition: object.h:11518
intptr_t ElementSizeInBytes() const
Definition: object.h:11531
void * DataAddr(intptr_t byte_offset) const
Definition: object.h:11571
static TypedDataViewPtr New(intptr_t class_id, Heap::Space space=Heap::kNew)
Definition: object.cc:25658
static bool IsTypedData(const Instance &obj)
Definition: object.h:11703
static intptr_t MaxElements(intptr_t class_id)
Definition: object.h:11684
static TypedDataPtr New(intptr_t class_id, intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.cc:25587
static UnhandledExceptionPtr New(const Instance &exception, const Instance &stacktrace, Heap::Space space=Heap::kNew)
Definition: object.cc:19939
static uword ToAddr(const UntaggedObject *raw_obj)
Definition: raw_object.h:522
bool InVMIsolateHeap() const
Definition: raw_object.cc:20
static UserTagPtr New(const String &label, Heap::Space space=Heap::kOld)
Definition: object.cc:26949
UserTagPtr MakeActive() const
Definition: object.cc:26928
StringPtr label() const
Definition: object.h:13168
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:411
static char * SCreate(const char *format,...) PRINTF_ATTRIBUTE(1
Definition: utils.cc:231
static const char * String()
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)
static std::unique_ptr< Program > ReadFromTypedData(const ExternalTypedData &typed_data, const char **error=nullptr)
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
Definition: dart_api.h:840
Dart_Handle(* Dart_EnvironmentCallback)(Dart_Handle name)
Definition: dart_api.h:3278
void(* Dart_StreamingWriteCallback)(void *callback_data, const uint8_t *buffer, intptr_t size)
Definition: dart_api.h:3935
@ Dart_KernelCompilationStatus_Unknown
Definition: dart_api.h:3784
@ Dart_KernelCompilationStatus_Ok
Definition: dart_api.h:3785
#define ILLEGAL_PORT
Definition: dart_api.h:1535
void(* Dart_IsolateCleanupCallback)(void *isolate_group_data, void *isolate_data)
Definition: dart_api.h:729
Dart_PerformanceMode
Definition: dart_api.h:1369
int64_t Dart_Port
Definition: dart_api.h:1525
void(* Dart_MessageNotifyCallback)(Dart_Isolate destination_isolate)
Definition: dart_api.h:1546
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:3234
void(* Dart_StreamingCloseCallback)(void *callback_data)
Definition: dart_api.h:3938
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:3255
void *(* Dart_FfiNativeResolver)(const char *name, uintptr_t args_n)
Definition: dart_api.h:3262
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
Dart_TypedData_Type
Definition: dart_api.h:2612
@ Dart_TypedData_kFloat32x4
Definition: dart_api.h:2626
@ Dart_TypedData_kInt32x4
Definition: dart_api.h:2625
@ Dart_TypedData_kUint8
Definition: dart_api.h:2615
@ Dart_TypedData_kUint32
Definition: dart_api.h:2620
@ Dart_TypedData_kInt32
Definition: dart_api.h:2619
@ Dart_TypedData_kUint16
Definition: dart_api.h:2618
@ Dart_TypedData_kFloat64x2
Definition: dart_api.h:2627
@ Dart_TypedData_kUint64
Definition: dart_api.h:2622
@ Dart_TypedData_kFloat32
Definition: dart_api.h:2623
@ Dart_TypedData_kInt16
Definition: dart_api.h:2617
@ Dart_TypedData_kFloat64
Definition: dart_api.h:2624
@ Dart_TypedData_kUint8Clamped
Definition: dart_api.h:2616
@ Dart_TypedData_kByteData
Definition: dart_api.h:2613
@ Dart_TypedData_kInt8
Definition: dart_api.h:2614
@ Dart_TypedData_kInt64
Definition: dart_api.h:2621
@ Dart_TypedData_kInvalid
Definition: dart_api.h:2628
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:3930
void(* Dart_IsolateShutdownCallback)(void *isolate_group_data, void *isolate_data)
Definition: dart_api.h:711
void *(* Dart_HeapSamplingCreateCallback)(Dart_Isolate isolate, Dart_IsolateGroup isolate_group, const char *cls_name, intptr_t allocation_size)
Definition: dart_api.h:1283
Dart_Handle(* Dart_LibraryTagHandler)(Dart_LibraryTag tag, Dart_Handle library_or_package_map_url, Dart_Handle url)
Definition: dart_api.h:3456
Dart_NativeArgument_Type
Definition: dart_api.h:3026
@ Dart_NativeArgument_kString
Definition: dart_api.h:3033
@ Dart_NativeArgument_kInt64
Definition: dart_api.h:3030
@ Dart_NativeArgument_kNativeFields
Definition: dart_api.h:3035
@ Dart_NativeArgument_kInstance
Definition: dart_api.h:3034
@ Dart_NativeArgument_kInt32
Definition: dart_api.h:3028
@ Dart_NativeArgument_kUint64
Definition: dart_api.h:3031
@ Dart_NativeArgument_kUint32
Definition: dart_api.h:3029
@ Dart_NativeArgument_kDouble
Definition: dart_api.h:3032
@ Dart_NativeArgument_kBool
Definition: dart_api.h:3027
int64_t Dart_IsolateGroupId
Definition: dart_api.h:1209
char *(* Dart_DwarfStackTraceFootnoteCallback)(void *addresses[], intptr_t count)
Definition: dart_api.h:4145
struct _Dart_WeakPersistentHandle * Dart_WeakPersistentHandle
Definition: dart_api.h:260
Dart_KernelCompilationVerbosityLevel
Definition: dart_api.h:3798
Dart_Handle(* Dart_DeferredLoadHandler)(intptr_t loading_unit_id)
Definition: dart_api.h:3491
void(* Dart_HeapSamplingDeleteCallback)(void *data)
Definition: dart_api.h:1288
void(* Dart_HeapSamplingReportCallback)(void *context, void *data)
Definition: dart_api.h:1281
#define ISOLATE_GROUP_METRIC_API(type, variable, name, unit)
#define CHECK_ERROR_HANDLE(error)
#define GET_LIST_ELEMENT(thread, type, obj, index)
#define Z
#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)
Definition: dart_api_impl.h:42
#define DARTSCOPE(thread)
Definition: dart_api_impl.h:77
#define CHECK_ISOLATE_GROUP(isolate_group)
Definition: dart_api_impl.h:31
#define RETURN_TYPE_ERROR(zone, dart_handle, type)
Definition: dart_api_impl.h:83
#define ASSERT_CALLBACK_STATE(thread)
#define CHECK_LENGTH(length, max_elements)
#define RETURN_NULL_ERROR(parameter)
Definition: dart_api_impl.h:97
#define CHECK_NO_ISOLATE(isolate)
Definition: dart_api_impl.h:53
#define START_NO_CALLBACK_SCOPE(thread)
#define API_TIMELINE_BEGIN_END(thread)
#define CHECK_API_SCOPE(thread)
Definition: dart_api_impl.h:64
#define CHECK_NULL(parameter)
#define END_NO_CALLBACK_SCOPE(thread)
#define CHECK_CALLBACK_STATE(thread)
#define CURRENT_FUNC
Definition: dart_api_impl.h:28
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
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
uint32_t uint32_t * format
uint32_t * target
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
const uint8_t * isolate_snapshot_data
Definition: gen_snapshot.cc:69
const uint8_t * vm_snapshot_data
Definition: main_impl.cc:52
va_start(args, format)
const uint8_t * vm_snapshot_instructions
Definition: main_impl.cc:53
va_end(args)
static Dart_Isolate main_isolate
Definition: main_impl.cc:73
static SnapshotKind snapshot_kind
Definition: gen_snapshot.cc:83
const uint8_t * isolate_snapshot_instructions
Definition: gen_snapshot.cc:70
Definition: dart_vm.cc:33
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 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)
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
Definition: hashmap_test.cc:13
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_SendPortGetIdEx(Dart_Handle port, Dart_PortEx *portex_id)
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 void Dart_InitializeNativeAssetsResolver(NativeAssetsApi *native_assets_api)
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_Handle Dart_NewSendPortEx(Dart_PortEx portex_id)
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)
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
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)
Definition: raw_object.cc:558
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_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)
static uint32_t Hash(uint32_t key)
Definition: hashmap_test.cc:65
DART_EXPORT void Dart_DeleteFinalizableHandle(Dart_FinalizableHandle object, Dart_Handle strong_ref_to_object)
void DumpTypeTable(Isolate *isolate)
Definition: object.cc:27075
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_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:27098
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)
NOT_IN_PRODUCT(LibraryPtr ReloadTestScript(const char *script))
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:27106
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 void Dart_EnableHeapSampling()
DART_EXPORT Dart_Handle Dart_HandleMessage()
DART_EXPORT void Dart_SetShouldPauseOnStart(bool should_pause)
DECLARE_FLAG(bool, show_invisible_frames)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
std::function< void()> closure
Definition: closure.h:14
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition: SkVx.h:680
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 T
Definition: precompiler.cc:65
#define REUSABLE_OBJECT_HANDLESCOPE(thread)
void write(SkWStream *wStream, const T &text)
Definition: skqp.cpp:188
SeparatedVector2 offset
Dart_KernelCompilationStatus status
Definition: dart_api.h:3792
int64_t port_id
Definition: dart_api.h:1527
int64_t origin_id
Definition: dart_api.h:1528
Definition: SkMD5.cpp:134
void * user_data
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