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

Unified Diff: Source/WebCore/bindings/dart/DartUtilities.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
Index: Source/WebCore/bindings/dart/DartUtilities.cpp
diff --git a/Source/WebCore/bindings/dart/DartUtilities.cpp b/Source/WebCore/bindings/dart/DartUtilities.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..58718477bc8dea0c32036aac289f74a6b2a9ee6c
--- /dev/null
+++ b/Source/WebCore/bindings/dart/DartUtilities.cpp
@@ -0,0 +1,429 @@
+// Copyright 2011, 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 "DartUtilities.h"
+
+#include "DartEventListener.h"
+#include "DartIsolateState.h"
+#include "DartMessagePort.h"
+#include "DartNode.h"
+#include "DartScriptArguments.h"
+#include "DartScriptValueSerializer.h"
+#include "Document.h"
+#include "Frame.h"
+#include "ScriptCallStack.h"
+#include "SerializedScriptValue.h"
+
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+const char* DartUtilities::domLibraryName = "dart:dom";
+
+PassRefPtr<StringImpl> DartUtilities::toStringImpl(Dart_Handle object, ConversionFlag flag, Dart_Handle& exception)
+{
+ if (flag == ConvertNullToEmptyString && Dart_IsNull(object))
+ return 0;
+
+ if (!Dart_IsString(object)) {
+ exception = Dart_NewString("String expected");
+ return 0;
+ }
+ if (!Dart_IsString16(object)) {
+ // FIXME: consider convertion to UTF16 in this case.
+ exception = Dart_NewString("32-bit string met, cannot be used in DOM API");
+ return 0;
+ }
+
+ // Note: hopefully we should never overflow length as the string would be just too long to fit
+ // into memory.
+ intptr_t length = 0;
+ Dart_StringLength(object, &length);
+ UChar* buffer;
+ // FIXME: check if string is externalized, and reuse that, if possible.
+ RefPtr<StringImpl> result = StringImpl::createUninitialized(length, buffer);
+ Dart_StringGet16(object, buffer, &length);
+ return result.release();
+}
+
+static void stringFinalizer(void* peer) {
+ StringImpl* stringImpl = reinterpret_cast<StringImpl*>(peer);
+ stringImpl->deref();
+}
+
+static Dart_Handle stringImplToDartString(StringImpl* stringImpl)
+{
+ if (!stringImpl)
+ return Dart_NewString8(0, 0);
+
+ // FIXME: maybe it makes sense only externalize strings longer than certain threshold, such as 5 symbols.
+ stringImpl->ref();
+ return Dart_NewExternalString16(stringImpl->characters(), stringImpl->length(),
+ stringImpl, stringFinalizer);
+}
+
+Dart_Handle DartUtilities::stringToDartString(const String& str)
+{
+ return stringImplToDartString(str.impl());
+}
+
+Dart_Handle DartUtilities::stringToDartString(const AtomicString& str)
+{
+ return stringImplToDartString(str.impl());
+}
+
+template <typename Trait>
+typename Trait::nativeType convert(Dart_Handle object, Dart_Handle& exception)
+{
+ typename Trait::nativeType value;
+ return !Dart_IsError(Trait::convert(object, &value)) ? value : typename Trait::nativeType();
+}
+
+struct IntegerTrait {
+ typedef int64_t nativeType;
+ static Dart_Handle convert(Dart_Handle object, int64_t* value)
+ {
+ return Dart_IntegerValue(object, value);
+ // FIXME: support bigints.
+ }
+};
+
+int64_t DartUtilities::toInteger(Dart_Handle object, Dart_Handle& exception)
+{
+ return convert<IntegerTrait>(object, exception);
+}
+
+int64_t DartUtilities::toInteger(Dart_Handle object)
+{
+ Dart_Handle exception = 0;
+ int64_t value = DartUtilities::toInteger(object, exception);
+ ASSERT(!exception);
+ return value;
+}
+
+struct DoubleTrait {
+ typedef double nativeType;
+ static Dart_Handle convert(Dart_Handle object, double* value)
+ {
+ if (!Dart_IsNumber(object))
+ return Dart_Error("the object !is Number");
+
+ object = Dart_InvokeDynamic(object, Dart_NewString("toDouble"), 0, 0);
+ if (Dart_IsError(object))
+ return object;
+
+ return Dart_DoubleValue(object, value);
+ }
+};
+
+double DartUtilities::toDouble(Dart_Handle object, Dart_Handle& exception)
+{
+ return convert<DoubleTrait>(object, exception);
+}
+
+double DartUtilities::toDouble(Dart_Handle object)
+{
+ Dart_Handle exception = 0;
+ double value = DartUtilities::toDouble(object, exception);
+ ASSERT(!exception);
+ return value;
+}
+
+struct BoolTrait {
+ typedef bool nativeType;
+ static Dart_Handle convert(Dart_Handle object, bool* value) { return Dart_BooleanValue(object, value); }
+};
+
+bool DartUtilities::toBool(Dart_Handle object, Dart_Handle& exception)
+{
+ return convert<BoolTrait>(object, exception);
+}
+
+bool DartUtilities::toBool(Dart_Handle object)
+{
+ Dart_Handle exception = 0;
+ bool value = DartUtilities::toBool(object, exception);
+ ASSERT(!exception);
+ return value;
+}
+
+PassRefPtr<EventListener> DartUtilities::toEventListener(Dart_Handle object, Dart_Handle& exception)
+{
+ if (Dart_IsNull(object)) {
+ exception = Dart_NewString("Null passed where Dart closure is expected");
+ return 0;
+ }
+
+ if (!Dart_IsClosure(object)) {
+ exception = Dart_NewString("Not a Dart closure passed");
+ return 0;
+ }
+
+ return DartEventListener::createOrFetch(object);
+}
+
+PassRefPtr<SerializedScriptValue> DartUtilities::toSerializedScriptValue(Dart_Handle value, Dart_Handle& exception)
+{
+ DartScriptValueSerializer serializer(value);
+ RefPtr<SerializedScriptValue> result = SerializedScriptValue::create(&serializer);
+ exception = serializer.exception();
+ return result.release();
+}
+
+PassRefPtr<EventTarget> DartUtilities::toEventTarget(Dart_Handle object, Dart_Handle& exception)
+{
+ // FIXME: currently it's too risky to remove, but when Optional=CallWithDefaultValue is
+ // implemented, we should give it a try and unify with the rest of conversion.
+ if (Dart_IsNull(object))
+ return 0;
+
+ return DartNode::toNative(object, exception);
+}
+
+// FIXME: this function requires better testing. Currently blocking as new MessageChannel hasn't been implemented yet.
+void DartUtilities::toMessagePortArray(Dart_Handle value, MessagePortArray& portArray, Dart_Handle& exception)
+{
+ Dart_Handle dom = Dart_LookupLibrary(Dart_NewString(DartUtilities::domLibraryName));
+ ASSERT(!Dart_IsError(dom));
+
+ Dart_Handle asList = Dart_InvokeStatic(dom, Dart_NewString("Utils"), Dart_NewString("convertToList"), 1, &value);
+ if (Dart_IsError(asList)) {
+ DartUtilities::reportProblem(DartUtilities::scriptExecutionContext(), asList);
+ exception = DartDOMWrapper::exceptionCodeToDartException(INVALID_STATE_ERR);
+ return;
+ }
+ ASSERT(Dart_IsList(asList));
+
+ intptr_t length = 0;
+ Dart_ListLength(asList, &length);
+ portArray.resize(length);
+ for (int i = 0; i < length; i++) {
+ Dart_Handle element = Dart_ListGetAt(asList, i);
+ if (Dart_IsError(element)) {
+ exception = DartDOMWrapper::exceptionCodeToDartException(INVALID_STATE_ERR);
+ return;
+ }
+
+ MessagePort* messagePort = DartMessagePort::toNative(element, exception).get();
+ if (exception) {
+ exception = DartDOMWrapper::exceptionCodeToDartException(INVALID_STATE_ERR);
+ return;
+ }
+
+ ASSERT(messagePort);
+ portArray[i] = messagePort;
+ }
+}
+
+class DartDOMData {
+public:
+ DartDOMData()
+ : m_scriptExecutionContext(0)
+ , m_domWindow(0)
+ , m_recursion(0)
+ {
+ }
+
+ DartDOMData(ScriptExecutionContext* context)
+ : m_scriptExecutionContext(context)
+ , m_recursion(0)
+ {
+ ASSERT(context);
+ ASSERT(context->isDocument()); // WorkerContext is not supported yet.
+ Document* document = static_cast<Document*>(context);
+ m_domWindow = document->domWindow();
+ }
+
+ ScriptExecutionContext* scriptExecutionContext() { return m_scriptExecutionContext; }
+ DOMWindow* domWindow() { return m_domWindow; }
+ DartDOMMap* domMap() { return &m_domMap; }
+ int* recursion() { return &m_recursion; }
+
+private:
+ ScriptExecutionContext* m_scriptExecutionContext;
+ DOMWindow* m_domWindow;
+ DartDOMMap m_domMap;
+ int m_recursion;
+};
+
+typedef HashMap<Dart_Isolate, DartDOMData*> IsolateToDartDOMDataMap;
+
+static IsolateToDartDOMDataMap& isolateToDartDOMDataMap()
+{
+ DEFINE_STATIC_LOCAL(IsolateToDartDOMDataMap, map, ());
+ return map;
+}
+
+static DartDOMData* domDataForIsolate(Dart_Isolate isolate)
+{
+ IsolateToDartDOMDataMap::iterator it = isolateToDartDOMDataMap().find(isolate);
+ ASSERT(it != isolateToDartDOMDataMap().end());
+ return it->second;
+}
+
+static DartDOMData* currentDOMData()
+{
+ return domDataForIsolate(DartIsolateState::current());
+}
+
+void DartUtilities::registerIsolateContext(Dart_Isolate isolate, ScriptExecutionContext* context)
+{
+ ASSERT(!isolateToDartDOMDataMap().contains(isolate));
+ isolateToDartDOMDataMap().set(isolate, new DartDOMData(context));
+}
+
+ScriptExecutionContext* DartUtilities::isolateContext(Dart_Isolate isolate)
+{
+ return domDataForIsolate(isolate)->scriptExecutionContext();
+}
+
+void DartUtilities::unregisterIsolateContext(Dart_Isolate isolate)
+{
+ IsolateToDartDOMDataMap::iterator it = isolateToDartDOMDataMap().find(isolate);
+ ASSERT(it != isolateToDartDOMDataMap().end());
+ delete it->second;
+ isolateToDartDOMDataMap().remove(it);
+}
+
+bool DartUtilities::isFullDomIsolate(Dart_Isolate isolate)
+{
+ return isolateToDartDOMDataMap().contains(isolate);
+}
+
+DOMWindow* DartUtilities::domWindowForIsolate(Dart_Isolate isolate)
+{
+ return domDataForIsolate(isolate)->domWindow();
+}
+
+DOMWindow* DartUtilities::domWindowForCurrentIsolate()
+{
+ return currentDOMData()->domWindow();
+}
+
+Dart_Handle DartUtilities::domLibraryForCurrentIsolate()
+{
+ // FIXME: Cache this on the isolate.
+ Dart_Handle library = Dart_LookupLibrary(Dart_NewString(domLibraryName));
+ ASSERT(!Dart_IsError(library));
+ return library;
+}
+
+DartDOMMap* DartUtilities::domMapForIsolate(Dart_Isolate isolate)
+{
+ return domDataForIsolate(isolate)->domMap();
+}
+
+DartDOMMap* DartUtilities::domMapForCurrentIsolate()
+{
+ return currentDOMData()->domMap();
+}
+
+int* DartUtilities::recursionForIsolate(Dart_Isolate isolate)
+{
+ return domDataForIsolate(isolate)->recursion();
+}
+
+int* DartUtilities::recursionForCurrentIsolate()
+{
+ return currentDOMData()->recursion();
+}
+
+ScriptExecutionContext* DartUtilities::scriptExecutionContext()
+{
+ return currentDOMData()->scriptExecutionContext();
+}
+
+bool DartUtilities::processingUserGesture()
+{
+ // FIXME: implement this.
+ return false;
+}
+
+PassRefPtr<ScriptArguments> DartUtilities::createScriptArguments(Dart_Handle argument)
+{
+ return DartScriptArguments::create(argument, DartIsolateState::current());
+}
+
+PassRefPtr<ScriptCallStack> DartUtilities::createScriptCallStack(size_t maxStackSize)
+{
+ // FIXME: wrap current dart call stack as ScriptCallStack.
+ Vector<ScriptCallFrame> wrappedCallFrames;
+ wrappedCallFrames.append(ScriptCallFrame("undefined", "undefined", 0));
+ return ScriptCallStack::create(wrappedCallFrames);
+}
+
+void DartUtilities::reportProblem(ScriptExecutionContext* context, Dart_Handle result)
+{
+ ASSERT(Dart_IsError(result));
+
+ const String internalErrorPrefix("Internal error: ");
+
+ String errorMessage;
+ // FIXME: source file info.
+ String sourceFile = "FIXME";
+ // FIXME: line number info.
+ int lineNumber = 0;
+ // FIXME: call stack info.
+ RefPtr<ScriptCallStack> callStack;
+
+ if (!Dart_ErrorHasException(result))
+ errorMessage = internalErrorPrefix + Dart_GetError(result);
+ else {
+ // Print the exception.
+ Dart_Handle exception = Dart_ErrorGetException(result);
+ ASSERT(!Dart_IsError(exception));
+
+ exception = Dart_ToString(exception);
+ if (Dart_IsError(exception))
+ errorMessage = String("Error converting exception to a string: ") + Dart_GetError(exception);
+ else
+ errorMessage = String("Exception: ") + DartUtilities::dartStringToString(exception);
+
+ // FIXME: Fill in the callStack, sourceFile, and lineNumber
+ // and remove the below once the Dart APIs to iterate over the
+ // trace are available.
+
+ // Print the stack trace.
+ Dart_Handle stacktrace = Dart_ErrorGetStacktrace(result);
+ ASSERT(!Dart_IsError(stacktrace));
+
+ stacktrace = Dart_ToString(stacktrace);
+ if (Dart_IsError(stacktrace))
+ errorMessage += String("\nError converting stack trace to a string: ") + Dart_GetError(stacktrace);
+ else
+ errorMessage += String("\nStack Trace: ") + DartUtilities::dartStringToString(stacktrace);
+ }
+
+ if (context && context->isDocument())
+ static_cast<Document*>(context)->reportException(errorMessage, lineNumber, sourceFile, callStack);
+}
+
+}
« no previous file with comments | « Source/WebCore/bindings/dart/DartUtilities.h ('k') | Source/WebCore/bindings/dart/custom/DartAudioBufferSourceNodeCustom.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698