提交 c6dce9ad 编写于 作者: A Adam Barth

Add DartController and friends

This CL adds the DartController and associated classes. These classes let you
load and execute dart code.

R=rafaelw@chromium.org
BUG=454613

Review URL: https://codereview.chromium.org/921903002
上级 12859157
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/engine/config.h"
#include "sky/engine/core/script/dart_controller.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "sky/engine/bindings2/builtin.h"
#include "sky/engine/bindings2/builtin_natives.h"
#include "sky/engine/bindings2/builtin_sky.h"
#include "sky/engine/core/app/AbstractModule.h"
#include "sky/engine/core/app/Module.h"
#include "sky/engine/core/dom/Element.h"
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/html/imports/HTMLImport.h"
#include "sky/engine/core/html/imports/HTMLImportChild.h"
#include "sky/engine/core/loader/FrameLoaderClient.h"
#include "sky/engine/core/script/dart_dependency_catcher.h"
#include "sky/engine/core/script/dart_loader.h"
#include "sky/engine/core/script/dom_dart_state.h"
#include "sky/engine/public/platform/Platform.h"
#include "sky/engine/tonic/dart_api_scope.h"
#include "sky/engine/tonic/dart_class_library.h"
#include "sky/engine/tonic/dart_error.h"
#include "sky/engine/tonic/dart_gc_controller.h"
#include "sky/engine/tonic/dart_isolate_scope.h"
#include "sky/engine/tonic/dart_state.h"
#include "sky/engine/wtf/text/TextPosition.h"
namespace blink {
#if ENABLE(ASSERT)
static const char* kCheckedModeArgs[] = {
"--enable_asserts",
"--enable_type_checks",
"--error_on_bad_type",
"--error_on_bad_override",
};
#endif
extern const uint8_t* kDartSnapshotBuffer;
DartController::DartController() : weak_factory_(this) {
}
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());
Dart_Handle library = Dart_LoadLibrary(
StringToDart(dart_state(), module->url()),
StringToDart(dart_state(), source), textPosition.m_line.zeroBasedInt(),
textPosition.m_column.zeroBasedInt());
if (LogIfError(library))
return;
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;
}
}
}
}
module->set_library(DartValue::Create(dart_state(), library));
const auto& dependencies = dependency_catcher.dependencies();
if (dependencies.isEmpty()) {
ExecuteModule(module);
} else {
dart_state()->loader().WaitForDependencies(
dependencies, base::Bind(&DartController::ExecuteModule,
weak_factory_.GetWeakPtr(), module));
}
}
void DartController::ExecuteModule(RefPtr<AbstractModule> module) {
DCHECK(Dart_CurrentIsolate() == dart_state()->isolate());
DartApiScope dart_api_scope;
LogIfError(Dart_FinalizeLoading(true));
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);
}
}
static void UnhandledExceptionCallback(Dart_Handle error) {
DCHECK(!Dart_IsError(error));
LOG(ERROR) << Dart_GetError(error);
}
static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url) {
return DartLoader::HandleLibraryTag(tag, library, url);
}
static void IsolateShutdownCallback(void* callback_data) {
// TODO(dart)
}
static bool IsServiceIsolateURL(const char* url_name) {
return url_name != nullptr &&
String(url_name) == DART_VM_SERVICE_ISOLATE_NAME;
}
// TODO(rafaelw): Right now this only supports the creation of the handle
// watcher isolate. Presumably, we'll want application isolates to spawn their
// own isolates.
static Dart_Isolate IsolateCreateCallback(const char* script_uri,
const char* main,
const char* package_root,
void* callback_data,
char** error) {
if (IsServiceIsolateURL(script_uri)) {
return Dart_CreateIsolate(script_uri, "main", kDartSnapshotBuffer, nullptr,
error);
}
// Create & start the handle watcher isolate
CHECK(kDartSnapshotBuffer);
DartState* dart_state = new DartState();
Dart_Isolate isolate = Dart_CreateIsolate("sky:handle_watcher", "",
kDartSnapshotBuffer, dart_state, error);
CHECK(isolate) << error;
dart_state->set_isolate(isolate);
CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler)));
{
DartApiScope apiScope;
Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
Builtin::SetNativeResolver(Builtin::kMojoCoreLibrary);
}
Dart_ExitIsolate();
CHECK(Dart_IsolateMakeRunnable(isolate));
return isolate;
}
static void CallHandleMessage(base::WeakPtr<DartState> dart_state) {
if (!dart_state)
return;
DartIsolateScope scope(dart_state->isolate());
DartApiScope api_scope;
LogIfError(Dart_HandleMessage());
}
static void MessageNotifyCallback(Dart_Isolate dest_isolate) {
DCHECK(Platform::current());
Platform::current()->mainThreadTaskRunner()->PostTask(FROM_HERE,
base::Bind(&CallHandleMessage, DartState::From(dest_isolate)->GetWeakPtr()));
}
static void EnsureHandleWatcherStarted() {
static bool handle_watcher_started = false;
if (handle_watcher_started)
return;
// TODO(dart): Call Dart_Cleanup (ensure the handle watcher isolate is closed)
// during shutdown.
Dart_Handle mojo_core_lib =
Builtin::LoadAndCheckLibrary(Builtin::kMojoCoreLibrary);
CHECK(!LogIfError((mojo_core_lib)));
Dart_Handle handle_watcher_type = Dart_GetType(
mojo_core_lib,
Dart_NewStringFromCString("MojoHandleWatcher"),
0,
nullptr);
CHECK(!LogIfError(handle_watcher_type));
CHECK(!LogIfError(Dart_Invoke(
handle_watcher_type,
Dart_NewStringFromCString("_start"),
0,
nullptr)));
// RunLoop until the handle watcher isolate is spun-up.
CHECK(!LogIfError(Dart_RunLoop()));
handle_watcher_started = true;
}
void DartController::CreateIsolateFor(Document* document) {
DCHECK(document);
CHECK(kDartSnapshotBuffer);
char* error = nullptr;
dom_dart_state_ = adoptPtr(new DOMDartState(document));
Dart_Isolate isolate = Dart_CreateIsolate(
document->url().string().utf8().data(), "main", kDartSnapshotBuffer,
static_cast<DartState*>(dom_dart_state_.get()), &error);
Dart_SetMessageNotifyCallback(MessageNotifyCallback);
CHECK(isolate) << error;
dom_dart_state_->set_isolate(isolate);
Dart_SetGcCallbacks(DartGCPrologue, DartGCEpilogue);
CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler)));
{
DartApiScope apiScope;
Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
Builtin::SetNativeResolver(Builtin::kMojoCoreLibrary);
BuiltinNatives::Init();
builtin_sky_ = adoptPtr(new BuiltinSky(dart_state()));
dart_state()->class_library().set_provider(builtin_sky_.get());
builtin_sky_->InstallWindow(dart_state());
document->frame()->loaderClient()->didCreateIsolate(isolate);
EnsureHandleWatcherStarted();
}
Dart_ExitIsolate();
}
void DartController::ClearForClose() {
DartIsolateScope scope(dom_dart_state_->isolate());
Dart_ShutdownIsolate();
dom_dart_state_.clear();
}
void DartController::InitVM() {
int argc = 0;
const char** argv = nullptr;
#if ENABLE(ASSERT)
argc = arraysize(kCheckedModeArgs);
argv = kCheckedModeArgs;
#endif
CHECK(Dart_SetVMFlags(argc, argv));
CHECK(Dart_Initialize(IsolateCreateCallback,
nullptr, // Isolate interrupt callback.
UnhandledExceptionCallback, IsolateShutdownCallback,
// File IO callbacks.
nullptr, nullptr, nullptr, nullptr, nullptr));
}
} // namespace blink
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKY_ENGINE_CORE_SCRIPT_DART_CONTROLLER_H_
#define SKY_ENGINE_CORE_SCRIPT_DART_CONTROLLER_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "dart/runtime/include/dart_api.h"
#include "sky/engine/wtf/OwnPtr.h"
#include "sky/engine/wtf/text/AtomicString.h"
#include "sky/engine/wtf/text/TextPosition.h"
namespace blink {
class AbstractModule;
class BuiltinSky;
class DOMDartState;
class Document;
class DartController {
public:
DartController();
~DartController();
static void InitVM();
void LoadModule(RefPtr<AbstractModule> module,
const String& source,
const TextPosition& textPosition);
void ClearForClose();
void CreateIsolateFor(Document*);
DOMDartState* dart_state() const { return dom_dart_state_.get(); }
private:
void ExecuteModule(RefPtr<AbstractModule> module);
OwnPtr<DOMDartState> dom_dart_state_;
OwnPtr<BuiltinSky> builtin_sky_;
base::WeakPtrFactory<DartController> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DartController);
};
}
#endif // SKY_ENGINE_CORE_SCRIPT_DART_CONTROLLER_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/engine/config.h"
#include "sky/engine/core/script/dart_dependency_catcher.h"
#include "sky/engine/core/script/dart_loader.h"
namespace blink {
DartDependencyCatcher::DartDependencyCatcher(DartLoader& loader) : loader_(loader) {
loader_.set_dependency_catcher(this);
}
DartDependencyCatcher::~DartDependencyCatcher() {
loader_.set_dependency_catcher(nullptr);
}
void DartDependencyCatcher::AddDependency(DartDependency* dependency) {
dependencies_.add(dependency);
}
} // namespace blink
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKY_ENGINE_CORE_SCRIPT_DEPENDENCY_CATCHER_H_
#define SKY_ENGINE_CORE_SCRIPT_DEPENDENCY_CATCHER_H_
#include "base/macros.h"
#include "sky/engine/wtf/HashSet.h"
namespace blink {
class DartLoader;
// A base class to represent a dependency.
class DartDependency {
};
// To catch the dependencies for a library, put a DartDependencyCatcher on the
// stack during the call to Dart_LoadLibrary.
class DartDependencyCatcher {
public:
explicit DartDependencyCatcher(DartLoader& loader);
~DartDependencyCatcher();
void AddDependency(DartDependency* dependency);
const HashSet<DartDependency*>& dependencies() const { return dependencies_; }
private:
DartLoader& loader_;
HashSet<DartDependency*> dependencies_;
DISALLOW_COPY_AND_ASSIGN(DartDependencyCatcher);
};
} // namespace blink
#endif // SKY_ENGINE_CORE_SCRIPT_DEPENDENCY_CATCHER_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/engine/config.h"
#include "sky/engine/core/script/dart_loader.h"
#include "base/callback.h"
#include "mojo/common/data_pipe_drainer.h"
#include "sky/engine/core/script/dart_dependency_catcher.h"
#include "sky/engine/core/script/dom_dart_state.h"
#include "sky/engine/platform/fetcher/MojoFetcher.h"
#include "sky/engine/platform/weborigin/KURL.h"
#include "sky/engine/tonic/dart_api_scope.h"
#include "sky/engine/tonic/dart_converter.h"
#include "sky/engine/tonic/dart_error.h"
#include "sky/engine/tonic/dart_isolate_scope.h"
#include "sky/engine/wtf/MainThread.h"
using mojo::common::DataPipeDrainer;
namespace blink {
namespace {
Dart_Handle CanonicalizeURL(DartState* state,
Dart_Handle library,
Dart_Handle url) {
String string = StringFromDart(url);
if (string.startsWith("dart:"))
return url;
// TODO(dart): Figure out how 'package:' should work in sky.
if (string.startsWith("package:")) {
string.replace("package:", "/gen/");
}
String library_url_string = StringFromDart(Dart_LibraryUrl(library));
KURL library_url = KURL(ParsedURLString, library_url_string);
KURL resolved_url = KURL(library_url, string);
return StringToDart(state, resolved_url.string());
}
} // namespace
// A DartLoader::Job represents a network load. It fetches data from the network
// and buffers the data in Vector. To cancel the job, delete this object.
class DartLoader::Job : public DartDependency,
public MojoFetcher::Client,
public DataPipeDrainer::Client {
public:
Job(DartLoader* loader, const KURL& url)
: loader_(loader), url_(url), fetcher_(this, url) {}
const KURL& url() const { return url_; }
protected:
DartLoader* loader_;
// TODO(abarth): Should we be using SharedBuffer to buffer the data?
Vector<uint8_t> buffer_;
private:
// MojoFetcher::Client
void OnReceivedResponse(mojo::URLResponsePtr response) override {
// TODO(abarth): Handle network errors.
drainer_ = adoptPtr(new DataPipeDrainer(this, response->body.Pass()));
}
// DataPipeDrainer::Client
void OnDataAvailable(const void* data, size_t num_bytes) override {
buffer_.append(static_cast<const uint8_t*>(data), num_bytes);
}
// Subclasses must implement OnDataComplete.
KURL url_;
MojoFetcher fetcher_;
OwnPtr<DataPipeDrainer> drainer_;
};
class DartLoader::ImportJob : public Job {
public:
using Job::Job;
private:
// DataPipeDrainer::Client
void OnDataComplete() override {
loader_->DidCompleteImportJob(this, buffer_);
}
};
class DartLoader::SourceJob : public Job {
public:
SourceJob(DartLoader* loader, const KURL& url, Dart_Handle library)
: Job(loader, url), library_(loader->dart_state(), library) {}
Dart_PersistentHandle library() const { return library_.value(); }
private:
// DataPipeDrainer::Client
void OnDataComplete() override {
loader_->DidCompleteSourceJob(this, buffer_);
}
DartPersistentValue library_;
};
// A DependencyWatcher represents a request to watch for when a given set of
// dependencies (either libraries or parts of libraries) have finished loading.
// When the dependencies are satisfied (including transitive dependencies), then
// the |callback| will be invoked.
class DartLoader::DependencyWatcher {
public:
DependencyWatcher(const HashSet<DartDependency*>& dependencies,
const base::Closure& callback)
: dependencies_(dependencies), callback_(callback) {
DCHECK(!dependencies_.isEmpty());
}
bool DidResolveDependency(DartDependency* resolved_dependency,
const HashSet<DartDependency*>& new_dependencies) {
const auto& it = dependencies_.find(resolved_dependency);
if (it == dependencies_.end())
return false;
dependencies_.remove(it);
for (const auto& dependency : new_dependencies)
dependencies_.add(dependency);
return dependencies_.isEmpty();
}
const base::Closure& callback() const { return callback_; }
private:
HashSet<DartDependency*> dependencies_;
base::Closure callback_;
};
// A WatcherSignaler is responsible for signaling DependencyWatchers when their
// dependencies resolve and for calling the DependencyWatcher's callback. We use
// a separate object of this task because we want to carefully manage when we
// call the callbacks, which can call into us again reentrantly.
//
// WatcherSignaler is designed to be placed on the stack as a RAII. After its
// destructor runs, we might have executed aribitrary script.
class DartLoader::WatcherSignaler {
public:
WatcherSignaler(DartLoader& loader, DartDependency* resolved_dependency)
: loader_(loader),
catcher_(adoptPtr(new DartDependencyCatcher(loader))),
resolved_dependency_(resolved_dependency) {}
~WatcherSignaler() {
Vector<DependencyWatcher*> completed_watchers;
for (const auto& watcher : loader_.dependency_watchers_) {
if (watcher->DidResolveDependency(resolved_dependency_,
catcher_->dependencies()))
completed_watchers.append(watcher.get());
}
// Notice that we remove the dependency catcher and extract all the
// callbacks before running any of them. We don't want to be re-entered
// below the callbacks and end up in an inconsistent state.
catcher_.clear();
Vector<base::Closure> callbacks;
for (const auto& watcher : completed_watchers) {
callbacks.append(watcher->callback());
loader_.dependency_watchers_.remove(watcher);
}
// Finally, run all the callbacks while touching only data on the stack.
for (const auto& callback : callbacks)
callback.Run();
}
private:
DartLoader& loader_;
OwnPtr<DartDependencyCatcher> catcher_;
DartDependency* resolved_dependency_;
};
DartLoader::DartLoader(DartState* dart_state)
: dart_state_(dart_state->GetWeakPtr()), dependency_catcher_(nullptr) {
}
DartLoader::~DartLoader() {
}
Dart_Handle DartLoader::HandleLibraryTag(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url) {
DCHECK(Dart_IsLibrary(library));
DCHECK(Dart_IsString(url));
if (tag == Dart_kCanonicalizeUrl)
return CanonicalizeURL(DartState::Current(), library, url);
if (tag == Dart_kImportTag) {
CHECK(WTF::isMainThread());
return DOMDartState::Current()->loader().Import(library, url);
}
if (tag == Dart_kSourceTag) {
CHECK(WTF::isMainThread());
return DOMDartState::Current()->loader().Source(library, url);
}
DCHECK(false);
return Dart_NewApiError("Unknown library tag.");
}
void DartLoader::WaitForDependencies(
const HashSet<DartDependency*>& dependencies,
const base::Closure& callback) {
dependency_watchers_.add(
adoptPtr(new DependencyWatcher(dependencies, callback)));
}
Dart_Handle DartLoader::Import(Dart_Handle library, Dart_Handle url) {
KURL parsed_url(ParsedURLString, StringFromDart(url));
const auto& result = pending_libraries_.add(parsed_url.string(), nullptr);
if (result.isNewEntry) {
OwnPtr<Job> job = adoptPtr(new ImportJob(this, parsed_url));
result.storedValue->value = job.get();
jobs_.add(job.release());
}
if (dependency_catcher_)
dependency_catcher_->AddDependency(result.storedValue->value);
return Dart_True();
}
Dart_Handle DartLoader::Source(Dart_Handle library, Dart_Handle url) {
KURL parsed_url(ParsedURLString, StringFromDart(url));
OwnPtr<Job> job = adoptPtr(new SourceJob(this, parsed_url, library));
if (dependency_catcher_)
dependency_catcher_->AddDependency(job.get());
jobs_.add(job.release());
return Dart_True();
}
void DartLoader::DidCompleteImportJob(ImportJob* job,
const Vector<uint8_t>& buffer) {
DCHECK(dart_state_);
DartIsolateScope scope(dart_state_->isolate());
DartApiScope api_scope;
WatcherSignaler watcher_signaler(*this, job);
String url_string = job->url().string();
LogIfError(Dart_LoadLibrary(
StringToDart(dart_state_.get(), url_string),
Dart_NewStringFromUTF8(buffer.data(), buffer.size()), 0, 0));
pending_libraries_.remove(url_string);
jobs_.remove(job);
}
void DartLoader::DidCompleteSourceJob(SourceJob* job,
const Vector<uint8_t>& buffer) {
DCHECK(dart_state_);
DartIsolateScope scope(dart_state_->isolate());
DartApiScope api_scope;
WatcherSignaler watcher_signaler(*this, job);
LogIfError(Dart_LoadSource(
Dart_HandleFromPersistent(job->library()),
StringToDart(dart_state_.get(), job->url().string()),
Dart_NewStringFromUTF8(buffer.data(), buffer.size()), 0, 0));
jobs_.remove(job);
}
} // namespace blink
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKY_ENGINE_CORE_SCRIPT_DART_LOADER_H_
#define SKY_ENGINE_CORE_SCRIPT_DART_LOADER_H_
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "dart/runtime/include/dart_api.h"
#include "sky/engine/wtf/HashMap.h"
#include "sky/engine/wtf/HashSet.h"
#include "sky/engine/wtf/OwnPtr.h"
#include "sky/engine/wtf/Vector.h"
#include "sky/engine/wtf/text/WTFString.h"
namespace blink {
class DartState;
class DartDependency;
class DartDependencyCatcher;
// TODO(abarth): This class seems more complicated than it needs to be. Is
// there some way of simplifying this system? For example, we have a bunch
// of inner classes that could potentially be factored out in some other way.
class DartLoader {
public:
explicit DartLoader(DartState* dart_state);
~DartLoader();
// TODO(dart): This can be called both on the main thread from application isolates
// or from the handle watcher isolate thread.
static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url);
void WaitForDependencies(const HashSet<DartDependency*>& dependencies,
const base::Closure& callback);
void set_dependency_catcher(DartDependencyCatcher* dependency_catcher) {
DCHECK(!dependency_catcher_ || !dependency_catcher);
dependency_catcher_ = dependency_catcher;
}
DartState* dart_state() const { return dart_state_.get(); }
private:
class Job;
class ImportJob;
class SourceJob;
class DependencyWatcher;
class WatcherSignaler;
Dart_Handle Import(Dart_Handle library, Dart_Handle url);
Dart_Handle Source(Dart_Handle library, Dart_Handle url);
void DidCompleteImportJob(ImportJob* job, const Vector<uint8_t>& buffer);
void DidCompleteSourceJob(SourceJob* job, const Vector<uint8_t>& buffer);
base::WeakPtr<DartState> dart_state_;
HashMap<String, Job*> pending_libraries_;
HashSet<OwnPtr<Job>> jobs_;
HashSet<OwnPtr<DependencyWatcher>> dependency_watchers_;
DartDependencyCatcher* dependency_catcher_;
DISALLOW_COPY_AND_ASSIGN(DartLoader);
};
} // namespace blink
#endif // SKY_ENGINE_CORE_SCRIPT_DART_LOADER_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/engine/config.h"
#include "sky/engine/core/script/dom_dart_state.h"
#include "sky/engine/core/dom/Document.h"
#include "sky/engine/core/script/dart_loader.h"
namespace blink {
DOMDartState::DOMDartState(Document* document)
: document_(document), loader_(adoptPtr(new DartLoader(this))) {
DCHECK(document_);
}
DOMDartState::~DOMDartState() {
}
DOMDartState* DOMDartState::Current() {
return static_cast<DOMDartState*>(DartState::Current());
}
Document* DOMDartState::CurrentDocument() {
return Current()->document_.get();
}
LocalFrame* DOMDartState::CurrentFrame() {
return Current()->document_->frame();
}
LocalDOMWindow* DOMDartState::CurrentWindow() {
return Current()->document_->domWindow();
}
}
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKY_ENGINE_CORE_SCRIPT_DOM_DART_STATE_H_
#define SKY_ENGINE_CORE_SCRIPT_DOM_DART_STATE_H_
#include "dart/runtime/include/dart_api.h"
#include "sky/engine/tonic/dart_state.h"
#include "sky/engine/core/dom/Document.h"
#include "sky/engine/wtf/RefPtr.h"
namespace blink {
class DartLoader;
class LocalFrame;
class LocalDOMWindow;
class DOMDartState : public DartState {
public:
explicit DOMDartState(Document* document);
~DOMDartState() override;
static DOMDartState* Current();
static Document* CurrentDocument();
static LocalFrame* CurrentFrame();
static LocalDOMWindow* CurrentWindow();
Document* document() const { return document_.get(); }
DartLoader& loader() const { return *loader_; }
private:
RefPtr<Document> document_;
OwnPtr<DartLoader> loader_;
};
}
#endif // SKY_ENGINE_CORE_SCRIPT_DOM_DART_STATE_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册