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 | |
5 | #include "vm/bootstrap_natives.h" |
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/message.h" |
13 | #include "vm/native_entry.h" |
14 | #include "vm/object.h" |
15 | #include "vm/object_store.h" |
16 | #include "vm/service.h" |
17 | #include "vm/service_isolate.h" |
18 | |
19 | namespace dart { |
20 | |
21 | // Native implementations for the dart:developer library. |
22 | DEFINE_NATIVE_ENTRY(Developer_debugger, 0, 2) { |
23 | GET_NON_NULL_NATIVE_ARGUMENT(Bool, when, arguments->NativeArgAt(0)); |
24 | #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) |
25 | GET_NATIVE_ARGUMENT(String, msg, arguments->NativeArgAt(1)); |
26 | Debugger* debugger = isolate->debugger(); |
27 | if (debugger == nullptr) { |
28 | return when.raw(); |
29 | } |
30 | if (when.value()) { |
31 | debugger->PauseDeveloper(msg); |
32 | } |
33 | #endif |
34 | return when.raw(); |
35 | } |
36 | |
37 | DEFINE_NATIVE_ENTRY(Developer_inspect, 0, 1) { |
38 | GET_NATIVE_ARGUMENT(Instance, inspectee, arguments->NativeArgAt(0)); |
39 | #ifndef PRODUCT |
40 | Service::SendInspectEvent(isolate, inspectee); |
41 | #endif // !PRODUCT |
42 | return inspectee.raw(); |
43 | } |
44 | |
45 | DEFINE_NATIVE_ENTRY(Developer_log, 0, 8) { |
46 | #if defined(PRODUCT) |
47 | return Object::null(); |
48 | #else |
49 | GET_NON_NULL_NATIVE_ARGUMENT(String, message, arguments->NativeArgAt(0)); |
50 | GET_NON_NULL_NATIVE_ARGUMENT(Integer, timestamp, arguments->NativeArgAt(1)); |
51 | GET_NON_NULL_NATIVE_ARGUMENT(Integer, sequence, arguments->NativeArgAt(2)); |
52 | GET_NON_NULL_NATIVE_ARGUMENT(Smi, level, arguments->NativeArgAt(3)); |
53 | GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(4)); |
54 | GET_NATIVE_ARGUMENT(Instance, dart_zone, arguments->NativeArgAt(5)); |
55 | GET_NATIVE_ARGUMENT(Instance, error, arguments->NativeArgAt(6)); |
56 | GET_NATIVE_ARGUMENT(Instance, stack_trace, arguments->NativeArgAt(7)); |
57 | Service::SendLogEvent(isolate, sequence.AsInt64Value(), |
58 | timestamp.AsInt64Value(), level.Value(), name, message, |
59 | dart_zone, error, stack_trace); |
60 | return Object::null(); |
61 | #endif // PRODUCT |
62 | } |
63 | |
64 | DEFINE_NATIVE_ENTRY(Developer_postEvent, 0, 2) { |
65 | #if defined(PRODUCT) |
66 | return Object::null(); |
67 | #else |
68 | GET_NON_NULL_NATIVE_ARGUMENT(String, event_kind, arguments->NativeArgAt(0)); |
69 | GET_NON_NULL_NATIVE_ARGUMENT(String, event_data, arguments->NativeArgAt(1)); |
70 | Service::SendExtensionEvent(isolate, event_kind, event_data); |
71 | return Object::null(); |
72 | #endif // PRODUCT |
73 | } |
74 | |
75 | DEFINE_NATIVE_ENTRY(Developer_lookupExtension, 0, 1) { |
76 | #if defined(PRODUCT) |
77 | return Object::null(); |
78 | #else |
79 | GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0)); |
80 | return isolate->LookupServiceExtensionHandler(name); |
81 | #endif // PRODUCT |
82 | } |
83 | |
84 | DEFINE_NATIVE_ENTRY(Developer_registerExtension, 0, 2) { |
85 | #if defined(PRODUCT) |
86 | return Object::null(); |
87 | #else |
88 | GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0)); |
89 | GET_NON_NULL_NATIVE_ARGUMENT(Instance, handler, arguments->NativeArgAt(1)); |
90 | // We don't allow service extensions to be registered for the |
91 | // service isolate. This can happen, for example, because the |
92 | // service isolate uses dart:io. If we decide that we want to start |
93 | // supporting this in the future, it will take some work. |
94 | if (!ServiceIsolate::IsServiceIsolateDescendant(isolate)) { |
95 | isolate->RegisterServiceExtensionHandler(name, handler); |
96 | } |
97 | return Object::null(); |
98 | #endif // PRODUCT |
99 | } |
100 | |
101 | DEFINE_NATIVE_ENTRY(Developer_getServiceMajorVersion, 0, 0) { |
102 | #if defined(PRODUCT) |
103 | return Smi::New(0); |
104 | #else |
105 | return Smi::New(SERVICE_PROTOCOL_MAJOR_VERSION); |
106 | #endif |
107 | } |
108 | |
109 | DEFINE_NATIVE_ENTRY(Developer_getServiceMinorVersion, 0, 0) { |
110 | #if defined(PRODUCT) |
111 | return Smi::New(0); |
112 | #else |
113 | return Smi::New(SERVICE_PROTOCOL_MINOR_VERSION); |
114 | #endif |
115 | } |
116 | |
117 | static void SendNull(const SendPort& port) { |
118 | const Dart_Port destination_port_id = port.Id(); |
119 | PortMap::PostMessage(Message::New(destination_port_id, Object::null(), |
120 | Message::kNormalPriority)); |
121 | } |
122 | |
123 | DEFINE_NATIVE_ENTRY(Developer_getServerInfo, 0, 1) { |
124 | GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
125 | #if defined(PRODUCT) |
126 | SendNull(port); |
127 | return Object::null(); |
128 | #else |
129 | ServiceIsolate::WaitForServiceIsolateStartup(); |
130 | if (!ServiceIsolate::IsRunning()) { |
131 | SendNull(port); |
132 | } else { |
133 | ServiceIsolate::RequestServerInfo(port); |
134 | } |
135 | return Object::null(); |
136 | #endif |
137 | } |
138 | |
139 | DEFINE_NATIVE_ENTRY(Developer_webServerControl, 0, 2) { |
140 | GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
141 | #if defined(PRODUCT) |
142 | SendNull(port); |
143 | return Object::null(); |
144 | #else |
145 | GET_NON_NULL_NATIVE_ARGUMENT(Bool, enabled, arguments->NativeArgAt(1)); |
146 | ServiceIsolate::WaitForServiceIsolateStartup(); |
147 | if (!ServiceIsolate::IsRunning()) { |
148 | SendNull(port); |
149 | } else { |
150 | ServiceIsolate::ControlWebServer(port, enabled.value()); |
151 | } |
152 | return Object::null(); |
153 | #endif |
154 | } |
155 | |
156 | DEFINE_NATIVE_ENTRY(Developer_getIsolateIDFromSendPort, 0, 1) { |
157 | #if defined(PRODUCT) |
158 | return Object::null(); |
159 | #else |
160 | GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
161 | int64_t port_id = port.Id(); |
162 | return String::NewFormatted(ISOLATE_SERVICE_ID_FORMAT_STRING, port_id); |
163 | #endif |
164 | } |
165 | |
166 | } // namespace dart |
167 | |