diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc index ed131668b64..a7e46617fd7 100644 --- a/runtime/vm/isolate.cc +++ b/runtime/vm/isolate.cc @@ -1569,31 +1569,46 @@ IsolateSpawnState::~IsolateSpawnState() { RawObject* IsolateSpawnState::ResolveFunction() { - // Resolve the library. - Library& lib = Library::Handle(); - if (library_url()) { - const String& lib_url = String::Handle(String::New(library_url())); - lib = Library::LookupLibrary(lib_url); - if (lib.IsNull() || lib.IsError()) { - const String& msg = String::Handle(String::NewFormatted( - "Unable to find library '%s'.", library_url())); - return LanguageError::New(msg); - } - } else { - lib = I->object_store()->root_library(); - } - ASSERT(!lib.IsNull()); - - // Resolve the function. const String& func_name = String::Handle(String::New(function_name())); + if (library_url() == NULL) { + // Handle spawnUri lookup rules. + // Check whether the root library defines a main function. + const Library& lib = Library::Handle(I->object_store()->root_library()); + Function& func = Function::Handle(lib.LookupLocalFunction(func_name)); + if (func.IsNull()) { + // Check whether main is reexported from the root library. + const Object& obj = Object::Handle(lib.LookupReExport(func_name)); + if (obj.IsFunction()) { + func ^= obj.raw(); + } + } + if (func.IsNull()) { + const String& msg = String::Handle(String::NewFormatted( + "Unable to resolve function '%s' in script '%s'.", + function_name(), script_url())); + return LanguageError::New(msg); + } + return func.raw(); + } + + ASSERT(script_url() == NULL); + // Resolve the library. + const String& lib_url = String::Handle(String::New(library_url())); + const Library& lib = Library::Handle(Library::LookupLibrary(lib_url)); + if (lib.IsNull() || lib.IsError()) { + const String& msg = String::Handle(String::NewFormatted( + "Unable to find library '%s'.", library_url())); + return LanguageError::New(msg); + } + + // Resolve the function. if (class_name() == NULL) { const Function& func = Function::Handle(lib.LookupLocalFunction(func_name)); if (func.IsNull()) { const String& msg = String::Handle(String::NewFormatted( "Unable to resolve function '%s' in library '%s'.", - function_name(), - (library_url() != NULL ? library_url() : script_url()))); + function_name(), library_url())); return LanguageError::New(msg); } return func.raw(); diff --git a/tests/isolate/spawn_uri_exported_main.dart b/tests/isolate/spawn_uri_exported_main.dart new file mode 100644 index 00000000000..afd0122978d --- /dev/null +++ b/tests/isolate/spawn_uri_exported_main.dart @@ -0,0 +1,5 @@ +export "spawn_uri_exported_main_lib.dart"; + +maine() { + print("This is not the maine you are looking for."); +} diff --git a/tests/isolate/spawn_uri_exported_main_lib.dart b/tests/isolate/spawn_uri_exported_main_lib.dart new file mode 100644 index 00000000000..750046575d5 --- /dev/null +++ b/tests/isolate/spawn_uri_exported_main_lib.dart @@ -0,0 +1,6 @@ +library spawn_uri_exported_main_lib; + +main(args, msg) { + print("From main!"); + msg.send(50); +} diff --git a/tests/isolate/spawn_uri_exported_main_test.dart b/tests/isolate/spawn_uri_exported_main_test.dart new file mode 100644 index 00000000000..252980d174e --- /dev/null +++ b/tests/isolate/spawn_uri_exported_main_test.dart @@ -0,0 +1,20 @@ +import "dart:async"; +import "dart:isolate"; +import "package:expect/expect.dart"; + +main() { + print("Spawning isolate."); + var t = new Timer(new Duration(seconds:5), () { + Expect.fail("Isolate was not spawned successfully."); + }); + var rp = new RawReceivePort(); + rp.handler = (msg) { + print("Spawned main called."); + Expect.equals(msg, 50); + rp.close(); + }; + Isolate.spawnUri(Uri.parse("spawn_uri_exported_main.dart"), null, rp.sendPort).then((_) { + print("Loaded"); + t.cancel(); + }); +}