1/*
2 * Copyright (C) 2008-2018 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
27#pragma once
28
29#include "WebCoreJSBuiltinInternals.h"
30#include <JavaScriptCore/HeapInlines.h>
31#include <JavaScriptCore/JSGlobalObject.h>
32#include <JavaScriptCore/LockDuringMarking.h>
33
34namespace WebCore {
35
36class DOMGuardedObject;
37class Event;
38class DOMWrapperWorld;
39class ScriptExecutionContext;
40
41using JSDOMStructureMap = HashMap<const JSC::ClassInfo*, JSC::WriteBarrier<JSC::Structure>>;
42using JSDOMConstructorMap = HashMap<const JSC::ClassInfo*, JSC::WriteBarrier<JSC::JSObject>>;
43using DOMGuardedObjectSet = HashSet<DOMGuardedObject*>;
44
45class WEBCORE_EXPORT JSDOMGlobalObject : public JSC::JSGlobalObject {
46 using Base = JSC::JSGlobalObject;
47protected:
48 struct JSDOMGlobalObjectData;
49
50 JSDOMGlobalObject(JSC::VM&, JSC::Structure*, Ref<DOMWrapperWorld>&&, const JSC::GlobalObjectMethodTable* = nullptr);
51 static void destroy(JSC::JSCell*);
52 void finishCreation(JSC::VM&);
53 void finishCreation(JSC::VM&, JSC::JSObject*);
54
55public:
56 Lock& gcLock() { return m_gcLock; }
57
58 JSDOMStructureMap& structures(const AbstractLocker&) { return m_structures; }
59 JSDOMConstructorMap& constructors(const AbstractLocker&) { return m_constructors; }
60
61 DOMGuardedObjectSet& guardedObjects(const AbstractLocker&) { return m_guardedObjects; }
62
63 ScriptExecutionContext* scriptExecutionContext() const;
64
65 // Make binding code generation easier.
66 JSDOMGlobalObject* globalObject() { return this; }
67
68 void setCurrentEvent(Event*);
69 Event* currentEvent() const;
70
71 static void visitChildren(JSC::JSCell*, JSC::SlotVisitor&);
72
73 DOMWrapperWorld& world() { return m_world.get(); }
74 bool worldIsNormal() const { return m_worldIsNormal; }
75 static ptrdiff_t offsetOfWorldIsNormal() { return OBJECT_OFFSETOF(JSDOMGlobalObject, m_worldIsNormal); }
76
77 JSBuiltinInternalFunctions& builtinInternalFunctions() { return m_builtinInternalFunctions; }
78
79protected:
80 static const JSC::ClassInfo s_info;
81
82public:
83 ~JSDOMGlobalObject();
84
85 static constexpr const JSC::ClassInfo* info() { return &s_info; }
86
87 static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSValue prototype)
88 {
89 return JSC::Structure::create(vm, 0, prototype, JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags), info());
90 }
91
92protected:
93 static void promiseRejectionTracker(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSPromise*, JSC::JSPromiseRejectionOperation);
94
95 JSDOMStructureMap m_structures;
96 JSDOMConstructorMap m_constructors;
97 DOMGuardedObjectSet m_guardedObjects;
98
99 Ref<DOMWrapperWorld> m_world;
100 uint8_t m_worldIsNormal;
101 Lock m_gcLock;
102
103private:
104 void addBuiltinGlobals(JSC::VM&);
105 friend void JSBuiltinInternalFunctions::initialize(JSDOMGlobalObject&);
106
107 Event* m_currentEvent { nullptr };
108
109 JSBuiltinInternalFunctions m_builtinInternalFunctions;
110};
111
112template<class ConstructorClass>
113inline JSC::JSObject* getDOMConstructor(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
114{
115 if (JSC::JSObject* constructor = const_cast<JSDOMGlobalObject&>(globalObject).constructors(NoLockingNecessary).get(ConstructorClass::info()).get())
116 return constructor;
117 JSC::JSObject* constructor = ConstructorClass::create(vm, ConstructorClass::createStructure(vm, const_cast<JSDOMGlobalObject&>(globalObject), ConstructorClass::prototypeForStructure(vm, globalObject)), const_cast<JSDOMGlobalObject&>(globalObject));
118 ASSERT(!const_cast<JSDOMGlobalObject&>(globalObject).constructors(NoLockingNecessary).contains(ConstructorClass::info()));
119 JSC::WriteBarrier<JSC::JSObject> temp;
120 JSDOMGlobalObject& mutableGlobalObject = const_cast<JSDOMGlobalObject&>(globalObject);
121 auto locker = JSC::lockDuringMarking(vm.heap, mutableGlobalObject.gcLock());
122 mutableGlobalObject.constructors(locker).add(ConstructorClass::info(), temp).iterator->value.set(vm, &globalObject, constructor);
123 return constructor;
124}
125
126WEBCORE_EXPORT JSDOMGlobalObject& callerGlobalObject(JSC::ExecState&);
127
128JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext&, DOMWrapperWorld&);
129
130} // namespace WebCore
131