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
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.
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.
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.
27 #include "CodeOrigin.h"
28 #include "JSActivation.h"
29 #include "JSFunction.h"
30 #include "JSGlobalObject.h"
31 #include "Interpreter.h"
32 #include "ObjectConstructor.h"
36 struct ArgumentsData
{
37 WTF_MAKE_NONCOPYABLE(ArgumentsData
); WTF_MAKE_FAST_ALLOCATED
;
40 WriteBarrier
<JSActivation
> activation
;
42 unsigned numArguments
;
44 WriteBarrier
<Unknown
>* registers
;
45 OwnArrayPtr
<WriteBarrier
<Unknown
> > registerArray
;
47 OwnArrayPtr
<bool> deletedArguments
;
49 WriteBarrier
<JSFunction
> callee
;
50 bool overrodeLength
: 1;
51 bool overrodeCallee
: 1;
52 bool overrodeCaller
: 1;
53 bool isStrictMode
: 1;
56 class Arguments
: public JSNonFinalObject
{
58 typedef JSNonFinalObject Base
;
60 static Arguments
* create(JSGlobalData
& globalData
, CallFrame
* callFrame
)
62 Arguments
* arguments
= new (NotNull
, allocateCell
<Arguments
>(globalData
.heap
)) Arguments(callFrame
);
63 arguments
->finishCreation(callFrame
);
67 enum { MaxArguments
= 0x10000 };
70 enum NoParametersType
{ NoParameters
};
72 Arguments(CallFrame
*);
73 Arguments(CallFrame
*, NoParametersType
);
76 static const ClassInfo s_info
;
78 static void visitChildren(JSCell
*, SlotVisitor
&);
80 void fillArgList(ExecState
*, MarkedArgumentBuffer
&);
82 uint32_t length(ExecState
* exec
) const
84 if (UNLIKELY(d
->overrodeLength
))
85 return get(exec
, exec
->propertyNames().length
).toUInt32(exec
);
86 return d
->numArguments
;
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
)
96 d
->activation
.set(globalData
, this, activation
);
97 d
->registers
= &activation
->registerAt(0);
100 static Structure
* createStructure(JSGlobalData
& globalData
, JSGlobalObject
* globalObject
, JSValue prototype
)
102 return Structure::create(globalData
, globalObject
, prototype
, TypeInfo(ObjectType
, StructureFlags
), &s_info
);
106 static const unsigned StructureFlags
= OverridesGetOwnPropertySlot
| OverridesVisitChildren
| OverridesGetPropertyNames
| JSObject::StructureFlags
;
108 void finishCreation(CallFrame
*);
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
*);
124 WriteBarrier
<Unknown
>& argument(size_t);
126 void init(CallFrame
*);
128 OwnPtr
<ArgumentsData
> d
;
131 Arguments
* asArguments(JSValue
);
133 inline Arguments
* asArguments(JSValue value
)
135 ASSERT(asObject(value
)->inherits(&Arguments::s_info
));
136 return static_cast<Arguments
*>(asObject(value
));
139 inline Arguments::Arguments(CallFrame
* callFrame
)
140 : JSNonFinalObject(callFrame
->globalData(), callFrame
->lexicalGlobalObject()->argumentsStructure())
141 , d(adoptPtr(new ArgumentsData
))
145 inline Arguments::Arguments(CallFrame
* callFrame
, NoParametersType
)
146 : JSNonFinalObject(callFrame
->globalData(), callFrame
->lexicalGlobalObject()->argumentsStructure())
147 , d(adoptPtr(new ArgumentsData
))
151 inline WriteBarrier
<Unknown
>& Arguments::argument(size_t i
)
153 return d
->registers
[CallFrame::argumentOffset(i
)];
156 inline void Arguments::finishCreation(CallFrame
* callFrame
)
158 Base::finishCreation(callFrame
->globalData());
159 ASSERT(inherits(&s_info
));
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();
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())
178 #endif // Arguments_h