2009-07-29 Matt Perry <mpcomplete@chromium.org>

        Reviewed by Adam Barth.

        Add a way to register V8 extensions for Isolated Worlds only.
        https://bugs.webkit.org/show_bug.cgi?id=27785

        * bindings/v8/ScriptController.cpp:
        (WebCore::ScriptController::evaluateInNewWorld):
        (WebCore::ScriptController::evaluateInNewContext):
        * bindings/v8/ScriptController.h:
        * bindings/v8/V8IsolatedWorld.cpp:
        (WebCore::V8IsolatedWorld::evaluate):
        * bindings/v8/V8IsolatedWorld.h:
        * bindings/v8/V8Proxy.cpp:
        (WebCore::V8Proxy::evaluateInNewWorld):
        (WebCore::V8Proxy::evaluateInNewContext):
        (WebCore::V8Proxy::createNewContext):
        (WebCore::V8Proxy::initContextIfNeeded):
        (WebCore::V8Proxy::registerExtensionWithV8):
        (WebCore::V8Proxy::registerExtension):
        * bindings/v8/V8Proxy.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@46594 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e1a6962a
2009-07-29 Matt Perry <mpcomplete@chromium.org>
Reviewed by Adam Barth.
Add a way to register V8 extensions for Isolated Worlds only.
https://bugs.webkit.org/show_bug.cgi?id=27785
* bindings/v8/ScriptController.cpp:
(WebCore::ScriptController::evaluateInNewWorld):
(WebCore::ScriptController::evaluateInNewContext):
* bindings/v8/ScriptController.h:
* bindings/v8/V8IsolatedWorld.cpp:
(WebCore::V8IsolatedWorld::evaluate):
* bindings/v8/V8IsolatedWorld.h:
* bindings/v8/V8Proxy.cpp:
(WebCore::V8Proxy::evaluateInNewWorld):
(WebCore::V8Proxy::evaluateInNewContext):
(WebCore::V8Proxy::createNewContext):
(WebCore::V8Proxy::initContextIfNeeded):
(WebCore::V8Proxy::registerExtensionWithV8):
(WebCore::V8Proxy::registerExtension):
* bindings/v8/V8Proxy.h:
2009-07-30 Mike Fenton <mike.fenton@torchmobile.com> 2009-07-30 Mike Fenton <mike.fenton@torchmobile.com>
Reviewed by Adam Treat. Reviewed by Adam Treat.
......
...@@ -180,14 +180,14 @@ bool ScriptController::processingUserGesture() const ...@@ -180,14 +180,14 @@ bool ScriptController::processingUserGesture() const
return false; return false;
} }
void ScriptController::evaluateInNewWorld(const Vector<ScriptSourceCode>& sources) void ScriptController::evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup)
{ {
m_proxy->evaluateInNewWorld(sources); m_proxy->evaluateInNewWorld(sources, extensionGroup);
} }
void ScriptController::evaluateInNewContext(const Vector<ScriptSourceCode>& sources) void ScriptController::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int extensionGroup)
{ {
m_proxy->evaluateInNewContext(sources); m_proxy->evaluateInNewContext(sources, extensionGroup);
} }
// Evaluate a script file in the environment of this proxy. // Evaluate a script file in the environment of this proxy.
......
...@@ -69,13 +69,13 @@ namespace WebCore { ...@@ -69,13 +69,13 @@ namespace WebCore {
// script gets its own global scope, its own prototypes for intrinsic // script gets its own global scope, its own prototypes for intrinsic
// JavaScript objects (String, Array, and so-on), and its own wrappers for // JavaScript objects (String, Array, and so-on), and its own wrappers for
// all DOM nodes and DOM constructors. // all DOM nodes and DOM constructors.
void evaluateInNewWorld(const Vector<ScriptSourceCode>&); void evaluateInNewWorld(const Vector<ScriptSourceCode>&, int extensionGroup);
// Executes JavaScript in a new context associated with the web frame. The // Executes JavaScript in a new context associated with the web frame. The
// script gets its own global scope and its own prototypes for intrinsic // script gets its own global scope and its own prototypes for intrinsic
// JavaScript objects (String, Array, and so-on). It shares the wrappers for // JavaScript objects (String, Array, and so-on). It shares the wrappers for
// all DOM nodes and DOM constructors. // all DOM nodes and DOM constructors.
void evaluateInNewContext(const Vector<ScriptSourceCode>&); void evaluateInNewContext(const Vector<ScriptSourceCode>&, int extensionGroup);
// JSC has a WindowShell object, but for V8, the ScriptController // JSC has a WindowShell object, but for V8, the ScriptController
// is the WindowShell. // is the WindowShell.
......
...@@ -52,10 +52,10 @@ static void contextWeakReferenceCallback(v8::Persistent<v8::Value> object, void* ...@@ -52,10 +52,10 @@ static void contextWeakReferenceCallback(v8::Persistent<v8::Value> object, void*
delete world; delete world;
} }
void V8IsolatedWorld::evaluate(const Vector<ScriptSourceCode>& sources, V8Proxy* proxy) void V8IsolatedWorld::evaluate(const Vector<ScriptSourceCode>& sources, V8Proxy* proxy, int extensionGroup)
{ {
v8::HandleScope scope; v8::HandleScope scope;
v8::Persistent<v8::Context> context = proxy->createNewContext(v8::Handle<v8::Object>()); v8::Persistent<v8::Context> context = proxy->createNewContext(v8::Handle<v8::Object>(), extensionGroup);
// Run code in the new context. // Run code in the new context.
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
......
...@@ -61,7 +61,7 @@ namespace WebCore { ...@@ -61,7 +61,7 @@ namespace WebCore {
// Evaluate JavaScript in a new isolated world. The script has access // Evaluate JavaScript in a new isolated world. The script has access
// to the DOM of the document associated with |proxy|. // to the DOM of the document associated with |proxy|.
static void evaluate(const Vector<ScriptSourceCode>& sources, V8Proxy* proxy); static void evaluate(const Vector<ScriptSourceCode>& sources, V8Proxy* proxy, int extensionGroup);
// Returns the isolated world associated with // Returns the isolated world associated with
// v8::Context::GetEntered(). Because worlds are isolated, the entire // v8::Context::GetEntered(). Because worlds are isolated, the entire
......
...@@ -279,13 +279,13 @@ bool V8Proxy::handleOutOfMemory() ...@@ -279,13 +279,13 @@ bool V8Proxy::handleOutOfMemory()
return true; return true;
} }
void V8Proxy::evaluateInNewWorld(const Vector<ScriptSourceCode>& sources) void V8Proxy::evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup)
{ {
initContextIfNeeded(); initContextIfNeeded();
V8IsolatedWorld::evaluate(sources, this); V8IsolatedWorld::evaluate(sources, this, extensionGroup);
} }
void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources) void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int extensionGroup)
{ {
initContextIfNeeded(); initContextIfNeeded();
...@@ -298,7 +298,7 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources) ...@@ -298,7 +298,7 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources)
ASSERT(V8DOMWrapper::convertDOMWrapperToNative<DOMWindow>(windowWrapper) == m_frame->domWindow()); ASSERT(V8DOMWrapper::convertDOMWrapperToNative<DOMWindow>(windowWrapper) == m_frame->domWindow());
v8::Persistent<v8::Context> context = createNewContext(v8::Handle<v8::Object>()); v8::Persistent<v8::Context> context = createNewContext(v8::Handle<v8::Object>(), extensionGroup);
v8::Context::Scope contextScope(context); v8::Context::Scope contextScope(context);
// Setup context id for JS debugger. // Setup context id for JS debugger.
...@@ -859,7 +859,7 @@ bool V8Proxy::checkNodeSecurity(Node* node) ...@@ -859,7 +859,7 @@ bool V8Proxy::checkNodeSecurity(Node* node)
return canAccessFrame(target, true); return canAccessFrame(target, true);
} }
v8::Persistent<v8::Context> V8Proxy::createNewContext(v8::Handle<v8::Object> global) v8::Persistent<v8::Context> V8Proxy::createNewContext(v8::Handle<v8::Object> global, int extensionGroup)
{ {
v8::Persistent<v8::Context> result; v8::Persistent<v8::Context> result;
...@@ -880,6 +880,9 @@ v8::Persistent<v8::Context> V8Proxy::createNewContext(v8::Handle<v8::Object> glo ...@@ -880,6 +880,9 @@ v8::Persistent<v8::Context> V8Proxy::createNewContext(v8::Handle<v8::Object> glo
OwnArrayPtr<const char*> extensionNames(new const char*[m_extensions.size()]); OwnArrayPtr<const char*> extensionNames(new const char*[m_extensions.size()]);
int index = 0; int index = 0;
for (V8ExtensionList::iterator it = m_extensions.begin(); it != m_extensions.end(); ++it) { for (V8ExtensionList::iterator it = m_extensions.begin(); it != m_extensions.end(); ++it) {
if (it->group && it->group != extensionGroup)
continue;
// Note: we check the loader URL here instead of the document URL // Note: we check the loader URL here instead of the document URL
// because we might be currently loading an URL into a blank page. // because we might be currently loading an URL into a blank page.
// See http://code.google.com/p/chromium/issues/detail?id=10924 // See http://code.google.com/p/chromium/issues/detail?id=10924
...@@ -982,7 +985,7 @@ void V8Proxy::initContextIfNeeded() ...@@ -982,7 +985,7 @@ void V8Proxy::initContextIfNeeded()
isV8Initialized = true; isV8Initialized = true;
} }
m_context = createNewContext(m_global); m_context = createNewContext(m_global, 0);
if (m_context.IsEmpty()) if (m_context.IsEmpty())
return; return;
...@@ -1216,10 +1219,27 @@ String V8Proxy::sourceName() ...@@ -1216,10 +1219,27 @@ String V8Proxy::sourceName()
return toWebCoreString(v8::Debug::Call(frameSourceName)); return toWebCoreString(v8::Debug::Call(frameSourceName));
} }
void V8Proxy::registerExtensionWithV8(v8::Extension* extension) {
// If the extension exists in our list, it was already registered with V8.
for (V8ExtensionList::iterator it = m_extensions.begin(); it != m_extensions.end(); ++it) {
if (it->extension == extension)
return;
}
v8::RegisterExtension(extension);
}
void V8Proxy::registerExtension(v8::Extension* extension, const String& schemeRestriction) void V8Proxy::registerExtension(v8::Extension* extension, const String& schemeRestriction)
{ {
v8::RegisterExtension(extension); registerExtensionWithV8(extension);
V8ExtensionInfo info = {schemeRestriction, extension}; V8ExtensionInfo info = {schemeRestriction, 0, extension};
m_extensions.push_back(info);
}
void V8Proxy::registerExtension(v8::Extension* extension, int extensionGroup)
{
registerExtensionWithV8(extension);
V8ExtensionInfo info = {String(), extensionGroup, extension};
m_extensions.push_back(info); m_extensions.push_back(info);
} }
......
...@@ -138,11 +138,14 @@ namespace WebCore { ...@@ -138,11 +138,14 @@ namespace WebCore {
const int kMaxRecursionDepth = 20; const int kMaxRecursionDepth = 20;
// Information about an extension that is registered for use with V8. If scheme // Information about an extension that is registered for use with V8. If
// is non-empty, it contains the URL scheme the extension should be used with. // scheme is non-empty, it contains the URL scheme the extension should be
// Otherwise, the extension is used with all schemes. // used with. If group is non-zero, the extension will only be loaded into
// script contexts that belong to that group. Otherwise, the extension is
// used with all schemes and contexts.
struct V8ExtensionInfo { struct V8ExtensionInfo {
String scheme; String scheme;
int group;
v8::Extension* extension; v8::Extension* extension;
}; };
typedef std::list<V8ExtensionInfo> V8ExtensionList; typedef std::list<V8ExtensionInfo> V8ExtensionList;
...@@ -211,12 +214,12 @@ namespace WebCore { ...@@ -211,12 +214,12 @@ namespace WebCore {
// global scope, its own prototypes for intrinsic JavaScript objects (String, // global scope, its own prototypes for intrinsic JavaScript objects (String,
// Array, and so-on), and its own wrappers for all DOM nodes and DOM // Array, and so-on), and its own wrappers for all DOM nodes and DOM
// constructors. // constructors.
void evaluateInNewWorld(const Vector<ScriptSourceCode>& sources); void evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup);
// Evaluate JavaScript in a new context. The script gets its own global scope // Evaluate JavaScript in a new context. The script gets its own global scope
// and its own prototypes for intrinsic JavaScript objects (String, Array, // and its own prototypes for intrinsic JavaScript objects (String, Array,
// and so-on). It shares the wrappers for all DOM nodes and DOM constructors. // and so-on). It shares the wrappers for all DOM nodes and DOM constructors.
void evaluateInNewContext(const Vector<ScriptSourceCode>&); void evaluateInNewContext(const Vector<ScriptSourceCode>&, int extensionGroup);
// Evaluate a script file in the current execution environment. // Evaluate a script file in the current execution environment.
// The caller must hold an execution context. // The caller must hold an execution context.
...@@ -339,14 +342,18 @@ namespace WebCore { ...@@ -339,14 +342,18 @@ namespace WebCore {
// WARNING: Call |installHiddenObjectPrototype| only on fresh contexts! // WARNING: Call |installHiddenObjectPrototype| only on fresh contexts!
static void installHiddenObjectPrototype(v8::Handle<v8::Context>); static void installHiddenObjectPrototype(v8::Handle<v8::Context>);
// Registers an extension to be available on webpages with a particular scheme // Registers a v8 extension to be available on webpages. The two forms
// If the scheme argument is empty, the extension is available on all pages. // offer various restrictions on what types of contexts the extension is
// Will only affect v8 contexts initialized after this call. Takes ownership // loaded into. If a scheme is provided, only pages whose URL has the given
// of the v8::Extension object passed. // scheme will match. If extensionGroup is provided, the extension will
// only be loaded into scripts run via evaluateInNewWorld with the
// matching group. Will only affect v8 contexts initialized after this
// call. Takes ownership of the v8::Extension object passed.
static void registerExtension(v8::Extension*, const String& schemeRestriction); static void registerExtension(v8::Extension*, const String& schemeRestriction);
static void registerExtension(v8::Extension*, int extensionGroup);
// FIXME: Separate these concerns from V8Proxy? // FIXME: Separate these concerns from V8Proxy?
v8::Persistent<v8::Context> createNewContext(v8::Handle<v8::Object> global); v8::Persistent<v8::Context> createNewContext(v8::Handle<v8::Object> global, int extensionGroup);
static bool installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window); static bool installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window);
void initContextIfNeeded(); void initContextIfNeeded();
...@@ -395,6 +402,8 @@ namespace WebCore { ...@@ -395,6 +402,8 @@ namespace WebCore {
return v8::Local<v8::Context>::New(m_utilityContext); return v8::Local<v8::Context>::New(m_utilityContext);
} }
static void registerExtensionWithV8(v8::Extension*);
Frame* m_frame; Frame* m_frame;
v8::Persistent<v8::Context> m_context; v8::Persistent<v8::Context> m_context;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment