| 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..8d17fbc3b7d317cac5987341d762f624877807d8 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 (const auto& entry : child_module->libraries()) {
|
| + 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 entry = Dart_LookupFunction(library, ToDart(name));
|
| + if (!Dart_IsFunction(entry) && !module->isApplication())
|
| + return;
|
| +
|
| + Dart_Handle result = Dart_Invoke(library, ToDart(name), 0, nullptr);
|
| + LogIfError(result);
|
| }
|
|
|
| static void UnhandledExceptionCallback(Dart_Handle error) {
|
|
|