]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/GetterSetter.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / GetterSetter.h
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
ed1e77d3 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
9dae56ea
A
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef GetterSetter_h
24#define GetterSetter_h
25
26#include "JSCell.h"
27
f9bf01c6 28#include "CallFrame.h"
ed1e77d3
A
29#include "JSGlobalObject.h"
30#include "NullGetterFunction.h"
31#include "NullSetterFunction.h"
14957cd0 32#include "Structure.h"
f9bf01c6 33
9dae56ea
A
34namespace JSC {
35
ed1e77d3
A
36class JSObject;
37
38// This is an internal value object which stores getter and setter functions
39// for a property. Instances of this class have the property that once a getter
40// or setter is set to a non-null value, then they cannot be changed. This means
41// that if a property holding a GetterSetter reference is constant-inferred and
42// that constant is observed to have a non-null setter (or getter) then we can
43// constant fold that setter (or getter).
44class GetterSetter final : public JSCell {
45 friend class JIT;
46
47private:
48 GetterSetter(VM& vm, JSGlobalObject* globalObject)
49 : JSCell(vm, vm.getterSetterStructure.get())
50 {
51 m_getter.set(vm, this, globalObject->nullGetterFunction());
52 m_setter.set(vm, this, globalObject->nullSetterFunction());
53 }
54
55public:
56 typedef JSCell Base;
57 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
58
59 static GetterSetter* create(VM& vm, JSGlobalObject* globalObject)
60 {
61 GetterSetter* getterSetter = new (NotNull, allocateCell<GetterSetter>(vm.heap)) GetterSetter(vm, globalObject);
62 getterSetter->finishCreation(vm);
63 return getterSetter;
64 }
65
66 static void visitChildren(JSCell*, SlotVisitor&);
67
68 JSObject* getter() const { return m_getter.get(); }
69
70 JSObject* getterConcurrently() const
71 {
72 JSObject* result = getter();
73 WTF::loadLoadFence();
74 return result;
75 }
76
77 bool isGetterNull() const { return !!jsDynamicCast<NullGetterFunction*>(m_getter.get()); }
78 bool isSetterNull() const { return !!jsDynamicCast<NullSetterFunction*>(m_setter.get()); }
79
80 // Set the getter. It's only valid to call this if you've never set the getter on this
81 // object.
82 void setGetter(VM& vm, JSGlobalObject* globalObject, JSObject* getter)
83 {
84 if (!getter)
85 getter = jsCast<JSObject*>(globalObject->nullGetterFunction());
86
87 RELEASE_ASSERT(isGetterNull());
88 WTF::storeStoreFence();
89 m_getter.set(vm, this, getter);
90 }
91
92 JSObject* setter() const { return m_setter.get(); }
93
94 JSObject* setterConcurrently() const
95 {
96 JSObject* result = setter();
97 WTF::loadLoadFence();
98 return result;
99 }
100
101 // Set the setter. It's only valid to call this if you've never set the setter on this
102 // object.
103 void setSetter(VM& vm, JSGlobalObject* globalObject, JSObject* setter)
104 {
105 if (!setter)
106 setter = jsCast<JSObject*>(globalObject->nullSetterFunction());
107
108 RELEASE_ASSERT(isSetterNull());
109 WTF::storeStoreFence();
110 m_setter.set(vm, this, setter);
111 }
112
113 GetterSetter* withGetter(VM&, JSGlobalObject*, JSObject* getter);
114 GetterSetter* withSetter(VM&, JSGlobalObject*, JSObject* setter);
115
116 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
9dae56ea 117 {
ed1e77d3 118 return Structure::create(vm, globalObject, prototype, TypeInfo(GetterSetterType), info());
9dae56ea
A
119 }
120
ed1e77d3
A
121 static ptrdiff_t offsetOfGetter()
122 {
123 return OBJECT_OFFSETOF(GetterSetter, m_getter);
124 }
125
126 static ptrdiff_t offsetOfSetter()
127 {
128 return OBJECT_OFFSETOF(GetterSetter, m_setter);
129 }
130
131 DECLARE_INFO;
132
133private:
134 WriteBarrier<JSObject> m_getter;
135 WriteBarrier<JSObject> m_setter;
136};
137
138GetterSetter* asGetterSetter(JSValue);
139
140inline GetterSetter* asGetterSetter(JSValue value)
141{
142 ASSERT_WITH_SECURITY_IMPLICATION(value.asCell()->isGetterSetter());
143 return static_cast<GetterSetter*>(value.asCell());
144}
145
146JSValue callGetter(ExecState*, JSValue base, JSValue getterSetter);
147void callSetter(ExecState*, JSValue base, JSValue getterSetter, JSValue, ECMAMode);
9dae56ea
A
148
149} // namespace JSC
150
151#endif // GetterSetter_h