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

Unified Diff: Source/bindings/v8/V8BlinkInJavaScript.cpp

Issue 138223002: WIP: Implement binding layer for Blink-in-JavaScript Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 11 months 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/bindings/v8/V8BlinkInJavaScript.h ('k') | Source/bindings/v8/V8PerIsolateData.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/v8/V8BlinkInJavaScript.cpp
diff --git a/Source/bindings/v8/V8BlinkInJavaScript.cpp b/Source/bindings/v8/V8BlinkInJavaScript.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..988a0eb98396e1614301529b7910d5defda890ab
--- /dev/null
+++ b/Source/bindings/v8/V8BlinkInJavaScript.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2014 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 "bindings/v8/V8BlinkInJavaScript.h"
+
+#include "BlinkInJavaScript.h"
+#include "V8Window.h"
+#include "bindings/v8/DOMWrapperWorld.h"
+#include "bindings/v8/ScriptController.h"
+#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8PerIsolateData.h"
+#include "bindings/v8/V8ScriptRunner.h"
+#include "bindings/v8/V8WindowShell.h"
+#include "core/dom/Document.h"
+#include "core/frame/Frame.h"
+
+namespace WebCore {
+
+static v8::Handle<v8::Value> compileBlinkInJavaScript(String className, v8::Isolate* isolate)
+{
+ size_t index;
+ // |kBlinkInJavaScriptSources| is defined in BlinkInJavaScript.h, which is auto-generated
+ // by make_blink_in_javascript.py.
+ for (index = 0; index < WTF_ARRAY_LENGTH(kBlinkInJavaScriptSources); index++) {
+ if (className == kBlinkInJavaScriptSources[index].name)
+ break;
+ }
+ RELEASE_ASSERT(index != WTF_ARRAY_LENGTH(kBlinkInJavaScriptSources));
+
+ String source(reinterpret_cast<const char*>(kBlinkInJavaScriptSources[index].source), kBlinkInJavaScriptSources[index].size);
+ return V8ScriptRunner::compileAndRunInternalScript(v8String(isolate, source), isolate);
+}
+
+static v8::Handle<v8::Value> convertWrapperForThisWorld(v8::Handle<v8::Value> wrapper, v8::Isolate* isolate)
+{
+ // We don't need to convert primitive values.
+ if (wrapper.IsEmpty() || !wrapper->IsObject())
+ return wrapper;
+
+ // FIXME: We need to support conversion for Objects, Functions, Arrays etc.
+
+ // FIXME: This implementation is a temporary hack just for window wrappers.
+ // What we really need here is something like the following code:
+ //
+ // if (WrapperTypeInfo* typeInfo = WrapperTypeInfo::wrapperTypeInfo(wrapper)) {
+ // return typeInfo->toV8(typeInfo->toNative(), v8::Handle<v8::Object>(), isolate);
+ // }
+ //
+ // To make the above code workable, we need to store toNative() and toV8() to WrapperTypeInfo.
+ // We also need to implement wrapperTypeInfo() which returns WrapperTypeInfo
+ // only when |wrapper| is a valid DOM wrapper.
+ if (V8Window::hasInstanceInAnyWorld(wrapper, isolate)) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(wrapper);
+ DOMWindow* imp = V8Window::toNative(object);
+ return toV8(imp, v8::Handle<v8::Object>(), isolate);
+ }
+ RELEASE_ASSERT(0);
+}
+
+v8::Handle<v8::Value> V8BlinkInJavaScript::runBlinkInJavaScript(String className, String functionName, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> argv[], v8::Isolate* isolate)
+{
+ Document* document = currentDocument();
+ if (!document || !document->frame())
+ return v8::Handle<v8::Value>();
+
+ // Blink-in-JavaScript runs in the same security level as content scripts of Chrome extensions.
+ // Specifically, Blink-in-JavaScript runs in a dedicated isolated world.
+ RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(BlinkInJavaScriptIsolatedWorldId, DOMWrapperWorld::blinkInJavaScriptWorldExtensionGroup);
+ V8WindowShell* isolatedWorldShell = document->frame()->script().windowShell(world.get());
+ if (!isolatedWorldShell->isContextInitialized())
+ return v8::Handle<v8::Value>();
+
+ v8::Handle<v8::Context> context = isolatedWorldShell->context();
+ v8::Handle<v8::Value> result;
+ String exceptionMessage;
+ bool exceptionCaught;
+ {
+ // Switch to the context of Blink-in-JavaScript's isolated world.
+ v8::Context::Scope contextScope(context);
+
+ v8::Handle<v8::Value> compiledClass = V8PerIsolateData::from(isolate)->compiledBlinkInJavaScript(className);
+ if (compiledClass.IsEmpty()) {
+ v8::Handle<v8::Value> installedClasses = V8PerIsolateData::from(isolate)->compiledBlinkInJavaScript("BlinkInJavaScriptController");
+ if (installedClasses.IsEmpty()) {
+ installedClasses = compileBlinkInJavaScript("BlinkInJavaScriptController", isolate);
+ V8PerIsolateData::from(isolate)->setCompiledBlinkInJavaScript("BlinkInJavaScriptController", installedClasses);
+ }
+ RELEASE_ASSERT(!installedClasses.IsEmpty());
+ RELEASE_ASSERT(installedClasses->IsObject());
+
+ compileBlinkInJavaScript(className, isolate);
+
+ compiledClass = v8::Handle<v8::Object>::Cast(installedClasses)->Get(v8String(isolate, className));
+ RELEASE_ASSERT(!compiledClass.IsEmpty());
+ RELEASE_ASSERT(compiledClass->IsObject());
+ V8PerIsolateData::from(isolate)->setCompiledBlinkInJavaScript(className, compiledClass);
+ }
+
+ v8::Handle<v8::Value> function = v8::Handle<v8::Object>::Cast(compiledClass)->Get(v8String(isolate, functionName));
+ RELEASE_ASSERT(!function.IsEmpty());
+ RELEASE_ASSERT(function->IsFunction());
+
+ // We have to convert argument wrappers to wrappers in Blink-in-JavaScript's isolated world.
+ receiver = convertWrapperForThisWorld(receiver, isolate);
+ for (int i = 0; i < argc; i++) {
+ argv[i] = convertWrapperForThisWorld(argv[i], isolate);
+ }
+
+ {
+ v8::TryCatch block;
+ result = V8ScriptRunner::callFunction(v8::Handle<v8::Function>::Cast(function), document, receiver, argc, argv, isolate);
+ exceptionCaught = block.HasCaught();
+ if (exceptionCaught) {
+ if (!block.Message().IsEmpty())
+ exceptionMessage = toCoreString(block.Message()->Get());
+ }
+ }
+
+ }
+
+ // We have to convert an exception thrown in Blink-in-JavaScript's isolated world
+ // to an exception in the original world.
+ if (exceptionCaught) {
+ // FIXME: Support other error types. We need to add V8 APIs to extract types from Exception objects.
+ return v8::Exception::Error(v8String(isolate, exceptionMessage));
+ }
+
+ // We have to convert a return wrapper created in Blink-in-JavaScript's isolated world
+ // to a wrapper in the original world.
+ return convertWrapperForThisWorld(result, isolate);
+}
+
+} // namespace WebCore
« no previous file with comments | « Source/bindings/v8/V8BlinkInJavaScript.h ('k') | Source/bindings/v8/V8PerIsolateData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698