]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSScope.h
JavaScriptCore-1218.33.tar.gz
[apple/javascriptcore.git] / runtime / JSScope.h
1 /*
2 * Copyright (C) 2012 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 #ifndef JSScope_h
27 #define JSScope_h
28
29 #include "JSObject.h"
30 #include "ResolveOperation.h"
31
32 namespace JSC {
33
34 class ScopeChainIterator;
35
36 class JSScope : public JSNonFinalObject {
37 public:
38 typedef JSNonFinalObject Base;
39
40 friend class LLIntOffsetsExtractor;
41 static size_t offsetOfNext();
42
43 JS_EXPORT_PRIVATE static JSObject* objectAtScope(JSScope*);
44
45 static JSValue resolve(CallFrame*, const Identifier&, ResolveOperations*);
46 static JSValue resolveBase(CallFrame*, const Identifier&, bool isStrict, ResolveOperations*, PutToBaseOperation*);
47 static JSValue resolveWithBase(CallFrame*, const Identifier&, Register* base, ResolveOperations*, PutToBaseOperation*);
48 static JSValue resolveWithThis(CallFrame*, const Identifier&, Register* base, ResolveOperations*);
49 static JSValue resolveGlobal(CallFrame*, const Identifier&, JSGlobalObject*, ResolveOperation*);
50 static void resolvePut(CallFrame*, JSValue base, const Identifier&, JSValue, PutToBaseOperation*);
51
52 static void visitChildren(JSCell*, SlotVisitor&);
53
54 bool isDynamicScope(bool& requiresDynamicChecks) const;
55
56 ScopeChainIterator begin();
57 ScopeChainIterator end();
58 JSScope* next();
59 int localDepth();
60
61 JSGlobalObject* globalObject();
62 VM* vm();
63 JSObject* globalThis();
64
65 protected:
66 JSScope(VM&, Structure*, JSScope* next);
67 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
68
69 private:
70 WriteBarrier<JSScope> m_next;
71 enum ReturnValues {
72 ReturnValue = 1,
73 ReturnBase = 2,
74 ReturnThis = 4,
75 ReturnBaseAndValue = ReturnValue | ReturnBase,
76 ReturnThisAndValue = ReturnValue | ReturnThis,
77 };
78 enum LookupMode { UnknownResolve, KnownResolve };
79 template <LookupMode, ReturnValues> static JSObject* resolveContainingScopeInternal(CallFrame*, const Identifier&, PropertySlot&, ResolveOperations*, PutToBaseOperation*, bool isStrict);
80 template <ReturnValues> static JSObject* resolveContainingScope(CallFrame*, const Identifier&, PropertySlot&, ResolveOperations*, PutToBaseOperation*, bool isStrict);
81 };
82
83 inline JSScope::JSScope(VM& vm, Structure* structure, JSScope* next)
84 : Base(vm, structure)
85 , m_next(vm, this, next, WriteBarrier<JSScope>::MayBeNull)
86 {
87 }
88
89 class ScopeChainIterator {
90 public:
91 ScopeChainIterator(JSScope* node)
92 : m_node(node)
93 {
94 }
95
96 JSObject* get() const { return JSScope::objectAtScope(m_node); }
97 JSObject* operator->() const { return JSScope::objectAtScope(m_node); }
98
99 ScopeChainIterator& operator++() { m_node = m_node->next(); return *this; }
100
101 // postfix ++ intentionally omitted
102
103 bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
104 bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
105
106 private:
107 JSScope* m_node;
108 };
109
110 inline ScopeChainIterator JSScope::begin()
111 {
112 return ScopeChainIterator(this);
113 }
114
115 inline ScopeChainIterator JSScope::end()
116 {
117 return ScopeChainIterator(0);
118 }
119
120 inline JSScope* JSScope::next()
121 {
122 return m_next.get();
123 }
124
125 inline JSGlobalObject* JSScope::globalObject()
126 {
127 return structure()->globalObject();
128 }
129
130 inline VM* JSScope::vm()
131 {
132 return Heap::heap(this)->vm();
133 }
134
135 inline Register& Register::operator=(JSScope* scope)
136 {
137 *this = JSValue(scope);
138 return *this;
139 }
140
141 inline JSScope* Register::scope() const
142 {
143 return jsCast<JSScope*>(jsValue());
144 }
145
146 inline VM& ExecState::vm() const
147 {
148 ASSERT(scope()->vm());
149 return *scope()->vm();
150 }
151
152 inline JSGlobalObject* ExecState::lexicalGlobalObject() const
153 {
154 return scope()->globalObject();
155 }
156
157 inline JSObject* ExecState::globalThisValue() const
158 {
159 return scope()->globalThis();
160 }
161
162 inline size_t JSScope::offsetOfNext()
163 {
164 return OBJECT_OFFSETOF(JSScope, m_next);
165 }
166
167 } // namespace JSC
168
169 #endif // JSScope_h