Flutter Engine
The Flutter Engine
developer.cc
Go to the documentation of this file.
1// Copyright (c) 2015, 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
6
7#include "include/dart_api.h"
8
9#include "vm/debugger.h"
10#include "vm/exceptions.h"
11#include "vm/flags.h"
12#include "vm/heap/heap.h"
13#include "vm/isolate.h"
14#include "vm/message.h"
15#include "vm/native_entry.h"
16#include "vm/object.h"
17#include "vm/object_graph.h"
18#include "vm/object_store.h"
19#include "vm/service.h"
20#include "vm/service_isolate.h"
21#include "vm/zone_text_buffer.h"
22
23namespace dart {
24
25// Native implementations for the dart:developer library.
26DEFINE_NATIVE_ENTRY(Developer_debugger, 0, 2) {
27 GET_NON_NULL_NATIVE_ARGUMENT(Bool, when, arguments->NativeArgAt(0));
28#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
29 GET_NATIVE_ARGUMENT(String, msg, arguments->NativeArgAt(1));
30 Debugger* debugger = isolate->debugger();
31 if (debugger == nullptr) {
32 return when.ptr();
33 }
34 if (when.value()) {
35 debugger->PauseDeveloper(msg);
36 }
37#endif
38 return when.ptr();
39}
40
41DEFINE_NATIVE_ENTRY(Developer_inspect, 0, 1) {
42 GET_NATIVE_ARGUMENT(Instance, inspectee, arguments->NativeArgAt(0));
43#ifndef PRODUCT
44 Service::SendInspectEvent(isolate, inspectee);
45#endif // !PRODUCT
46 return inspectee.ptr();
47}
48
49DEFINE_NATIVE_ENTRY(Developer_log, 0, 8) {
50#if defined(PRODUCT)
51 return Object::null();
52#else
53 GET_NON_NULL_NATIVE_ARGUMENT(String, message, arguments->NativeArgAt(0));
54 GET_NON_NULL_NATIVE_ARGUMENT(Integer, timestamp, arguments->NativeArgAt(1));
55 GET_NON_NULL_NATIVE_ARGUMENT(Integer, sequence, arguments->NativeArgAt(2));
56 GET_NON_NULL_NATIVE_ARGUMENT(Smi, level, arguments->NativeArgAt(3));
57 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(4));
58 GET_NATIVE_ARGUMENT(Instance, dart_zone, arguments->NativeArgAt(5));
59 GET_NATIVE_ARGUMENT(Instance, error, arguments->NativeArgAt(6));
60 GET_NATIVE_ARGUMENT(Instance, stack_trace, arguments->NativeArgAt(7));
61 Service::SendLogEvent(isolate, sequence.AsInt64Value(),
62 timestamp.AsInt64Value(), level.Value(), name, message,
63 dart_zone, error, stack_trace);
64 return Object::null();
65#endif // PRODUCT
66}
67
68DEFINE_NATIVE_ENTRY(Developer_postEvent, 0, 2) {
69#if defined(PRODUCT)
70 return Object::null();
71#else
72 GET_NON_NULL_NATIVE_ARGUMENT(String, event_kind, arguments->NativeArgAt(0));
73 GET_NON_NULL_NATIVE_ARGUMENT(String, event_data, arguments->NativeArgAt(1));
74 Service::SendExtensionEvent(isolate, event_kind, event_data);
75 return Object::null();
76#endif // PRODUCT
77}
78
79DEFINE_NATIVE_ENTRY(Developer_lookupExtension, 0, 1) {
80#if defined(PRODUCT)
81 return Object::null();
82#else
83 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0));
84 return isolate->LookupServiceExtensionHandler(name);
85#endif // PRODUCT
86}
87
88DEFINE_NATIVE_ENTRY(Developer_registerExtension, 0, 2) {
89#if defined(PRODUCT)
90 return Object::null();
91#else
92 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0));
93 GET_NON_NULL_NATIVE_ARGUMENT(Instance, handler, arguments->NativeArgAt(1));
94 // We don't allow service extensions to be registered for the
95 // service isolate. This can happen, for example, because the
96 // service isolate uses dart:io. If we decide that we want to start
97 // supporting this in the future, it will take some work.
98 if (!isolate->is_service_isolate()) {
99 isolate->RegisterServiceExtensionHandler(name, handler);
100 }
101 return Object::null();
102#endif // PRODUCT
103}
104
105DEFINE_NATIVE_ENTRY(Developer_getServiceMajorVersion, 0, 0) {
106#if defined(PRODUCT)
107 return Smi::New(0);
108#else
110#endif
111}
112
113DEFINE_NATIVE_ENTRY(Developer_getServiceMinorVersion, 0, 0) {
114#if defined(PRODUCT)
115 return Smi::New(0);
116#else
118#endif
119}
120
121static void SendNull(const SendPort& port) {
122 const Dart_Port destination_port_id = port.Id();
123 PortMap::PostMessage(Message::New(destination_port_id, Object::null(),
125}
126
127DEFINE_NATIVE_ENTRY(Developer_getServerInfo, 0, 1) {
128 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
129#if defined(PRODUCT)
130 SendNull(port);
131 return Object::null();
132#else
135 SendNull(port);
136 } else {
138 }
139 return Object::null();
140#endif
141}
142
143DEFINE_NATIVE_ENTRY(Developer_webServerControl, 0, 3) {
144 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
145#if defined(PRODUCT)
146 SendNull(port);
147 return Object::null();
148#else
149 GET_NON_NULL_NATIVE_ARGUMENT(Bool, enabled, arguments->NativeArgAt(1));
150 GET_NATIVE_ARGUMENT(Bool, silence_output, arguments->NativeArgAt(2));
153 SendNull(port);
154 } else {
155 ServiceIsolate::ControlWebServer(port, enabled.value(), silence_output);
156 }
157 return Object::null();
158#endif
159}
160
161DEFINE_NATIVE_ENTRY(Developer_getIsolateIdFromSendPort, 0, 1) {
162#if defined(PRODUCT)
163 return Object::null();
164#else
165 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
166 int64_t port_id = port.Id();
168#endif
169}
170
171DEFINE_NATIVE_ENTRY(Developer_getObjectId, 0, 1) {
172#if defined(PRODUCT)
173 return Object::null();
174#else
175 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0));
177 RingServiceIdZone& ring_service_id_zone =
178 *reinterpret_cast<RingServiceIdZone*>(js.id_zone());
179 return String::New(ring_service_id_zone.GetServiceId(instance));
180#endif
181}
182
183DEFINE_NATIVE_ENTRY(Developer_reachability_barrier, 0, 0) {
184 IsolateGroup* isolate_group = thread->isolate_group();
185 ASSERT(isolate_group != nullptr);
186 Heap* heap = isolate_group->heap();
187 ASSERT(heap != nullptr);
188 return Integer::New(heap->ReachabilityBarrier());
189}
190
191DEFINE_NATIVE_ENTRY(Developer_NativeRuntime_buildId, 0, 0) {
192#if defined(DART_PRECOMPILED_RUNTIME)
193 IsolateGroup* isolate_group = thread->isolate_group();
194 ASSERT(isolate_group != nullptr);
195 if (const uint8_t* instructions =
196 isolate_group->source()->snapshot_instructions) {
197 const auto& build_id = OS::GetAppBuildId(instructions);
198 if (build_id.data != nullptr) {
200 for (intptr_t i = 0; i < build_id.len; i++) {
201 buffer.Printf("%2.2x", build_id.data[i]);
202 }
203 return String::New(buffer.buffer());
204 }
205 }
206#endif
207 return String::null();
208}
209
210DEFINE_NATIVE_ENTRY(Developer_NativeRuntime_writeHeapSnapshotToFile, 0, 1) {
211#if defined(DART_ENABLE_HEAP_SNAPSHOT_WRITER)
212 const String& filename =
213 String::CheckedHandle(zone, arguments->NativeArgAt(0));
214 bool successful = false;
215 {
216 FileHeapSnapshotWriter file_writer(thread, filename.ToCString(),
217 &successful);
218 HeapSnapshotWriter writer(thread, &file_writer);
219 writer.Write();
220 }
221 if (!successful) {
223 "Could not create & write heapsnapshot to disc. Possibly due to "
224 "missing embedder functionality.");
225 }
226#else
228 "Heap snapshots are only supported in non-product mode.");
229#endif // !defined(PRODUCT)
230 return Object::null();
231}
232
233} // namespace dart
void PauseDeveloper(const String &msg)
Definition: debugger.cc:3728
static DART_NORETURN void ThrowUnsupportedError(const char *msg)
Definition: exceptions.cc:1106
intptr_t ReachabilityBarrier()
Definition: heap.h:271
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition: object.cc:22984
const uint8_t * snapshot_instructions
Definition: isolate.h:194
Heap * heap() const
Definition: isolate.h:296
IsolateGroupSource * source() const
Definition: isolate.h:286
static std::unique_ptr< Message > New(Args &&... args)
Definition: message.h:72
@ kNormalPriority
Definition: message.h:28
static BuildId GetAppBuildId(const uint8_t *snapshot_instructions)
static ObjectPtr null()
Definition: object.h:433
static bool PostMessage(std::unique_ptr< Message > message, bool before_events=false)
Definition: port.cc:152
virtual char * GetServiceId(const Object &obj)
Definition: service.cc:380
static void ControlWebServer(const SendPort &sp, bool enable, const Bool &silenceOutput)
static void RequestServerInfo(const SendPort &sp)
static void WaitForServiceIsolateStartup()
static void SendExtensionEvent(Isolate *isolate, const String &event_kind, const String &event_data)
Definition: service.cc:4876
static void SendInspectEvent(Isolate *isolate, const Object &inspectee)
Definition: service.cc:4829
static void SendLogEvent(Isolate *isolate, int64_t sequence_number, int64_t timestamp, intptr_t level, const String &name, const String &message, const Instance &zone, const Object &error, const Instance &stack_trace)
Definition: service.cc:4850
static SmiPtr New(intptr_t value)
Definition: object.h:10006
static StringPtr NewFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition: object.cc:24004
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition: object.cc:24126
int64_t Dart_Port
Definition: dart_api.h:1525
#define ASSERT(E)
VkInstance instance
Definition: main.cc:48
const uint8_t uint32_t uint32_t GError ** error
Win32Message message
Definition: dart_vm.cc:33
const char *const name
static void SendNull(const SendPort &port)
Definition: developer.cc:121
DEFINE_NATIVE_ENTRY(List_allocate, 0, 2)
Definition: array.cc:13
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
#define GET_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:84
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:74
#define SERVICE_PROTOCOL_MAJOR_VERSION
Definition: service.h:20
#define ISOLATE_SERVICE_ID_FORMAT_STRING
Definition: service.h:48
#define SERVICE_PROTOCOL_MINOR_VERSION
Definition: service.h:21