diff options
Diffstat (limited to 'WebCore/bindings/v8/V8Proxy.h')
| -rw-r--r-- | WebCore/bindings/v8/V8Proxy.h | 171 |
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() |
