18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *  Copyright (C) 2009 Google, Inc. All rights reserved.
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Lesser General Public
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Lesser General Public License for more details.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Lesser General Public
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License along with this library; if not, write to the Free Software
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef JSDOMBinding_h
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define JSDOMBinding_h
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDOMGlobalObject.h"
26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "JSDOMWrapper.h"
27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "DOMWrapperWorld.h"
28d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Document.h"
292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <heap/Weak.h>
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <runtime/Completion.h>
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <runtime/Lookup.h>
32dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include <wtf/Forward.h>
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Noncopyable.h>
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    class JSGlobalData;
37cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    class DebuggerCallFrame;
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    class Document;
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    class Frame;
44cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    class JSNode;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    class KURL;
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    class Node;
47cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    class ScriptController;
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    class ScriptCachedFrameData;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    typedef int ExceptionCode;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // FIXME: This class should collapse into JSDOMWrapper once all JSDOMWrappers are
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // updated to store a globalObject pointer.
542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    class JSDOMWrapperWithGlobalPointer : public JSDOMWrapper {
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    public:
56e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        JSDOMGlobalObject* globalObject() const
57e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        {
582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return static_cast<JSDOMGlobalObject*>(JSDOMWrapper::globalObject());
59e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        }
600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ScriptExecutionContext* scriptExecutionContext() const
620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // FIXME: Should never be 0, but can be due to bug 27640.
64d0825bca7fe65beaee391d30da42e937db621564Steve Block            return globalObject()->scriptExecutionContext();
650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSValue prototype)
68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        {
692bde8e466a4451c7319e3a072d118917957d6554Steve Block            return JSC::Structure::create(globalData, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    protected:
732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        JSDOMWrapperWithGlobalPointer(JSC::Structure* structure, JSDOMGlobalObject* globalObject)
742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            : JSDOMWrapper(globalObject, structure)
750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // FIXME: This ASSERT is valid, but fires in fast/dom/gc-6.html when trying to create
770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // new JavaScript objects on detached windows due to DOMWindow::document()
780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // needing to reach through the frame to get to the Document*.  See bug 27640.
790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // ASSERT(globalObject->scriptExecutionContext());
800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    };
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Base class for all constructor objects in the JSC bindings.
842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    class DOMConstructorObject : public JSDOMWrapperWithGlobalPointer {
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    public:
862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSValue prototype)
870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
882bde8e466a4451c7319e3a072d118917957d6554Steve Block            return JSC::Structure::create(globalData, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    protected:
922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        static const unsigned StructureFlags = JSC::ImplementsHasInstance | JSC::OverridesMarkChildren | JSDOMWrapperWithGlobalPointer::StructureFlags;
932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        DOMConstructorObject(JSC::Structure* structure, JSDOMGlobalObject* globalObject)
942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            : JSDOMWrapperWithGlobalPointer(structure, globalObject)
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    };
980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Constructors using this base class depend on being in a Document and
1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // can never be used from a WorkerContext.
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    class DOMConstructorWithDocument : public DOMConstructorObject {
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    public:
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        Document* document() const
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return static_cast<Document*>(scriptExecutionContext());
1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    protected:
1092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        DOMConstructorWithDocument(JSC::Structure* structure, JSDOMGlobalObject* globalObject)
1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            : DOMConstructorObject(structure, globalObject)
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(globalObject->scriptExecutionContext()->isDocument());
1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    };
1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    void markActiveObjectsForContext(JSC::MarkStack&, JSC::JSGlobalData&, ScriptExecutionContext*);
1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    void markDOMObjectWrapper(JSC::MarkStack&, JSC::JSGlobalData& globalData, void* object);
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*);
1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, JSC::Structure*, const JSC::ClassInfo*);
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    inline JSDOMGlobalObject* deprecatedGlobalObjectForPrototype(JSC::ExecState* exec)
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // FIXME: Callers to this function should be using the global object
1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // from which the object is being created, instead of assuming the lexical one.
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // e.g. subframe.document.body should use the subframe's global object, not the lexical one.
1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec, JSDOMGlobalObject* globalObject)
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (JSC::Structure* structure = getCachedDOMStructure(globalObject, &WrapperClass::s_info))
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return structure;
1342bde8e466a4451c7319e3a072d118917957d6554Steve Block        return cacheDOMStructure(globalObject, WrapperClass::createStructure(exec->globalData(), WrapperClass::createPrototype(exec, globalObject)), &WrapperClass::s_info);
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    template<class WrapperClass> inline JSC::Structure* deprecatedGetDOMStructure(JSC::ExecState* exec)
1385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // FIXME: This function is wrong.  It uses the wrong global object for creating the prototype structure.
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return getDOMStructure<WrapperClass>(exec, deprecatedGlobalObjectForPrototype(exec));
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    template<class WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject)
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return static_cast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(globalObject))->storedPrototype()));
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Overload these functions to provide a fast path for wrapper access.
1492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    inline JSDOMWrapper* getInlineCachedWrapper(DOMWrapperWorld*, void*) { return 0; }
1502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    inline bool setInlineCachedWrapper(DOMWrapperWorld*, void*, JSDOMWrapper*) { return false; }
1512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    inline bool clearInlineCachedWrapper(DOMWrapperWorld*, void*, JSDOMWrapper*) { return false; }
1522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Overload these functions to provide a custom WeakHandleOwner.
1542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld* world, void*) { return world->defaultWrapperOwner(); }
1552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    inline void* wrapperContext(DOMWrapperWorld*, void* domObject) { return domObject; }
1562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    template <typename DOMClass> inline JSDOMWrapper* getCachedWrapper(DOMWrapperWorld* world, DOMClass* domObject)
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (JSDOMWrapper* wrapper = getInlineCachedWrapper(world, domObject))
1602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return wrapper;
1612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return world->m_wrappers.get(domObject).get();
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    template <typename DOMClass> inline void cacheWrapper(DOMWrapperWorld* world, DOMClass* domObject, JSDOMWrapper* wrapper)
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (setInlineCachedWrapper(world, domObject, wrapper))
1672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
1682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(!world->m_wrappers.contains(domObject));
1692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        world->m_wrappers.set(domObject, JSC::Weak<JSDOMWrapper>(*world->globalData(), wrapper, wrapperOwner(world, domObject), wrapperContext(world, domObject)));
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    template <typename DOMClass> inline void uncacheWrapper(DOMWrapperWorld* world, DOMClass* domObject, JSDOMWrapper* wrapper)
1732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
1742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (clearInlineCachedWrapper(world, domObject, wrapper))
1752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
1762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(world->m_wrappers.find(domObject)->second.get() == wrapper);
1772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        world->m_wrappers.remove(domObject);
1782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    #define CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, className, object) createWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
1812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    #define CREATE_DOM_NODE_WRAPPER(exec, globalObject, className, object) static_cast<JSNode*>(createWrapper<JS##className>(exec, globalObject, static_cast<className*>(object)))
1822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    template<class WrapperClass, class DOMClass> inline JSDOMWrapper* createWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(node);
1852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(!getCachedWrapper(currentWorld(exec), node));
1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, node);
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // FIXME: The entire function can be removed, once we fix caching.
1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // This function is a one-off hack to make Nodes cache in the right global object.
1892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        cacheWrapper(currentWorld(exec), node, wrapper);
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return wrapper;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    template<class WrapperClass, class DOMClass> inline JSC::JSValue wrap(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* domObject)
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!domObject)
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return JSC::jsNull();
1972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (JSDOMWrapper* wrapper = getCachedWrapper(currentWorld(exec), domObject))
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return wrapper;
1992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return createWrapper<WrapperClass>(exec, globalObject, domObject);
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const JSC::HashTable* getHashTableForGlobalData(JSC::JSGlobalData&, const JSC::HashTable* staticTable);
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void reportException(JSC::ExecState*, JSC::JSValue exception);
205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    void reportCurrentException(JSC::ExecState*);
206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Convert a DOM implementation exception code into a JavaScript exception in the execution state.
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void setDOMException(JSC::ExecState*, ExceptionCode);
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
210d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSC::JSValue jsString(JSC::ExecState*, const String&); // empty if the string is null
211d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSC::JSValue jsStringSlowCase(JSC::ExecState*, JSStringCache&, StringImpl*);
212d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSC::JSValue jsString(JSC::ExecState*, const KURL&); // empty if the URL is null
213d0825bca7fe65beaee391d30da42e937db621564Steve Block    inline JSC::JSValue jsString(JSC::ExecState* exec, const AtomicString& s)
214d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
215d0825bca7fe65beaee391d30da42e937db621564Steve Block        return jsString(exec, s.string());
216d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
217d0825bca7fe65beaee391d30da42e937db621564Steve Block
2185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&); // null if the string is null
2195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSC::JSValue jsStringOrNull(JSC::ExecState*, const KURL&); // null if the URL is null
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const String&); // undefined if the string is null
2225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const KURL&); // undefined if the URL is null
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSC::JSValue jsStringOrFalse(JSC::ExecState*, const String&); // boolean false if the string is null
2255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSC::JSValue jsStringOrFalse(JSC::ExecState*, const KURL&); // boolean false if the URL is null
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
227cad810f21b803229eb11403f9209855525a25d57Steve Block    // See JavaScriptCore for explanation: Should be used for any string that is already owned by another
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // object, to let the engine know that collecting the JSString wrapper is unlikely to save memory.
229a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    JSC::JSValue jsOwnedStringOrNull(JSC::ExecState*, const String&);
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
231dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    String identifierToString(const JSC::Identifier&);
232dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    String ustringToString(const JSC::UString&);
233dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSC::UString stringToUString(const String&);
234dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
235dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    AtomicString identifierToAtomicString(const JSC::Identifier&);
236dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    AtomicString ustringToAtomicString(const JSC::UString&);
237dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    AtomicStringImpl* findAtomicString(const JSC::Identifier&);
238dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    String valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null
240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    String valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null or undefined
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24268513a70bcd92384395513322f1b801e7bf9c729Steve Block    inline int32_t finiteInt32Value(JSC::JSValue value, JSC::ExecState* exec, bool& okay)
24368513a70bcd92384395513322f1b801e7bf9c729Steve Block    {
24468513a70bcd92384395513322f1b801e7bf9c729Steve Block        double number = value.toNumber(exec);
24568513a70bcd92384395513322f1b801e7bf9c729Steve Block        okay = isfinite(number);
24668513a70bcd92384395513322f1b801e7bf9c729Steve Block        return JSC::toInt32(number);
24768513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
24868513a70bcd92384395513322f1b801e7bf9c729Steve Block
249d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Returns a Date instance for the specified value, or null if the value is NaN or infinity.
250d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSC::JSValue jsDateOrNull(JSC::ExecState*, double);
251d0825bca7fe65beaee391d30da42e937db621564Steve Block    // NaN if the value can't be converted to a date.
252d0825bca7fe65beaee391d30da42e937db621564Steve Block    double valueToDate(JSC::ExecState*, JSC::JSValue);
253d0825bca7fe65beaee391d30da42e937db621564Steve Block
2540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // FIXME: These are a stop-gap until all toJS calls can be converted to pass a globalObject
2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    template <typename T>
2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    inline JSC::JSValue toJS(JSC::ExecState* exec, T* ptr)
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr);
2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    template <typename T>
2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr)
2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr.get());
2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    template <typename T>
2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* exec, T* ptr)
2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return toJSNewlyCreated(exec, deprecatedGlobalObjectForPrototype(exec), ptr);
2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    template <typename T>
2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<T> ptr)
2730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return toJS(exec, globalObject, ptr.get());
2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
277231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Validates that the passed object is a sequence type per section 4.1.13 of the WebIDL spec.
278231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    JSC::JSObject* toJSSequence(JSC::ExecState*, JSC::JSValue, unsigned&);
279231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool checkNodeSecurity(JSC::ExecState*, Node*);
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Helpers for Window, History, and Location classes to implement cross-domain policy.
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Besides the cross-domain check, they need non-caching versions of staticFunctionGetter for
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // because we do not want current property values involved at all.
285cad810f21b803229eb11403f9209855525a25d57Steve Block    // FIXME: These functions should be named frameAllowsAccessFrom, because the access is *to* the frame.
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool allowsAccessFromFrame(JSC::ExecState*, Frame*);
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool allowsAccessFromFrame(JSC::ExecState*, Frame*, String& message);
288cad810f21b803229eb11403f9209855525a25d57Steve Block    DOMWindow* activeDOMWindow(JSC::ExecState*);
289cad810f21b803229eb11403f9209855525a25d57Steve Block    DOMWindow* firstDOMWindow(JSC::ExecState*);
290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void printErrorMessageForFrame(Frame*, const String& message);
292dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier& propertyName);
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Frame* toDynamicFrame(JSC::ExecState*);
295f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    bool processingUserGesture();
296d0825bca7fe65beaee391d30da42e937db621564Steve Block
297d0825bca7fe65beaee391d30da42e937db621564Steve Block    inline JSC::JSValue jsString(JSC::ExecState* exec, const String& s)
298d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
299d0825bca7fe65beaee391d30da42e937db621564Steve Block        StringImpl* stringImpl = s.impl();
300d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!stringImpl || !stringImpl->length())
301d0825bca7fe65beaee391d30da42e937db621564Steve Block            return jsEmptyString(exec);
302d0825bca7fe65beaee391d30da42e937db621564Steve Block
303d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (stringImpl->length() == 1 && stringImpl->characters()[0] <= 0xFF)
304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return jsString(exec, stringToUString(s));
305d0825bca7fe65beaee391d30da42e937db621564Steve Block
306d0825bca7fe65beaee391d30da42e937db621564Steve Block        JSStringCache& stringCache = currentWorld(exec)->m_stringCache;
307d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (JSC::JSString* wrapper = stringCache.get(stringImpl))
308d0825bca7fe65beaee391d30da42e937db621564Steve Block            return wrapper;
309d0825bca7fe65beaee391d30da42e937db621564Steve Block
310d0825bca7fe65beaee391d30da42e937db621564Steve Block        return jsStringSlowCase(exec, stringCache, stringImpl);
311d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
312d0825bca7fe65beaee391d30da42e937db621564Steve Block
313dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inline DOMObjectWrapperMap& domObjectWrapperMapFor(JSC::ExecState* exec)
314dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
315dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return currentWorld(exec)->m_wrappers;
316dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
317dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
318dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inline String ustringToString(const JSC::UString& u)
319dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
320f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return u.impl();
321dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
322dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
323dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inline JSC::UString stringToUString(const String& s)
324dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
325dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return JSC::UString(s.impl());
326dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
327dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
328dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inline String identifierToString(const JSC::Identifier& i)
329dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
330f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return i.impl();
331dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
332dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
333dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inline AtomicString ustringToAtomicString(const JSC::UString& u)
334dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
335f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return AtomicString(u.impl());
336dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
337dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
338dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inline AtomicString identifierToAtomicString(const JSC::Identifier& identifier)
339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
340f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return AtomicString(identifier.impl());
341dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
342dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // JSDOMBinding_h
346