| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/assert.h" | 5 #include "platform/assert.h" |
| 6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/dart.h" | 8 #include "vm/dart.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 const String& error_str = String::Handle( | 232 const String& error_str = String::Handle( |
| 233 String::New("Error starting Isolate, class not loaded : ")); | 233 String::New("Error starting Isolate, class not loaded : ")); |
| 234 const Error& error = Error::Handle(LanguageError::New(error_str)); | 234 const Error& error = Error::Handle(LanguageError::New(error_str)); |
| 235 Isolate::Current()->object_store()->set_sticky_error(error); | 235 Isolate::Current()->object_store()->set_sticky_error(error); |
| 236 return false; | 236 return false; |
| 237 } | 237 } |
| 238 return true; // No errors. | 238 return true; // No errors. |
| 239 } | 239 } |
| 240 | 240 |
| 241 | 241 |
| 242 static char* BuildIsolateName(const char* script_name, | 242 static char* GetRootScriptUri(Isolate* isolate) { |
| 243 const char* class_name, | 243 const Library& library = |
| 244 const char* func_name) { | 244 Library::Handle(isolate->object_store()->root_library()); |
| 245 // Skip past any slashes in the script name. | 245 ASSERT(!library.IsNull()); |
| 246 const char* last_slash = strrchr(script_name, '/'); | 246 const String& script_name = String::Handle(library.url()); |
| 247 if (last_slash != NULL) { | 247 return isolate->current_zone()->MakeCopyOfString(script_name.ToCString()); |
| 248 script_name = last_slash + 1; | 248 } |
| 249 } | |
| 250 | 249 |
| 251 char* chars = NULL; | 250 |
| 252 if (class_name && class_name[0] != '\0') { | 251 static char* BuildMainName(const char* class_name) { |
| 253 const char* kFormat = "%s/%s.%s"; | 252 intptr_t len = OS::SNPrint(NULL, 0, "%s.main", class_name) + 1; |
| 254 intptr_t len = OS::SNPrint(NULL, 0, kFormat, script_name, class_name, | 253 char* chars = reinterpret_cast<char*>( |
| 255 func_name) + 1; | 254 Isolate::Current()->current_zone()->Allocate(len)); |
| 256 chars = reinterpret_cast<char*>( | 255 OS::SNPrint(chars, len, "%s.main", class_name); |
| 257 Isolate::Current()->current_zone()->Allocate(len)); | |
| 258 OS::SNPrint(chars, len, kFormat, script_name, class_name, func_name); | |
| 259 } else { | |
| 260 const char* kFormat = "%s/%s"; | |
| 261 intptr_t len = OS::SNPrint(NULL, 0, kFormat, script_name, func_name) + 1; | |
| 262 chars = reinterpret_cast<char*>( | |
| 263 Isolate::Current()->current_zone()->Allocate(len)); | |
| 264 OS::SNPrint(chars, len, kFormat, script_name, func_name); | |
| 265 } | |
| 266 return chars; | 256 return chars; |
| 267 } | 257 } |
| 268 | 258 |
| 269 | 259 |
| 270 DEFINE_NATIVE_ENTRY(IsolateNatives_start, 2) { | 260 DEFINE_NATIVE_ENTRY(IsolateNatives_start, 2) { |
| 271 Isolate* preserved_isolate = Isolate::Current(); | 261 Isolate* preserved_isolate = Isolate::Current(); |
| 272 GET_NATIVE_ARGUMENT(Instance, runnable, arguments->At(0)); | 262 GET_NATIVE_ARGUMENT(Instance, runnable, arguments->At(0)); |
| 273 // arguments->At(1) unused. | 263 // arguments->At(1) unused. |
| 274 const Class& runnable_class = Class::Handle(runnable.clazz()); | 264 const Class& runnable_class = Class::Handle(runnable.clazz()); |
| 275 const char* class_name = String::Handle(runnable_class.Name()).ToCString(); | 265 const char* class_name = String::Handle(runnable_class.Name()).ToCString(); |
| 276 const Library& library = Library::Handle(runnable_class.library()); | 266 const Library& library = Library::Handle(runnable_class.library()); |
| 277 ASSERT(!library.IsNull()); | 267 ASSERT(!library.IsNull()); |
| 278 const char* library_url = String::Handle(library.url()).ToCString(); | 268 const char* library_url = String::Handle(library.url()).ToCString(); |
| 279 intptr_t port_id = 0; | 269 intptr_t port_id = 0; |
| 280 LongJump jump; | 270 LongJump jump; |
| 281 bool init_successful = true; | 271 bool init_successful = true; |
| 282 Isolate* spawned_isolate = NULL; | 272 Isolate* spawned_isolate = NULL; |
| 283 void* callback_data = preserved_isolate->init_callback_data(); | 273 void* callback_data = preserved_isolate->init_callback_data(); |
| 284 char* error = NULL; | 274 char* error = NULL; |
| 285 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); | 275 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); |
| 286 const char* isolate_name = BuildIsolateName(library_url, class_name, "main"); | 276 const char* root_script_uri = GetRootScriptUri(preserved_isolate); |
| 277 const char* main = BuildMainName(class_name); |
| 287 if (callback == NULL) { | 278 if (callback == NULL) { |
| 288 error = strdup("Null callback specified for isolate creation\n"); | 279 error = strdup("Null callback specified for isolate creation\n"); |
| 289 } else if (callback(isolate_name, callback_data, &error)) { | 280 } else if (callback(root_script_uri, main, callback_data, &error)) { |
| 290 spawned_isolate = Isolate::Current(); | 281 spawned_isolate = Isolate::Current(); |
| 291 ASSERT(spawned_isolate != NULL); | 282 ASSERT(spawned_isolate != NULL); |
| 292 // Check arguments to see if the specified library and classes are | 283 // Check arguments to see if the specified library and classes are |
| 293 // loaded, this check will throw an exception if they are not loaded. | 284 // loaded, this check will throw an exception if they are not loaded. |
| 294 if (init_successful && CheckArguments(library_url, class_name)) { | 285 if (init_successful && CheckArguments(library_url, class_name)) { |
| 295 port_id = spawned_isolate->main_port(); | 286 port_id = spawned_isolate->main_port(); |
| 296 spawned_isolate->set_spawn_data( | 287 spawned_isolate->set_spawn_data( |
| 297 reinterpret_cast<uword>( | 288 reinterpret_cast<uword>( |
| 298 new IsolateStartData(strdup(library_url), | 289 new IsolateStartData(strdup(library_url), |
| 299 strdup(class_name), | 290 strdup(class_name), |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 } | 370 } |
| 380 | 371 |
| 381 | 372 |
| 382 static void ThrowIsolateSpawnException(const String& message) { | 373 static void ThrowIsolateSpawnException(const String& message) { |
| 383 GrowableArray<const Object*> args(1); | 374 GrowableArray<const Object*> args(1); |
| 384 args.Add(&message); | 375 args.Add(&message); |
| 385 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); | 376 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); |
| 386 } | 377 } |
| 387 | 378 |
| 388 | 379 |
| 380 static bool CanonicalizeUri(Isolate* isolate, |
| 381 const Library& library, |
| 382 const String& uri, |
| 383 char** canonical_uri, |
| 384 char** error) { |
| 385 Zone* zone = isolate->current_zone(); |
| 386 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); |
| 387 if (handler == NULL) { |
| 388 *error = zone->PrintToString( |
| 389 "Unable to canonicalize uri '%s': no library tag handler found.", |
| 390 uri.ToCString()); |
| 391 return false; |
| 392 } |
| 393 Dart_Handle result = handler(kCanonicalizeUrl, |
| 394 Api::NewHandle(isolate, library.raw()), |
| 395 Api::NewHandle(isolate, uri.raw())); |
| 396 const Object& obj = Object::Handle(Api::UnwrapHandle(result)); |
| 397 if (obj.IsError()) { |
| 398 Error& error_obj = Error::Handle(); |
| 399 error_obj ^= obj.raw(); |
| 400 *error = zone->PrintToString("Unable to canonicalize uri '%s': %s", |
| 401 uri.ToCString(), error_obj.ToErrorCString()); |
| 402 return false; |
| 403 } else if (obj.IsString()) { |
| 404 String& string_obj = String::Handle(); |
| 405 string_obj ^= obj.raw(); |
| 406 *canonical_uri = zone->MakeCopyOfString(string_obj.ToCString()); |
| 407 return true; |
| 408 } else { |
| 409 *error = zone->PrintToString("Unable to canonicalize uri '%s': " |
| 410 "library tag handler returned wrong type", |
| 411 uri.ToCString()); |
| 412 return false; |
| 413 } |
| 414 } |
| 415 |
| 416 |
| 389 class SpawnState { | 417 class SpawnState { |
| 390 public: | 418 public: |
| 391 explicit SpawnState(const Function& func) | 419 explicit SpawnState(const Function& func) |
| 392 : isolate_(NULL), | 420 : isolate_(NULL), |
| 421 script_url_(NULL), |
| 393 library_url_(NULL), | 422 library_url_(NULL), |
| 394 function_name_(NULL) { | 423 function_name_(NULL) { |
| 424 script_url_ = strdup(GetRootScriptUri(Isolate::Current())); |
| 395 const Class& cls = Class::Handle(func.owner()); | 425 const Class& cls = Class::Handle(func.owner()); |
| 396 ASSERT(cls.IsTopLevel()); | 426 ASSERT(cls.IsTopLevel()); |
| 397 const Library& lib = Library::Handle(cls.library()); | 427 const Library& lib = Library::Handle(cls.library()); |
| 398 const String& lib_url = String::Handle(lib.url()); | 428 const String& lib_url = String::Handle(lib.url()); |
| 399 library_url_ = strdup(lib_url.ToCString()); | 429 library_url_ = strdup(lib_url.ToCString()); |
| 400 | 430 |
| 401 const String& func_name = String::Handle(func.name()); | 431 const String& func_name = String::Handle(func.name()); |
| 402 function_name_ = strdup(func_name.ToCString()); | 432 function_name_ = strdup(func_name.ToCString()); |
| 403 } | 433 } |
| 404 | 434 |
| 435 explicit SpawnState(const char* script_url) |
| 436 : isolate_(NULL), |
| 437 library_url_(NULL), |
| 438 function_name_(NULL) { |
| 439 script_url_ = strdup(script_url); |
| 440 library_url_ = NULL; |
| 441 function_name_ = strdup("main"); |
| 442 } |
| 443 |
| 405 ~SpawnState() { | 444 ~SpawnState() { |
| 445 free(script_url_); |
| 406 free(library_url_); | 446 free(library_url_); |
| 407 free(function_name_); | 447 free(function_name_); |
| 408 } | 448 } |
| 409 | 449 |
| 410 Isolate* isolate() const { return isolate_; } | 450 Isolate* isolate() const { return isolate_; } |
| 411 void set_isolate(Isolate* value) { isolate_ = value; } | 451 void set_isolate(Isolate* value) { isolate_ = value; } |
| 452 char* script_url() const { return script_url_; } |
| 412 char* library_url() const { return library_url_; } | 453 char* library_url() const { return library_url_; } |
| 413 char* function_name() const { return function_name_; } | 454 char* function_name() const { return function_name_; } |
| 414 | 455 |
| 415 RawFunction* ResolveFunction() { | 456 RawObject* ResolveFunction() { |
| 416 const String& lib_url = | 457 // Resolve the library. |
| 417 String::Handle(String::NewSymbol(library_url())); | 458 Library& lib = Library::Handle(); |
| 459 if (library_url()) { |
| 460 const String& lib_url = String::Handle(String::New(library_url())); |
| 461 lib = Library::LookupLibrary(lib_url); |
| 462 if (lib.IsNull() || lib.IsError()) { |
| 463 const String& msg = String::Handle(String::NewFormatted( |
| 464 "Unable to find library '%s'.", library_url())); |
| 465 return LanguageError::New(msg); |
| 466 } |
| 467 } else { |
| 468 lib = isolate()->object_store()->root_library(); |
| 469 } |
| 470 ASSERT(!lib.IsNull()); |
| 471 |
| 472 // Resolve the function. |
| 418 const String& func_name = | 473 const String& func_name = |
| 419 String::Handle(String::NewSymbol(function_name())); | 474 String::Handle(String::New(function_name())); |
| 420 | 475 const Function& func = Function::Handle(lib.LookupLocalFunction(func_name)); |
| 421 const Library& lib = Library::Handle(Library::LookupLibrary(lib_url)); | 476 if (func.IsNull()) { |
| 422 if (lib.IsNull() || lib.IsError()) { | 477 const String& msg = String::Handle(String::NewFormatted( |
| 423 return Function::null(); | 478 "Unable to resolve function '%s' in library '%s'.", |
| 479 function_name(), (library_url() ? library_url() : script_url()))); |
| 480 return LanguageError::New(msg); |
| 424 } | 481 } |
| 425 return lib.LookupLocalFunction(func_name); | 482 return func.raw(); |
| 426 } | 483 } |
| 427 | 484 |
| 428 void Cleanup() { | 485 void Cleanup() { |
| 429 SwitchIsolateScope switch_scope(isolate()); | 486 SwitchIsolateScope switch_scope(isolate()); |
| 430 Dart::ShutdownIsolate(); | 487 Dart::ShutdownIsolate(); |
| 431 } | 488 } |
| 432 | 489 |
| 433 private: | 490 private: |
| 434 Isolate* isolate_; | 491 Isolate* isolate_; |
| 492 char* script_url_; |
| 435 char* library_url_; | 493 char* library_url_; |
| 436 char* function_name_; | 494 char* function_name_; |
| 437 }; | 495 }; |
| 438 | 496 |
| 439 | 497 |
| 440 static bool CreateIsolate(SpawnState* state, char** error) { | 498 static bool CreateIsolate(SpawnState* state, char** error) { |
| 441 Isolate* parent_isolate = Isolate::Current(); | 499 Isolate* parent_isolate = Isolate::Current(); |
| 442 | 500 |
| 443 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); | 501 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); |
| 444 ASSERT(callback); | 502 ASSERT(callback != NULL); |
| 445 const char* isolate_name = BuildIsolateName(state->library_url(), | |
| 446 "", | |
| 447 state->function_name()); | |
| 448 void* init_data = parent_isolate->init_callback_data(); | 503 void* init_data = parent_isolate->init_callback_data(); |
| 449 bool retval = (callback)(isolate_name, init_data, error); | 504 bool retval = (callback)(state->script_url(), |
| 450 if (retval) { | 505 state->function_name(), |
| 451 Isolate* child_isolate = Isolate::Current(); | 506 init_data, |
| 452 ASSERT(child_isolate); | 507 error); |
| 453 state->set_isolate(child_isolate); | 508 if (!retval) { |
| 509 Isolate::SetCurrent(parent_isolate); |
| 510 return false; |
| 511 } |
| 454 | 512 |
| 455 // Attempt to resolve the entry function now, so that we fail fast | 513 Isolate* child_isolate = Isolate::Current(); |
| 456 // in the case that the embedder's isolate create callback is | 514 ASSERT(child_isolate); |
| 457 // violating its contract. | 515 state->set_isolate(child_isolate); |
| 458 // | 516 |
| 459 // TODO(turnidge): Revisit this once we have an isolate death api. | 517 // Attempt to resolve the entry function now, so that we fail fast |
| 460 { | 518 // in the case that the function cannot be resolved. |
| 461 Zone zone(child_isolate); | 519 // |
| 462 HandleScope handle_scope(child_isolate); | 520 // TODO(turnidge): Revisit this once we have an isolate death api. |
| 463 const Function& func = Function::Handle(state->ResolveFunction()); | 521 bool resolve_error = false; |
| 464 if (func.IsNull()) { | 522 { |
| 465 *error = strdup(zone.PrintToString( | 523 Zone zone(child_isolate); |
| 466 "Internal error while starting isolate '%s': " | 524 HandleScope handle_scope(child_isolate); |
| 467 "unable to resolve entry function '%s'.", | 525 const Object& result = Object::Handle(state->ResolveFunction()); |
| 468 child_isolate->name(), state->function_name())); | 526 if (result.IsError()) { |
| 469 retval = false; | 527 Error& errobj = Error::Handle(); |
| 470 } | 528 errobj ^= result.raw(); |
| 529 *error = strdup(errobj.ToErrorCString()); |
| 530 resolve_error = true; |
| 471 } | 531 } |
| 472 } | 532 } |
| 473 if (!retval) { | 533 if (resolve_error) { |
| 474 Dart::ShutdownIsolate(); | 534 Dart::ShutdownIsolate(); |
| 535 Isolate::SetCurrent(parent_isolate); |
| 536 return false; |
| 475 } | 537 } |
| 538 |
| 476 Isolate::SetCurrent(parent_isolate); | 539 Isolate::SetCurrent(parent_isolate); |
| 477 return retval; | 540 return true; |
| 478 } | 541 } |
| 479 | 542 |
| 480 | 543 |
| 481 static bool RunIsolate2(uword parameter) { | 544 static bool RunIsolate2(uword parameter) { |
| 482 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 545 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 483 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data()); | 546 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data()); |
| 484 isolate->set_spawn_data(NULL); | 547 isolate->set_spawn_data(NULL); |
| 485 { | 548 { |
| 486 StartIsolateScope start_scope(isolate); | 549 StartIsolateScope start_scope(isolate); |
| 487 Zone zone(isolate); | 550 Zone zone(isolate); |
| 488 HandleScope handle_scope(isolate); | 551 HandleScope handle_scope(isolate); |
| 489 ASSERT(ClassFinalizer::FinalizePendingClasses()); | 552 ASSERT(ClassFinalizer::FinalizePendingClasses()); |
| 490 Object& result = Object::Handle(); | 553 Object& result = Object::Handle(); |
| 491 | 554 |
| 492 const Function& func = Function::Handle(state->ResolveFunction()); | 555 result = state->ResolveFunction(); |
| 493 delete state; | 556 delete state; |
| 494 state = NULL; | 557 state = NULL; |
| 495 ASSERT(!func.IsNull()); | 558 if (result.IsError()) { |
| 496 | 559 StoreError(isolate, result); |
| 560 return false; |
| 561 } |
| 562 ASSERT(result.IsFunction()); |
| 563 Function& func = Function::Handle(isolate); |
| 564 func ^= result.raw(); |
| 497 GrowableArray<const Object*> args(0); | 565 GrowableArray<const Object*> args(0); |
| 498 const Array& kNoArgNames = Array::Handle(); | 566 const Array& kNoArgNames = Array::Handle(); |
| 499 result = DartEntry::InvokeStatic(func, args, kNoArgNames); | 567 result = DartEntry::InvokeStatic(func, args, kNoArgNames); |
| 500 if (result.IsError()) { | 568 if (result.IsError()) { |
| 501 StoreError(isolate, result); | 569 StoreError(isolate, result); |
| 502 return false; | 570 return false; |
| 503 } | 571 } |
| 504 } | 572 } |
| 505 return true; | 573 return true; |
| 506 } | 574 } |
| 507 | 575 |
| 508 | 576 |
| 509 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) { | 577 static void Spawn(NativeArguments* arguments, SpawnState* state) { |
| 510 GET_NATIVE_ARGUMENT(Closure, closure, arguments->At(0)); | |
| 511 const Function& func = Function::Handle(closure.function()); | |
| 512 const Class& cls = Class::Handle(func.owner()); | |
| 513 if (!func.IsClosureFunction() || !func.is_static() || !cls.IsTopLevel()) { | |
| 514 const String& msg = String::Handle(String::New( | |
| 515 "spawnFunction expects to be passed a closure to a top-level static " | |
| 516 "function")); | |
| 517 ThrowIllegalArgException(msg); | |
| 518 } | |
| 519 | |
| 520 #if defined(DEBUG) | |
| 521 const Context& ctx = Context::Handle(closure.context()); | |
| 522 ASSERT(ctx.num_variables() == 0); | |
| 523 #endif | |
| 524 | |
| 525 // Create a new isolate. | 578 // Create a new isolate. |
| 526 char* error = NULL; | 579 char* error = NULL; |
| 527 SpawnState* state = new SpawnState(func); | |
| 528 if (!CreateIsolate(state, &error)) { | 580 if (!CreateIsolate(state, &error)) { |
| 529 delete state; | 581 delete state; |
| 530 const String& msg = String::Handle(String::New(error)); | 582 const String& msg = String::Handle(String::New(error)); |
| 583 free(error); |
| 531 ThrowIsolateSpawnException(msg); | 584 ThrowIsolateSpawnException(msg); |
| 532 } | 585 } |
| 533 | 586 |
| 534 // Try to create a SendPort for the new isolate. | 587 // Try to create a SendPort for the new isolate. |
| 535 const Object& port = Object::Handle( | 588 const Object& port = Object::Handle( |
| 536 DartLibraryCalls::NewSendPort(state->isolate()->main_port())); | 589 DartLibraryCalls::NewSendPort(state->isolate()->main_port())); |
| 537 if (port.IsError()) { | 590 if (port.IsError()) { |
| 538 state->Cleanup(); | 591 state->Cleanup(); |
| 539 delete state; | 592 delete state; |
| 540 Exceptions::PropagateError(port); | 593 Exceptions::PropagateError(port); |
| 541 } | 594 } |
| 542 | 595 |
| 543 // Start the new isolate. | 596 // Start the new isolate. |
| 544 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); | 597 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); |
| 545 state->isolate()->message_handler()->Run( | 598 state->isolate()->message_handler()->Run( |
| 546 Dart::thread_pool(), RunIsolate2, ShutdownIsolate, | 599 Dart::thread_pool(), RunIsolate2, ShutdownIsolate, |
| 547 reinterpret_cast<uword>(state->isolate())); | 600 reinterpret_cast<uword>(state->isolate())); |
| 548 | 601 |
| 549 arguments->SetReturn(port); | 602 arguments->SetReturn(port); |
| 550 } | 603 } |
| 551 | 604 |
| 552 | 605 |
| 606 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) { |
| 607 GET_NATIVE_ARGUMENT(Closure, closure, arguments->At(0)); |
| 608 const Function& func = Function::Handle(closure.function()); |
| 609 const Class& cls = Class::Handle(func.owner()); |
| 610 if (!func.IsClosureFunction() || !func.is_static() || !cls.IsTopLevel()) { |
| 611 const String& msg = String::Handle(String::New( |
| 612 "spawnFunction expects to be passed a closure to a top-level static " |
| 613 "function")); |
| 614 ThrowIllegalArgException(msg); |
| 615 } |
| 616 |
| 617 #if defined(DEBUG) |
| 618 const Context& ctx = Context::Handle(closure.context()); |
| 619 ASSERT(ctx.num_variables() == 0); |
| 620 #endif |
| 621 |
| 622 Spawn(arguments, new SpawnState(func)); |
| 623 } |
| 624 |
| 625 |
| 626 DEFINE_NATIVE_ENTRY(isolate_spawnUri, 1) { |
| 627 GET_NATIVE_ARGUMENT(String, uri, arguments->At(0)); |
| 628 |
| 629 // Canonicalize the uri with respect to the current isolate. |
| 630 char* error = NULL; |
| 631 char* canonical_uri = NULL; |
| 632 const Library& root_lib = |
| 633 Library::Handle(arguments->isolate()->object_store()->root_library()); |
| 634 if (!CanonicalizeUri(arguments->isolate(), root_lib, uri, |
| 635 &canonical_uri, &error)) { |
| 636 const String& msg = String::Handle(String::New(error)); |
| 637 free(error); |
| 638 ThrowIsolateSpawnException(msg); |
| 639 } |
| 640 |
| 641 Spawn(arguments, new SpawnState(canonical_uri)); |
| 642 } |
| 643 |
| 644 |
| 553 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { | 645 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { |
| 554 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); | 646 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); |
| 555 if (port.IsError()) { | 647 if (port.IsError()) { |
| 556 Exceptions::PropagateError(port); | 648 Exceptions::PropagateError(port); |
| 557 } | 649 } |
| 558 arguments->SetReturn(port); | 650 arguments->SetReturn(port); |
| 559 } | 651 } |
| 560 | 652 |
| 561 } // namespace dart | 653 } // namespace dart |
| OLD | NEW |