Add support for private names
[WebKit-https.git] / Source / JavaScriptCore / 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*, PropertyName, PropertySlot&);
113         static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
114         static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
115         static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
116         static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
117         static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
118         static bool deleteProperty(JSCell*, ExecState*, PropertyName);
119         static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
120         static bool defineOwnProperty(JSObject*, ExecState*, 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