]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/Arguments.h
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / runtime / Arguments.h
1 /*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
5 * Copyright (C) 2007 Maks Orlovich
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24 #ifndef Arguments_h
25 #define Arguments_h
26
27 #include "CodeOrigin.h"
28 #include "JSActivation.h"
29 #include "JSFunction.h"
30 #include "JSGlobalObject.h"
31 #include "Interpreter.h"
32 #include "ObjectConstructor.h"
33
34 namespace JSC {
35
36 struct ArgumentsData {
37 WTF_MAKE_NONCOPYABLE(ArgumentsData); WTF_MAKE_FAST_ALLOCATED;
38 public:
39 ArgumentsData() { }
40 WriteBarrier<JSActivation> activation;
41
42 unsigned numArguments;
43
44 WriteBarrier<Unknown>* registers;
45 OwnArrayPtr<WriteBarrier<Unknown> > registerArray;
46
47 OwnArrayPtr<bool> deletedArguments;
48
49 WriteBarrier<JSFunction> callee;
50 bool overrodeLength : 1;
51 bool overrodeCallee : 1;
52 bool overrodeCaller : 1;
53 bool isStrictMode : 1;
54 };
55
56 class Arguments : public JSNonFinalObject {
57 public:
58 typedef JSNonFinalObject Base;
59
60 static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame)
61 {
62 Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);
63 arguments->finishCreation(callFrame);
64 return arguments;
65 }
66
67 enum { MaxArguments = 0x10000 };
68
69 private:
70 enum NoParametersType { NoParameters };
71
72 Arguments(CallFrame*);
73 Arguments(CallFrame*, NoParametersType);
74
75 public:
76 static const ClassInfo s_info;
77
78 static void visitChildren(JSCell*, SlotVisitor&);
79
80 void fillArgList(ExecState*, MarkedArgumentBuffer&);
81
82 uint32_t length(ExecState* exec) const
83 {
84 if (UNLIKELY(d->overrodeLength))
85 return get(exec, exec->propertyNames().length).toUInt32(exec);
86 return d->numArguments;
87 }
88
89 void copyToArguments(ExecState*, CallFrame*, uint32_t length);
90 void tearOff(CallFrame*);
91 bool isTornOff() const { return d->registerArray; }
92 void didTearOffActivation(JSGlobalData& globalData, JSActivation* activation)
93 {
94 if (isTornOff())
95 return;
96 d->activation.set(globalData, this, activation);
97 d->registers = &activation->registerAt(0);
98 }
99
100 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
101 {
102 return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
103 }
104
105 protected:
106 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
107
108 void finishCreation(CallFrame*);
109
110 private:
111 static void destroy(JSCell*);
112 static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier& propertyName, PropertySlot&);
113 static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
114 static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
115 static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
116 static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
117 static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
118 static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
119 static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
120 static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
121 void createStrictModeCallerIfNecessary(ExecState*);
122 void createStrictModeCalleeIfNecessary(ExecState*);
123
124 WriteBarrier<Unknown>& argument(size_t);
125
126 void init(CallFrame*);
127
128 OwnPtr<ArgumentsData> d;
129 };
130
131 Arguments* asArguments(JSValue);
132
133 inline Arguments* asArguments(JSValue value)
134 {
135 ASSERT(asObject(value)->inherits(&Arguments::s_info));
136 return static_cast<Arguments*>(asObject(value));
137 }
138
139 inline Arguments::Arguments(CallFrame* callFrame)
140 : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
141 , d(adoptPtr(new ArgumentsData))
142 {
143 }
144
145 inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
146 : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
147 , d(adoptPtr(new ArgumentsData))
148 {
149 }
150
151 inline WriteBarrier<Unknown>& Arguments::argument(size_t i)
152 {
153 return d->registers[CallFrame::argumentOffset(i)];
154 }
155
156 inline void Arguments::finishCreation(CallFrame* callFrame)
157 {
158 Base::finishCreation(callFrame->globalData());
159 ASSERT(inherits(&s_info));
160
161 JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
162 d->numArguments = callFrame->argumentCount();
163 d->registers = reinterpret_cast<WriteBarrier<Unknown>*>(callFrame->registers());
164 d->callee.set(callFrame->globalData(), this, callee);
165 d->overrodeLength = false;
166 d->overrodeCallee = false;
167 d->overrodeCaller = false;
168 d->isStrictMode = callFrame->codeBlock()->isStrictMode();
169
170 // The bytecode generator omits op_tear_off_activation in cases of no
171 // declared parameters, so we need to tear off immediately.
172 if (d->isStrictMode || !callee->jsExecutable()->parameterCount())
173 tearOff(callFrame);
174 }
175
176 } // namespace JSC
177
178 #endif // Arguments_h