Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Unified Diff: Source/WebCore/bindings/dart/DartController.cpp

Issue 8802010: Dart bindings for WebKit (Closed) Base URL: http://svn.webkit.org/repository/webkit/trunk
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/WebCore/bindings/dart/DartController.h ('k') | Source/WebCore/bindings/dart/DartDOMWrapper.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/WebCore/bindings/dart/DartController.cpp
diff --git a/Source/WebCore/bindings/dart/DartController.cpp b/Source/WebCore/bindings/dart/DartController.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..51ac0767c5522938f76c45cc911540c25f46cdea
--- /dev/null
+++ b/Source/WebCore/bindings/dart/DartController.cpp
@@ -0,0 +1,307 @@
+// Copyright (c) 2009, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "DartController.h"
+
+#include "DOMWindow.h"
+#include "DartApplicationLoader.h"
+#include "DartBuiltinLibrarySource.h"
+#include "DartClassInfo.h"
+#include "DartDOMLibrarySource.h"
+#include "DartDOMWindow.h"
+#include "DartDOMWrapper.h"
+#include "DartFlags.h"
+#include "DartIsolateState.h"
+#include "DartUtilities.h"
+#include "Document.h"
+#include "Frame.h"
+#include "IDBPendingTransactionMonitor.h"
+#include "JavaScriptController.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "ScriptExecutionContext.h"
+#include "Settings.h"
+#include "StorageNamespace.h"
+
+#include "npruntime_impl.h"
+#include <bindings/npruntime.h>
+
+namespace WebCore {
+
+static void initDOMIsolate()
+{
+ DartApiScope dartApiScope;
+
+ // Create the dom library.
+ Dart_Handle dom = Dart_LoadLibrary(Dart_NewString(DartUtilities::domLibraryName), Dart_NewString("#library(\"Dom\");"));
+ ASSERT(!Dart_IsError(dom));
+ Dart_LibraryImportLibrary(dom, Dart_LookupLibrary(Dart_NewString("dart:coreimpl")));
+ // FIXME: add return value checks.
+ Dart_LoadSource(dom, Dart_NewString("DOMExtensions"), Dart_NewString(dartDOMLibrarySource));
+ Dart_CreateNativeWrapperClass(dom, Dart_NewString("DOMWrapperBase"), DartDOMWrapper::wrapperNativeFieldCount());
+
+ // Inject builtin library to forward core functionality to dom.
+ // FIXME: We need to provide something for non-DOM isolates as well.
+ Dart_Handle core = Dart_LookupLibrary(Dart_NewString("dart:core"));
+ Dart_LoadSource(core, Dart_NewString("dart:builtin"), Dart_NewString(dartBuiltinLibrarySource));
+ Dart_LibraryImportLibrary(core, dom);
+
+ DartClassInfo::registerClasses(dom);
+}
+
+DartPerScriptState::DartPerScriptState(Document* document, NPObject* layoutTestController)
+ : m_dartApplicationLoader(adoptRef(new DartApplicationLoader(document, layoutTestController)))
+ , m_isolate(DartIsolateState::create(document, m_dartApplicationLoader.get()))
+{
+ initDOMIsolate();
+ isolateToDartApplicationLoaderMap().set(m_isolate, m_dartApplicationLoader.get());
+ // DartIsolateState::create pushes newly create isolate, undo it.
+ DartIsolateState::pop();
+}
+
+DartPerScriptState::~DartPerScriptState()
+{
+ *DartUtilities::recursionForIsolate(m_isolate) = 0;
+ isolateToDartApplicationLoaderMap().remove(m_isolate);
+ DartIsolateState::shutdown(m_isolate);
+}
+
+DartController::DartController(Frame* frame)
+ : m_frame(frame)
+ , m_states()
+ , m_layoutTestController(0)
+{
+ // The DartController's constructor must be called in the Frame's
+ // constructor, so it can properly maintain the unit of related
+ // browsing contexts.
+
+ // The DartController must be created after the frame's loader and
+ // tree nodes are initialized.
+ ASSERT(frame->loader());
+ ASSERT(frame->tree());
+}
+
+void DartController::clearWindowShell()
+{
+ m_states.clear();
+}
+
+class PostMessageTask : public ScriptExecutionContext::Task {
+public:
+ PostMessageTask(Dart_Isolate destinationIsolate, Dart_Port destinationPort, Dart_Port replyPort, Dart_Message message)
+ : m_destinationIsolate(destinationIsolate)
+ , m_destinationPort(destinationPort)
+ , m_replyPort(replyPort)
+ , m_message(message) { }
+
+ ~PostMessageTask()
+ {
+ free(m_message);
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ // FIXME: one shouldn't trust isFullDomIsolate as another
+ // isolate with the same address might be allocated. Apparently better
+ // way would be to maintain a way to tell all the tasks that they are
+ // cancelled from now on. For example, we may maintain a list of all
+ // pending tasks and iterate over it.
+ // destinationIsolate might have been shut down before.
+ if (!DartUtilities::isFullDomIsolate(m_destinationIsolate))
+ return;
+ DartIsolateState::Scope scope(m_destinationIsolate);
+ DartApiScope apiScope;
+ Dart_Handle result = Dart_HandleMessage(m_destinationPort, m_replyPort, m_message);
+ if (Dart_IsError(result))
+ DartUtilities::reportProblem(context, result);
+ }
+
+private:
+ Dart_Isolate m_destinationIsolate;
+ Dart_Port m_destinationPort;
+ Dart_Port m_replyPort;
+ Dart_Message m_message;
+};
+
+static bool postMessageCallback(Dart_Isolate destinationIsolate, Dart_Port destinationPort, Dart_Port replyPort, Dart_Message message)
+{
+ ASSERT(DartUtilities::isFullDomIsolate(destinationIsolate));
+ ScriptExecutionContext* destinationContext = DartUtilities::isolateContext(destinationIsolate);
+ destinationContext->postTask(adoptPtr(new PostMessageTask(destinationIsolate, destinationPort, replyPort, message)));
+ return true;
+}
+
+static void closePortCallback(Dart_Isolate, Dart_Port)
+{
+}
+
+void DartController::setupDOMEnabledIsolate(ScriptExecutionContext* context)
+{
+ ASSERT(context);
+ Dart_SetMessageCallbacks(&postMessageCallback, &closePortCallback);
+ DartUtilities::registerIsolateContext(Dart_CurrentIsolate(), context);
+}
+
+bool DartController::initializeIsolateCallback(void* data, char** errorMsg)
+{
+ Dart_Isolate isolate = Dart_CreateIsolate(0, data, errorMsg);
+ if (!isolate)
+ return false;
+
+ DartApiScope dartApiScope;
+
+ // It's safe to reinitialize DOM in all isolates: unless Dart isolate is
+ // registered with DartUtilities::registerIsolatecContext, it's DOM functionality
+ // will be disabled: we won't be able to resolve top level accessors.
+ initDOMIsolate();
+
+ DartApplicationLoader* dartApplicationLoader = reinterpret_cast<DartApplicationLoader*>(data);
+ // FIXME: when DartVM has shutdown callback, we'll be able to deref it.
+ dartApplicationLoader->ref();
+
+ ASSERT(!dartApplicationLoader->isLoadingMainIsolate());
+ dartApplicationLoader->reinjectSources();
+
+ return true;
+}
+
+void DartController::initVMIfNeeded()
+{
+ static bool hasBeenInitialized = false;
+ if (hasBeenInitialized)
+ return;
+
+ int argc = DartFlags::count();
+ const char** argv = const_cast<const char**>(DartFlags::flags());
+ Dart_SetVMFlags(argc, argv);
+ Dart_Initialize(&initializeIsolateCallback);
+ hasBeenInitialized = true;
+}
+
+bool DartController::isScriptTypeSupported(const String& mimeType)
+{
+ DEFINE_STATIC_LOCAL(HashSet<String>, types, ());
+ if (types.isEmpty()) {
+ types.add("application/dart");
+ types.add("application/dart-app");
+ types.add("application/dart-script");
+ }
+ return !mimeType.isEmpty() && types.contains(mimeType);
+}
+
+void DartController::evaluate(const ScriptSourceCode& sourceCode)
+{
+ if (!m_frame->page()->settings()->isDartEnabled())
+ return;
+
+ initVMIfNeeded();
+
+ // FIXME: it may make sense to ensure that we'll never call evaluate more than once for the same script tag.
+ DartPerScriptState* state = new DartPerScriptState(frame()->document(), m_layoutTestController);
+ ASSERT(state->isolate());
+ m_states.append(adoptPtr(state));
+
+ DartIsolateState::Scope scope(state->isolate());
+ state->dartApplicationLoader()->load(sourceCode.url(), sourceCode.source());
+}
+
+void DartController::bindToWindowObject(Frame*, const String& key, NPObject* object)
+{
+ // FIXME: production code should not know anything about layoutTestController.
+ if (key != "layoutTestController")
+ return;
+
+ // FIXME: proper management of lifetime.
+ ASSERT(m_states.isEmpty());
+ m_layoutTestController = object;
+}
+
+Dart_Handle DartController::callFunction(Dart_Handle function, int argc, Dart_Handle* argv)
+{
+ // FIXME: Introduce Dart variant of V8GCController::checkMemoryUsage();
+ const int kMaxRecursionDepth = 22;
+
+ int* recursion = DartUtilities::recursionForCurrentIsolate();
+
+ if (*recursion >= kMaxRecursionDepth)
+ return Dart_Error("Maximum call stack size exceeded");
+
+ // FIXME: implement InspectorInstrumentationCookie stuff a la v8.
+ (*recursion)++;
+ Dart_Handle result = Dart_InvokeClosure(function, argc, argv);
+ (*recursion)--;
+
+ // Release the storage mutex if applicable.
+ didLeaveScriptContext(*recursion);
+
+ // Handle fatal error in Dart VM a la v8.
+
+ return result;
+}
+
+void DartController::didLeaveScriptContext(int recursion)
+{
+ // FIXME: common to v8, should be factored out.
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+#if ENABLE(INDEXED_DATABASE)
+ // If we've just left a script context and indexed database has been
+ // instantiated, we must let its transaction coordinator know so it can terminate
+ // any not-yet-started transactions.
+ IDBPendingTransactionMonitor::abortPendingTransactions();
+#endif // ENABLE(INDEXED_DATABASE)
+ // If we've just left a top level script context and local storage has been
+ // instantiated, we must ensure that any storage locks have been freed.
+ // Per http://dev.w3.org/html5/spec/Overview.html#storage-mutex
+ if (recursion)
+ return;
+ if (page->group().hasLocalStorage())
+ page->group().localStorage()->unlock();
+}
+
+DartController* DartController::retrieve(Frame* frame)
+{
+ if (!frame)
+ return 0;
+ // FIXME: check if can execute Dart scripts.
+ if (!frame->script()->javaScript()->canExecuteScripts(NotAboutToExecuteScript))
+ return 0;
+ return frame->script()->dart();
+}
+
+DartController* DartController::retrieve(ScriptExecutionContext* context)
+{
+ if (!context || !context->isDocument())
+ return 0;
+ return retrieve(static_cast<Document*>(context)->frame());
+}
+
+}
« no previous file with comments | « Source/WebCore/bindings/dart/DartController.h ('k') | Source/WebCore/bindings/dart/DartDOMWrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698