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