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

Side by Side Diff: runtime/vm/service_isolate.cc

Issue 920813003: Refactor service code and service method parameters (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/service_isolate.h ('k') | runtime/vm/service_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/service_isolate.h"
6
7 #include "vm/compiler.h"
8 #include "vm/dart_api_impl.h"
9 #include "vm/dart_entry.h"
10 #include "vm/isolate.h"
11 #include "vm/lockers.h"
12 #include "vm/message.h"
13 #include "vm/message_handler.h"
14 #include "vm/native_entry.h"
15 #include "vm/native_arguments.h"
16 #include "vm/object.h"
17 #include "vm/object_store.h"
18 #include "vm/port.h"
19 #include "vm/service.h"
20 #include "vm/symbols.h"
21 #include "vm/thread_pool.h"
22
23 namespace dart {
24
25 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests.");
26 DEFINE_FLAG(bool, trace_service_pause_events, false,
27 "Trace VM service isolate pause events.");
28
29 struct ResourcesEntry {
30 const char* path_;
31 const char* resource_;
32 int length_;
33 };
34
35 extern ResourcesEntry __service_resources_[];
36
37 class Resources {
38 public:
39 static const int kNoSuchInstance = -1;
40 static int ResourceLookup(const char* path, const char** resource) {
41 ResourcesEntry* table = ResourceTable();
42 for (int i = 0; table[i].path_ != NULL; i++) {
43 const ResourcesEntry& entry = table[i];
44 if (strcmp(path, entry.path_) == 0) {
45 *resource = entry.resource_;
46 ASSERT(entry.length_ > 0);
47 return entry.length_;
48 }
49 }
50 return kNoSuchInstance;
51 }
52
53 static const char* Path(int idx) {
54 ASSERT(idx >= 0);
55 ResourcesEntry* entry = At(idx);
56 if (entry == NULL) {
57 return NULL;
58 }
59 ASSERT(entry->path_ != NULL);
60 return entry->path_;
61 }
62
63 static int Length(int idx) {
64 ASSERT(idx >= 0);
65 ResourcesEntry* entry = At(idx);
66 if (entry == NULL) {
67 return kNoSuchInstance;
68 }
69 ASSERT(entry->path_ != NULL);
70 return entry->length_;
71 }
72
73 static const uint8_t* Resource(int idx) {
74 ASSERT(idx >= 0);
75 ResourcesEntry* entry = At(idx);
76 if (entry == NULL) {
77 return NULL;
78 }
79 return reinterpret_cast<const uint8_t*>(entry->resource_);
80 }
81
82 private:
83 static ResourcesEntry* At(int idx) {
84 ASSERT(idx >= 0);
85 ResourcesEntry* table = ResourceTable();
86 for (int i = 0; table[i].path_ != NULL; i++) {
87 if (idx == i) {
88 return &table[i];
89 }
90 }
91 return NULL;
92 }
93
94 static ResourcesEntry* ResourceTable() {
95 return &__service_resources_[0];
96 }
97
98 DISALLOW_ALLOCATION();
99 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
100 };
101
102
103 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
104 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
105 return reinterpret_cast<uint8_t*>(new_ptr);
106 }
107
108
109 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) {
110 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort);
111 if (rp.IsNull()) {
112 return ILLEGAL_PORT;
113 }
114 return rp.Id();
115 }
116
117
118 // These must be kept in sync with service/constants.dart
119 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
120 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
121
122 static RawArray* MakeServiceControlMessage(Dart_Port port_id, intptr_t code,
123 const String& name) {
124 const Array& list = Array::Handle(Array::New(4));
125 ASSERT(!list.IsNull());
126 const Integer& code_int = Integer::Handle(Integer::New(code));
127 const Integer& port_int = Integer::Handle(Integer::New(port_id));
128 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
129 list.SetAt(0, code_int);
130 list.SetAt(1, port_int);
131 list.SetAt(2, send_port);
132 list.SetAt(3, name);
133 return list.raw();
134 }
135
136
137 const char* ServiceIsolate::kName = "vm-service";
138 Isolate* ServiceIsolate::isolate_ = NULL;
139 Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT;
140 Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT;
141 Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL;
142 Monitor* ServiceIsolate::monitor_ = NULL;
143 bool ServiceIsolate::initializing_ = true;
144
145
146 class RegisterRunningIsolatesVisitor : public IsolateVisitor {
147 public:
148 explicit RegisterRunningIsolatesVisitor(Isolate* service_isolate)
149 : IsolateVisitor(),
150 register_function_(Function::Handle(service_isolate)),
151 service_isolate_(service_isolate) {
152 ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
153 // Get library.
154 const String& library_url = Symbols::DartVMService();
155 ASSERT(!library_url.IsNull());
156 const Library& library =
157 Library::Handle(Library::LookupLibrary(library_url));
158 ASSERT(!library.IsNull());
159 // Get function.
160 const String& function_name =
161 String::Handle(String::New("_registerIsolate"));
162 ASSERT(!function_name.IsNull());
163 register_function_ = library.LookupFunctionAllowPrivate(function_name);
164 ASSERT(!register_function_.IsNull());
165 }
166
167 virtual void VisitIsolate(Isolate* isolate) {
168 ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
169 if (ServiceIsolate::IsServiceIsolate(isolate) ||
170 (isolate == Dart::vm_isolate())) {
171 // We do not register the service or vm isolate.
172 return;
173 }
174 // Setup arguments for call.
175 Dart_Port port_id = isolate->main_port();
176 const Integer& port_int = Integer::Handle(Integer::New(port_id));
177 ASSERT(!port_int.IsNull());
178 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
179 const String& name = String::Handle(String::New(isolate->name()));
180 ASSERT(!name.IsNull());
181 const Array& args = Array::Handle(Array::New(3));
182 ASSERT(!args.IsNull());
183 args.SetAt(0, port_int);
184 args.SetAt(1, send_port);
185 args.SetAt(2, name);
186 Object& r = Object::Handle(service_isolate_);
187 r = DartEntry::InvokeFunction(register_function_, args);
188 if (FLAG_trace_service) {
189 OS::Print("vm-service: Isolate %s %" Pd64 " registered.\n",
190 name.ToCString(),
191 port_id);
192 }
193 ASSERT(!r.IsError());
194 }
195
196 private:
197 Function& register_function_;
198 Isolate* service_isolate_;
199 };
200
201
202
203 class ServiceIsolateNatives : public AllStatic {
204 public:
205 static void SendIsolateServiceMessage(Dart_NativeArguments args) {
206 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
207 Isolate* isolate = arguments->isolate();
208 StackZone zone(isolate);
209 HANDLESCOPE(isolate);
210 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, sp, arguments->NativeArgAt(0));
211 GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(1));
212
213 // Set the type of the OOB message.
214 message.SetAt(0, Smi::Handle(isolate, Smi::New(Message::kServiceOOBMsg)));
215
216 // Serialize message.
217 uint8_t* data = NULL;
218 MessageWriter writer(&data, &allocator, false);
219 writer.WriteMessage(message);
220
221 // TODO(turnidge): Throw an exception when the return value is false?
222 PortMap::PostMessage(new Message(sp.Id(), data, writer.BytesWritten(),
223 Message::kOOBPriority));
224 }
225
226 static void SendRootServiceMessage(Dart_NativeArguments args) {
227 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
228 Isolate* isolate = arguments->isolate();
229 StackZone zone(isolate);
230 HANDLESCOPE(isolate);
231 GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0));
232 Service::HandleRootMessage(message);
233 }
234
235 static void SetEventMask(Dart_NativeArguments args) {
236 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
237 Isolate* isolate = arguments->isolate();
238 StackZone zone(isolate);
239 HANDLESCOPE(isolate);
240 GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(0));
241 Service::SetEventMask(mask.AsTruncatedUint32Value());
242 }
243
244 static void OnStart(Dart_NativeArguments args) {
245 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
246 Isolate* isolate = arguments->isolate();
247 StackZone zone(isolate);
248 HANDLESCOPE(isolate);
249 {
250 if (FLAG_trace_service) {
251 OS::Print("vm-service: Booting dart:vmservice library.\n");
252 }
253 // Boot the dart:vmservice library.
254 Dart_EnterScope();
255 Dart_Handle url_str =
256 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId));
257 Dart_Handle library = Dart_LookupLibrary(url_str);
258 ASSERT(Dart_IsLibrary(library));
259 Dart_Handle result =
260 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL);
261 ASSERT(!Dart_IsError(result));
262 Dart_Port port = ExtractPort(isolate, result);
263 ASSERT(port != ILLEGAL_PORT);
264 ServiceIsolate::SetServicePort(port);
265 Dart_ExitScope();
266 }
267
268 {
269 if (FLAG_trace_service) {
270 OS::Print("vm-service: Registering running isolates.\n");
271 }
272 // Register running isolates with service.
273 RegisterRunningIsolatesVisitor register_isolates(isolate);
274 Isolate::VisitIsolates(&register_isolates);
275 }
276 }
277 };
278
279
280 struct ServiceNativeEntry {
281 const char* name;
282 int num_arguments;
283 Dart_NativeFunction function;
284 };
285
286
287 static ServiceNativeEntry _ServiceNativeEntries[] = {
288 {"VMService_SendIsolateServiceMessage", 2,
289 ServiceIsolateNatives::SendIsolateServiceMessage},
290 {"VMService_SendRootServiceMessage", 1,
291 ServiceIsolateNatives::SendRootServiceMessage},
292 {"VMService_SetEventMask", 1,
293 ServiceIsolateNatives::SetEventMask},
294 {"VMService_OnStart", 0,
295 ServiceIsolateNatives::OnStart },
296 };
297
298
299 static Dart_NativeFunction ServiceNativeResolver(Dart_Handle name,
300 int num_arguments,
301 bool* auto_setup_scope) {
302 const Object& obj = Object::Handle(Api::UnwrapHandle(name));
303 if (!obj.IsString()) {
304 return NULL;
305 }
306 const char* function_name = obj.ToCString();
307 ASSERT(function_name != NULL);
308 ASSERT(auto_setup_scope != NULL);
309 *auto_setup_scope = true;
310 intptr_t n = sizeof(_ServiceNativeEntries) /
311 sizeof(_ServiceNativeEntries[0]);
312 for (intptr_t i = 0; i < n; i++) {
313 ServiceNativeEntry entry = _ServiceNativeEntries[i];
314 if ((strcmp(function_name, entry.name) == 0) &&
315 (num_arguments == entry.num_arguments)) {
316 return entry.function;
317 }
318 }
319 return NULL;
320 }
321
322
323 bool ServiceIsolate::NameEquals(const char* name) {
324 ASSERT(name != NULL);
325 return strcmp(name, kName) == 0;
326 }
327
328
329 bool ServiceIsolate::Exists() {
330 MonitorLocker ml(monitor_);
331 return isolate_ != NULL;
332 }
333
334
335 bool ServiceIsolate::IsRunning() {
336 MonitorLocker ml(monitor_);
337 return (port_ != ILLEGAL_PORT) && (isolate_ != NULL);
338 }
339
340
341 bool ServiceIsolate::IsServiceIsolate(Isolate* isolate) {
342 MonitorLocker ml(monitor_);
343 return isolate == isolate_;
344 }
345
346
347 Dart_Port ServiceIsolate::Port() {
348 MonitorLocker ml(monitor_);
349 return port_;
350 }
351
352
353 Dart_Port ServiceIsolate::WaitForLoadPort() {
354 MonitorLocker ml(monitor_);
355
356 while (initializing_ && (load_port_ == ILLEGAL_PORT)) {
357 ml.Wait();
358 }
359
360 return load_port_;
361 }
362
363
364 Dart_Port ServiceIsolate::LoadPort() {
365 MonitorLocker ml(monitor_);
366 return load_port_;
367 }
368
369
370 bool ServiceIsolate::SendIsolateStartupMessage() {
371 if (!IsRunning()) {
372 return false;
373 }
374 Isolate* isolate = Isolate::Current();
375 if (IsServiceIsolate(isolate)) {
376 return false;
377 }
378 ASSERT(isolate != NULL);
379 HANDLESCOPE(isolate);
380 const String& name = String::Handle(String::New(isolate->name()));
381 ASSERT(!name.IsNull());
382 const Array& list = Array::Handle(
383 MakeServiceControlMessage(Dart_GetMainPortId(),
384 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID,
385 name));
386 ASSERT(!list.IsNull());
387 uint8_t* data = NULL;
388 MessageWriter writer(&data, &allocator, false);
389 writer.WriteMessage(list);
390 intptr_t len = writer.BytesWritten();
391 if (FLAG_trace_service) {
392 OS::Print("vm-service: Isolate %s %" Pd64 " registered.\n",
393 name.ToCString(),
394 Dart_GetMainPortId());
395 }
396 return PortMap::PostMessage(
397 new Message(port_, data, len, Message::kNormalPriority));
398 }
399
400
401 bool ServiceIsolate::SendIsolateShutdownMessage() {
402 if (!IsRunning()) {
403 return false;
404 }
405 Isolate* isolate = Isolate::Current();
406 if (IsServiceIsolate(isolate)) {
407 return false;
408 }
409 ASSERT(isolate != NULL);
410 HANDLESCOPE(isolate);
411 const String& name = String::Handle(String::New(isolate->name()));
412 ASSERT(!name.IsNull());
413 const Array& list = Array::Handle(
414 MakeServiceControlMessage(Dart_GetMainPortId(),
415 VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID,
416 name));
417 ASSERT(!list.IsNull());
418 uint8_t* data = NULL;
419 MessageWriter writer(&data, &allocator, false);
420 writer.WriteMessage(list);
421 intptr_t len = writer.BytesWritten();
422 if (FLAG_trace_service) {
423 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n",
424 name.ToCString(),
425 Dart_GetMainPortId());
426 }
427 return PortMap::PostMessage(
428 new Message(port_, data, len, Message::kNormalPriority));
429 }
430
431
432 void ServiceIsolate::SetServicePort(Dart_Port port) {
433 MonitorLocker ml(monitor_);
434 port_ = port;
435 }
436
437
438 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) {
439 MonitorLocker ml(monitor_);
440 isolate_ = isolate;
441 if (isolate_ != NULL) {
442 isolate_->is_service_isolate_ = true;
443 }
444 }
445
446 void ServiceIsolate::SetLoadPort(Dart_Port port) {
447 MonitorLocker ml(monitor_);
448 load_port_ = port;
449 }
450
451
452 void ServiceIsolate::MaybeInjectVMServiceLibrary(Isolate* isolate) {
453 ASSERT(isolate != NULL);
454 ASSERT(isolate->name() != NULL);
455 if (!ServiceIsolate::NameEquals(isolate->name())) {
456 // Not service isolate.
457 return;
458 }
459 if (Exists()) {
460 // Service isolate already exists.
461 return;
462 }
463 SetServiceIsolate(isolate);
464
465 StackZone zone(isolate);
466 HANDLESCOPE(isolate);
467
468 // Register dart:vmservice library.
469 const String& url_str = String::Handle(Symbols::DartVMService().raw());
470 const Library& library = Library::Handle(Library::New(url_str));
471 library.Register();
472 library.set_native_entry_resolver(ServiceNativeResolver);
473
474 // Temporarily install our library tag handler.
475 isolate->set_library_tag_handler(LibraryTagHandler);
476
477 // Get script source.
478 const char* resource = NULL;
479 const char* path = "/vmservice.dart";
480 intptr_t r = Resources::ResourceLookup(path, &resource);
481 ASSERT(r != Resources::kNoSuchInstance);
482 ASSERT(resource != NULL);
483 const String& source_str = String::Handle(
484 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r));
485 ASSERT(!source_str.IsNull());
486 const Script& script = Script::Handle(
487 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag));
488
489 // Compile script.
490 Dart_EnterScope(); // Need to enter scope for tag handler.
491 library.SetLoadInProgress();
492 const Error& error = Error::Handle(isolate,
493 Compiler::Compile(library, script));
494 ASSERT(error.IsNull());
495 Dart_Handle result = Dart_FinalizeLoading(false);
496 ASSERT(!Dart_IsError(result));
497 Dart_ExitScope();
498
499 // Uninstall our library tag handler.
500 isolate->set_library_tag_handler(NULL);
501 }
502
503
504 void ServiceIsolate::FinishedInitializing() {
505 MonitorLocker ml(monitor_);
506 initializing_ = false;
507 ml.NotifyAll();
508 }
509
510
511 class RunServiceTask : public ThreadPool::Task {
512 public:
513 virtual void Run() {
514 ASSERT(Isolate::Current() == NULL);
515 char* error = NULL;
516 Isolate* isolate = NULL;
517
518 Dart_IsolateCreateCallback create_callback =
519 ServiceIsolate::create_callback();
520 // TODO(johnmccutchan): Support starting up service isolate without embedder
521 // provided isolate creation callback.
522 if (create_callback == NULL) {
523 ServiceIsolate::FinishedInitializing();
524 return;
525 }
526
527 isolate =
528 reinterpret_cast<Isolate*>(create_callback(ServiceIsolate::kName,
529 NULL,
530 NULL,
531 NULL,
532 &error));
533 if (isolate == NULL) {
534 OS::PrintErr("vm-service: Isolate creation error: %s\n", error);
535 ServiceIsolate::FinishedInitializing();
536 return;
537 }
538
539 Isolate::SetCurrent(NULL);
540
541 RunMain(isolate);
542
543 ServiceIsolate::FinishedInitializing();
544
545 isolate->message_handler()->Run(Dart::thread_pool(),
546 NULL,
547 ShutdownIsolate,
548 reinterpret_cast<uword>(isolate));
549 }
550
551 protected:
552 static void ShutdownIsolate(uword parameter) {
553 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
554 ASSERT(ServiceIsolate::IsServiceIsolate(isolate));
555 {
556 // Print the error if there is one. This may execute dart code to
557 // print the exception object, so we need to use a StartIsolateScope.
558 StartIsolateScope start_scope(isolate);
559 StackZone zone(isolate);
560 HandleScope handle_scope(isolate);
561 Error& error = Error::Handle();
562 error = isolate->object_store()->sticky_error();
563 if (!error.IsNull()) {
564 OS::PrintErr("vm-service: Error: %s\n", error.ToErrorCString());
565 }
566 Dart::RunShutdownCallback();
567 }
568 {
569 // Shut the isolate down.
570 SwitchIsolateScope switch_scope(isolate);
571 Dart::ShutdownIsolate();
572 }
573 ServiceIsolate::SetServiceIsolate(NULL);
574 ServiceIsolate::SetServicePort(ILLEGAL_PORT);
575 if (FLAG_trace_service) {
576 OS::Print("vm-service: Shutdown.\n");
577 }
578 }
579
580 void RunMain(Isolate* isolate) {
581 StartIsolateScope iso_scope(isolate);
582 StackZone zone(isolate);
583 HANDLESCOPE(isolate);
584 // Invoke main which will return the loadScriptPort.
585 const Library& root_library =
586 Library::Handle(isolate, isolate->object_store()->root_library());
587 if (root_library.IsNull()) {
588 if (FLAG_trace_service) {
589 OS::Print("vm-service: Embedder did not install a script.");
590 }
591 // Service isolate is not supported by embedder.
592 return;
593 }
594 ASSERT(!root_library.IsNull());
595 const String& entry_name = String::Handle(isolate, String::New("main"));
596 ASSERT(!entry_name.IsNull());
597 const Function& entry =
598 Function::Handle(isolate,
599 root_library.LookupFunctionAllowPrivate(entry_name));
600 if (entry.IsNull()) {
601 // Service isolate is not supported by embedder.
602 if (FLAG_trace_service) {
603 OS::Print("vm-service: Embedder did not provide a main function.");
604 }
605 return;
606 }
607 ASSERT(!entry.IsNull());
608 const Object& result =
609 Object::Handle(isolate,
610 DartEntry::InvokeFunction(entry,
611 Object::empty_array()));
612 ASSERT(!result.IsNull());
613 if (result.IsError()) {
614 // Service isolate did not initialize properly.
615 if (FLAG_trace_service) {
616 const Error& error = Error::Cast(result);
617 OS::Print("vm-service: Calling main resulted in an error: %s",
618 error.ToErrorCString());
619 }
620 return;
621 }
622 ASSERT(result.IsReceivePort());
623 const ReceivePort& rp = ReceivePort::Cast(result);
624 ServiceIsolate::SetLoadPort(rp.Id());
625 }
626 };
627
628
629 void ServiceIsolate::Run() {
630 ASSERT(monitor_ == NULL);
631 monitor_ = new Monitor();
632 ASSERT(monitor_ != NULL);
633 // Grab the isolate create callback here to avoid race conditions with tests
634 // that change this after Dart_Initialize returns.
635 create_callback_ = Isolate::CreateCallback();
636 Dart::thread_pool()->Run(new RunServiceTask());
637 }
638
639
640 Dart_Handle ServiceIsolate::GetSource(const char* name) {
641 ASSERT(name != NULL);
642 int i = 0;
643 while (true) {
644 const char* path = Resources::Path(i);
645 if (path == NULL) {
646 break;
647 }
648 ASSERT(*path != '\0');
649 // Skip the '/'.
650 path++;
651 if (strcmp(name, path) == 0) {
652 const uint8_t* str = Resources::Resource(i);
653 intptr_t length = Resources::Length(i);
654 return Dart_NewStringFromUTF8(str, length);
655 }
656 i++;
657 }
658 return Dart_Null();
659 }
660
661
662 Dart_Handle ServiceIsolate::LibraryTagHandler(Dart_LibraryTag tag,
663 Dart_Handle library,
664 Dart_Handle url) {
665 if (tag == Dart_kCanonicalizeUrl) {
666 // url is already canonicalized.
667 return url;
668 }
669 if (tag != Dart_kSourceTag) {
670 FATAL("ServiceIsolate::LibraryTagHandler encountered an unexpected tag.");
671 }
672 ASSERT(tag == Dart_kSourceTag);
673 const char* url_string = NULL;
674 Dart_Handle result = Dart_StringToCString(url, &url_string);
675 if (Dart_IsError(result)) {
676 return result;
677 }
678 Dart_Handle source = GetSource(url_string);
679 if (Dart_IsError(source)) {
680 return source;
681 }
682 return Dart_LoadSource(library, url, source, 0, 0);
683 }
684
685 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/service_isolate.h ('k') | runtime/vm/service_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698