Flutter Engine
The Flutter Engine
ffi_test_functions_vmspecific.cc
Go to the documentation of this file.
1// Copyright (c) 2019, 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// This file contains test functions for the dart:ffi test cases.
6
7#include <stddef.h>
8#include <stdlib.h>
9#include <sys/types.h>
10#include <csignal>
11#include <cstdio>
12#include <cstdlib>
13#include <cstring>
14
15#include "platform/globals.h"
17#if defined(DART_HOST_OS_WINDOWS)
18#include <psapi.h>
19#include <windows.h>
20#else
21#include <unistd.h>
22#endif
23
24// Only OK to use here because this is test code.
25#include <condition_variable> // NOLINT(build/c++11)
26#include <functional> // NOLINT(build/c++11)
27#include <mutex> // NOLINT(build/c++11)
28#include <queue> // NOLINT(build/c++11)
29#include <thread> // NOLINT(build/c++11)
30
31#include <setjmp.h> // NOLINT
32#include <signal.h> // NOLINT
33#include <iostream>
34#include <limits>
35
36// TODO(dartbug.com/40579): This requires static linking to either link
37// dart.exe or dart_precompiled_runtime.exe on Windows.
38// The sample currently fails on Windows in AOT mode.
39#include "include/dart_api.h"
41
42#include "include/dart_api_dl.h"
43
44namespace dart {
45
46#define CHECK(X) \
47 if (!(X)) { \
48 fprintf(stderr, "%s\n", "Check failed: " #X); \
49 return 1; \
50 }
51
52#define CHECK_EQ(X, Y) CHECK((X) == (Y))
53
54#define ENSURE(X) \
55 if (!(X)) { \
56 fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, "Check failed: " #X); \
57 exit(1); \
58 }
59
60////////////////////////////////////////////////////////////////////////////////
61// Functions for stress-testing.
62
64 Dart_ExecuteInternalCommand("gc-on-nth-allocation",
65 reinterpret_cast<void*>(1));
66 return 0x8000000000000000;
67}
68
70 Dart_ExecuteInternalCommand("gc-on-nth-allocation",
71 reinterpret_cast<void*>(1));
72 return 0x80000000;
73}
74
76 Dart_ExecuteInternalCommand("gc-on-nth-allocation",
77 reinterpret_cast<void*>(1));
78 return 0x80000000 * -1.0;
79}
80
81// Requires boxing on 32-bit and 64-bit systems, even if the top 32-bits are
82// truncated.
84 Dart_ExecuteInternalCommand("gc-on-nth-allocation",
85 reinterpret_cast<void*>(1));
86 uint64_t origin = 0x8100000082000000;
87 return reinterpret_cast<void*>(origin);
88}
89
90DART_EXPORT void TriggerGC(uint64_t count) {
91 Dart_ExecuteInternalCommand("gc-now", nullptr);
92}
93
94DART_EXPORT void CollectOnNthAllocation(intptr_t num_allocations) {
95 Dart_ExecuteInternalCommand("gc-on-nth-allocation",
96 reinterpret_cast<void*>(num_allocations));
97}
98
99// Triggers GC. Has 11 dummy arguments as unboxed odd integers which should be
100// ignored by GC.
102 uint64_t b,
103 uint64_t c,
104 uint64_t d,
105 uint64_t e,
106 uint64_t f,
107 uint64_t g,
108 uint64_t h,
109 uint64_t i,
110 uint64_t j,
111 uint64_t k) {
112 Dart_ExecuteInternalCommand("gc-now", nullptr);
113}
114
116 return Dart_ExecuteInternalCommand("is-thread-in-generated", nullptr) !=
117 nullptr
118 ? 1
119 : 0;
120}
121
122#if !defined(DART_HOST_OS_WINDOWS)
124 std::condition_variable* var,
125 std::mutex* mut) {
126 std::function<void()> callback = [&]() {
127 mut->lock();
128 var->notify_all();
129 mut->unlock();
130
131 // Wait for mutator thread to continue (and block) before leaving the
132 // safepoint.
133 while (Dart_ExecuteInternalCommand("is-mutator-in-native", isolate) !=
134 nullptr) {
135 usleep(10 * 1000 /*10 ms*/);
136 }
137 };
138
139 struct {
140 void* isolate;
141 std::function<void()>* callback;
142 } args = {.isolate = isolate, .callback = &callback};
143
144 Dart_ExecuteInternalCommand("run-in-safepoint-and-rw-code", &args);
145 return nullptr;
146}
147
149 std::mutex mutex;
150 std::condition_variable cvar;
151 std::unique_ptr<std::thread> helper;
152};
153
154DART_EXPORT void* TestUnprotectCode(void (*fn)(void*)) {
156
157 {
158 std::unique_lock<std::mutex> lock(state->mutex); // locks the mutex
159 state->helper.reset(new std::thread(UnprotectCodeOtherThread,
160 Dart_CurrentIsolate(), &state->cvar,
161 &state->mutex));
162
163 state->cvar.wait(lock);
164 }
165
166 if (fn != nullptr) {
167 fn(state);
168 return nullptr;
169 } else {
170 return state;
171 }
172}
173
175 helper->helper->join();
176 delete helper;
177}
178#else
179// Our version of VSC++ doesn't support std::thread yet.
180DART_EXPORT void WaitForHelper(void* helper) {}
181DART_EXPORT void* TestUnprotectCode(void (*fn)(void)) {
182 return nullptr;
183}
184#endif
185
186// Defined in ffi_test_functions.S.
187//
188// Clobbers some registers with special meaning in Dart before re-entry, for
189// stress-testing. Not used on 32-bit Windows due to complications with Windows
190// "safeseh".
191// TODO(47824): Figure out how ARM/ARM64 syntax is different on Windows.
192#if defined(DART_TARGET_OS_WINDOWS) && \
193 (defined(HOST_ARCH_IA32) || defined(HOST_ARCH_ARM) || \
194 defined(HOST_ARCH_ARM64))
195void ClobberAndCall(void (*fn)()) {
196 fn();
197}
198#else
199extern "C" void ClobberAndCall(void (*fn)());
200#endif
201
202DART_EXPORT intptr_t TestGC(void (*do_gc)()) {
203 ClobberAndCall(do_gc);
204 return 0;
205}
206
208 intptr_t success;
209 void (*callback)();
210};
211
212#if defined(DART_TARGET_OS_LINUX)
213
214thread_local sigjmp_buf buf;
215void CallbackTestSignalHandler(int) {
216 siglongjmp(buf, 1);
217}
218
219intptr_t ExpectAbort(void (*fn)()) {
220 fprintf(stderr, "**** EXPECT STACKTRACE TO FOLLOW. THIS IS OK. ****\n");
221
222 struct sigaction old_action = {};
223 intptr_t result = sigsetjmp(buf, /*savesigs=*/1);
224 if (result == 0) {
225 // Install signal handler.
226 struct sigaction handler = {};
227 handler.sa_handler = CallbackTestSignalHandler;
228 sigemptyset(&handler.sa_mask);
229 handler.sa_flags = 0;
230
231 sigaction(SIGABRT, &handler, &old_action);
232
233 fn();
234 } else {
235 // Caught the setjmp.
236 sigaction(SIGABRT, &old_action, nullptr);
237 exit(0);
238 }
239 fprintf(stderr, "Expected abort!!!\n");
240 exit(1);
241}
242
243void* TestCallbackOnThreadOutsideIsolate(void* parameter) {
244 CallbackTestData* data = reinterpret_cast<CallbackTestData*>(parameter);
245 data->success = ExpectAbort(data->callback);
246 return nullptr;
247}
248
249intptr_t TestCallbackOtherThreadHelper(void* (*tester)(void*), void (*fn)()) {
250 CallbackTestData data = {1, fn};
251 pthread_attr_t attr;
252 intptr_t result = pthread_attr_init(&attr);
253 CHECK_EQ(result, 0);
254
255 pthread_t tid;
256 result = pthread_create(&tid, &attr, tester, &data);
257 CHECK_EQ(result, 0);
258
259 result = pthread_attr_destroy(&attr);
260 CHECK_EQ(result, 0);
261
262 void* retval;
263 result = pthread_join(tid, &retval);
264
265 // Doesn't actually return because the other thread will exit when the test is
266 // finished.
267 return 1;
268}
269
270// Run a callback on another thread and verify that it triggers SIGABRT.
271DART_EXPORT intptr_t TestCallbackWrongThread(void (*fn)()) {
272 return TestCallbackOtherThreadHelper(&TestCallbackOnThreadOutsideIsolate, fn);
273}
274
275// Verify that we get SIGABRT when invoking a native callback outside an
276// isolate.
277DART_EXPORT intptr_t TestCallbackOutsideIsolate(void (*fn)()) {
279
281 CallbackTestData data = {1, fn};
282 TestCallbackOnThreadOutsideIsolate(&data);
283 Dart_EnterIsolate(current);
284
285 return data.success;
286}
287
288DART_EXPORT intptr_t TestCallbackWrongIsolate(void (*fn)()) {
289 return ExpectAbort(fn);
290}
291
292DART_EXPORT intptr_t TestCallbackLeaf(void (*fn)()) {
293#if defined(DEBUG)
294 // Calling a callback from a leaf call will crash when trying to leave the
295 // safepoint.
296 return ExpectAbort(fn);
297#else
298 // The above will only crash in debug as ASSERTS are disabled in all other
299 // build modes.
300 return 0;
301#endif
302}
303
304void CallDebugName() {
306}
307
308DART_EXPORT intptr_t TestLeafCallApi(void (*fn)()) {
309 // This should be fine since it's a simple function that returns a const
310 // string. Though any API call should be considered unsafe from leaf calls.
312#if defined(DEBUG)
313 // This will fail because it requires running in DARTSCOPE.
314 return ExpectAbort(&CallDebugName);
315#else
316 // The above will only crash in debug as ASSERTS are disabled in all other
317 // build modes.
318 return 0;
319#endif
320}
321
322#endif // defined(DART_TARGET_OS_LINUX)
323
324// Restore default SIGPIPE handler, which is only needed on mac
325// since that is the only platform we explicitly ignore it.
326// See Platform::Initialize() in platform_macos.cc.
328#if defined(DART_HOST_OS_MACOS)
329 signal(SIGPIPE, SIG_DFL);
330#endif
331}
332
335}
336
338 struct Helper {
339 static void ShutdownCallback(void* ig_data, void* isolate_data) {
340 char* string = reinterpret_cast<char*>(isolate_data);
341 ENSURE(string[0] == 'a');
342 string[0] = 'x';
343 }
344 static void CleanupCallback(void* ig_data, void* isolate_data) {
345 char* string = reinterpret_cast<char*>(isolate_data);
346 ENSURE(string[2] == 'c');
347 string[2] = 'z';
348 }
349 };
350
353
354 char* error = nullptr;
355 Dart_Isolate child =
356 Dart_CreateIsolateInGroup(parent, name, &Helper::ShutdownCallback,
357 &Helper::CleanupCallback, peer, &error);
358 if (child == nullptr) {
359 Dart_EnterIsolate(parent);
361 free(error);
362 Dart_ThrowException(error_obj);
363 return nullptr;
364 }
366 Dart_EnterIsolate(parent);
367 return child;
368}
369
371 int64_t main_isolate_port,
372 const char* library_uri,
373 const char* function_name,
374 bool errors_are_fatal,
375 Dart_Port on_error_port,
376 Dart_Port on_exit_port) {
379 Dart_EnterIsolate(child_isolate);
380 {
382
383 Dart_Handle library_name = Dart_NewStringFromCString(library_uri);
384 ENSURE(!Dart_IsError(library_name));
385
386 Dart_Handle library = Dart_LookupLibrary(library_name);
387 ENSURE(!Dart_IsError(library));
388
390 ENSURE(!Dart_IsError(fun));
391
392 Dart_Handle port = Dart_NewInteger(main_isolate_port);
394
395 Dart_Handle args[] = {
396 port,
397 };
398
399 Dart_Handle result = Dart_Invoke(library, fun, 1, args);
400 if (Dart_IsError(result)) {
401 fprintf(stderr, "Failed to invoke %s/%s in child isolate: %s\n",
402 library_uri, function_name, Dart_GetError(result));
403 }
405
407 }
408
409 char* error = nullptr;
410 ENSURE(
411 Dart_RunLoopAsync(errors_are_fatal, on_error_port, on_exit_port, &error));
412
413 Dart_EnterIsolate(parent);
414}
415
416////////////////////////////////////////////////////////////////////////////////
417// Initialize `dart_api_dl.h`
420}
421
422////////////////////////////////////////////////////////////////////////////////
423// Functions for async callbacks example.
424//
425// sample_async_callback.dart
426
427void Fatal(char const* file, int line, char const* error) {
428 printf("FATAL %s:%i\n", file, line);
429 printf("%s\n", error);
432 abort();
433}
434
435#define FATAL(error) Fatal(__FILE__, __LINE__, error)
436
437DART_EXPORT void SleepOnAnyOS(intptr_t seconds) {
438#if defined(DART_HOST_OS_WINDOWS)
439 Sleep(1000 * seconds);
440#else
441 sleep(seconds);
442#endif
443}
444
445intptr_t (*my_callback_blocking_fp_)(intptr_t);
447
450
451typedef std::function<void()> Work;
452
453// Notify Dart through a port that the C lib has pending async callbacks.
454//
455// Expects heap allocated `work` so delete can be called on it.
456//
457// The `send_port` should be from the isolate which registered the callback.
458void NotifyDart(Dart_Port send_port, const Work* work) {
459 const intptr_t work_addr = reinterpret_cast<intptr_t>(work);
460 printf("C : Posting message (port: %" Px64 ", work: %" Px ").\n",
461 send_port, work_addr);
462
463 Dart_CObject dart_object;
464 dart_object.type = Dart_CObject_kInt64;
465 dart_object.value.as_int64 = work_addr;
466
467 const bool result = Dart_PostCObject_DL(send_port, &dart_object);
468 if (!result) {
469 FATAL("C : Posting message to port failed.");
470 }
471}
472
473// Do a callback to Dart in a blocking way, being interested in the result.
474//
475// Dart returns `a + 3`.
476intptr_t MyCallbackBlocking(intptr_t a) {
477 std::mutex mutex;
478 std::unique_lock<std::mutex> lock(mutex);
479 intptr_t result;
480 auto callback = my_callback_blocking_fp_; // Define storage duration.
481 std::condition_variable cv;
482 bool notified = false;
483 const Work work = [a, &result, callback, &mutex, &cv, &notified]() {
484 result = callback(a);
485 printf("C Da: Notify result ready.\n");
486 std::unique_lock<std::mutex> lock(mutex);
487 notified = true;
488 cv.notify_one();
489 };
490 const Work* work_ptr = new Work(work); // Copy to heap.
492 printf("C : Waiting for result.\n");
493 while (!notified) {
494 cv.wait(lock);
495 }
496 printf("C : Received result.\n");
497 return result;
498}
499
500// Do a callback to Dart in a non-blocking way.
501//
502// Dart sums all numbers posted to it.
503void MyCallbackNonBlocking(intptr_t a) {
504 auto callback = my_callback_non_blocking_fp_; // Define storage duration.
505 const Work work = [a, callback]() { callback(a); };
506 // Copy to heap to make it outlive the function scope.
507 const Work* work_ptr = new Work(work);
509}
510
511// Simulated work for Thread #1.
512//
513// Simulates heavy work with sleeps.
514void Work1() {
515 printf("C T1: Work1 Start.\n");
516 SleepOnAnyOS(1);
517 const intptr_t val1 = 3;
518 printf("C T1: MyCallbackBlocking(%" Pd ").\n", val1);
519 const intptr_t val2 = MyCallbackBlocking(val1); // val2 = 6.
520 printf("C T1: MyCallbackBlocking returned %" Pd ".\n", val2);
521 SleepOnAnyOS(1);
522 const intptr_t val3 = val2 - 1; // val3 = 5.
523 printf("C T1: MyCallbackNonBlocking(%" Pd ").\n", val3);
524 MyCallbackNonBlocking(val3); // Post 5 to Dart.
525 printf("C T1: Work1 Done.\n");
526}
527
528// Simulated work for Thread #2.
529//
530// Simulates lighter work, no sleeps.
531void Work2() {
532 printf("C T2: Work2 Start.\n");
533 const intptr_t val1 = 5;
534 printf("C T2: MyCallbackNonBlocking(%" Pd ").\n", val1);
535 MyCallbackNonBlocking(val1); // Post 5 to Dart.
536 const intptr_t val2 = 1;
537 printf("C T2: MyCallbackBlocking(%" Pd ").\n", val2);
538 const intptr_t val3 = MyCallbackBlocking(val2); // val3 = 4.
539 printf("C T2: MyCallbackBlocking returned %" Pd ".\n", val3);
540 printf("C T2: MyCallbackNonBlocking(%" Pd ").\n", val3);
541 MyCallbackNonBlocking(val3); // Post 4 to Dart.
542 printf("C T2: Work2 Done.\n");
543}
544
545// Simulator that simulates concurrent work with multiple threads.
547 public:
548 static void StartWorkSimulator() {
549 running_work_simulator_ = new SimulateWork();
550 running_work_simulator_->Start();
551 }
552
553 static void StopWorkSimulator() {
554 running_work_simulator_->Stop();
555 delete running_work_simulator_;
556 running_work_simulator_ = nullptr;
557 }
558
559 private:
560 static SimulateWork* running_work_simulator_;
561
562 void Start() {
563 printf("C Da: Starting SimulateWork.\n");
564 printf("C Da: Starting worker threads.\n");
565 thread1 = new std::thread(Work1);
566 thread2 = new std::thread(Work2);
567 printf("C Da: Started SimulateWork.\n");
568 }
569
570 void Stop() {
571 printf("C Da: Stopping SimulateWork.\n");
572 printf("C Da: Waiting for worker threads to finish.\n");
573 thread1->join();
574 thread2->join();
575 delete thread1;
576 delete thread2;
577 printf("C Da: Stopped SimulateWork.\n");
578 }
579
580 std::thread* thread1;
581 std::thread* thread2;
582};
583SimulateWork* SimulateWork::running_work_simulator_ = 0;
584
586 intptr_t (*callback1)(intptr_t)) {
587 my_callback_blocking_fp_ = callback1;
589}
590
592 void (*callback)(intptr_t)) {
595}
596
599}
600
603}
604
606 printf("C Da: ExecuteCallback(%" Pp ").\n",
607 reinterpret_cast<intptr_t>(work_ptr));
608 const Work work = *work_ptr;
609 work();
610 delete work_ptr;
611 printf("C Da: ExecuteCallback done.\n");
612}
613
614////////////////////////////////////////////////////////////////////////////////
615// Functions for async callbacks example.
616//
617// sample_native_port_call.dart
618
620
621DART_EXPORT void* Calloc(size_t count, size_t size) {
622 return calloc(count, size);
623}
624
625DART_EXPORT void FreeFinalizer(void*, void* value) {
626 free(value);
627}
628
630 public:
631 PendingCall(void** buffer, size_t* length)
632 : response_buffer_(buffer), response_length_(length) {
633 receive_port_ =
634 Dart_NewNativePort_DL("cpp-response", &PendingCall::HandleResponse,
635 /*handle_concurrently=*/false);
636 }
637 ~PendingCall() { Dart_CloseNativePort_DL(receive_port_); }
638
639 Dart_Port port() const { return receive_port_; }
640
642 std::unique_lock<std::mutex> lock(mutex);
643 const bool success = Dart_PostCObject_DL(port, object);
644 if (!success) FATAL("Failed to send message, invalid port or isolate died");
645
646 printf("C : Waiting for result.\n");
647 while (!notified) {
648 cv.wait(lock);
649 }
650 }
651
653 if (message->type != Dart_CObject_kArray) {
654 FATAL("C : Wrong Data: message->type != Dart_CObject_kArray.\n");
655 }
656 Dart_CObject** c_response_args = message->value.as_array.values;
657 Dart_CObject* c_pending_call = c_response_args[0];
658 Dart_CObject* c_message = c_response_args[1];
659 printf("C : HandleResponse (call: %" Px ", message: %" Px ").\n",
660 reinterpret_cast<intptr_t>(c_pending_call),
661 reinterpret_cast<intptr_t>(c_message));
662
663 auto pending_call = reinterpret_cast<PendingCall*>(
664 c_pending_call->type == Dart_CObject_kInt64
665 ? c_pending_call->value.as_int64
666 : c_pending_call->value.as_int32);
667
668 pending_call->ResolveCall(c_message);
669 }
670
671 private:
672 static bool NonEmptyBuffer(void** value) { return *value != nullptr; }
673
674 void ResolveCall(Dart_CObject* bytes) {
675 assert(bytes->type == Dart_CObject_kTypedData);
676 if (bytes->type != Dart_CObject_kTypedData) {
677 FATAL("C : Wrong Data: bytes->type != Dart_CObject_kTypedData.\n");
678 }
679 const intptr_t response_length = bytes->value.as_typed_data.length;
680 const uint8_t* response_buffer = bytes->value.as_typed_data.values;
681 printf("C : ResolveCall(length: %" Pd ", buffer: %" Px ").\n",
682 response_length, reinterpret_cast<intptr_t>(response_buffer));
683
684 void* buffer = malloc(response_length);
685 memmove(buffer, response_buffer, response_length);
686
687 *response_buffer_ = buffer;
688 *response_length_ = response_length;
689
690 printf("C : Notify result ready.\n");
691 std::unique_lock<std::mutex> lock(mutex);
692 notified = true;
693 cv.notify_one();
694 }
695
696 std::mutex mutex;
697 std::condition_variable cv;
698 bool notified = false;
699
700 Dart_Port receive_port_;
701 void** response_buffer_;
702 size_t* response_length_;
703};
704
705// Do a callback to Dart in a blocking way, being interested in the result.
706//
707// Dart returns `a + 3`.
708uint8_t MyCallback1(uint8_t a) {
709 const char* methodname = "myCallback1";
710 size_t request_length = sizeof(uint8_t) * 1;
711 void* request_buffer = malloc(request_length); // FreeFinalizer.
712 reinterpret_cast<uint8_t*>(request_buffer)[0] = a; // Populate buffer.
713 void* response_buffer = nullptr;
714 size_t response_length = 0;
715
716 PendingCall pending_call(&response_buffer, &response_length);
717
718 Dart_CObject c_send_port;
719 c_send_port.type = Dart_CObject_kSendPort;
720 c_send_port.value.as_send_port.id = pending_call.port();
722
723 Dart_CObject c_pending_call;
724 c_pending_call.type = Dart_CObject_kInt64;
725 c_pending_call.value.as_int64 = reinterpret_cast<int64_t>(&pending_call);
726
727 Dart_CObject c_method_name;
728 c_method_name.type = Dart_CObject_kString;
729 c_method_name.value.as_string = const_cast<char*>(methodname);
730
731 Dart_CObject c_request_data;
732 c_request_data.type = Dart_CObject_kExternalTypedData;
734 c_request_data.value.as_external_typed_data.length = request_length;
735 c_request_data.value.as_external_typed_data.data =
736 static_cast<uint8_t*>(request_buffer);
737 c_request_data.value.as_external_typed_data.peer = request_buffer;
739
740 Dart_CObject* c_request_arr[] = {&c_send_port, &c_pending_call,
741 &c_method_name, &c_request_data};
742 Dart_CObject c_request;
743 c_request.type = Dart_CObject_kArray;
744 c_request.value.as_array.values = c_request_arr;
745 c_request.value.as_array.length =
746 sizeof(c_request_arr) / sizeof(c_request_arr[0]);
747
748 printf("C : Dart_PostCObject_(request: %" Px ", call: %" Px ").\n",
749 reinterpret_cast<intptr_t>(&c_request),
750 reinterpret_cast<intptr_t>(&c_pending_call));
751 pending_call.PostAndWait(send_port_, &c_request);
752 printf("C : Received result.\n");
753
754 const intptr_t result = reinterpret_cast<uint8_t*>(response_buffer)[0];
755 free(response_buffer);
756
757 return result;
758}
759
760// Do a callback to Dart in a non-blocking way.
761//
762// Dart sums all numbers posted to it.
763void MyCallback2(uint8_t a) {
764 const char* methodname = "myCallback2";
765 void* request_buffer = malloc(sizeof(uint8_t) * 1); // FreeFinalizer.
766 reinterpret_cast<uint8_t*>(request_buffer)[0] = a; // Populate buffer.
767 const size_t request_length = sizeof(uint8_t) * 1;
768
769 Dart_CObject c_send_port;
770 c_send_port.type = Dart_CObject_kNull;
771
772 Dart_CObject c_pending_call;
773 c_pending_call.type = Dart_CObject_kNull;
774
775 Dart_CObject c_method_name;
776 c_method_name.type = Dart_CObject_kString;
777 c_method_name.value.as_string = const_cast<char*>(methodname);
778
779 Dart_CObject c_request_data;
780 c_request_data.type = Dart_CObject_kExternalTypedData;
782 c_request_data.value.as_external_typed_data.length = request_length;
783 c_request_data.value.as_external_typed_data.data =
784 static_cast<uint8_t*>(request_buffer);
785 c_request_data.value.as_external_typed_data.peer = request_buffer;
787
788 Dart_CObject* c_request_arr[] = {&c_send_port, &c_pending_call,
789 &c_method_name, &c_request_data};
790 Dart_CObject c_request;
791 c_request.type = Dart_CObject_kArray;
792 c_request.value.as_array.values = c_request_arr;
793 c_request.value.as_array.length =
794 sizeof(c_request_arr) / sizeof(c_request_arr[0]);
795
796 printf("C : Dart_PostCObject_(request: %" Px ", call: %" Px ").\n",
797 reinterpret_cast<intptr_t>(&c_request),
798 reinterpret_cast<intptr_t>(&c_pending_call));
799 Dart_PostCObject_DL(send_port_, &c_request);
800}
801
802// Simulated work for Thread #1.
803//
804// Simulates heavy work with sleeps.
805void Work1_2() {
806 printf("C T1: Work1 Start.\n");
807 SleepOnAnyOS(1);
808 const intptr_t val1 = 3;
809 printf("C T1: MyCallback1(%" Pd ").\n", val1);
810 const intptr_t val2 = MyCallback1(val1); // val2 = 6.
811 printf("C T1: MyCallback1 returned %" Pd ".\n", val2);
812 SleepOnAnyOS(1);
813 const intptr_t val3 = val2 - 1; // val3 = 5.
814 printf("C T1: MyCallback2(%" Pd ").\n", val3);
815 MyCallback2(val3); // Post 5 to Dart.
816 printf("C T1: Work1 Done.\n");
817}
818
819// Simulated work for Thread #2.
820//
821// Simulates lighter work, no sleeps.
822void Work2_2() {
823 printf("C T2: Work2 Start.\n");
824 const intptr_t val1 = 5;
825 printf("C T2: MyCallback2(%" Pd ").\n", val1);
826 MyCallback2(val1); // Post 5 to Dart.
827 const intptr_t val2 = 1;
828 printf("C T2: MyCallback1(%" Pd ").\n", val2);
829 const intptr_t val3 = MyCallback1(val2); // val3 = 4.
830 printf("C T2: MyCallback1 returned %" Pd ".\n", val3);
831 printf("C T2: MyCallback2(%" Pd ").\n", val3);
832 MyCallback2(val3); // Post 4 to Dart.
833 printf("C T2: Work2 Done.\n");
834}
835
836// Simulator that simulates concurrent work with multiple threads.
838 public:
839 static void StartWorkSimulator() {
840 running_work_simulator_ = new SimulateWork2();
841 running_work_simulator_->Start();
842 }
843
844 static void StopWorkSimulator() {
845 running_work_simulator_->Stop();
846 delete running_work_simulator_;
847 running_work_simulator_ = nullptr;
848 }
849
850 private:
851 static SimulateWork2* running_work_simulator_;
852
853 void Start() {
854 printf("C Da: Starting SimulateWork.\n");
855 printf("C Da: Starting worker threads.\n");
856 thread1 = new std::thread(Work1_2);
857 thread2 = new std::thread(Work2_2);
858 printf("C Da: Started SimulateWork.\n");
859 }
860
861 void Stop() {
862 printf("C Da: Stopping SimulateWork.\n");
863 printf("C Da: Waiting for worker threads to finish.\n");
864 thread1->join();
865 thread2->join();
866 delete thread1;
867 delete thread2;
868 printf("C Da: Stopped SimulateWork.\n");
869 }
870
871 std::thread* thread1;
872 std::thread* thread2;
873};
874SimulateWork2* SimulateWork2::running_work_simulator_ = 0;
875
877 send_port_ = send_port;
878}
879
882}
883
886}
887
888////////////////////////////////////////////////////////////////////////////////
889// Helpers used for lightweight isolate tests.
890////////////////////////////////////////////////////////////////////////////////
891
893 Dart_Isolate (*dart_current_isolate)(),
894 void (*dart_enter_isolate)(Dart_Isolate),
895 void (*dart_exit_isolate)(),
896 intptr_t num_threads) {
897 // Guaranteed to be initialized exactly once (no race between multiple
898 // threads).
899 static std::mutex mutex;
900 static std::condition_variable cvar;
901 static intptr_t thread_count = 0;
902
903 const Dart_Isolate isolate = dart_current_isolate();
904 dart_exit_isolate();
905 {
906 std::unique_lock<std::mutex> lock(mutex);
907 ++thread_count;
908 while (thread_count < num_threads) {
909 cvar.wait(lock);
910 }
911 cvar.notify_all();
912 }
913 dart_enter_isolate(isolate);
914}
915
916////////////////////////////////////////////////////////////////////////////////
917// Helpers used for isolate exit tests.
918////////////////////////////////////////////////////////////////////////////////
919
920// This method consumes and ignores unwind error raised by `Isolate.exit` called
921// by dart `callIsolateExit` method.
923 Dart_Handle root_lib = Dart_RootLibrary();
924 fprintf(stderr, "IsolateExitTest_LookupAndCallIsolateExit i:%d\n", i);
925 if (i > 0) {
926 Dart_Handle method_name =
927 Dart_NewStringFromCString("recurseLookupAndCallWorker");
928 Dart_Handle dart_args[1];
929 dart_args[0] = Dart_NewInteger(i - 1);
930 Dart_Handle result = Dart_Invoke(root_lib, method_name, 1, dart_args);
932 } else {
933 Dart_Handle method_name = Dart_NewStringFromCString("callIsolateExit");
934 Dart_Handle result = Dart_Invoke(root_lib, method_name, 0, nullptr);
935 if (Dart_IsError(result)) {
936 fprintf(stderr,
937 "%d failed to invoke %s in child isolate: %s, carrying on..\n", i,
938 "callIsolateExit", Dart_GetError(result));
939 }
941 }
942}
943
944////////////////////////////////////////////////////////////////////////////////
945// Functions for handle tests.
946//
947// vmspecific_handle_test.dart (statically linked).
948// vmspecific_handle_dynamically_linked_test.dart (dynamically linked).
949
950static void RunFinalizer(void* isolate_callback_data, void* peer) {
951 printf("Running finalizer for weak handle.\n");
952}
953
954// Tests that passing handles through FFI calls works, and that the FFI call
955// sets up the VM state etc. correctly so that the handle API calls work.
957 // Can use "h" until this function returns.
958
959 // A persistent handle which outlives this call. Lifetime managed in C.
960 auto persistent_handle = Dart_NewPersistentHandle(h);
961
962 Dart_Handle handle_2 = Dart_HandleFromPersistent(persistent_handle);
963 Dart_DeletePersistentHandle(persistent_handle);
964 if (Dart_IsError(handle_2)) {
965 Dart_PropagateError(handle_2);
966 }
967
968 Dart_Handle return_value;
969 if (!Dart_IsNull(h) && !Dart_IsInteger(h)) {
970 // A weak handle which outlives this call. Lifetime managed in C.
971 auto weak_handle = Dart_NewWeakPersistentHandle(
972 h, reinterpret_cast<void*>(0x1234), 64, RunFinalizer);
973 return_value = Dart_HandleFromWeakPersistent(weak_handle);
974
975 // Deleting a weak handle is not required, it deletes itself on
976 // finalization.
977 // Deleting a weak handle cancels the finalizer.
979 } else {
980 return_value = h;
981 }
982
983 return return_value;
984}
985
987 Dart_Handle closureHandle) {
988 printf("ClosureCallbackThroughHandle %p %p\n", callback, closureHandle);
989 callback(closureHandle);
990}
991
993 printf("ReturnHandleInCallback %p\n", callback);
994 Dart_Handle handle = callback();
995 if (Dart_IsError(handle)) {
996 printf("callback() returned an error, propagating error\n");
997 // Do C/C++ resource cleanup if needed, before propagating error.
998 Dart_PropagateError(handle);
999 }
1000 return handle;
1001}
1002
1003// Recurses til `i` reaches 0. Throws some Dart_Invoke in there as well.
1005 Dart_Handle (*callback)(int64_t),
1006 int64_t i) {
1007 printf("HandleRecursion %" Pd64 "\n", i);
1008 const bool do_invoke = i % 3 == 0;
1009 const bool do_gc = i % 7 == 3;
1010 if (do_gc) {
1011 Dart_ExecuteInternalCommand("gc-now", nullptr);
1012 }
1014 if (do_invoke) {
1015 Dart_Handle method_name = Dart_NewStringFromCString("a");
1016 if (Dart_IsError(method_name)) {
1017 Dart_PropagateError(method_name);
1018 }
1019 Dart_Handle arg = Dart_NewInteger(i - 1);
1020 if (Dart_IsError(arg)) {
1022 }
1023 printf("Dart_Invoke\n");
1024 result = Dart_Invoke(object, method_name, 1, &arg);
1025 } else {
1026 printf("callback\n");
1027 result = callback(i - 1);
1028 }
1029 if (do_gc) {
1030 Dart_ExecuteInternalCommand("gc-now", nullptr);
1031 }
1032 if (Dart_IsError(result)) {
1033 // Do C/C++ resource cleanup if needed, before propagating error.
1034 printf("Dart_PropagateError %" Pd64 "\n", i);
1036 }
1037 printf("return %" Pd64 "\n", i);
1038 return result;
1039}
1040
1042 printf("HandleReadFieldValue\n");
1043 Dart_Handle field_name = Dart_NewStringFromCString("a");
1044 if (Dart_IsError(field_name)) {
1045 printf("Dart_PropagateError(field_name)\n");
1046 Dart_PropagateError(field_name);
1047 }
1048 Dart_Handle field_value = Dart_GetField(handle, field_name);
1049 if (Dart_IsError(field_value)) {
1050 printf("Dart_PropagateError(field_value)\n");
1051 Dart_PropagateError(field_value);
1052 }
1053 int64_t value;
1054 Dart_Handle err = Dart_IntegerToInt64(field_value, &value);
1055 if (Dart_IsError(err)) {
1057 }
1058 return value;
1059}
1060
1061// Does not have a handle in it's own signature, so does not enter and exit
1062// scope in the trampoline.
1066 if (Dart_IsError(result)) {
1068 }
1070 return 0;
1071}
1072
1075 const bool is_error = Dart_IsError(result);
1076 printf("ThrowOnReturnOfError is_error %s\n", is_error ? "true" : "false");
1077 return result;
1078}
1079
1081 return Dart_True();
1082}
1083
1085 auto persistent_handle = Dart_NewPersistentHandle_DL(h);
1086
1087 Dart_Handle handle_2 = Dart_HandleFromPersistent_DL(persistent_handle);
1088 Dart_SetPersistentHandle_DL(persistent_handle, h);
1089 Dart_DeletePersistentHandle_DL(persistent_handle);
1090
1091 auto weak_handle = Dart_NewWeakPersistentHandle_DL(
1092 handle_2, reinterpret_cast<void*>(0x1234), 64, RunFinalizer);
1093 Dart_Handle return_value = Dart_HandleFromWeakPersistent_DL(weak_handle);
1094
1095 Dart_DeleteWeakPersistentHandle_DL(weak_handle);
1096
1097 return return_value;
1098}
1099
1100////////////////////////////////////////////////////////////////////////////////
1101// Example for doing closure callbacks with help of `dart_api.h`.
1102//
1103// sample_ffi_functions_callbacks_closures.dart
1104
1107
1110}
1111
1113 closure_to_callback_ = Dart_NewPersistentHandle_DL(h);
1114}
1115
1117 Dart_Handle closure_handle =
1118 Dart_HandleFromPersistent_DL(closure_to_callback_);
1119 callback_(closure_handle);
1120}
1121
1123 Dart_DeletePersistentHandle_DL(closure_to_callback_);
1124}
1125
1126////////////////////////////////////////////////////////////////////////////////
1127// NativeFinalizer tests
1128
1129DART_EXPORT void SetArgumentTo42(void* token) {
1130 *reinterpret_cast<intptr_t*>(token) = 42;
1131}
1132
1133////////////////////////////////////////////////////////////////////////////////
1134// Functions for testing @Native.
1135
1137 Dart_Handle root_lib = Dart_RootLibrary();
1138 Dart_Handle lib_url = Dart_LibraryUrl(root_lib);
1139 ENSURE(!Dart_IsError(lib_url));
1140 return lib_url;
1141}
1142
1143intptr_t ReturnIntPtr(intptr_t x) {
1144 return x;
1145}
1146
1147intptr_t PassAsHandle(Dart_Handle handle) {
1148 intptr_t result = 0;
1150 return result;
1151}
1152
1153intptr_t PassAsPointer(void* ptr) {
1154 return reinterpret_cast<intptr_t>(ptr);
1155}
1156
1157intptr_t PassAsPointerAndValue(void* ptr, intptr_t value) {
1158 return value;
1159}
1160
1161intptr_t PassAsValueAndPointer(intptr_t value, void* ptr) {
1162 return value;
1163}
1164
1165intptr_t* AllocateResource(intptr_t value) {
1166 return new intptr_t(value);
1167}
1168
1169void DeleteResource(intptr_t* resource) {
1170 delete resource;
1171}
1172
1173intptr_t GetResourceValue(intptr_t* resource) {
1174 return *resource;
1175}
1176
1177void DummyResourceFinalizer(void* isolate_peer, void* peer) {
1178 *reinterpret_cast<intptr_t*>(peer) = 0;
1179}
1180
1184}
1185
1186intptr_t AddPtrAndInt(void* self, intptr_t x) {
1187 return reinterpret_cast<intptr_t>(self) + x;
1188}
1189
1191 intptr_t field = 0;
1193 return field + x;
1194}
1195
1196intptr_t AddPtrAndPtr(void* self, void* other) {
1197 return reinterpret_cast<intptr_t>(self) + reinterpret_cast<intptr_t>(other);
1198}
1199
1200intptr_t AddHandleFieldAndPtr(Dart_Handle self, void* other) {
1201 intptr_t field = 0;
1203 return field + reinterpret_cast<intptr_t>(other);
1204}
1205
1207 intptr_t field1 = 0;
1209 intptr_t field2 = 0;
1210 ENSURE(!Dart_IsError(Dart_GetNativeInstanceField(other, 0, &field2)));
1211 return field1 + field2;
1212}
1213
1214intptr_t AddPtrAndHandleField(void* self, Dart_Handle other) {
1215 intptr_t field = 0;
1216 ENSURE(!Dart_IsError(Dart_GetNativeInstanceField(other, 0, &field)));
1217 return reinterpret_cast<intptr_t>(self) + field;
1218}
1219
1221 return value;
1222}
1223
1224static void* FfiNativeResolver(const char* name, uintptr_t args_n) {
1225 if (strcmp(name, "Dart_SetNativeInstanceField") == 0 && args_n == 3) {
1226 return reinterpret_cast<void*>(Dart_SetNativeInstanceField);
1227 }
1228 if (strcmp(name, "IsThreadInGenerated") == 0 && args_n == 0) {
1229 return reinterpret_cast<void*>(IsThreadInGenerated);
1230 }
1231 if (strcmp(name, "ReturnIntPtr") == 0 && args_n == 1) {
1232 return reinterpret_cast<void*>(ReturnIntPtr);
1233 }
1234 if (strcmp(name, "PassAsHandle") == 0 && args_n == 1) {
1235 return reinterpret_cast<void*>(PassAsHandle);
1236 }
1237 if (strcmp(name, "PassAsPointer") == 0 && args_n == 1) {
1238 return reinterpret_cast<void*>(PassAsPointer);
1239 }
1240 if (strcmp(name, "PassAsPointerAndValue") == 0 && args_n == 2) {
1241 return reinterpret_cast<void*>(PassAsPointerAndValue);
1242 }
1243 if (strcmp(name, "PassAsValueAndPointer") == 0 && args_n == 2) {
1244 return reinterpret_cast<void*>(PassAsValueAndPointer);
1245 }
1246 if (strcmp(name, "AllocateResource") == 0 && args_n == 1) {
1247 return reinterpret_cast<void*>(AllocateResource);
1248 }
1249 if (strcmp(name, "DeleteResource") == 0 && args_n == 1) {
1250 return reinterpret_cast<void*>(DeleteResource);
1251 }
1252 if (strcmp(name, "GetResourceValue") == 0 && args_n == 1) {
1253 return reinterpret_cast<void*>(GetResourceValue);
1254 }
1255 if (strcmp(name, "SetResourceFinalizer") == 0 && args_n == 2) {
1256 return reinterpret_cast<void*>(SetResourceFinalizer);
1257 }
1258 if (strcmp(name, "AddPtrAndInt") == 0 && args_n == 2) {
1259 return reinterpret_cast<void*>(AddPtrAndInt);
1260 }
1261 if (strcmp(name, "AddHandleFieldAndInt") == 0 && args_n == 2) {
1262 return reinterpret_cast<void*>(AddHandleFieldAndInt);
1263 }
1264 if (strcmp(name, "AddPtrAndPtr") == 0 && args_n == 2) {
1265 return reinterpret_cast<void*>(AddPtrAndPtr);
1266 }
1267 if (strcmp(name, "AddHandleFieldAndPtr") == 0 && args_n == 2) {
1268 return reinterpret_cast<void*>(AddHandleFieldAndPtr);
1269 }
1270 if (strcmp(name, "AddHandleFieldAndHandleField") == 0 && args_n == 2) {
1271 return reinterpret_cast<void*>(AddHandleFieldAndHandleField);
1272 }
1273 if (strcmp(name, "AddPtrAndHandleField") == 0 && args_n == 2) {
1274 return reinterpret_cast<void*>(AddPtrAndHandleField);
1275 }
1276 if (strcmp(name, "ReturnIntPtrMethod") == 0 && args_n == 2) {
1277 return reinterpret_cast<void*>(ReturnIntPtrMethod);
1278 }
1279 // This should be unreachable in tests.
1280 ENSURE(false);
1281}
1282
1284 Dart_Handle library = Dart_LookupLibrary(url);
1285 ENSURE(!Dart_IsError(library));
1288}
1289
1290DART_EXPORT void WaitUntilNThreadsEnterBarrier(intptr_t num_threads) {
1291 ThreadPoolTest_BarrierSync(Dart_CurrentIsolate_DL, Dart_EnterIsolate_DL,
1292 Dart_ExitIsolate_DL, num_threads);
1293}
1294
1295////////////////////////////////////////////////////////////////////////////////
1296// Helper for the regression test for b/216834909
1297////////////////////////////////////////////////////////////////////////////////
1298
1299#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID) || \
1300 defined(DART_HOST_OS_MACOS)
1301static bool Regress216834909_hang_at_exit = true;
1302
1303static void Regress216834909_AtExit() {
1304 if (Regress216834909_hang_at_exit) {
1305 while (true) {
1306 sleep(60 * 60); // Sleep for 1 hour.
1307 }
1308 }
1309}
1310
1311DART_EXPORT void Regress216834909_SetAtExit(int64_t install) {
1312 if (install != 0) {
1313 // Set and arm atexit routine.
1314 atexit(&Regress216834909_AtExit);
1315 Regress216834909_hang_at_exit = true;
1316 } else {
1317 // Disarm atexit routine.
1318 Regress216834909_hang_at_exit = false;
1319 }
1320}
1321#endif
1322
1324 return Dart_IsNull(object);
1325}
1326
1327namespace {
1328struct RefCountedResource {
1329 void* resource;
1330 intptr_t refcount;
1331};
1332} // namespace
1333
1334// We only ever have one ref counted resource in our test, use global lock.
1336
1338 auto peer =
1339 static_cast<RefCountedResource*>(malloc(sizeof(RefCountedResource)));
1340 auto resource = malloc(128);
1341 memset(resource, 0, 128);
1342 peer->resource = resource;
1343 peer->refcount = 0; // We're not going to count the reference here.
1344 return peer;
1345}
1346
1347DART_EXPORT void IncreaseRefcount(RefCountedResource* peer) {
1349 peer->refcount++;
1351}
1352
1353// And delete if zero.
1355 auto* resource = static_cast<RefCountedResource*>(peer);
1357 resource->refcount--;
1358 if (resource->refcount <= 0) {
1359 free(resource->resource);
1360 free(peer);
1361 }
1363}
1364
1366 Dart_UpdateExternalSize_DL(nullptr, 0);
1367 Dart_UpdateFinalizableExternalSize_DL(nullptr, Dart_Null(), 0);
1368}
1369
1371 void* this_,
1372 int id,
1373 int flags,
1374 int actions,
1375 int maxValueLength,
1376 int currentValueLength,
1377 int textSelectionBase,
1378 int textSelectionExtent,
1379 int platformViewId,
1380 int scrollChildren,
1381 int scrollIndex,
1382 double scrollPosition,
1383 double scrollExtentMax,
1384 double scrollExtentMin,
1385 double left,
1386 double top,
1387 double right,
1388 double bottom,
1389 double elevation,
1390 double thickness,
1391 Dart_Handle label,
1392 Dart_Handle labelAttributes,
1394 Dart_Handle valueAttributes,
1395 Dart_Handle increasedValue,
1396 Dart_Handle increasedValueAttributes,
1397 Dart_Handle decreasedValue,
1398 Dart_Handle decreasedValueAttributes,
1399 Dart_Handle hint,
1400 Dart_Handle hintAttributes,
1401 Dart_Handle tooltip,
1402 int textDirection,
1404 Dart_Handle childrenInTraversalOrder,
1405 Dart_Handle childrenInHitTestOrder,
1406 Dart_Handle localContextActions) {
1407 if (!Dart_IsString(tooltip)) {
1408 FATAL("expected Dart_IsString(tooltip)");
1409 }
1410 const char* cstr;
1411 auto to_cstring_result = Dart_StringToCString(tooltip, &cstr);
1412 if (Dart_IsError(to_cstring_result)) {
1413 FATAL(Dart_GetError(to_cstring_result));
1414 }
1415 if (strcmp(cstr, "tooltip") != 0) {
1416 printf("cstr %s\n", cstr);
1417 FATAL("cstr not equal to \"tooltip\"");
1418 }
1419}
1420
1422 Dart_Handle o1,
1423 Dart_Handle o2,
1424 Dart_Handle o3,
1425 Dart_Handle o4,
1426 Dart_Handle o5,
1427 Dart_Handle o6,
1428 Dart_Handle o7,
1429 Dart_Handle o8,
1430 Dart_Handle o9,
1431 Dart_Handle o10,
1432 Dart_Handle o11,
1433 Dart_Handle o12,
1434 Dart_Handle o13,
1435 Dart_Handle o14,
1436 Dart_Handle o15,
1437 Dart_Handle o16,
1438 Dart_Handle o17,
1439 Dart_Handle o18,
1440 Dart_Handle o19) {
1441#define CHECK_STRING(o) \
1442 if (!Dart_IsString(o)) { \
1443 FATAL("expected Dart_IsString"); \
1444 }
1445 CHECK_STRING(o0);
1446 CHECK_STRING(o1);
1447 CHECK_STRING(o2);
1448 CHECK_STRING(o3);
1449 CHECK_STRING(o4);
1450 CHECK_STRING(o5);
1451 CHECK_STRING(o6);
1452 CHECK_STRING(o7);
1453 CHECK_STRING(o8);
1454 CHECK_STRING(o9);
1455 CHECK_STRING(o10);
1456 CHECK_STRING(o11);
1457 CHECK_STRING(o12);
1458 CHECK_STRING(o13);
1459 CHECK_STRING(o14);
1460 CHECK_STRING(o15);
1461 CHECK_STRING(o16);
1462 CHECK_STRING(o17);
1463 CHECK_STRING(o18);
1464 CHECK_STRING(o19);
1465}
1466#undef CHECK_STRING
1467
1468} // namespace dart
int count
Definition: FontMgrTest.cpp:50
static bool install(SkBitmap *bm, const SkImageInfo &info, const SkRasterHandleAllocator::Rec &rec)
Definition: SkCanvas.cpp:2856
static SkString resource(SkPDFResourceType type, int index)
static void HandleResponse(Dart_Port p, Dart_CObject *message)
void PostAndWait(Dart_Port port, Dart_CObject *object)
PendingCall(void **buffer, size_t *length)
#define ILLEGAL_PORT
Definition: dart_api.h:1535
int64_t Dart_Port
Definition: dart_api.h:1525
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
struct _Dart_Isolate * Dart_Isolate
Definition: dart_api.h:88
@ Dart_TypedData_kUint8
Definition: dart_api.h:2615
Dart_Handle Dart_PersistentHandle
Definition: dart_api.h:259
struct _Dart_FinalizableHandle * Dart_FinalizableHandle
Definition: dart_api.h:261
intptr_t Dart_InitializeApiDL(void *data)
Definition: dart_api_dl.c:45
@ Dart_CObject_kInt64
@ Dart_CObject_kTypedData
@ Dart_CObject_kSendPort
@ Dart_CObject_kString
@ Dart_CObject_kArray
@ Dart_CObject_kNull
@ Dart_CObject_kExternalTypedData
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
static bool b
struct MyStruct a[10]
#define DART_EXPORT
#define CHECK_EQ(X, Y)
#define FATAL(error)
#define CHECK_STRING(o)
#define ENSURE(X)
AtkStateType state
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
Dart_NativeFunction function
Definition: fuchsia.cc:51
size_t length
Win32Message message
#define MSAN_UNPOISON(ptr, len)
double x
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: SkSLString.cpp:83
exit(kErrorExitCode)
Definition: dart_vm.cc:33
DART_EXPORT void WaitForHelper(HelperThreadState *helper)
DART_EXPORT void StopWorkSimulator()
intptr_t PassAsPointer(void *ptr)
DART_EXPORT void * TestUnprotectCode(void(*fn)(void *))
DART_EXPORT intptr_t TestGC(void(*do_gc)())
DART_EXPORT Dart_Handle Dart_SetFfiNativeResolver(Dart_Handle library, Dart_FfiNativeResolver resolver)
DART_EXPORT void ManyHandles(Dart_Handle o0, Dart_Handle o1, Dart_Handle o2, Dart_Handle o3, Dart_Handle o4, Dart_Handle o5, Dart_Handle o6, Dart_Handle o7, Dart_Handle o8, Dart_Handle o9, Dart_Handle o10, Dart_Handle o11, Dart_Handle o12, Dart_Handle o13, Dart_Handle o14, Dart_Handle o15, Dart_Handle o16, Dart_Handle o17, Dart_Handle o18, Dart_Handle o19)
DART_EXPORT void Dart_PrepareToAbort()
DART_EXPORT Dart_Isolate IGH_CreateIsolate(const char *name, void *peer)
DART_EXPORT Dart_WeakPersistentHandle Dart_NewWeakPersistentHandle(Dart_Handle object, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT intptr_t InitDartApiDL(void *data)
DART_EXPORT void Dart_EnterScope()
DART_EXPORT void SemanticsUpdateBuilderUpdateNode(void *this_, int id, int flags, int actions, int maxValueLength, int currentValueLength, int textSelectionBase, int textSelectionExtent, int platformViewId, int scrollChildren, int scrollIndex, double scrollPosition, double scrollExtentMax, double scrollExtentMin, double left, double top, double right, double bottom, double elevation, double thickness, Dart_Handle label, Dart_Handle labelAttributes, Dart_Handle value, Dart_Handle valueAttributes, Dart_Handle increasedValue, Dart_Handle increasedValueAttributes, Dart_Handle decreasedValue, Dart_Handle decreasedValueAttributes, Dart_Handle hint, Dart_Handle hintAttributes, Dart_Handle tooltip, int textDirection, Dart_Handle transform, Dart_Handle childrenInTraversalOrder, Dart_Handle childrenInHitTestOrder, Dart_Handle localContextActions)
DART_EXPORT Dart_Handle GetRootLibraryUrl()
const char *const name
intptr_t AddPtrAndHandleField(void *self, Dart_Handle other)
DART_EXPORT void * LargePointer()
DART_EXPORT Dart_Handle PassObjectToC(Dart_Handle h)
DART_EXPORT void CollectOnNthAllocation(intptr_t num_allocations)
DART_EXPORT double SmallDouble()
DART_EXPORT void IsolateExitTest_LookupAndCallIsolateExit(int i)
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_DebugName()
DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj, int index, intptr_t *value)
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
intptr_t AddPtrAndPtr(void *self, void *other)
intptr_t * AllocateResource(intptr_t value)
DART_EXPORT Dart_Handle Dart_True()
DART_EXPORT Dart_Handle Dart_RootLibrary()
DART_EXPORT void IGH_StartIsolate(Dart_Isolate child_isolate, int64_t main_isolate_port, const char *library_uri, const char *function_name, bool errors_are_fatal, Dart_Port on_error_port, Dart_Port on_exit_port)
DART_EXPORT bool IsNull(Dart_Handle object)
intptr_t ReturnIntPtr(intptr_t x)
DART_EXPORT Dart_Handle PassObjectToCUseDynamicLinking(Dart_Handle h)
void ClobberAndCall(void(*fn)())
void * malloc(size_t size)
Definition: allocation.cc:19
DART_EXPORT void SetArgumentTo42(void *token)
DART_EXPORT void * Dart_ExecuteInternalCommand(const char *command, void *arg)
DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value)
std::function< void()> Work
void Fatal(char const *file, int line, char const *error)
DART_EXPORT void RegisterMyCallbackBlocking(Dart_Port send_port, intptr_t(*callback1)(intptr_t))
DART_EXPORT void Dart_PropagateError(Dart_Handle handle)
DART_EXPORT void TestDeprecatedSymbols()
DART_EXPORT int64_t MinInt32()
DART_EXPORT int64_t HandleReadFieldValue(Dart_Handle handle)
void(* callback_)(Dart_Handle)
DART_EXPORT void ReleaseClosureCallback()
void DummyResourceFinalizer(void *isolate_peer, void *peer)
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 RefCountedResource * AllocateRefcountedResource()
DART_EXPORT Dart_Handle Dart_HandleFromWeakPersistent(Dart_WeakPersistentHandle object)
intptr_t PassAsValueAndPointer(intptr_t value, void *ptr)
DART_EXPORT void InvokeClosureCallback()
DART_EXPORT void StopWorkSimulator2()
DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
static void * FfiNativeResolver(const char *name, uintptr_t args_n)
DART_EXPORT void SetFfiNativeResolverForTest(Dart_Handle url)
void NotifyDart(Dart_Port send_port, const Work *work)
DART_EXPORT int64_t MinInt64()
DART_EXPORT void RegisterMyCallbackNonBlocking(Dart_Port send_port, void(*callback)(intptr_t))
DART_EXPORT Dart_Isolate Dart_CurrentIsolate()
intptr_t PassAsPointerAndValue(void *ptr, intptr_t value)
DART_EXPORT void SleepOnAnyOS(intptr_t seconds)
DART_EXPORT void Dart_DumpNativeStackTrace(void *context)
DART_EXPORT const char * Dart_VersionString()
intptr_t AddHandleFieldAndHandleField(Dart_Handle self, Dart_Handle other)
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_SetNativeInstanceField(Dart_Handle obj, int index, intptr_t value)
DART_EXPORT void Dart_DeleteWeakPersistentHandle(Dart_WeakPersistentHandle object)
DART_EXPORT Dart_Handle TrueHandle()
intptr_t MyCallbackBlocking(intptr_t a)
void SetResourceFinalizer(Dart_Handle handle, intptr_t *resource)
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 void IGH_MsanUnpoison(void *start, intptr_t length)
intptr_t GetResourceValue(intptr_t *resource)
DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal, Dart_Port on_error_port, Dart_Port on_exit_port, char **error)
DART_EXPORT void WaitUntilNThreadsEnterBarrier(intptr_t num_threads)
DART_EXPORT void TriggerGC(uint64_t count)
DART_EXPORT void DecreaseRefcount(void *peer)
static void RunFinalizer(void *isolate_callback_data, void *peer)
DART_EXPORT Dart_Handle ThrowOnReturnOfError(Dart_Handle(*callback)())
DART_EXPORT void RegisterClosureCallback(Dart_Handle h)
DART_EXPORT void Dart_ExitIsolate()
DART_EXPORT void * Calloc(size_t count, size_t size)
std::mutex ref_counted_resource_mutex
void DeleteResource(intptr_t *resource)
DART_EXPORT void ThreadPoolTest_BarrierSync(Dart_Isolate(*dart_current_isolate)(), void(*dart_enter_isolate)(Dart_Isolate), void(*dart_exit_isolate)(), intptr_t num_threads)
DART_EXPORT void StartWorkSimulator()
Dart_Port my_callback_non_blocking_send_port_
void * calloc(size_t n, size_t size)
Definition: allocation.cc:11
DART_EXPORT void ExecuteCallback(Work *work_ptr)
intptr_t AddHandleFieldAndInt(Dart_Handle self, intptr_t x)
void MyCallbackNonBlocking(intptr_t a)
DART_EXPORT void Dart_ExitScope()
intptr_t ReturnIntPtrMethod(Dart_Handle self, intptr_t value)
Dart_Port my_callback_blocking_send_port_
DART_EXPORT int64_t PropagateErrorWithoutHandle(Dart_Handle(*callback)())
DART_EXPORT void IncreaseRefcount(RefCountedResource *peer)
void MyCallback2(uint8_t a)
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT void ClosureCallbackThroughHandle(void(*callback)(Dart_Handle), Dart_Handle closureHandle)
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception)
intptr_t AddHandleFieldAndPtr(Dart_Handle self, void *other)
DART_EXPORT void RegisterClosureCallbackFP(void(*callback)(Dart_Handle))
DART_EXPORT bool Dart_IsInteger(Dart_Handle object)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library)
void Helper(uword arg)
uint8_t MyCallback1(uint8_t a)
DART_EXPORT Dart_Handle ReturnHandleInCallback(Dart_Handle(*callback)())
DART_EXPORT Dart_Handle Dart_Null()
DART_EXPORT bool Dart_IsString(Dart_Handle object)
intptr_t PassAsHandle(Dart_Handle handle)
const char *const function_name
static int8_t data[kExtLength]
DART_EXPORT uint8_t IsThreadInGenerated()
DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle object, const char **cstr)
DART_EXPORT Dart_Handle Dart_HandleFromPersistent(Dart_PersistentHandle object)
void(* my_callback_non_blocking_fp_)(intptr_t)
DART_EXPORT void RegisterSendPort(Dart_Port send_port)
Dart_PersistentHandle closure_to_callback_
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DART_EXPORT void Regress37069(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e, uint64_t f, uint64_t g, uint64_t h, uint64_t i, uint64_t j, uint64_t k)
DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object)
DART_EXPORT void RestoreSIGPIPEHandler()
DART_EXPORT void FreeFinalizer(void *, void *value)
DART_EXPORT void StartWorkSimulator2()
intptr_t AddPtrAndInt(void *self, intptr_t x)
DART_EXPORT Dart_Handle Dart_IntegerToInt64(Dart_Handle integer, int64_t *value)
intptr_t(* my_callback_blocking_fp_)(intptr_t)
DART_EXPORT Dart_Handle HandleRecursion(Dart_Handle object, Dart_Handle(*callback)(int64_t), int64_t i)
DART_EXPORT void * UnprotectCodeOtherThread(void *isolate, std::condition_variable *var, std::mutex *mut)
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 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
Definition: tester.py:1
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
SkScalar h
#define Pp
Definition: globals.h:425
#define Px
Definition: globals.h:410
#define Pd64
Definition: globals.h:416
#define Px64
Definition: globals.h:418
#define Pd
Definition: globals.h:408
struct _Dart_CObject::@86::@87 as_send_port
Dart_HandleFinalizer callback
union _Dart_CObject::@86 value
Dart_CObject_Type type
uint8_t * data
struct _Dart_CObject::@86::@90 as_typed_data
const char * as_string
struct _Dart_CObject::@86::@91 as_external_typed_data
struct _Dart_CObject::@86::@89 as_array
struct _Dart_CObject ** values
Dart_Port origin_id
std::unique_ptr< std::thread > helper