Flutter Engine
system.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 "system.h"
6 
7 #include <array>
8 
9 #include <fcntl.h>
10 #include <lib/fdio/directory.h>
11 #include <lib/fdio/io.h>
12 #include <lib/fdio/limits.h>
13 #include <lib/fdio/namespace.h>
14 #include <lib/zx/channel.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17 #include <zircon/process.h>
18 #include <zircon/processargs.h>
19 
20 #include "flutter/fml/unique_fd.h"
23 
24 using tonic::ToDart;
25 
26 namespace zircon {
27 namespace dart {
28 
29 namespace {
30 
31 constexpr char kGetSizeResult[] = "GetSizeResult";
32 constexpr char kHandlePairResult[] = "HandlePairResult";
33 constexpr char kHandleResult[] = "HandleResult";
34 constexpr char kReadResult[] = "ReadResult";
35 constexpr char kHandleInfo[] = "HandleInfo";
36 constexpr char kReadEtcResult[] = "ReadEtcResult";
37 constexpr char kWriteResult[] = "WriteResult";
38 constexpr char kFromFileResult[] = "FromFileResult";
39 constexpr char kMapResult[] = "MapResult";
40 
41 class ByteDataScope {
42  public:
43  explicit ByteDataScope(Dart_Handle dart_handle) : dart_handle_(dart_handle) {
44  Acquire();
45  }
46 
47  explicit ByteDataScope(size_t size) {
48  dart_handle_ = Dart_NewTypedData(Dart_TypedData_kByteData, size);
49  FML_DCHECK(!tonic::LogIfError(dart_handle_));
50  Acquire();
51  FML_DCHECK(size == size_);
52  }
53 
54  ~ByteDataScope() {
55  if (is_valid_) {
56  Release();
57  }
58  }
59 
60  void* data() const { return data_; }
61  size_t size() const { return size_; }
62  Dart_Handle dart_handle() const { return dart_handle_; }
63  bool is_valid() const { return is_valid_; }
64 
65  void Release() {
66  FML_DCHECK(is_valid_);
67  Dart_Handle result = Dart_TypedDataReleaseData(dart_handle_);
68  tonic::LogIfError(result);
69  is_valid_ = false;
70  data_ = nullptr;
71  size_ = 0;
72  }
73 
74  private:
75  void Acquire() {
76  FML_DCHECK(size_ == 0);
77  FML_DCHECK(data_ == nullptr);
78  FML_DCHECK(!is_valid_);
79 
80  Dart_TypedData_Type type;
81  intptr_t size;
82  Dart_Handle result =
83  Dart_TypedDataAcquireData(dart_handle_, &type, &data_, &size);
84  is_valid_ =
85  !tonic::LogIfError(result) && type == Dart_TypedData_kByteData && data_;
86  if (is_valid_) {
87  size_ = size;
88  } else {
89  size_ = 0;
90  }
91  }
92 
93  Dart_Handle dart_handle_;
94  bool is_valid_ = false;
95  size_t size_ = 0;
96  void* data_ = nullptr;
97 };
98 
99 Dart_Handle MakeHandleList(const std::vector<zx_handle_t>& in_handles) {
100  tonic::DartClassLibrary& class_library =
102  Dart_Handle handle_type = class_library.GetClass("zircon", "Handle");
103  Dart_Handle list = Dart_NewListOfTypeFilled(
104  handle_type, Handle::CreateInvalid(), in_handles.size());
105  if (Dart_IsError(list))
106  return list;
107  for (size_t i = 0; i < in_handles.size(); i++) {
108  Dart_Handle result =
109  Dart_ListSetAt(list, i, ToDart(Handle::Create(in_handles[i])));
110  if (Dart_IsError(result))
111  return result;
112  }
113  return list;
114 }
115 
116 template <class... Args>
117 Dart_Handle ConstructDartObject(const char* class_name, Args&&... args) {
118  tonic::DartClassLibrary& class_library =
120  Dart_Handle type =
121  Dart_HandleFromPersistent(class_library.GetClass("zircon", class_name));
123 
124  const char* cstr;
125  Dart_StringToCString(Dart_ToString(type), &cstr);
126 
127  std::array<Dart_Handle, sizeof...(Args)> args_array{
128  {std::forward<Args>(args)...}};
129  Dart_Handle object =
130  Dart_New(type, Dart_EmptyString(), sizeof...(Args), args_array.data());
131  FML_DCHECK(!tonic::LogIfError(object));
132  return object;
133 }
134 
135 Dart_Handle MakeHandleInfoList(
136  const std::vector<zx_handle_info_t>& in_handles) {
137  tonic::DartClassLibrary& class_library =
139  Dart_Handle handle_info_type = class_library.GetClass("zircon", kHandleInfo);
140  Dart_Handle empty_handle_info = ConstructDartObject(
141  kHandleInfo, ToDart(Handle::CreateInvalid()), ToDart(-1), ToDart(-1));
142  Dart_Handle list = Dart_NewListOfTypeFilled(
143  handle_info_type, empty_handle_info, in_handles.size());
144  if (Dart_IsError(list))
145  return list;
146  for (size_t i = 0; i < in_handles.size(); i++) {
147  Dart_Handle handle = ToDart(Handle::Create(in_handles[i].handle));
148  Dart_Handle result = Dart_ListSetAt(
149  list, i,
150  ConstructDartObject(kHandleInfo, handle, ToDart(in_handles[i].type),
151  ToDart(in_handles[i].rights)));
152  if (Dart_IsError(result))
153  return result;
154  }
155  return list;
156 }
157 
158 fdio_ns_t* GetNamespace() {
159  // Grab the fdio_ns_t* out of the isolate.
160  Dart_Handle zircon_lib = Dart_LookupLibrary(ToDart("dart:zircon"));
161  FML_DCHECK(!tonic::LogIfError(zircon_lib));
162  Dart_Handle namespace_type =
163  Dart_GetType(zircon_lib, ToDart("_Namespace"), 0, nullptr);
164  FML_DCHECK(!tonic::LogIfError(namespace_type));
165  Dart_Handle namespace_field =
166  Dart_GetField(namespace_type, ToDart("_namespace"));
167  FML_DCHECK(!tonic::LogIfError(namespace_field));
168  uint64_t fdio_ns_ptr;
169  Dart_Handle result = Dart_IntegerToUint64(namespace_field, &fdio_ns_ptr);
170  FML_DCHECK(!tonic::LogIfError(result));
171 
172  return reinterpret_cast<fdio_ns_t*>(fdio_ns_ptr);
173 }
174 
175 fml::UniqueFD FdFromPath(std::string path) {
176  // Get a VMO for the file.
177  fdio_ns_t* ns = reinterpret_cast<fdio_ns_t*>(GetNamespace());
178  fml::UniqueFD dirfd(fdio_ns_opendir(ns));
179  if (!dirfd.is_valid())
180  return fml::UniqueFD();
181 
182  const char* c_path = path.c_str();
183  if (path.length() > 0 && c_path[0] == '/')
184  c_path = &c_path[1];
185  return fml::UniqueFD(openat(dirfd.get(), c_path, O_RDONLY));
186 }
187 
188 } // namespace
189 
191 
192 Dart_Handle System::ChannelCreate(uint32_t options) {
193  zx_handle_t out0 = 0, out1 = 0;
194  zx_status_t status = zx_channel_create(options, &out0, &out1);
195  if (status != ZX_OK) {
196  return ConstructDartObject(kHandlePairResult, ToDart(status));
197  } else {
198  return ConstructDartObject(kHandlePairResult, ToDart(status),
199  ToDart(Handle::Create(out0)),
200  ToDart(Handle::Create(out1)));
201  }
202 }
203 
204 zx_status_t System::ConnectToService(std::string path,
205  fml::RefPtr<Handle> channel) {
206  return fdio_ns_connect(GetNamespace(), path.c_str(),
208  channel->ReleaseHandle());
209 }
210 
211 zx::channel System::CloneChannelFromFileDescriptor(int fd) {
212  zx::handle handle;
213  zx_status_t status = fdio_fd_clone(fd, handle.reset_and_get_address());
214  if (status != ZX_OK)
215  return zx::channel();
216 
217  zx_info_handle_basic_t info = {};
218  status =
219  handle.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), NULL, NULL);
220 
221  if (status != ZX_OK || info.type != ZX_OBJ_TYPE_CHANNEL)
222  return zx::channel();
223 
224  return zx::channel(handle.release());
225 }
226 
227 Dart_Handle System::ChannelFromFile(std::string path) {
228  fml::UniqueFD fd = FdFromPath(path);
229  if (!fd.is_valid()) {
230  return ConstructDartObject(kHandleResult, ToDart(ZX_ERR_IO));
231  }
232 
233  // Get channel from fd.
234  zx::channel channel = CloneChannelFromFileDescriptor(fd.get());
235  if (!channel) {
236  return ConstructDartObject(kHandleResult, ToDart(ZX_ERR_IO));
237  }
238 
239  return ConstructDartObject(kHandleResult, ToDart(ZX_OK),
240  ToDart(Handle::Create(channel.release())));
241 }
242 
244  const tonic::DartByteData& data,
245  std::vector<Handle*> handles) {
246  if (!channel || !channel->is_valid()) {
247  data.Release();
248  return ZX_ERR_BAD_HANDLE;
249  }
250 
251  std::vector<zx_handle_t> zx_handles;
252  for (Handle* handle : handles) {
253  zx_handles.push_back(handle->handle());
254  }
255 
256  zx_status_t status = zx_channel_write(channel->handle(), 0, data.data(),
257  data.length_in_bytes(),
258  zx_handles.data(), zx_handles.size());
259  // Handles are always consumed.
260  for (Handle* handle : handles) {
261  handle->ReleaseHandle();
262  }
263 
264  data.Release();
265  return status;
266 }
267 
269  fml::RefPtr<Handle> channel,
270  const tonic::DartByteData& data,
271  std::vector<HandleDisposition*> handle_dispositions) {
272  if (!channel || !channel->is_valid()) {
273  data.Release();
274  return ZX_ERR_BAD_HANDLE;
275  }
276 
277  std::vector<zx_handle_disposition_t> zx_handle_dispositions;
278  for (HandleDisposition* handle : handle_dispositions) {
279  FML_DCHECK(handle->result() == ZX_OK);
280  zx_handle_dispositions.push_back({.operation = handle->operation(),
281  .handle = handle->handle()->handle(),
282  .type = handle->type(),
283  .rights = handle->rights(),
284  .result = ZX_OK});
285  }
286 
287  zx_status_t status = zx_channel_write_etc(
288  channel->handle(), 0, data.data(), data.length_in_bytes(),
289  zx_handle_dispositions.data(), zx_handle_dispositions.size());
290 
291  for (size_t i = 0; i < handle_dispositions.size(); ++i) {
292  handle_dispositions[i]->set_result(zx_handle_dispositions[i].result);
293 
294  // Handles that are not copied (i.e. moved) are always consumed.
295  if (handle_dispositions[i]->operation() != ZX_HANDLE_OP_DUPLICATE) {
296  handle_dispositions[i]->handle()->ReleaseHandle();
297  }
298  }
299 
300  data.Release();
301  return status;
302 }
303 
305  if (!channel || !channel->is_valid()) {
306  return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
307  }
308 
309  uint32_t actual_bytes = 0;
310  uint32_t actual_handles = 0;
311 
312  // Query the size of the next message.
313  zx_status_t status = zx_channel_read(channel->handle(), 0, nullptr, nullptr,
314  0, 0, &actual_bytes, &actual_handles);
315  if (status != ZX_ERR_BUFFER_TOO_SMALL) {
316  // An empty message or an error.
317  return ConstructDartObject(kReadResult, ToDart(status));
318  }
319 
320  // Allocate space for the bytes and handles.
321  ByteDataScope bytes(actual_bytes);
322  FML_DCHECK(bytes.is_valid());
323  std::vector<zx_handle_t> handles(actual_handles);
324 
325  // Make the call to actually get the message.
326  status = zx_channel_read(channel->handle(), 0, bytes.data(), handles.data(),
327  bytes.size(), handles.size(), &actual_bytes,
328  &actual_handles);
329  FML_DCHECK(status != ZX_OK || bytes.size() == actual_bytes);
330 
331  bytes.Release();
332 
333  if (status == ZX_OK) {
334  FML_DCHECK(handles.size() == actual_handles);
335 
336  // return a ReadResult object.
337  return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
338  ToDart(actual_bytes), MakeHandleList(handles));
339  } else {
340  return ConstructDartObject(kReadResult, ToDart(status));
341  }
342 }
343 
345  if (!channel || !channel->is_valid()) {
346  return ConstructDartObject(kReadEtcResult, ToDart(ZX_ERR_BAD_HANDLE));
347  }
348 
349  uint32_t actual_bytes = 0;
350  uint32_t actual_handles = 0;
351 
352  // Query the size of the next message.
353  zx_status_t status = zx_channel_read(channel->handle(), 0, nullptr, nullptr,
354  0, 0, &actual_bytes, &actual_handles);
355  if (status != ZX_ERR_BUFFER_TOO_SMALL) {
356  // An empty message or an error.
357  return ConstructDartObject(kReadEtcResult, ToDart(status));
358  }
359 
360  // Allocate space for the bytes and handles.
361  ByteDataScope bytes(actual_bytes);
362  FML_DCHECK(bytes.is_valid());
363  std::vector<zx_handle_info_t> handles(actual_handles);
364 
365  // Make the call to actually get the message.
366  status = zx_channel_read_etc(channel->handle(), 0, bytes.data(),
367  handles.data(), bytes.size(), handles.size(),
368  &actual_bytes, &actual_handles);
369  FML_DCHECK(status != ZX_OK || bytes.size() == actual_bytes);
370 
371  bytes.Release();
372 
373  if (status == ZX_OK) {
374  FML_DCHECK(handles.size() == actual_handles);
375 
376  // return a ReadResult object.
377  return ConstructDartObject(kReadEtcResult, ToDart(status),
378  bytes.dart_handle(), ToDart(actual_bytes),
379  MakeHandleInfoList(handles));
380  } else {
381  return ConstructDartObject(kReadEtcResult, ToDart(status));
382  }
383 }
384 
385 Dart_Handle System::EventpairCreate(uint32_t options) {
386  zx_handle_t out0 = 0, out1 = 0;
387  zx_status_t status = zx_eventpair_create(0, &out0, &out1);
388  if (status != ZX_OK) {
389  return ConstructDartObject(kHandlePairResult, ToDart(status));
390  } else {
391  return ConstructDartObject(kHandlePairResult, ToDart(status),
392  ToDart(Handle::Create(out0)),
393  ToDart(Handle::Create(out1)));
394  }
395 }
396 
397 Dart_Handle System::SocketCreate(uint32_t options) {
398  zx_handle_t out0 = 0, out1 = 0;
399  zx_status_t status = zx_socket_create(options, &out0, &out1);
400  if (status != ZX_OK) {
401  return ConstructDartObject(kHandlePairResult, ToDart(status));
402  } else {
403  return ConstructDartObject(kHandlePairResult, ToDart(status),
404  ToDart(Handle::Create(out0)),
405  ToDart(Handle::Create(out1)));
406  }
407 }
408 
410  const tonic::DartByteData& data,
411  int options) {
412  if (!socket || !socket->is_valid()) {
413  data.Release();
414  return ConstructDartObject(kWriteResult, ToDart(ZX_ERR_BAD_HANDLE));
415  }
416 
417  size_t actual;
418  zx_status_t status = zx_socket_write(socket->handle(), options, data.data(),
419  data.length_in_bytes(), &actual);
420  data.Release();
421  return ConstructDartObject(kWriteResult, ToDart(status), ToDart(actual));
422 }
423 
424 Dart_Handle System::SocketRead(fml::RefPtr<Handle> socket, size_t size) {
425  if (!socket || !socket->is_valid()) {
426  return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
427  }
428 
429  ByteDataScope bytes(size);
430  size_t actual;
431  zx_status_t status =
432  zx_socket_read(socket->handle(), 0, bytes.data(), size, &actual);
433  bytes.Release();
434  if (status == ZX_OK) {
435  FML_DCHECK(actual <= size);
436  return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
437  ToDart(actual));
438  }
439 
440  return ConstructDartObject(kReadResult, ToDart(status));
441 }
442 
443 Dart_Handle System::VmoCreate(uint64_t size, uint32_t options) {
444  zx_handle_t vmo = ZX_HANDLE_INVALID;
445  zx_status_t status = zx_vmo_create(size, options, &vmo);
446  if (status != ZX_OK) {
447  return ConstructDartObject(kHandleResult, ToDart(status));
448  } else {
449  return ConstructDartObject(kHandleResult, ToDart(status),
450  ToDart(Handle::Create(vmo)));
451  }
452 }
453 
454 Dart_Handle System::VmoFromFile(std::string path) {
455  fml::UniqueFD fd = FdFromPath(path);
456  if (!fd.is_valid())
457  return ConstructDartObject(kFromFileResult, ToDart(ZX_ERR_IO));
458 
459  struct stat stat_struct;
460  if (fstat(fd.get(), &stat_struct) == -1)
461  return ConstructDartObject(kFromFileResult, ToDart(ZX_ERR_IO));
462  zx_handle_t vmo = ZX_HANDLE_INVALID;
463  zx_status_t status = fdio_get_vmo_clone(fd.get(), &vmo);
464  if (status != ZX_OK)
465  return ConstructDartObject(kFromFileResult, ToDart(status));
466 
467  return ConstructDartObject(kFromFileResult, ToDart(status),
468  ToDart(Handle::Create(vmo)),
469  ToDart(stat_struct.st_size));
470 }
471 
473  if (!vmo || !vmo->is_valid()) {
474  return ConstructDartObject(kGetSizeResult, ToDart(ZX_ERR_BAD_HANDLE));
475  }
476 
477  uint64_t size;
478  zx_status_t status = zx_vmo_get_size(vmo->handle(), &size);
479 
480  return ConstructDartObject(kGetSizeResult, ToDart(status), ToDart(size));
481 }
482 
483 zx_status_t System::VmoSetSize(fml::RefPtr<Handle> vmo, uint64_t size) {
484  if (!vmo || !vmo->is_valid()) {
485  return ZX_ERR_BAD_HANDLE;
486  }
487  return zx_vmo_set_size(vmo->handle(), size);
488 }
489 
491  uint64_t offset,
492  const tonic::DartByteData& data) {
493  if (!vmo || !vmo->is_valid()) {
494  data.Release();
495  return ZX_ERR_BAD_HANDLE;
496  }
497 
498  zx_status_t status =
499  zx_vmo_write(vmo->handle(), data.data(), offset, data.length_in_bytes());
500 
501  data.Release();
502  return status;
503 }
504 
506  uint64_t offset,
507  size_t size) {
508  if (!vmo || !vmo->is_valid()) {
509  return ConstructDartObject(kReadResult, ToDart(ZX_ERR_BAD_HANDLE));
510  }
511 
512  // TODO: constrain size?
513  ByteDataScope bytes(size);
514  zx_status_t status = zx_vmo_read(vmo->handle(), bytes.data(), offset, size);
515  bytes.Release();
516  if (status == ZX_OK) {
517  return ConstructDartObject(kReadResult, ToDart(status), bytes.dart_handle(),
518  ToDart(size));
519  }
520  return ConstructDartObject(kReadResult, ToDart(status));
521 }
522 
523 struct SizedRegion {
524  SizedRegion(void* r, size_t s) : region(r), size(s) {}
525  void* region;
526  size_t size;
527 };
528 
529 void System::VmoMapFinalizer(void* isolate_callback_data, void* peer) {
530  SizedRegion* r = reinterpret_cast<SizedRegion*>(peer);
531  zx_vmar_unmap(zx_vmar_root_self(), reinterpret_cast<uintptr_t>(r->region),
532  r->size);
533  delete r;
534 }
535 
537  if (!vmo || !vmo->is_valid())
538  return ConstructDartObject(kMapResult, ToDart(ZX_ERR_BAD_HANDLE));
539 
540  uint64_t size;
541  zx_status_t status = zx_vmo_get_size(vmo->handle(), &size);
542  if (status != ZX_OK)
543  return ConstructDartObject(kMapResult, ToDart(status));
544 
545  uintptr_t mapped_addr;
546  status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ, 0, vmo->handle(),
547  0, size, &mapped_addr);
548  if (status != ZX_OK)
549  return ConstructDartObject(kMapResult, ToDart(status));
550 
551  void* data = reinterpret_cast<void*>(mapped_addr);
552  Dart_Handle object = Dart_NewExternalTypedData(Dart_TypedData_kUint8, data,
553  static_cast<intptr_t>(size));
554  FML_DCHECK(!tonic::LogIfError(object));
555 
556  SizedRegion* r = new SizedRegion(data, size);
557  Dart_NewFinalizableHandle(object, reinterpret_cast<void*>(r),
558  static_cast<intptr_t>(size) + sizeof(*r),
559  System::VmoMapFinalizer);
560 
561  return ConstructDartObject(kMapResult, ToDart(ZX_OK), object);
562 }
563 
565  return zx_clock_get_monotonic();
566 }
567 
568 // clang-format: off
569 
570 #define FOR_EACH_STATIC_BINDING(V) \
571  V(System, ChannelCreate) \
572  V(System, ChannelFromFile) \
573  V(System, ChannelWrite) \
574  V(System, ChannelWriteEtc) \
575  V(System, ChannelQueryAndRead) \
576  V(System, ChannelQueryAndReadEtc) \
577  V(System, EventpairCreate) \
578  V(System, ConnectToService) \
579  V(System, SocketCreate) \
580  V(System, SocketWrite) \
581  V(System, SocketRead) \
582  V(System, VmoCreate) \
583  V(System, VmoFromFile) \
584  V(System, VmoGetSize) \
585  V(System, VmoSetSize) \
586  V(System, VmoRead) \
587  V(System, VmoWrite) \
588  V(System, VmoMap) \
589  V(System, ClockGetMonotonic)
590 
591 // clang-format: on
592 
593 // Tonic is missing a comma.
594 #define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD) \
595  DART_REGISTER_NATIVE_STATIC(CLASS, METHOD),
596 
598 
599 void System::RegisterNatives(tonic::DartLibraryNatives* natives) {
601 }
602 
603 } // namespace dart
604 } // namespace zircon
static zx_status_t ChannelWrite(fml::RefPtr< Handle > channel, const tonic::DartByteData &data, std::vector< Handle *> handles)
Definition: system.cc:243
G_BEGIN_DECLS FlValue * args
DEF_SWITCHES_START snapshot asset path
Definition: switches.h:32
KeyCallType type
static Dart_Handle EventpairCreate(uint32_t options)
Definition: system.cc:385
static Dart_Handle CreateInvalid()
Definition: handle.cc:32
Definition: handle.cc:14
const void * data() const
#define FML_DCHECK(condition)
Definition: logging.h:86
static zx_status_t VmoWrite(fml::RefPtr< Handle > vmo, uint64_t offset, const tonic::DartByteData &data)
Definition: system.cc:490
static Dart_Handle SocketWrite(fml::RefPtr< Handle > socket, const tonic::DartByteData &data, int options)
Definition: system.cc:409
Dart_PersistentHandle GetClass(const DartWrapperInfo &info)
static Dart_Handle SocketCreate(uint32_t options)
Definition: system.cc:397
static DartState * Current()
Definition: dart_state.cc:56
GAsyncResult * result
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
UniqueObject< int, internal::os_unix::UniqueFDTraits > UniqueFD
Definition: unique_fd.h:100
static Dart_Handle VmoFromFile(std::string path)
Definition: system.cc:454
#define ZX_FS_RIGHT_WRITABLE
Definition: system.h:24
const T & get() const
Definition: unique_object.h:87
static Dart_Handle VmoCreate(uint64_t size, uint32_t options)
Definition: system.cc:443
static fml::RefPtr< Handle > Create(zx_handle_t handle)
Definition: handle.cc:28
bool is_valid() const
Definition: unique_object.h:89
static Dart_Handle ChannelQueryAndReadEtc(fml::RefPtr< Handle > channel)
Definition: system.cc:344
static uint64_t ClockGetMonotonic()
Definition: system.cc:564
Definition: dart_vm.cc:39
static Dart_Handle ChannelQueryAndRead(fml::RefPtr< Handle > channel)
Definition: system.cc:304
#define FOR_EACH_STATIC_BINDING(V)
Definition: system.cc:570
size_t length_in_bytes() const
static zx_status_t ConnectToService(std::string path, fml::RefPtr< Handle > channel)
Definition: system.cc:204
DartClassLibrary & class_library()
Definition: dart_state.h:59
static zx_status_t ChannelWriteEtc(fml::RefPtr< Handle > channel, const tonic::DartByteData &data, std::vector< HandleDisposition *> handle_dispositions)
Definition: system.cc:268
static Dart_Handle VmoMap(fml::RefPtr< Handle > vmo)
Definition: system.cc:536
SizedRegion(void *r, size_t s)
Definition: system.cc:524
#define DART_NATIVE_CALLBACK_STATIC(CLASS, METHOD)
static Dart_Handle SocketRead(fml::RefPtr< Handle > socket, size_t size)
Definition: system.cc:424
IMPLEMENT_WRAPPERTYPEINFO(zircon, Handle)
static Dart_Handle ChannelFromFile(std::string path)
Definition: system.cc:227
static Dart_Handle VmoGetSize(fml::RefPtr< Handle > vmo)
Definition: system.cc:472
static Dart_Handle VmoRead(fml::RefPtr< Handle > vmo, uint64_t offset, size_t size)
Definition: system.cc:505
Dart_Handle ToDart(const T &object)
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
static Dart_Handle ChannelCreate(uint32_t options)
Definition: system.cc:192
#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD)
Definition: system.cc:594
void Release() const
static zx_status_t VmoSetSize(fml::RefPtr< Handle > vmo, uint64_t size)
Definition: system.cc:483
#define ZX_FS_RIGHT_READABLE
Definition: system.h:22