Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: mojo/dart/embedder/mojo_natives.cc

Issue 1417523003: Move implementation of dart:mojo.internal to mojo/public/platform/dart (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdio.h>
6 #include <string.h>
7
8 #include <memory>
9 #include <vector>
10
11 #include "dart/runtime/include/dart_api.h"
12 #include "mojo/dart/embedder/builtin.h"
13 #include "mojo/public/c/system/core.h"
14 #include "mojo/public/cpp/environment/logging.h"
15 #include "mojo/public/cpp/system/core.h"
16 #include "mojo/public/cpp/system/macros.h"
17
18 namespace mojo {
19 namespace dart {
20
21 #define MOJO_NATIVE_LIST(V) \
22 V(MojoSharedBuffer_Create, 2) \
23 V(MojoSharedBuffer_Duplicate, 2) \
24 V(MojoSharedBuffer_Map, 5) \
25 V(MojoSharedBuffer_Unmap, 1) \
26 V(MojoDataPipe_Create, 3) \
27 V(MojoDataPipe_WriteData, 4) \
28 V(MojoDataPipe_BeginWriteData, 3) \
29 V(MojoDataPipe_EndWriteData, 2) \
30 V(MojoDataPipe_ReadData, 4) \
31 V(MojoDataPipe_BeginReadData, 3) \
32 V(MojoDataPipe_EndReadData, 2) \
33 V(MojoMessagePipe_Create, 1) \
34 V(MojoMessagePipe_Write, 5) \
35 V(MojoMessagePipe_Read, 5) \
36 V(Mojo_GetTimeTicksNow, 0) \
37 V(MojoHandle_Close, 1) \
38 V(MojoHandle_Wait, 3) \
39 V(MojoHandle_RegisterFinalizer, 2) \
40 V(MojoHandle_WaitMany, 3) \
41 V(MojoHandleWatcher_GrowStateArrays, 1) \
42 V(MojoHandleWatcher_WaitMany, 2) \
43 V(MojoHandleWatcher_SendControlData, 4) \
44 V(MojoHandleWatcher_RecvControlData, 1) \
45 V(MojoHandleWatcher_SetControlHandle, 1) \
46 V(MojoHandleWatcher_GetControlHandle, 0)
47
48 MOJO_NATIVE_LIST(DECLARE_FUNCTION);
49
50 static struct NativeEntries {
51 const char* name;
52 Dart_NativeFunction function;
53 int argument_count;
54 } MojoEntries[] = {MOJO_NATIVE_LIST(REGISTER_FUNCTION)};
55
56 Dart_NativeFunction MojoNativeLookup(Dart_Handle name,
57 int argument_count,
58 bool* auto_setup_scope) {
59 const char* function_name = nullptr;
60 Dart_Handle result = Dart_StringToCString(name, &function_name);
61 DART_CHECK_VALID(result);
62 assert(function_name != nullptr);
63 assert(auto_setup_scope != nullptr);
64 *auto_setup_scope = true;
65 size_t num_entries = MOJO_ARRAYSIZE(MojoEntries);
66 for (size_t i = 0; i < num_entries; ++i) {
67 const struct NativeEntries& entry = MojoEntries[i];
68 if (!strcmp(function_name, entry.name) &&
69 (entry.argument_count == argument_count)) {
70 return entry.function;
71 }
72 }
73 return nullptr;
74 }
75
76 const uint8_t* MojoNativeSymbol(Dart_NativeFunction nf) {
77 size_t num_entries = MOJO_ARRAYSIZE(MojoEntries);
78 for (size_t i = 0; i < num_entries; ++i) {
79 const struct NativeEntries& entry = MojoEntries[i];
80 if (entry.function == nf) {
81 return reinterpret_cast<const uint8_t*>(entry.name);
82 }
83 }
84 return nullptr;
85 }
86
87 static void SetNullReturn(Dart_NativeArguments arguments) {
88 Dart_SetReturnValue(arguments, Dart_Null());
89 }
90
91 static void SetInvalidArgumentReturn(Dart_NativeArguments arguments) {
92 Dart_SetIntegerReturnValue(
93 arguments, static_cast<int64_t>(MOJO_RESULT_INVALID_ARGUMENT));
94 }
95
96 static Dart_Handle SignalsStateToDart(const MojoHandleSignalsState& state) {
97 Dart_Handle list = Dart_NewList(2);
98 Dart_Handle arg0 = Dart_NewInteger(state.satisfied_signals);
99 Dart_Handle arg1 = Dart_NewInteger(state.satisfiable_signals);
100 Dart_ListSetAt(list, 0, arg0);
101 Dart_ListSetAt(list, 1, arg1);
102 return list;
103 }
104
105 #define CHECK_INTEGER_ARGUMENT(args, num, result, failure) \
106 { \
107 Dart_Handle __status; \
108 __status = Dart_GetNativeIntegerArgument(args, num, result); \
109 if (Dart_IsError(__status)) { \
110 Set##failure##Return(arguments); \
111 return; \
112 } \
113 } \
114
115 struct CloserCallbackPeer {
116 MojoHandle handle;
117 };
118
119 static void MojoHandleCloserCallback(void* isolate_data,
120 Dart_WeakPersistentHandle handle,
121 void* peer) {
122 CloserCallbackPeer* callback_peer =
123 reinterpret_cast<CloserCallbackPeer*>(peer);
124 if (callback_peer->handle != MOJO_HANDLE_INVALID) {
125 MojoResult res = MojoClose(callback_peer->handle);
126 if (res == MOJO_RESULT_OK) {
127 // If this finalizer callback successfully closes a handle, it means that
128 // the handle has leaked from the Dart code, which is an error.
129 MOJO_LOG(ERROR) << "Handle Finalizer closing handle:\n\tisolate: "
130 << "\n\thandle: " << callback_peer->handle;
131 }
132 }
133 delete callback_peer;
134 }
135
136 // Setup a weak persistent handle for a MojoHandle that calls MojoClose on the
137 // handle when the MojoHandle is GC'd or the VM is going down.
138 void MojoHandle_RegisterFinalizer(Dart_NativeArguments arguments) {
139 Dart_Handle mojo_handle_instance = Dart_GetNativeArgument(arguments, 0);
140 if (!Dart_IsInstance(mojo_handle_instance)) {
141 SetInvalidArgumentReturn(arguments);
142 return;
143 }
144
145 int64_t raw_handle = static_cast<int64_t>(MOJO_HANDLE_INVALID);
146 CHECK_INTEGER_ARGUMENT(arguments, 1, &raw_handle, InvalidArgument);
147 if (raw_handle == static_cast<int64_t>(MOJO_HANDLE_INVALID)) {
148 SetInvalidArgumentReturn(arguments);
149 return;
150 }
151
152 // Add the handle to this isolate's set.
153 MojoHandle handle = static_cast<MojoHandle>(raw_handle);
154
155 // Set up a finalizer.
156 CloserCallbackPeer* callback_peer = new CloserCallbackPeer();
157 callback_peer->handle = handle;
158 Dart_NewWeakPersistentHandle(mojo_handle_instance,
159 reinterpret_cast<void*>(callback_peer),
160 sizeof(CloserCallbackPeer),
161 MojoHandleCloserCallback);
162 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
163 }
164
165 void Mojo_GetTimeTicksNow(Dart_NativeArguments arguments) {
166 MojoTimeTicks ticks = MojoGetTimeTicksNow();
167 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(ticks));
168 }
169
170 void MojoHandle_Close(Dart_NativeArguments arguments) {
171 int64_t raw_handle;
172 CHECK_INTEGER_ARGUMENT(arguments, 0, &raw_handle, InvalidArgument);
173
174 // Remove the handle from this isolate's set.
175 MojoHandle handle = static_cast<MojoHandle>(raw_handle);
176 MojoResult res = MojoClose(handle);
177
178 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
179 }
180
181 void MojoHandle_Wait(Dart_NativeArguments arguments) {
182 int64_t handle = 0;
183 int64_t signals = 0;
184 int64_t deadline = 0;
185 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
186 CHECK_INTEGER_ARGUMENT(arguments, 1, &signals, InvalidArgument);
187 CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);
188
189 MojoHandleSignalsState state;
190 MojoResult r = mojo::Wait(mojo::Handle(static_cast<MojoHandle>(handle)),
191 static_cast<MojoHandleSignals>(signals),
192 static_cast<MojoDeadline>(deadline), &state);
193
194 // The return value is structured as a list of length 2:
195 // [0] MojoResult
196 // [1] MojoHandleSignalsState. (may be null)
197 Dart_Handle list = Dart_NewList(2);
198 Dart_ListSetAt(list, 0, Dart_NewInteger(r));
199 if (mojo::WaitManyResult(r).AreSignalsStatesValid()) {
200 Dart_ListSetAt(list, 1, SignalsStateToDart(state));
201 } else {
202 Dart_ListSetAt(list, 1, Dart_Null());
203 }
204 Dart_SetReturnValue(arguments, list);
205 }
206
207 void MojoHandle_WaitMany(Dart_NativeArguments arguments) {
208 int64_t deadline = 0;
209 Dart_Handle handles = Dart_GetNativeArgument(arguments, 0);
210 Dart_Handle signals = Dart_GetNativeArgument(arguments, 1);
211 CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);
212
213 if (!Dart_IsList(handles) || !Dart_IsList(signals)) {
214 SetInvalidArgumentReturn(arguments);
215 return;
216 }
217
218 intptr_t handles_len = 0;
219 intptr_t signals_len = 0;
220 Dart_ListLength(handles, &handles_len);
221 Dart_ListLength(signals, &signals_len);
222 if (handles_len != signals_len) {
223 SetInvalidArgumentReturn(arguments);
224 return;
225 }
226
227 std::vector<mojo::Handle> mojo_handles(handles_len);
228 std::vector<MojoHandleSignals> mojo_signals(handles_len);
229
230 for (int i = 0; i < handles_len; i++) {
231 Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
232 Dart_Handle dart_signal = Dart_ListGetAt(signals, i);
233 if (!Dart_IsInteger(dart_handle) || !Dart_IsInteger(dart_signal)) {
234 SetInvalidArgumentReturn(arguments);
235 return;
236 }
237 int64_t mojo_handle = 0;
238 int64_t mojo_signal = 0;
239 Dart_IntegerToInt64(dart_handle, &mojo_handle);
240 Dart_IntegerToInt64(dart_signal, &mojo_signal);
241 mojo_handles[i] = mojo::Handle(mojo_handle);
242 mojo_signals[i] = static_cast<MojoHandleSignals>(mojo_signal);
243 }
244
245 std::vector<MojoHandleSignalsState> states(handles_len);
246 mojo::WaitManyResult wmr = mojo::WaitMany(
247 mojo_handles, mojo_signals, static_cast<MojoDeadline>(deadline), &states);
248
249 // The return value is structured as a list of length 3:
250 // [0] MojoResult
251 // [1] index of handle that caused a return (may be null)
252 // [2] list of MojoHandleSignalsState. (may be null)
253 Dart_Handle list = Dart_NewList(3);
254 Dart_ListSetAt(list, 0, Dart_NewInteger(wmr.result));
255 if (wmr.IsIndexValid())
256 Dart_ListSetAt(list, 1, Dart_NewInteger(wmr.index));
257 else
258 Dart_ListSetAt(list, 1, Dart_Null());
259 if (wmr.AreSignalsStatesValid()) {
260 Dart_Handle stateList = Dart_NewList(handles_len);
261 for (int i = 0; i < handles_len; i++) {
262 Dart_ListSetAt(stateList, i, SignalsStateToDart(states[i]));
263 }
264 Dart_ListSetAt(list, 2, stateList);
265 } else {
266 Dart_ListSetAt(list, 2, Dart_Null());
267 }
268 Dart_SetReturnValue(arguments, list);
269 }
270
271 void MojoSharedBuffer_Create(Dart_NativeArguments arguments) {
272 int64_t num_bytes = 0;
273 int64_t flags = 0;
274 CHECK_INTEGER_ARGUMENT(arguments, 0, &num_bytes, Null);
275 CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
276
277 MojoCreateSharedBufferOptions options;
278 options.struct_size = sizeof(MojoCreateSharedBufferOptions);
279 options.flags = static_cast<MojoCreateSharedBufferOptionsFlags>(flags);
280
281 MojoHandle out = MOJO_HANDLE_INVALID;;
282 MojoResult res = MojoCreateSharedBuffer(
283 &options, static_cast<int32_t>(num_bytes), &out);
284
285 Dart_Handle list = Dart_NewList(2);
286 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
287 Dart_ListSetAt(list, 1, Dart_NewInteger(out));
288 Dart_SetReturnValue(arguments, list);
289 }
290
291 void MojoSharedBuffer_Duplicate(Dart_NativeArguments arguments) {
292 int64_t handle = 0;
293 int64_t flags = 0;
294 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
295 CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
296
297 MojoDuplicateBufferHandleOptions options;
298 options.struct_size = sizeof(MojoDuplicateBufferHandleOptions);
299 options.flags = static_cast<MojoDuplicateBufferHandleOptionsFlags>(flags);
300
301 MojoHandle out = MOJO_HANDLE_INVALID;;
302 MojoResult res = MojoDuplicateBufferHandle(
303 static_cast<MojoHandle>(handle), &options, &out);
304
305 Dart_Handle list = Dart_NewList(2);
306 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
307 Dart_ListSetAt(list, 1, Dart_NewInteger(out));
308 Dart_SetReturnValue(arguments, list);
309 }
310
311 static void MojoBufferUnmapCallback(void* isolate_data,
312 Dart_WeakPersistentHandle handle,
313 void* peer) {
314 MojoUnmapBuffer(peer);
315 }
316
317 void MojoSharedBuffer_Map(Dart_NativeArguments arguments) {
318 int64_t handle = 0;
319 int64_t offset = 0;
320 int64_t num_bytes = 0;
321 int64_t flags = 0;
322 Dart_Handle mojo_buffer = Dart_GetNativeArgument(arguments, 0);
323 CHECK_INTEGER_ARGUMENT(arguments, 1, &handle, Null);
324 CHECK_INTEGER_ARGUMENT(arguments, 2, &offset, Null);
325 CHECK_INTEGER_ARGUMENT(arguments, 3, &num_bytes, Null);
326 CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);
327
328 void* out;
329 MojoResult res = MojoMapBuffer(static_cast<MojoHandle>(handle),
330 offset,
331 num_bytes,
332 &out,
333 static_cast<MojoMapBufferFlags>(flags));
334
335 Dart_Handle list = Dart_NewList(2);
336 Dart_Handle typed_data;
337 if (res == MOJO_RESULT_OK) {
338 typed_data = Dart_NewExternalTypedData(
339 Dart_TypedData_kByteData, out, num_bytes);
340 Dart_NewWeakPersistentHandle(
341 mojo_buffer, out, num_bytes, MojoBufferUnmapCallback);
342 } else {
343 typed_data = Dart_Null();
344 }
345 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
346 Dart_ListSetAt(list, 1, typed_data);
347 Dart_SetReturnValue(arguments, list);
348 }
349
350 void MojoSharedBuffer_Unmap(Dart_NativeArguments arguments) {
351 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 0);
352 if (Dart_GetTypeOfExternalTypedData(typed_data) == Dart_TypedData_kInvalid) {
353 SetInvalidArgumentReturn(arguments);
354 return;
355 }
356
357 Dart_TypedData_Type typ;
358 void *data;
359 intptr_t len;
360 Dart_TypedDataAcquireData(typed_data, &typ, &data, &len);
361 MojoResult res = MojoUnmapBuffer(data);
362 Dart_TypedDataReleaseData(typed_data);
363
364 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
365 }
366
367 void MojoDataPipe_Create(Dart_NativeArguments arguments) {
368 int64_t element_bytes = 0;
369 int64_t capacity_bytes = 0;
370 int64_t flags = 0;
371 CHECK_INTEGER_ARGUMENT(arguments, 0, &element_bytes, Null);
372 CHECK_INTEGER_ARGUMENT(arguments, 1, &capacity_bytes, Null);
373 CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
374
375 MojoCreateDataPipeOptions options;
376 options.struct_size = sizeof(MojoCreateDataPipeOptions);
377 options.flags = static_cast<MojoCreateDataPipeOptionsFlags>(flags);
378 options.element_num_bytes = static_cast<uint32_t>(element_bytes);
379 options.capacity_num_bytes = static_cast<uint32_t>(capacity_bytes);
380
381 MojoHandle producer = MOJO_HANDLE_INVALID;
382 MojoHandle consumer = MOJO_HANDLE_INVALID;
383 MojoResult res = MojoCreateDataPipe(&options, &producer, &consumer);
384
385 Dart_Handle list = Dart_NewList(3);
386 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
387 Dart_ListSetAt(list, 1, Dart_NewInteger(producer));
388 Dart_ListSetAt(list, 2, Dart_NewInteger(consumer));
389 Dart_SetReturnValue(arguments, list);
390 }
391
392 void MojoDataPipe_WriteData(Dart_NativeArguments arguments) {
393 int64_t handle = 0;
394 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
395
396 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
397 if (!Dart_IsTypedData(typed_data)) {
398 SetNullReturn(arguments);
399 return;
400 }
401
402 int64_t num_bytes = 0;
403 CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
404 if (num_bytes <= 0) {
405 SetNullReturn(arguments);
406 return;
407 }
408
409 int64_t flags = 0;
410 CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
411
412 Dart_TypedData_Type type;
413 void* data;
414 intptr_t data_length;
415 Dart_TypedDataAcquireData(typed_data, &type, &data, &data_length);
416 uint32_t length = static_cast<uint32_t>(num_bytes);
417 MojoResult res = MojoWriteData(
418 static_cast<MojoHandle>(handle),
419 data,
420 &length,
421 static_cast<MojoWriteDataFlags>(flags));
422 Dart_TypedDataReleaseData(typed_data);
423
424 Dart_Handle list = Dart_NewList(2);
425 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
426 Dart_ListSetAt(list, 1, Dart_NewInteger(length));
427 Dart_SetReturnValue(arguments, list);
428 }
429
430 void MojoDataPipe_BeginWriteData(Dart_NativeArguments arguments) {
431 int64_t handle = 0;
432 int64_t buffer_bytes = 0;
433 int64_t flags = 0;
434 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
435 CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
436 CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
437
438 void* buffer;
439 uint32_t size = static_cast<uint32_t>(buffer_bytes);
440 MojoResult res = MojoBeginWriteData(
441 static_cast<MojoHandle>(handle),
442 &buffer,
443 &size,
444 static_cast<MojoWriteDataFlags>(flags));
445
446 Dart_Handle list = Dart_NewList(2);
447 Dart_Handle typed_data;
448 if (res == MOJO_RESULT_OK) {
449 typed_data = Dart_NewExternalTypedData(
450 Dart_TypedData_kByteData, buffer, size);
451 } else {
452 typed_data = Dart_Null();
453 }
454 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
455 Dart_ListSetAt(list, 1, typed_data);
456 Dart_SetReturnValue(arguments, list);
457 }
458
459 void MojoDataPipe_EndWriteData(Dart_NativeArguments arguments) {
460 int64_t handle = 0;
461 int64_t num_bytes_written = 0;
462 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
463 CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_written, InvalidArgument);
464
465 MojoResult res = MojoEndWriteData(
466 static_cast<MojoHandle>(handle),
467 static_cast<uint32_t>(num_bytes_written));
468
469 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
470 }
471
472 void MojoDataPipe_ReadData(Dart_NativeArguments arguments) {
473 int64_t handle = 0;
474 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
475
476 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
477 if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
478 SetNullReturn(arguments);
479 return;
480 }
481 // When querying the amount of data available to read from the pipe,
482 // null is passed in for typed_data.
483
484 int64_t num_bytes = 0;
485 CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
486
487 int64_t flags = 0;
488 CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
489
490 Dart_TypedData_Type typ;
491 void* data = nullptr;
492 intptr_t bdlen = 0;
493 if (!Dart_IsNull(typed_data)) {
494 Dart_TypedDataAcquireData(typed_data, &typ, &data, &bdlen);
495 }
496 uint32_t len = static_cast<uint32_t>(num_bytes);
497 MojoResult res = MojoReadData(
498 static_cast<MojoHandle>(handle),
499 data,
500 &len,
501 static_cast<MojoReadDataFlags>(flags));
502 if (!Dart_IsNull(typed_data)) {
503 Dart_TypedDataReleaseData(typed_data);
504 }
505
506 Dart_Handle list = Dart_NewList(2);
507 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
508 Dart_ListSetAt(list, 1, Dart_NewInteger(len));
509 Dart_SetReturnValue(arguments, list);
510 }
511
512 void MojoDataPipe_BeginReadData(Dart_NativeArguments arguments) {
513 int64_t handle = 0;
514 int64_t buffer_bytes = 0;
515 int64_t flags = 0;
516 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
517 CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
518 CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
519
520 void* buffer;
521 uint32_t size = static_cast<uint32_t>(buffer_bytes);
522 MojoResult res = MojoBeginReadData(
523 static_cast<MojoHandle>(handle),
524 const_cast<const void**>(&buffer),
525 &size,
526 static_cast<MojoWriteDataFlags>(flags));
527
528 Dart_Handle list = Dart_NewList(2);
529 Dart_Handle typed_data;
530 if (res == MOJO_RESULT_OK) {
531 typed_data = Dart_NewExternalTypedData(
532 Dart_TypedData_kByteData, buffer, size);
533 } else {
534 typed_data = Dart_Null();
535 }
536 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
537 Dart_ListSetAt(list, 1, typed_data);
538 Dart_SetReturnValue(arguments, list);
539 }
540
541 void MojoDataPipe_EndReadData(Dart_NativeArguments arguments) {
542 int64_t handle = 0;
543 int64_t num_bytes_read = 0;
544 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
545 CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_read, InvalidArgument);
546
547 MojoResult res = MojoEndReadData(
548 static_cast<MojoHandle>(handle),
549 static_cast<uint32_t>(num_bytes_read));
550
551 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
552 }
553
554 void MojoMessagePipe_Create(Dart_NativeArguments arguments) {
555 int64_t flags = 0;
556 CHECK_INTEGER_ARGUMENT(arguments, 0, &flags, Null);
557
558 MojoCreateMessagePipeOptions options;
559 options.struct_size = sizeof(MojoCreateMessagePipeOptions);
560 options.flags = static_cast<MojoCreateMessagePipeOptionsFlags>(flags);
561
562 MojoHandle end1 = MOJO_HANDLE_INVALID;
563 MojoHandle end2 = MOJO_HANDLE_INVALID;
564 MojoResult res = MojoCreateMessagePipe(&options, &end1, &end2);
565
566 Dart_Handle list = Dart_NewList(3);
567 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
568 Dart_ListSetAt(list, 1, Dart_NewInteger(end1));
569 Dart_ListSetAt(list, 2, Dart_NewInteger(end2));
570 Dart_SetReturnValue(arguments, list);
571 }
572
573 void MojoMessagePipe_Write(Dart_NativeArguments arguments) {
574 int64_t handle = 0;
575 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
576
577 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
578 if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
579 SetInvalidArgumentReturn(arguments);
580 return;
581 }
582
583 int64_t num_bytes = 0;
584 CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, InvalidArgument);
585 if ((Dart_IsNull(typed_data) && (num_bytes != 0)) ||
586 (!Dart_IsNull(typed_data) && (num_bytes <= 0))) {
587 SetInvalidArgumentReturn(arguments);
588 return;
589 }
590
591 Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
592 if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
593 SetInvalidArgumentReturn(arguments);
594 return;
595 }
596
597 int64_t flags = 0;
598 CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, InvalidArgument);
599
600 // Grab the data if there is any.
601 Dart_TypedData_Type typ;
602 void* bytes = nullptr;
603 intptr_t bdlen = 0;
604 if (!Dart_IsNull(typed_data)) {
605 Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &bdlen);
606 }
607
608 // Grab the handles if there are any.
609 std::unique_ptr<MojoHandle[]> mojo_handles;
610 intptr_t handles_len = 0;
611 if (!Dart_IsNull(handles)) {
612 Dart_ListLength(handles, &handles_len);
613 if (handles_len > 0) {
614 mojo_handles.reset(new MojoHandle[handles_len]);
615 }
616 for (int i = 0; i < handles_len; i++) {
617 Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
618 if (!Dart_IsInteger(dart_handle)) {
619 SetInvalidArgumentReturn(arguments);
620 return;
621 }
622 int64_t mojo_handle = 0;
623 Dart_IntegerToInt64(dart_handle, &mojo_handle);
624 mojo_handles[i] = static_cast<MojoHandle>(mojo_handle);
625 }
626 }
627
628 MojoResult res = MojoWriteMessage(
629 static_cast<MojoHandle>(handle),
630 const_cast<const void*>(bytes),
631 static_cast<uint32_t>(num_bytes),
632 mojo_handles.get(),
633 static_cast<uint32_t>(handles_len),
634 static_cast<MojoWriteMessageFlags>(flags));
635
636 // Release the data.
637 if (!Dart_IsNull(typed_data)) {
638 Dart_TypedDataReleaseData(typed_data);
639 }
640
641 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
642 }
643
644 void MojoMessagePipe_Read(Dart_NativeArguments arguments) {
645 int64_t handle = 0;
646 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
647
648 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
649 if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
650 SetNullReturn(arguments);
651 return;
652 }
653 // When querying the amount of data available to read from the pipe,
654 // null is passed in for typed_data.
655
656 int64_t num_bytes = 0;
657 CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
658 if ((Dart_IsNull(typed_data) && (num_bytes != 0)) ||
659 (!Dart_IsNull(typed_data) && (num_bytes <= 0))) {
660 SetNullReturn(arguments);
661 return;
662 }
663
664 Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
665 if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
666 SetNullReturn(arguments);
667 return;
668 }
669
670 int64_t flags = 0;
671 CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);
672
673 // Grab the data if there is any.
674 Dart_TypedData_Type typ;
675 void* bytes = nullptr;
676 intptr_t byte_data_len = 0;
677 if (!Dart_IsNull(typed_data)) {
678 Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &byte_data_len);
679 }
680 uint32_t blen = static_cast<uint32_t>(num_bytes);
681
682 // Grab the handles if there are any.
683 std::unique_ptr<MojoHandle[]> mojo_handles;
684 intptr_t handles_len = 0;
685 if (!Dart_IsNull(handles)) {
686 Dart_ListLength(handles, &handles_len);
687 mojo_handles.reset(new MojoHandle[handles_len]);
688 }
689 uint32_t hlen = static_cast<uint32_t>(handles_len);
690
691 MojoResult res = MojoReadMessage(
692 static_cast<MojoHandle>(handle),
693 bytes,
694 &blen,
695 mojo_handles.get(),
696 &hlen,
697 static_cast<MojoReadMessageFlags>(flags));
698
699 // Release the data.
700 if (!Dart_IsNull(typed_data)) {
701 Dart_TypedDataReleaseData(typed_data);
702 }
703
704 if (!Dart_IsNull(handles)) {
705 for (int i = 0; i < handles_len; i++) {
706 Dart_ListSetAt(handles, i, Dart_NewInteger(mojo_handles[i]));
707 }
708 }
709
710 Dart_Handle list = Dart_NewList(3);
711 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
712 Dart_ListSetAt(list, 1, Dart_NewInteger(blen));
713 Dart_ListSetAt(list, 2, Dart_NewInteger(hlen));
714 Dart_SetReturnValue(arguments, list);
715 }
716
717 struct MojoWaitManyState {
718 MojoWaitManyState() {}
719
720 std::vector<uint32_t> handles;
721 std::vector<uint32_t> signals;
722 std::vector<uint32_t> out_index;
723 std::vector<MojoHandleSignalsState> out_signals;
724
725 static MojoWaitManyState* GetInstance();
726
727 private:
728 MOJO_DISALLOW_COPY_AND_ASSIGN(MojoWaitManyState);
729 };
730
731 // This global is safe because it is only accessed by the single handle watcher
732 // isolate. If multiple handle watcher isolates are ever needed, it will need
733 // to be replicated.
734 MojoWaitManyState* MojoWaitManyState::GetInstance() {
735 static MojoWaitManyState* state = new MojoWaitManyState;
736 return state;
737 }
738
739 void MojoHandleWatcher_GrowStateArrays(Dart_NativeArguments arguments) {
740 int64_t new_length;
741 CHECK_INTEGER_ARGUMENT(arguments, 0, &new_length, InvalidArgument);
742
743 MojoWaitManyState& handle_watcher_wait_state =
744 *MojoWaitManyState::GetInstance();
745
746 handle_watcher_wait_state.handles.resize(new_length);
747 handle_watcher_wait_state.signals.resize(new_length);
748 handle_watcher_wait_state.out_index.resize(1);
749 handle_watcher_wait_state.out_signals.resize(new_length);
750
751 Dart_Handle dart_handles = Dart_NewExternalTypedData(
752 Dart_TypedData_kUint32, handle_watcher_wait_state.handles.data(),
753 handle_watcher_wait_state.handles.size());
754 if (Dart_IsError(dart_handles)) {
755 Dart_PropagateError(dart_handles);
756 }
757 if (Dart_IsNull(dart_handles)) {
758 SetNullReturn(arguments);
759 return;
760 }
761
762 Dart_Handle dart_signals = Dart_NewExternalTypedData(
763 Dart_TypedData_kUint32, handle_watcher_wait_state.signals.data(),
764 handle_watcher_wait_state.signals.size());
765 if (Dart_IsError(dart_signals)) {
766 Dart_PropagateError(dart_signals);
767 }
768 if (Dart_IsNull(dart_signals)) {
769 SetNullReturn(arguments);
770 return;
771 }
772
773 Dart_Handle dart_out_index = Dart_NewExternalTypedData(
774 Dart_TypedData_kUint32, handle_watcher_wait_state.out_index.data(),
775 handle_watcher_wait_state.out_index.size());
776 if (Dart_IsError(dart_out_index)) {
777 Dart_PropagateError(dart_out_index);
778 }
779 if (Dart_IsNull(dart_out_index)) {
780 SetNullReturn(arguments);
781 return;
782 }
783
784 Dart_Handle dart_out_signals = Dart_NewExternalTypedData(
785 Dart_TypedData_kUint64, handle_watcher_wait_state.out_signals.data(),
786 handle_watcher_wait_state.out_signals.size());
787 if (Dart_IsError(dart_out_signals)) {
788 Dart_PropagateError(dart_out_signals);
789 }
790 if (Dart_IsNull(dart_out_signals)) {
791 SetNullReturn(arguments);
792 return;
793 }
794
795 Dart_Handle list = Dart_NewList(4);
796 Dart_ListSetAt(list, 0, dart_handles);
797 Dart_ListSetAt(list, 1, dart_signals);
798 Dart_ListSetAt(list, 2, dart_out_index);
799 Dart_ListSetAt(list, 3, dart_out_signals);
800 Dart_SetReturnValue(arguments, list);
801 }
802
803 void MojoHandleWatcher_WaitMany(Dart_NativeArguments arguments) {
804 int64_t handles_len = 0;
805 int64_t deadline = 0;
806 CHECK_INTEGER_ARGUMENT(arguments, 0, &handles_len, InvalidArgument);
807 CHECK_INTEGER_ARGUMENT(arguments, 1, &deadline, InvalidArgument);
808
809 MojoWaitManyState& handle_watcher_wait_state =
810 *MojoWaitManyState::GetInstance();
811
812 uint32_t* handles = handle_watcher_wait_state.handles.data();
813 uint32_t* signals = handle_watcher_wait_state.signals.data();
814 uint32_t* out_index = handle_watcher_wait_state.out_index.data();
815 MojoHandleSignalsState* out_signals =
816 handle_watcher_wait_state.out_signals.data();
817
818 Dart_IsolateBlocked();
819 MojoResult mojo_result = MojoWaitMany(handles, signals, handles_len, deadline,
820 out_index, out_signals);
821 Dart_IsolateUnblocked();
822
823 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(mojo_result));
824 }
825
826 struct ControlData {
827 int64_t handle;
828 Dart_Port port;
829 int64_t data;
830 };
831
832 void MojoHandleWatcher_SendControlData(Dart_NativeArguments arguments) {
833 int64_t control_handle = 0;
834 int64_t client_handle = 0;
835 CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
836 CHECK_INTEGER_ARGUMENT(arguments, 1, &client_handle, InvalidArgument);
837
838 Dart_Handle send_port_handle = Dart_GetNativeArgument(arguments, 2);
839 Dart_Port send_port_id = ILLEGAL_PORT;
840 if (!Dart_IsNull(send_port_handle)) {
841 Dart_Handle result = Dart_SendPortGetId(send_port_handle, &send_port_id);
842 if (Dart_IsError(result)) {
843 SetInvalidArgumentReturn(arguments);
844 return;
845 }
846 }
847
848 int64_t data = 0;
849 CHECK_INTEGER_ARGUMENT(arguments, 3, &data, InvalidArgument);
850
851 ControlData cd;
852 cd.handle = client_handle;
853 cd.port = send_port_id;
854 cd.data = data;
855 const void* bytes = reinterpret_cast<const void*>(&cd);
856 MojoResult res = MojoWriteMessage(
857 control_handle, bytes, sizeof(cd), nullptr, 0, 0);
858 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
859 }
860
861 void MojoHandleWatcher_RecvControlData(Dart_NativeArguments arguments) {
862 int64_t control_handle = 0;
863 CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, Null);
864
865 ControlData cd;
866 void* bytes = reinterpret_cast<void*>(&cd);
867 uint32_t num_bytes = sizeof(cd);
868 uint32_t num_handles = 0;
869 MojoResult res = MojoReadMessage(
870 control_handle, bytes, &num_bytes, nullptr, &num_handles, 0);
871 if (res != MOJO_RESULT_OK) {
872 SetNullReturn(arguments);
873 return;
874 }
875
876 Dart_Handle list = Dart_NewList(3);
877 Dart_ListSetAt(list, 0, Dart_NewInteger(cd.handle));
878 if (cd.port != ILLEGAL_PORT) {
879 Dart_ListSetAt(list, 1, Dart_NewSendPort(cd.port));
880 }
881 Dart_ListSetAt(list, 2, Dart_NewInteger(cd.data));
882 Dart_SetReturnValue(arguments, list);
883 }
884
885 static int64_t mojo_control_handle = MOJO_HANDLE_INVALID;
886 void MojoHandleWatcher_SetControlHandle(Dart_NativeArguments arguments) {
887 int64_t control_handle;
888 CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
889 mojo_control_handle = control_handle;
890 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
891 }
892
893 void MojoHandleWatcher_GetControlHandle(Dart_NativeArguments arguments) {
894 Dart_SetIntegerReturnValue(arguments, mojo_control_handle);
895 }
896
897 } // namespace dart
898 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698