Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
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);
393 ENSURE(!Dart_IsError(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, &cv, &notified]() {
484 result = callback(a);
485 printf("C Da: Notify result ready.\n");
486 notified = true;
487 cv.notify_one();
488 };
489 const Work* work_ptr = new Work(work); // Copy to heap.
491 printf("C : Waiting for result.\n");
492 while (!notified) {
493 cv.wait(lock);
494 }
495 printf("C : Received result.\n");
496 return result;
497}
498
499// Do a callback to Dart in a non-blocking way.
500//
501// Dart sums all numbers posted to it.
502void MyCallbackNonBlocking(intptr_t a) {
503 auto callback = my_callback_non_blocking_fp_; // Define storage duration.
504 const Work work = [a, callback]() { callback(a); };
505 // Copy to heap to make it outlive the function scope.
506 const Work* work_ptr = new Work(work);
508}
509
510// Simulated work for Thread #1.
511//
512// Simulates heavy work with sleeps.
513void Work1() {
514 printf("C T1: Work1 Start.\n");
515 SleepOnAnyOS(1);
516 const intptr_t val1 = 3;
517 printf("C T1: MyCallbackBlocking(%" Pd ").\n", val1);
518 const intptr_t val2 = MyCallbackBlocking(val1); // val2 = 6.
519 printf("C T1: MyCallbackBlocking returned %" Pd ".\n", val2);
520 SleepOnAnyOS(1);
521 const intptr_t val3 = val2 - 1; // val3 = 5.
522 printf("C T1: MyCallbackNonBlocking(%" Pd ").\n", val3);
523 MyCallbackNonBlocking(val3); // Post 5 to Dart.
524 printf("C T1: Work1 Done.\n");
525}
526
527// Simulated work for Thread #2.
528//
529// Simulates lighter work, no sleeps.
530void Work2() {
531 printf("C T2: Work2 Start.\n");
532 const intptr_t val1 = 5;
533 printf("C T2: MyCallbackNonBlocking(%" Pd ").\n", val1);
534 MyCallbackNonBlocking(val1); // Post 5 to Dart.
535 const intptr_t val2 = 1;
536 printf("C T2: MyCallbackBlocking(%" Pd ").\n", val2);
537 const intptr_t val3 = MyCallbackBlocking(val2); // val3 = 4.
538 printf("C T2: MyCallbackBlocking returned %" Pd ".\n", val3);
539 printf("C T2: MyCallbackNonBlocking(%" Pd ").\n", val3);
540 MyCallbackNonBlocking(val3); // Post 4 to Dart.
541 printf("C T2: Work2 Done.\n");
542}
543
544// Simulator that simulates concurrent work with multiple threads.
546 public:
547 static void StartWorkSimulator() {
548 running_work_simulator_ = new SimulateWork();
549 running_work_simulator_->Start();
550 }
551
552 static void StopWorkSimulator() {
553 running_work_simulator_->Stop();
554 delete running_work_simulator_;
555 running_work_simulator_ = nullptr;
556 }
557
558 private:
559 static SimulateWork* running_work_simulator_;
560
561 void Start() {
562 printf("C Da: Starting SimulateWork.\n");
563 printf("C Da: Starting worker threads.\n");
564 thread1 = new std::thread(Work1);
565 thread2 = new std::thread(Work2);
566 printf("C Da: Started SimulateWork.\n");
567 }
568
569 void Stop() {
570 printf("C Da: Stopping SimulateWork.\n");
571 printf("C Da: Waiting for worker threads to finish.\n");
572 thread1->join();
573 thread2->join();
574 delete thread1;
575 delete thread2;
576 printf("C Da: Stopped SimulateWork.\n");
577 }
578
579 std::thread* thread1;
580 std::thread* thread2;
581};
582SimulateWork* SimulateWork::running_work_simulator_ = 0;
583
585 intptr_t (*callback1)(intptr_t)) {
586 my_callback_blocking_fp_ = callback1;
588}
589
595
599
603
605 printf("C Da: ExecuteCallback(%" Pp ").\n",
606 reinterpret_cast<intptr_t>(work_ptr));
607 const Work work = *work_ptr;
608 work();
609 delete work_ptr;
610 printf("C Da: ExecuteCallback done.\n");
611}
612
613////////////////////////////////////////////////////////////////////////////////
614// Functions for async callbacks example.
615//
616// sample_native_port_call.dart
617
619
620DART_EXPORT void* Calloc(size_t count, size_t size) {
621 return calloc(count, size);
622}
623
624DART_EXPORT void FreeFinalizer(void*, void* value) {
625 free(value);
626}
627
629 public:
630 PendingCall(void** buffer, size_t* length)
631 : response_buffer_(buffer), response_length_(length) {
632 receive_port_ =
633 Dart_NewNativePort_DL("cpp-response", &PendingCall::HandleResponse,
634 /*handle_concurrently=*/false);
635 }
636 ~PendingCall() { Dart_CloseNativePort_DL(receive_port_); }
637
638 Dart_Port port() const { return receive_port_; }
639
641 std::unique_lock<std::mutex> lock(mutex);
642 const bool success = Dart_PostCObject_DL(port, object);
643 if (!success) FATAL("Failed to send message, invalid port or isolate died");
644
645 printf("C : Waiting for result.\n");
646 while (!notified) {
647 cv.wait(lock);
648 }
649 }
650
652 if (message->type != Dart_CObject_kArray) {
653 FATAL("C : Wrong Data: message->type != Dart_CObject_kArray.\n");
654 }
655 Dart_CObject** c_response_args = message->value.as_array.values;
656 Dart_CObject* c_pending_call = c_response_args[0];
657 Dart_CObject* c_message = c_response_args[1];
658 printf("C : HandleResponse (call: %" Px ", message: %" Px ").\n",
659 reinterpret_cast<intptr_t>(c_pending_call),
660 reinterpret_cast<intptr_t>(c_message));
661
662 auto pending_call = reinterpret_cast<PendingCall*>(
663 c_pending_call->type == Dart_CObject_kInt64
664 ? c_pending_call->value.as_int64
665 : c_pending_call->value.as_int32);
666
667 pending_call->ResolveCall(c_message);
668 }
669
670 private:
671 static bool NonEmptyBuffer(void** value) { return *value != nullptr; }
672
673 void ResolveCall(Dart_CObject* bytes) {
674 assert(bytes->type == Dart_CObject_kTypedData);
675 if (bytes->type != Dart_CObject_kTypedData) {
676 FATAL("C : Wrong Data: bytes->type != Dart_CObject_kTypedData.\n");
677 }
678 const intptr_t response_length = bytes->value.as_typed_data.length;
679 const uint8_t* response_buffer = bytes->value.as_typed_data.values;
680 printf("C : ResolveCall(length: %" Pd ", buffer: %" Px ").\n",
681 response_length, reinterpret_cast<intptr_t>(response_buffer));
682
683 void* buffer = malloc(response_length);
684 memmove(buffer, response_buffer, response_length);
685
686 *response_buffer_ = buffer;
687 *response_length_ = response_length;
688
689 printf("C : Notify result ready.\n");
690 notified = true;
691 cv.notify_one();
692 }
693
694 std::mutex mutex;
695 std::condition_variable cv;
696 bool notified = false;
697
698 Dart_Port receive_port_;
699 void** response_buffer_;
700 size_t* response_length_;
701};
702
703// Do a callback to Dart in a blocking way, being interested in the result.
704//
705// Dart returns `a + 3`.
706uint8_t MyCallback1(uint8_t a) {
707 const char* methodname = "myCallback1";
708 size_t request_length = sizeof(uint8_t) * 1;
709 void* request_buffer = malloc(request_length); // FreeFinalizer.
710 reinterpret_cast<uint8_t*>(request_buffer)[0] = a; // Populate buffer.
711 void* response_buffer = nullptr;
712 size_t response_length = 0;
713
714 PendingCall pending_call(&response_buffer, &response_length);
715
716 Dart_CObject c_send_port;
717 c_send_port.type = Dart_CObject_kSendPort;
718 c_send_port.value.as_send_port.id = pending_call.port();
720
721 Dart_CObject c_pending_call;
722 c_pending_call.type = Dart_CObject_kInt64;
723 c_pending_call.value.as_int64 = reinterpret_cast<int64_t>(&pending_call);
724
725 Dart_CObject c_method_name;
726 c_method_name.type = Dart_CObject_kString;
727 c_method_name.value.as_string = const_cast<char*>(methodname);
728
729 Dart_CObject c_request_data;
730 c_request_data.type = Dart_CObject_kExternalTypedData;
732 c_request_data.value.as_external_typed_data.length = request_length;
733 c_request_data.value.as_external_typed_data.data =
734 static_cast<uint8_t*>(request_buffer);
735 c_request_data.value.as_external_typed_data.peer = request_buffer;
737
738 Dart_CObject* c_request_arr[] = {&c_send_port, &c_pending_call,
739 &c_method_name, &c_request_data};
740 Dart_CObject c_request;
741 c_request.type = Dart_CObject_kArray;
742 c_request.value.as_array.values = c_request_arr;
743 c_request.value.as_array.length =
744 sizeof(c_request_arr) / sizeof(c_request_arr[0]);
745
746 printf("C : Dart_PostCObject_(request: %" Px ", call: %" Px ").\n",
747 reinterpret_cast<intptr_t>(&c_request),
748 reinterpret_cast<intptr_t>(&c_pending_call));
749 pending_call.PostAndWait(send_port_, &c_request);
750 printf("C : Received result.\n");
751
752 const intptr_t result = reinterpret_cast<uint8_t*>(response_buffer)[0];
753 free(response_buffer);
754
755 return result;
756}
757
758// Do a callback to Dart in a non-blocking way.
759//
760// Dart sums all numbers posted to it.
761void MyCallback2(uint8_t a) {
762 const char* methodname = "myCallback2";
763 void* request_buffer = malloc(sizeof(uint8_t) * 1); // FreeFinalizer.
764 reinterpret_cast<uint8_t*>(request_buffer)[0] = a; // Populate buffer.
765 const size_t request_length = sizeof(uint8_t) * 1;
766
767 Dart_CObject c_send_port;
768 c_send_port.type = Dart_CObject_kNull;
769
770 Dart_CObject c_pending_call;
771 c_pending_call.type = Dart_CObject_kNull;
772
773 Dart_CObject c_method_name;
774 c_method_name.type = Dart_CObject_kString;
775 c_method_name.value.as_string = const_cast<char*>(methodname);
776
777 Dart_CObject c_request_data;
778 c_request_data.type = Dart_CObject_kExternalTypedData;
780 c_request_data.value.as_external_typed_data.length = request_length;
781 c_request_data.value.as_external_typed_data.data =
782 static_cast<uint8_t*>(request_buffer);
783 c_request_data.value.as_external_typed_data.peer = request_buffer;
785
786 Dart_CObject* c_request_arr[] = {&c_send_port, &c_pending_call,
787 &c_method_name, &c_request_data};
788 Dart_CObject c_request;
789 c_request.type = Dart_CObject_kArray;
790 c_request.value.as_array.values = c_request_arr;
791 c_request.value.as_array.length =
792 sizeof(c_request_arr) / sizeof(c_request_arr[0]);
793
794 printf("C : Dart_PostCObject_(request: %" Px ", call: %" Px ").\n",
795 reinterpret_cast<intptr_t>(&c_request),
796 reinterpret_cast<intptr_t>(&c_pending_call));
797 Dart_PostCObject_DL(send_port_, &c_request);
798}
799
800// Simulated work for Thread #1.
801//
802// Simulates heavy work with sleeps.
803void Work1_2() {
804 printf("C T1: Work1 Start.\n");
805 SleepOnAnyOS(1);
806 const intptr_t val1 = 3;
807 printf("C T1: MyCallback1(%" Pd ").\n", val1);
808 const intptr_t val2 = MyCallback1(val1); // val2 = 6.
809 printf("C T1: MyCallback1 returned %" Pd ".\n", val2);
810 SleepOnAnyOS(1);
811 const intptr_t val3 = val2 - 1; // val3 = 5.
812 printf("C T1: MyCallback2(%" Pd ").\n", val3);
813 MyCallback2(val3); // Post 5 to Dart.
814 printf("C T1: Work1 Done.\n");
815}
816
817// Simulated work for Thread #2.
818//
819// Simulates lighter work, no sleeps.
820void Work2_2() {
821 printf("C T2: Work2 Start.\n");
822 const intptr_t val1 = 5;
823 printf("C T2: MyCallback2(%" Pd ").\n", val1);
824 MyCallback2(val1); // Post 5 to Dart.
825 const intptr_t val2 = 1;
826 printf("C T2: MyCallback1(%" Pd ").\n", val2);
827 const intptr_t val3 = MyCallback1(val2); // val3 = 4.
828 printf("C T2: MyCallback1 returned %" Pd ".\n", val3);
829 printf("C T2: MyCallback2(%" Pd ").\n", val3);
830 MyCallback2(val3); // Post 4 to Dart.
831 printf("C T2: Work2 Done.\n");
832}
833
834// Simulator that simulates concurrent work with multiple threads.
836 public:
837 static void StartWorkSimulator() {
838 running_work_simulator_ = new SimulateWork2();
839 running_work_simulator_->Start();
840 }
841
842 static void StopWorkSimulator() {
843 running_work_simulator_->Stop();
844 delete running_work_simulator_;
845 running_work_simulator_ = nullptr;
846 }
847
848 private:
849 static SimulateWork2* running_work_simulator_;
850
851 void Start() {
852 printf("C Da: Starting SimulateWork.\n");
853 printf("C Da: Starting worker threads.\n");
854 thread1 = new std::thread(Work1_2);
855 thread2 = new std::thread(Work2_2);
856 printf("C Da: Started SimulateWork.\n");
857 }
858
859 void Stop() {
860 printf("C Da: Stopping SimulateWork.\n");
861 printf("C Da: Waiting for worker threads to finish.\n");
862 thread1->join();
863 thread2->join();
864 delete thread1;
865 delete thread2;
866 printf("C Da: Stopped SimulateWork.\n");
867 }
868
869 std::thread* thread1;
870 std::thread* thread2;
871};
872SimulateWork2* SimulateWork2::running_work_simulator_ = 0;
873
875 send_port_ = send_port;
876}
877
881
885
886////////////////////////////////////////////////////////////////////////////////
887// Helpers used for lightweight isolate tests.
888////////////////////////////////////////////////////////////////////////////////
889
891 Dart_Isolate (*dart_current_isolate)(),
892 void (*dart_enter_isolate)(Dart_Isolate),
893 void (*dart_exit_isolate)(),
894 intptr_t num_threads) {
895 // Guaranteed to be initialized exactly once (no race between multiple
896 // threads).
897 static std::mutex mutex;
898 static std::condition_variable cvar;
899 static intptr_t thread_count = 0;
900
901 const Dart_Isolate isolate = dart_current_isolate();
902 dart_exit_isolate();
903 {
904 std::unique_lock<std::mutex> lock(mutex);
905 ++thread_count;
906 while (thread_count < num_threads) {
907 cvar.wait(lock);
908 }
909 cvar.notify_all();
910 }
911 dart_enter_isolate(isolate);
912}
913
914////////////////////////////////////////////////////////////////////////////////
915// Helpers used for isolate exit tests.
916////////////////////////////////////////////////////////////////////////////////
917
918// This method consumes and ignores unwind error raised by `Isolate.exit` called
919// by dart `callIsolateExit` method.
921 Dart_Handle root_lib = Dart_RootLibrary();
922 fprintf(stderr, "IsolateExitTest_LookupAndCallIsolateExit i:%d\n", i);
923 if (i > 0) {
924 Dart_Handle method_name =
925 Dart_NewStringFromCString("recurseLookupAndCallWorker");
926 Dart_Handle dart_args[1];
927 dart_args[0] = Dart_NewInteger(i - 1);
928 Dart_Handle result = Dart_Invoke(root_lib, method_name, 1, dart_args);
930 } else {
931 Dart_Handle method_name = Dart_NewStringFromCString("callIsolateExit");
932 Dart_Handle result = Dart_Invoke(root_lib, method_name, 0, nullptr);
933 if (Dart_IsError(result)) {
934 fprintf(stderr,
935 "%d failed to invoke %s in child isolate: %s, carrying on..\n", i,
936 "callIsolateExit", Dart_GetError(result));
937 }
939 }
940}
941
942////////////////////////////////////////////////////////////////////////////////
943// Functions for handle tests.
944//
945// vmspecific_handle_test.dart (statically linked).
946// vmspecific_handle_dynamically_linked_test.dart (dynamically linked).
947
948static void RunFinalizer(void* isolate_callback_data, void* peer) {
949 printf("Running finalizer for weak handle.\n");
950}
951
952// Tests that passing handles through FFI calls works, and that the FFI call
953// sets up the VM state etc. correctly so that the handle API calls work.
955 // Can use "h" until this function returns.
956
957 // A persistent handle which outlives this call. Lifetime managed in C.
958 auto persistent_handle = Dart_NewPersistentHandle(h);
959
960 Dart_Handle handle_2 = Dart_HandleFromPersistent(persistent_handle);
961 Dart_DeletePersistentHandle(persistent_handle);
962 if (Dart_IsError(handle_2)) {
963 Dart_PropagateError(handle_2);
964 }
965
966 Dart_Handle return_value;
967 if (!Dart_IsNull(h) && !Dart_IsInteger(h)) {
968 // A weak handle which outlives this call. Lifetime managed in C.
969 auto weak_handle = Dart_NewWeakPersistentHandle(
970 h, reinterpret_cast<void*>(0x1234), 64, RunFinalizer);
971 return_value = Dart_HandleFromWeakPersistent(weak_handle);
972
973 // Deleting a weak handle is not required, it deletes itself on
974 // finalization.
975 // Deleting a weak handle cancels the finalizer.
977 } else {
978 return_value = h;
979 }
980
981 return return_value;
982}
983
985 Dart_Handle closureHandle) {
986 printf("ClosureCallbackThroughHandle %p %p\n", callback, closureHandle);
987 callback(closureHandle);
988}
989
991 printf("ReturnHandleInCallback %p\n", callback);
992 Dart_Handle handle = callback();
993 if (Dart_IsError(handle)) {
994 printf("callback() returned an error, propagating error\n");
995 // Do C/C++ resource cleanup if needed, before propagating error.
996 Dart_PropagateError(handle);
997 }
998 return handle;
999}
1000
1001// Recurses til `i` reaches 0. Throws some Dart_Invoke in there as well.
1003 Dart_Handle (*callback)(int64_t),
1004 int64_t i) {
1005 printf("HandleRecursion %" Pd64 "\n", i);
1006 const bool do_invoke = i % 3 == 0;
1007 const bool do_gc = i % 7 == 3;
1008 if (do_gc) {
1009 Dart_ExecuteInternalCommand("gc-now", nullptr);
1010 }
1012 if (do_invoke) {
1013 Dart_Handle method_name = Dart_NewStringFromCString("a");
1014 if (Dart_IsError(method_name)) {
1015 Dart_PropagateError(method_name);
1016 }
1017 Dart_Handle arg = Dart_NewInteger(i - 1);
1018 if (Dart_IsError(arg)) {
1020 }
1021 printf("Dart_Invoke\n");
1022 result = Dart_Invoke(object, method_name, 1, &arg);
1023 } else {
1024 printf("callback\n");
1025 result = callback(i - 1);
1026 }
1027 if (do_gc) {
1028 Dart_ExecuteInternalCommand("gc-now", nullptr);
1029 }
1030 if (Dart_IsError(result)) {
1031 // Do C/C++ resource cleanup if needed, before propagating error.
1032 printf("Dart_PropagateError %" Pd64 "\n", i);
1034 }
1035 printf("return %" Pd64 "\n", i);
1036 return result;
1037}
1038
1040 printf("HandleReadFieldValue\n");
1041 Dart_Handle field_name = Dart_NewStringFromCString("a");
1042 if (Dart_IsError(field_name)) {
1043 printf("Dart_PropagateError(field_name)\n");
1044 Dart_PropagateError(field_name);
1045 }
1046 Dart_Handle field_value = Dart_GetField(handle, field_name);
1047 if (Dart_IsError(field_value)) {
1048 printf("Dart_PropagateError(field_value)\n");
1049 Dart_PropagateError(field_value);
1050 }
1051 int64_t value;
1052 Dart_Handle err = Dart_IntegerToInt64(field_value, &value);
1053 if (Dart_IsError(err)) {
1055 }
1056 return value;
1057}
1058
1059// Does not have a handle in it's own signature, so does not enter and exit
1060// scope in the trampoline.
1070
1073 const bool is_error = Dart_IsError(result);
1074 printf("ThrowOnReturnOfError is_error %s\n", is_error ? "true" : "false");
1075 return result;
1076}
1077
1081
1083 auto persistent_handle = Dart_NewPersistentHandle_DL(h);
1084
1085 Dart_Handle handle_2 = Dart_HandleFromPersistent_DL(persistent_handle);
1086 Dart_SetPersistentHandle_DL(persistent_handle, h);
1087 Dart_DeletePersistentHandle_DL(persistent_handle);
1088
1089 auto weak_handle = Dart_NewWeakPersistentHandle_DL(
1090 handle_2, reinterpret_cast<void*>(0x1234), 64, RunFinalizer);
1091 Dart_Handle return_value = Dart_HandleFromWeakPersistent_DL(weak_handle);
1092
1093 Dart_DeleteWeakPersistentHandle_DL(weak_handle);
1094
1095 return return_value;
1096}
1097
1098////////////////////////////////////////////////////////////////////////////////
1099// Example for doing closure callbacks with help of `dart_api.h`.
1100//
1101// sample_ffi_functions_callbacks_closures.dart
1102
1105
1109
1111 closure_to_callback_ = Dart_NewPersistentHandle_DL(h);
1112}
1113
1115 Dart_Handle closure_handle =
1116 Dart_HandleFromPersistent_DL(closure_to_callback_);
1117 callback_(closure_handle);
1118}
1119
1121 Dart_DeletePersistentHandle_DL(closure_to_callback_);
1122}
1123
1124////////////////////////////////////////////////////////////////////////////////
1125// NativeFinalizer tests
1126
1127DART_EXPORT void SetArgumentTo42(void* token) {
1128 *reinterpret_cast<intptr_t*>(token) = 42;
1129}
1130
1131////////////////////////////////////////////////////////////////////////////////
1132// Functions for testing @Native.
1133
1135 Dart_Handle root_lib = Dart_RootLibrary();
1136 Dart_Handle lib_url = Dart_LibraryUrl(root_lib);
1137 ENSURE(!Dart_IsError(lib_url));
1138 return lib_url;
1139}
1140
1141intptr_t ReturnIntPtr(intptr_t x) {
1142 return x;
1143}
1144
1145intptr_t PassAsHandle(Dart_Handle handle) {
1146 intptr_t result = 0;
1148 return result;
1149}
1150
1151intptr_t PassAsPointer(void* ptr) {
1152 return reinterpret_cast<intptr_t>(ptr);
1153}
1154
1155intptr_t PassAsPointerAndValue(void* ptr, intptr_t value) {
1156 return value;
1157}
1158
1159intptr_t PassAsValueAndPointer(intptr_t value, void* ptr) {
1160 return value;
1161}
1162
1163intptr_t* AllocateResource(intptr_t value) {
1164 return new intptr_t(value);
1165}
1166
1167void DeleteResource(intptr_t* resource) {
1168 delete resource;
1169}
1170
1171intptr_t GetResourceValue(intptr_t* resource) {
1172 return *resource;
1173}
1174
1175void DummyResourceFinalizer(void* isolate_peer, void* peer) {
1176 *reinterpret_cast<intptr_t*>(peer) = 0;
1177}
1178
1179void SetResourceFinalizer(Dart_Handle handle, intptr_t* resource) {
1180 Dart_NewFinalizableHandle(handle, resource, sizeof(Dart_FinalizableHandle),
1182}
1183
1184intptr_t AddPtrAndInt(void* self, intptr_t x) {
1185 return reinterpret_cast<intptr_t>(self) + x;
1186}
1187
1189 intptr_t field = 0;
1191 return field + x;
1192}
1193
1194intptr_t AddPtrAndPtr(void* self, void* other) {
1195 return reinterpret_cast<intptr_t>(self) + reinterpret_cast<intptr_t>(other);
1196}
1197
1198intptr_t AddHandleFieldAndPtr(Dart_Handle self, void* other) {
1199 intptr_t field = 0;
1201 return field + reinterpret_cast<intptr_t>(other);
1202}
1203
1205 intptr_t field1 = 0;
1207 intptr_t field2 = 0;
1208 ENSURE(!Dart_IsError(Dart_GetNativeInstanceField(other, 0, &field2)));
1209 return field1 + field2;
1210}
1211
1212intptr_t AddPtrAndHandleField(void* self, Dart_Handle other) {
1213 intptr_t field = 0;
1214 ENSURE(!Dart_IsError(Dart_GetNativeInstanceField(other, 0, &field)));
1215 return reinterpret_cast<intptr_t>(self) + field;
1216}
1217
1218intptr_t ReturnIntPtrMethod(Dart_Handle self, intptr_t value) {
1219 return value;
1220}
1221
1222static void* FfiNativeResolver(const char* name, uintptr_t args_n) {
1223 if (strcmp(name, "Dart_SetNativeInstanceField") == 0 && args_n == 3) {
1224 return reinterpret_cast<void*>(Dart_SetNativeInstanceField);
1225 }
1226 if (strcmp(name, "IsThreadInGenerated") == 0 && args_n == 0) {
1227 return reinterpret_cast<void*>(IsThreadInGenerated);
1228 }
1229 if (strcmp(name, "ReturnIntPtr") == 0 && args_n == 1) {
1230 return reinterpret_cast<void*>(ReturnIntPtr);
1231 }
1232 if (strcmp(name, "PassAsHandle") == 0 && args_n == 1) {
1233 return reinterpret_cast<void*>(PassAsHandle);
1234 }
1235 if (strcmp(name, "PassAsPointer") == 0 && args_n == 1) {
1236 return reinterpret_cast<void*>(PassAsPointer);
1237 }
1238 if (strcmp(name, "PassAsPointerAndValue") == 0 && args_n == 2) {
1239 return reinterpret_cast<void*>(PassAsPointerAndValue);
1240 }
1241 if (strcmp(name, "PassAsValueAndPointer") == 0 && args_n == 2) {
1242 return reinterpret_cast<void*>(PassAsValueAndPointer);
1243 }
1244 if (strcmp(name, "AllocateResource") == 0 && args_n == 1) {
1245 return reinterpret_cast<void*>(AllocateResource);
1246 }
1247 if (strcmp(name, "DeleteResource") == 0 && args_n == 1) {
1248 return reinterpret_cast<void*>(DeleteResource);
1249 }
1250 if (strcmp(name, "GetResourceValue") == 0 && args_n == 1) {
1251 return reinterpret_cast<void*>(GetResourceValue);
1252 }
1253 if (strcmp(name, "SetResourceFinalizer") == 0 && args_n == 2) {
1254 return reinterpret_cast<void*>(SetResourceFinalizer);
1255 }
1256 if (strcmp(name, "AddPtrAndInt") == 0 && args_n == 2) {
1257 return reinterpret_cast<void*>(AddPtrAndInt);
1258 }
1259 if (strcmp(name, "AddHandleFieldAndInt") == 0 && args_n == 2) {
1260 return reinterpret_cast<void*>(AddHandleFieldAndInt);
1261 }
1262 if (strcmp(name, "AddPtrAndPtr") == 0 && args_n == 2) {
1263 return reinterpret_cast<void*>(AddPtrAndPtr);
1264 }
1265 if (strcmp(name, "AddHandleFieldAndPtr") == 0 && args_n == 2) {
1266 return reinterpret_cast<void*>(AddHandleFieldAndPtr);
1267 }
1268 if (strcmp(name, "AddHandleFieldAndHandleField") == 0 && args_n == 2) {
1269 return reinterpret_cast<void*>(AddHandleFieldAndHandleField);
1270 }
1271 if (strcmp(name, "AddPtrAndHandleField") == 0 && args_n == 2) {
1272 return reinterpret_cast<void*>(AddPtrAndHandleField);
1273 }
1274 if (strcmp(name, "ReturnIntPtrMethod") == 0 && args_n == 2) {
1275 return reinterpret_cast<void*>(ReturnIntPtrMethod);
1276 }
1277 // This should be unreachable in tests.
1278 ENSURE(false);
1279}
1280
1287
1288DART_EXPORT void WaitUntilNThreadsEnterBarrier(intptr_t num_threads) {
1289 ThreadPoolTest_BarrierSync(Dart_CurrentIsolate_DL, Dart_EnterIsolate_DL,
1290 Dart_ExitIsolate_DL, num_threads);
1291}
1292
1293////////////////////////////////////////////////////////////////////////////////
1294// Helper for the regression test for b/216834909
1295////////////////////////////////////////////////////////////////////////////////
1296
1297#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID) || \
1298 defined(DART_HOST_OS_MACOS)
1299static bool Regress216834909_hang_at_exit = true;
1300
1301static void Regress216834909_AtExit() {
1302 if (Regress216834909_hang_at_exit) {
1303 while (true) {
1304 sleep(60 * 60); // Sleep for 1 hour.
1305 }
1306 }
1307}
1308
1309DART_EXPORT void Regress216834909_SetAtExit(int64_t install) {
1310 if (install != 0) {
1311 // Set and arm atexit routine.
1312 atexit(&Regress216834909_AtExit);
1313 Regress216834909_hang_at_exit = true;
1314 } else {
1315 // Disarm atexit routine.
1316 Regress216834909_hang_at_exit = false;
1317 }
1318}
1319#endif
1320
1322 return Dart_IsNull(object);
1323}
1324
1325namespace {
1326struct RefCountedResource {
1327 void* resource;
1328 intptr_t refcount;
1329};
1330} // namespace
1331
1332// We only ever have one ref counted resource in our test, use global lock.
1334
1336 auto peer =
1337 static_cast<RefCountedResource*>(malloc(sizeof(RefCountedResource)));
1338 auto resource = malloc(128);
1339 memset(resource, 0, 128);
1340 peer->resource = resource;
1341 peer->refcount = 0; // We're not going to count the reference here.
1342 return peer;
1343}
1344
1345DART_EXPORT void IncreaseRefcount(RefCountedResource* peer) {
1347 peer->refcount++;
1349}
1350
1351// And delete if zero.
1353 auto* resource = static_cast<RefCountedResource*>(peer);
1355 resource->refcount--;
1356 if (resource->refcount <= 0) {
1357 free(resource->resource);
1358 free(peer);
1359 }
1361}
1362
1364 Dart_UpdateExternalSize_DL(nullptr, 0);
1365 Dart_UpdateFinalizableExternalSize_DL(nullptr, Dart_Null(), 0);
1366}
1367
1369 void* this_,
1370 int id,
1371 int flags,
1372 int actions,
1373 int maxValueLength,
1374 int currentValueLength,
1375 int textSelectionBase,
1376 int textSelectionExtent,
1377 int platformViewId,
1378 int scrollChildren,
1379 int scrollIndex,
1380 double scrollPosition,
1381 double scrollExtentMax,
1382 double scrollExtentMin,
1383 double left,
1384 double top,
1385 double right,
1386 double bottom,
1387 double elevation,
1388 double thickness,
1389 Dart_Handle label,
1390 Dart_Handle labelAttributes,
1391 Dart_Handle value,
1392 Dart_Handle valueAttributes,
1393 Dart_Handle increasedValue,
1394 Dart_Handle increasedValueAttributes,
1395 Dart_Handle decreasedValue,
1396 Dart_Handle decreasedValueAttributes,
1397 Dart_Handle hint,
1398 Dart_Handle hintAttributes,
1399 Dart_Handle tooltip,
1400 int textDirection,
1402 Dart_Handle childrenInTraversalOrder,
1403 Dart_Handle childrenInHitTestOrder,
1404 Dart_Handle localContextActions) {
1405 if (!Dart_IsString(tooltip)) {
1406 FATAL("expected Dart_IsString(tooltip)");
1407 }
1408 const char* cstr;
1409 auto to_cstring_result = Dart_StringToCString(tooltip, &cstr);
1410 if (Dart_IsError(to_cstring_result)) {
1411 FATAL(Dart_GetError(to_cstring_result));
1412 }
1413 if (strcmp(cstr, "tooltip") != 0) {
1414 printf("cstr %s\n", cstr);
1415 FATAL("cstr not equal to \"tooltip\"");
1416 }
1417}
1418
1420 Dart_Handle o1,
1421 Dart_Handle o2,
1422 Dart_Handle o3,
1423 Dart_Handle o4,
1424 Dart_Handle o5,
1425 Dart_Handle o6,
1426 Dart_Handle o7,
1427 Dart_Handle o8,
1428 Dart_Handle o9,
1429 Dart_Handle o10,
1430 Dart_Handle o11,
1431 Dart_Handle o12,
1432 Dart_Handle o13,
1433 Dart_Handle o14,
1434 Dart_Handle o15,
1435 Dart_Handle o16,
1436 Dart_Handle o17,
1437 Dart_Handle o18,
1438 Dart_Handle o19) {
1439#define CHECK_STRING(o) \
1440 if (!Dart_IsString(o)) { \
1441 FATAL("expected Dart_IsString"); \
1442 }
1443 CHECK_STRING(o0);
1444 CHECK_STRING(o1);
1445 CHECK_STRING(o2);
1446 CHECK_STRING(o3);
1447 CHECK_STRING(o4);
1448 CHECK_STRING(o5);
1449 CHECK_STRING(o6);
1450 CHECK_STRING(o7);
1451 CHECK_STRING(o8);
1452 CHECK_STRING(o9);
1453 CHECK_STRING(o10);
1454 CHECK_STRING(o11);
1455 CHECK_STRING(o12);
1456 CHECK_STRING(o13);
1457 CHECK_STRING(o14);
1458 CHECK_STRING(o15);
1459 CHECK_STRING(o16);
1460 CHECK_STRING(o17);
1461 CHECK_STRING(o18);
1462 CHECK_STRING(o19);
1463}
1464#undef CHECK_STRING
1465
1466} // namespace dart
int count
#define ENSURE(X)
static bool install(SkBitmap *bm, const SkImageInfo &info, const SkRasterHandleAllocator::Rec &rec)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
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:1530
int64_t Dart_Port
Definition dart_api.h:1524
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:2606
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]
DART_EXPORT some_resource * AllocateResource()
#define DART_EXPORT
#define CHECK_EQ(X, Y)
#define FATAL(error)
#define CHECK_STRING(o)
AtkStateType state
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
size_t length
Win32Message message
#define MSAN_UNPOISON(ptr, len)
double x
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
exit(kErrorExitCode)
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)
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)
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
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