Chromium Code Reviews| Index: sky/engine/core/script/dart_controller.cc |
| diff --git a/sky/engine/core/script/dart_controller.cc b/sky/engine/core/script/dart_controller.cc |
| index a46fcc256a4803d8cfb571070d373c630f121df7..1fc4fc881d2d9702eafb79c79514fe276f787082 100644 |
| --- a/sky/engine/core/script/dart_controller.cc |
| +++ b/sky/engine/core/script/dart_controller.cc |
| @@ -8,6 +8,7 @@ |
| #include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/single_thread_task_runner.h" |
| +#include "dart/runtime/include/dart_mirrors_api.h" |
| #include "sky/engine/bindings/builtin.h" |
| #include "sky/engine/bindings/builtin_natives.h" |
| #include "sky/engine/bindings/builtin_sky.h" |
| @@ -43,77 +44,102 @@ static const char* kCheckedModeArgs[] = { |
| extern const uint8_t* kDartSnapshotBuffer; |
| -DartController::DartController() : weak_factory_(this) { |
| +DartController::DartController() { |
| } |
| DartController::~DartController() { |
| } |
| -void DartController::LoadModule(RefPtr<AbstractModule> module, |
| - const String& source, |
| - const TextPosition& textPosition) { |
| - DartIsolateScope isolate_scope(dart_state()->isolate()); |
| - DartApiScope dart_api_scope; |
| - |
| - DartDependencyCatcher dependency_catcher(dart_state()->loader()); |
| +bool DartController::ImportChildLibraries(AbstractModule* module, |
| + Dart_Handle library) { |
| + // If the document has never seen an <import> tag, it won't have an import |
| + // controller, and thus will return null for its root HTMLImport. We could |
| + // remove this null-check by always creating an ImportController. |
| + HTMLImport* root = module->document()->import(); |
| + if (!root) |
| + return true; |
| + |
| + // TODO(abarth): Why doesn't HTMLImport do these casts for us? |
| + for (HTMLImportChild* child = |
| + static_cast<HTMLImportChild*>(root->firstChild()); |
| + child; child = static_cast<HTMLImportChild*>(child->next())) { |
| + if (Element* link = child->link()) { |
| + String name = link->getAttribute(HTMLNames::asAttr); |
| + |
| + Module* child_module = child->module(); |
| + if (!child_module) |
| + continue; |
| + for (auto entry : child_module->libraries()) { |
|
abarth-chromium
2015/02/19 02:51:40
s/auto/const auto&/
You almost always want to use
|
| + if (entry.library()->is_empty()) |
| + continue; |
| + if (LogIfError(Dart_LibraryImportLibrary( |
| + library, entry.library()->dart_value(), |
| + StringToDart(dart_state(), name)))) |
| + return false; |
| + } |
| + } |
| + } |
| + return true; |
| +} |
| +Dart_Handle DartController::CreateLibrary(AbstractModule* module, |
| + const String& source, |
| + const TextPosition& textPosition) { |
| Dart_Handle library = Dart_LoadLibrary( |
| - StringToDart(dart_state(), module->url()), |
| + StringToDart(dart_state(), module->UrlForLibraryAt(textPosition)), |
| StringToDart(dart_state(), source), textPosition.m_line.zeroBasedInt(), |
| textPosition.m_column.zeroBasedInt()); |
| if (LogIfError(library)) |
| - return; |
| + return nullptr; |
| - if (HTMLImport* parent = module->document()->import()) { |
| - for (HTMLImportChild* child = static_cast<HTMLImportChild*>(parent->firstChild()); |
| - child; child = static_cast<HTMLImportChild*>(child->next())) { |
| - if (Element* link = child->link()) { |
| - String name = link->getAttribute(HTMLNames::asAttr); |
| - |
| - Module* childModule = child->module(); |
| - if (childModule |
| - && childModule->library() |
| - && !childModule->library()->is_empty()) { |
| - if (LogIfError(Dart_LibraryImportLibrary( |
| - library, childModule->library()->dart_value(), |
| - StringToDart(dart_state(), name)))) |
| - return; |
| - } |
| - } |
| - } |
| - } |
| + if (!ImportChildLibraries(module, library)) |
| + return nullptr; |
| - module->set_library(DartValue::Create(dart_state(), library)); |
| - const auto& dependencies = dependency_catcher.dependencies(); |
| + return library; |
| +} |
| - if (dependencies.isEmpty()) { |
| - ExecuteModule(module); |
| - } else { |
| - dart_state()->loader().WaitForDependencies( |
| - dependencies, base::Bind(&DartController::ExecuteModule, |
| - weak_factory_.GetWeakPtr(), module)); |
| - } |
| +void DartController::LoadScriptInModule( |
| + AbstractModule* module, |
| + const String& source, |
| + const TextPosition& position, |
| + const LoadFinishedCallback& finished_callback) { |
| + DartIsolateScope isolate_scope(dart_state()->isolate()); |
| + DartApiScope dart_api_scope; |
| + |
| + DartDependencyCatcher dependency_catcher(dart_state()->loader()); |
| + Dart_Handle library_handle = CreateLibrary(module, source, position); |
| + if (!library_handle) |
| + return finished_callback.Run(nullptr, nullptr); |
| + RefPtr<DartValue> library = DartValue::Create(dart_state(), library_handle); |
| + module->AddLibrary(library, position); |
| + |
| + // TODO(eseidel): Better if the library/module retained its dependencies and |
| + // dependency waiting could be separate from library creation. |
| + dart_state()->loader().WaitForDependencies( |
| + dependency_catcher.dependencies(), |
| + base::Bind(finished_callback, module, library)); |
| } |
| -void DartController::ExecuteModule(RefPtr<AbstractModule> module) { |
| +void DartController::ExecuteLibraryInModule(AbstractModule* module, |
| + Dart_Handle library) { |
| + ASSERT(library); |
| DCHECK(Dart_CurrentIsolate() == dart_state()->isolate()); |
| DartApiScope dart_api_scope; |
| // Don't continue if we failed to load the module. |
| if (LogIfError(Dart_FinalizeLoading(true))) |
| return; |
| - Dart_Handle library = module->library()->dart_value(); |
| const char* name = module->isApplication() ? "main" : "init"; |
| - Dart_Handle closure_name = Dart_NewStringFromCString(name); |
| - Dart_Handle result = Dart_Invoke(library, closure_name, 0, nullptr); |
| - |
| - if (module->isApplication()) { |
| - // TODO(dart): This will throw an API error if main() is absent. It would be |
| - // better to test whether main() is present first, then attempt to invoke it |
| - // so as to capture & report other errors. |
| - LogIfError(result); |
| - } |
| + |
| + // main() is required, but init() is not: |
| + // TODO(rmacnak): Dart_LookupFunction won't find re-exports, etc. |
| + Dart_Handle main = Dart_LookupFunction(library, ToDart(name)); |
|
abarth-chromium
2015/02/19 02:51:40
s/main/entry/ ? It's not always main.
|
| + if (!Dart_IsFunction(main) && !module->isApplication()) |
| + return; |
| + |
| + Dart_Handle result = Dart_Invoke(library, ToDart(name), 0, nullptr); |
| + LogIfError(result); |
| } |
| static void UnhandledExceptionCallback(Dart_Handle error) { |