summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/v8/V8Proxy.h
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/v8/V8Proxy.h')
-rw-r--r--WebCore/bindings/v8/V8Proxy.h171
1 files changed, 97 insertions, 74 deletions
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index d8f546c..900ee18 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -31,20 +31,14 @@
#ifndef V8Proxy_h
#define V8Proxy_h
-#include "Node.h"
-#include "NodeFilter.h"
-#include "PlatformString.h" // for WebCore::String
#include "ScriptSourceCode.h" // for WebCore::ScriptSourceCode
#include "SecurityOrigin.h" // for WebCore::SecurityOrigin
-#include "V8CustomBinding.h"
-#include "V8DOMMap.h"
+#include "SharedPersistent.h"
+#include "V8AbstractEventListener.h"
#include "V8DOMWrapper.h"
-#include "V8EventListenerList.h"
#include "V8GCController.h"
#include "V8Index.h"
-#include "V8Utilities.h"
#include <v8.h>
-#include <wtf/Assertions.h>
#include <wtf/PassRefPtr.h> // so generated bindings don't have to
#include <wtf/Vector.h>
@@ -57,49 +51,15 @@
namespace WebCore {
- class CSSRule;
- class CSSRuleList;
- class CSSStyleDeclaration;
- class CSSValue;
- class CSSValueList;
- class ClientRectList;
- class DOMImplementation;
class DOMWindow;
- class Document;
- class Element;
- class Event;
- class EventListener;
- class EventTarget;
class Frame;
- class HTMLCollection;
- class HTMLDocument;
- class HTMLElement;
- class HTMLOptionsCollection;
- class MediaList;
- class MimeType;
- class MimeTypeArray;
- class NamedNodeMap;
- class Navigator;
class Node;
- class NodeFilter;
- class NodeList;
- class Plugin;
- class PluginArray;
class SVGElement;
-#if ENABLE(SVG)
- class SVGElementInstance;
-#endif
- class Screen;
class ScriptExecutionContext;
-#if ENABLE(DOM_STORAGE)
- class Storage;
- class StorageEvent;
-#endif
class String;
- class StyleSheet;
- class StyleSheetList;
class V8EventListener;
- class V8ObjectEventListener;
+ class V8IsolatedWorld;
+ class WorldContextHandle;
// FIXME: use standard logging facilities in WebCore.
void logInfo(Frame*, const String& message, const String& url);
@@ -123,6 +83,16 @@ namespace WebCore {
void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedAttribute*, size_t attributeCount);
+ inline void configureAttribute(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute& attribute)
+ {
+ (attribute.onProto ? proto : instance)->SetAccessor(v8::String::New(attribute.name),
+ attribute.getter,
+ attribute.setter,
+ attribute.data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute.data)),
+ attribute.settings,
+ attribute.attribute);
+ }
+
// BatchedConstant translates into calls to Set() for setting up an object's
// constants. It sets the constant on both the FunctionTemplate and the
// ObjectTemplate. PropertyAttributes is always ReadOnly.
@@ -133,6 +103,17 @@ namespace WebCore {
void batchConfigureConstants(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedConstant*, size_t constantCount);
+ struct BatchedCallback {
+ const char* const name;
+ v8::InvocationCallback callback;
+ };
+
+ void batchConfigureCallbacks(v8::Handle<v8::ObjectTemplate>,
+ v8::Handle<v8::Signature>,
+ v8::PropertyAttribute,
+ const BatchedCallback*,
+ size_t callbackCount);
+
const int kMaxRecursionDepth = 20;
// Information about an extension that is registered for use with V8. If
@@ -145,7 +126,7 @@ namespace WebCore {
int group;
v8::Extension* extension;
};
- typedef WTF::Vector<V8ExtensionInfo> V8ExtensionList;
+ typedef WTF::Vector<V8ExtensionInfo> V8Extensions;
class V8Proxy {
public:
@@ -158,7 +139,7 @@ namespace WebCore {
GeneralError
};
- explicit V8Proxy(Frame* frame) : m_frame(frame), m_inlineCode(false), m_timerCallback(false), m_recursion(0) { }
+ explicit V8Proxy(Frame*);
~V8Proxy();
@@ -194,14 +175,36 @@ namespace WebCore {
// and clears all timeouts on the DOM window.
void disconnectFrame();
- bool isEnabled();
-
- V8EventListenerList* eventListeners() { return &m_eventListeners; }
- V8EventListenerList* objectListeners() { return &m_objectListeners; }
-
#if ENABLE(SVG)
static void setSVGContext(void*, SVGElement*);
static SVGElement* svgContext(void*);
+
+ // These helper functions are required in case we are given a PassRefPtr
+ // to a (possibly) newly created object and must prevent its reference
+ // count from dropping to zero as would happen in code like
+ //
+ // V8Proxy::setSVGContext(imp->getNewlyCreatedObject().get(), context);
+ // foo(imp->getNewlyCreatedObject().get());
+ //
+ // In the above two lines each time getNewlyCreatedObject() is called it
+ // creates a new object because we don't ref() it. (So our attemts to
+ // associate a context with it fail.) Such code should be rewritten to
+ //
+ // foo(V8Proxy::withSVGContext(imp->getNewlyCreatedObject(), context).get());
+ //
+ // where PassRefPtr::~PassRefPtr() is invoked only after foo() is
+ // called.
+ template <typename T>
+ static PassRefPtr<T> withSVGContext(PassRefPtr<T> object, SVGElement* context)
+ {
+ setSVGContext(object.get(), context);
+ return object;
+ }
+ static void* withSVGContext(void* object, SVGElement* context)
+ {
+ setSVGContext(object, context);
+ return object;
+ }
#endif
void setEventHandlerLineNumber(int lineNumber) { m_handlerLineNumber = lineNumber; }
@@ -211,7 +214,7 @@ namespace WebCore {
// global scope, its own prototypes for intrinsic JavaScript objects (String,
// Array, and so-on), and its own wrappers for all DOM nodes and DOM
// constructors.
- void evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup);
+ void evaluateInIsolatedWorld(int worldId, const Vector<ScriptSourceCode>& sources, int extensionGroup);
// Evaluate JavaScript in a new context. The script gets its own global scope
// and its own prototypes for intrinsic JavaScript objects (String, Array,
@@ -239,7 +242,12 @@ namespace WebCore {
// To create JS Wrapper objects, we create a cache of a 'boiler plate'
// object, and then simply Clone that object each time we need a new one.
// This is faster than going through the full object creation process.
- v8::Local<v8::Object> createWrapperFromCache(V8ClassIndex::V8WrapperType);
+ v8::Local<v8::Object> createWrapperFromCache(V8ClassIndex::V8WrapperType type)
+ {
+ int classIndex = V8ClassIndex::ToInt(type);
+ v8::Local<v8::Object> clone(m_wrapperBoilerplates->CloneElementAt(classIndex));
+ return clone.IsEmpty() ? createWrapperFromCacheSlowCase(type) : clone;
+ }
// Returns the window object associated with a context.
static DOMWindow* retrieveWindow(v8::Handle<v8::Context>);
@@ -331,14 +339,16 @@ namespace WebCore {
// Function for retrieving the line number and source name for the top
// JavaScript stack frame.
- static int sourceLineNumber();
- static String sourceName();
+ //
+ // It will return true if the line number was successfully retrieved and written
+ // into the |result| parameter, otherwise the function will return false. It may
+ // fail due to a stck overflow in the underlying JavaScript implentation, handling
+ // of such exception is up to the caller.
+ static bool sourceLineNumber(int& result);
+ static bool sourceName(String& result);
- // Returns a local handle of the context.
- v8::Local<v8::Context> context()
- {
- return v8::Local<v8::Context>::New(m_context);
- }
+ v8::Local<v8::Context> context();
+ v8::Local<v8::Context> mainWorldContext();
bool setContextDebugId(int id);
static int contextDebugId(v8::Handle<v8::Context>);
@@ -365,10 +375,6 @@ namespace WebCore {
void updateDocumentWrapper(v8::Handle<v8::Value> wrapper);
private:
- static const char* kContextDebugDataType;
- static const char* kContextDebugDataValue;
-
- void disconnectEventListeners();
void setSecurityToken();
void clearDocumentWrapper();
@@ -382,6 +388,15 @@ namespace WebCore {
// Dispose global handles of m_contexts and friends.
void disposeContextHandles();
+ // If m_recursionCount is 0, let LocalStorage know so we can release
+ // the storage mutex.
+ void releaseStorageMutex();
+
+ void resetIsolatedWorlds();
+
+ // Returns false when we're out of memory in V8.
+ bool setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext);
+
static bool canAccessPrivate(DOMWindow*);
static const char* rangeExceptionName(int exceptionCode);
@@ -407,11 +422,15 @@ namespace WebCore {
return v8::Local<v8::Context>::New(m_utilityContext);
}
+ v8::Local<v8::Object> createWrapperFromCacheSlowCase(V8ClassIndex::V8WrapperType);
+
static void registerExtensionWithV8(v8::Extension*);
+ static bool registeredExtensionWithV8(v8::Extension*);
Frame* m_frame;
v8::Persistent<v8::Context> m_context;
+
// For each possible type of wrapper, we keep a boilerplate object.
// The boilerplate is used to create additional wrappers of the same
// type. We keep a single persistent handle to an array of the
@@ -426,14 +445,6 @@ namespace WebCore {
int m_handlerLineNumber;
- // A list of event listeners created for this frame,
- // the list gets cleared when removing all timeouts.
- V8EventListenerList m_eventListeners;
-
- // A list of event listeners create for XMLHttpRequest object for this frame,
- // the list gets cleared when removing all timeouts.
- V8EventListenerList m_objectListeners;
-
// True for <a href="javascript:foo()"> and false for <script>foo()</script>.
// Only valid during execution.
bool m_inlineCode;
@@ -447,8 +458,18 @@ namespace WebCore {
// excessive recursion in the binding layer.
int m_recursion;
- // List of extensions registered with the context.
- static V8ExtensionList m_extensions;
+ // All of the extensions registered with the context.
+ static V8Extensions m_extensions;
+
+ // The isolated worlds we are tracking for this frame. We hold them alive
+ // here so that they can be used again by future calls to
+ // evaluateInIsolatedWorld().
+ //
+ // Note: although the pointer is raw, the instance is kept alive by a strong
+ // reference to the v8 context it contains, which is not made weak until we
+ // call world->destroy().
+ typedef HashMap<int, V8IsolatedWorld*> IsolatedWorldMap;
+ IsolatedWorldMap m_isolatedWorlds;
};
template <int tag, typename T>
@@ -467,6 +488,8 @@ namespace WebCore {
}
+ v8::Local<v8::Context> toV8Context(ScriptExecutionContext*, const WorldContextHandle& worldContext);
+
// Used by an interceptor callback that it hasn't found anything to
// intercept.
inline static v8::Local<v8::Object> notHandledByInterceptor()