2
* Copyright (C) 2012 Apple Inc. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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.
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.
30
#include "ResolveOperation.h"
34
class ScopeChainIterator;
36
class JSScope : public JSNonFinalObject {
38
typedef JSNonFinalObject Base;
40
friend class LLIntOffsetsExtractor;
41
static size_t offsetOfNext();
43
JS_EXPORT_PRIVATE static JSObject* objectAtScope(JSScope*);
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*);
52
static void visitChildren(JSCell*, SlotVisitor&);
54
bool isDynamicScope(bool& requiresDynamicChecks) const;
56
ScopeChainIterator begin();
57
ScopeChainIterator end();
61
JSGlobalObject* globalObject();
62
JSGlobalData* globalData();
63
JSObject* globalThis();
66
JSScope(JSGlobalData&, Structure*, JSScope* next);
67
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
70
WriteBarrier<JSScope> m_next;
75
ReturnBaseAndValue = ReturnValue | ReturnBase,
76
ReturnThisAndValue = ReturnValue | ReturnThis,
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);
83
inline JSScope::JSScope(JSGlobalData& globalData, Structure* structure, JSScope* next)
84
: Base(globalData, structure)
85
, m_next(globalData, this, next, WriteBarrier<JSScope>::MayBeNull)
89
class ScopeChainIterator {
91
ScopeChainIterator(JSScope* node)
96
JSObject* get() const { return JSScope::objectAtScope(m_node); }
97
JSObject* operator->() const { return JSScope::objectAtScope(m_node); }
99
ScopeChainIterator& operator++() { m_node = m_node->next(); return *this; }
101
// postfix ++ intentionally omitted
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; }
110
inline ScopeChainIterator JSScope::begin()
112
return ScopeChainIterator(this);
115
inline ScopeChainIterator JSScope::end()
117
return ScopeChainIterator(0);
120
inline JSScope* JSScope::next()
125
inline JSGlobalObject* JSScope::globalObject()
127
return structure()->globalObject();
130
inline JSGlobalData* JSScope::globalData()
132
return Heap::heap(this)->globalData();
135
inline Register& Register::operator=(JSScope* scope)
137
*this = JSValue(scope);
141
inline JSScope* Register::scope() const
143
return jsCast<JSScope*>(jsValue());
146
inline JSGlobalData& ExecState::globalData() const
148
ASSERT(scope()->globalData());
149
return *scope()->globalData();
152
inline JSGlobalObject* ExecState::lexicalGlobalObject() const
154
return scope()->globalObject();
157
inline JSObject* ExecState::globalThisValue() const
159
return scope()->globalThis();
162
inline size_t JSScope::offsetOfNext()
164
return OBJECT_OFFSETOF(JSScope, m_next);