]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/JSScope.h
JavaScriptCore-1218.0.1.tar.gz
[apple/javascriptcore.git] / runtime / JSScope.h
CommitLineData
93a37866
A
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
32namespace JSC {
33
34class ScopeChainIterator;
35
36class JSScope : public JSNonFinalObject {
37public:
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
65protected:
66 JSScope(VM&, Structure*, JSScope* next);
67 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
68
69private:
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
83inline JSScope::JSScope(VM& vm, Structure* structure, JSScope* next)
84 : Base(vm, structure)
85 , m_next(vm, this, next, WriteBarrier<JSScope>::MayBeNull)
86{
87}
88
89class ScopeChainIterator {
90public:
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
106private:
107 JSScope* m_node;
108};
109
110inline ScopeChainIterator JSScope::begin()
111{
112 return ScopeChainIterator(this);
113}
114
115inline ScopeChainIterator JSScope::end()
116{
117 return ScopeChainIterator(0);
118}
119
120inline JSScope* JSScope::next()
121{
122 return m_next.get();
123}
124
125inline JSGlobalObject* JSScope::globalObject()
126{
127 return structure()->globalObject();
128}
129
130inline VM* JSScope::vm()
131{
132 return Heap::heap(this)->vm();
133}
134
135inline Register& Register::operator=(JSScope* scope)
136{
137 *this = JSValue(scope);
138 return *this;
139}
140
141inline JSScope* Register::scope() const
142{
143 return jsCast<JSScope*>(jsValue());
144}
145
146inline VM& ExecState::vm() const
147{
148 ASSERT(scope()->vm());
149 return *scope()->vm();
150}
151
152inline JSGlobalObject* ExecState::lexicalGlobalObject() const
153{
154 return scope()->globalObject();
155}
156
157inline JSObject* ExecState::globalThisValue() const
158{
159 return scope()->globalThis();
160}
161
162inline size_t JSScope::offsetOfNext()
163{
164 return OBJECT_OFFSETOF(JSScope, m_next);
165}
166
167} // namespace JSC
168
169#endif // JSScope_h