2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 * Copyright (C) 2007 Maks Orlovich
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
26 #include "Arguments.h"
28 #include "JSActivation.h"
29 #include "JSFunction.h"
30 #include "JSGlobalObject.h"
36 ASSERT_CLASS_FITS_IN_CELL(Arguments
);
38 const ClassInfo
Arguments::info
= { "Arguments", 0, 0, 0 };
40 Arguments::~Arguments()
42 if (d
->extraArguments
!= d
->extraArgumentsFixedBuffer
)
43 delete [] d
->extraArguments
;
46 void Arguments::mark()
50 if (d
->registerArray
) {
51 for (unsigned i
= 0; i
< d
->numParameters
; ++i
) {
52 if (!d
->registerArray
[i
].marked())
53 d
->registerArray
[i
].mark();
57 if (d
->extraArguments
) {
58 unsigned numExtraArguments
= d
->numArguments
- d
->numParameters
;
59 for (unsigned i
= 0; i
< numExtraArguments
; ++i
) {
60 if (!d
->extraArguments
[i
].marked())
61 d
->extraArguments
[i
].mark();
65 if (!d
->callee
->marked())
68 if (d
->activation
&& !d
->activation
->marked())
69 d
->activation
->mark();
72 void Arguments::fillArgList(ExecState
* exec
, ArgList
& args
)
74 if (LIKELY(!d
->deletedArguments
)) {
75 if (LIKELY(!d
->numParameters
)) {
76 args
.initialize(d
->extraArguments
, d
->numArguments
);
80 if (d
->numParameters
== d
->numArguments
) {
81 args
.initialize(&d
->registers
[d
->firstParameterIndex
], d
->numArguments
);
85 unsigned parametersLength
= min(d
->numParameters
, d
->numArguments
);
87 for (; i
< parametersLength
; ++i
)
88 args
.append(d
->registers
[d
->firstParameterIndex
+ i
].jsValue(exec
));
89 for (; i
< d
->numArguments
; ++i
)
90 args
.append(d
->extraArguments
[i
- d
->numParameters
].jsValue(exec
));
94 unsigned parametersLength
= min(d
->numParameters
, d
->numArguments
);
96 for (; i
< parametersLength
; ++i
) {
97 if (!d
->deletedArguments
[i
])
98 args
.append(d
->registers
[d
->firstParameterIndex
+ i
].jsValue(exec
));
100 args
.append(get(exec
, i
));
102 for (; i
< d
->numArguments
; ++i
) {
103 if (!d
->deletedArguments
[i
])
104 args
.append(d
->extraArguments
[i
- d
->numParameters
].jsValue(exec
));
106 args
.append(get(exec
, i
));
110 bool Arguments::getOwnPropertySlot(ExecState
* exec
, unsigned i
, PropertySlot
& slot
)
112 if (i
< d
->numArguments
&& (!d
->deletedArguments
|| !d
->deletedArguments
[i
])) {
113 if (i
< d
->numParameters
) {
114 slot
.setRegisterSlot(&d
->registers
[d
->firstParameterIndex
+ i
]);
116 slot
.setValue(d
->extraArguments
[i
- d
->numParameters
].jsValue(exec
));
120 return JSObject::getOwnPropertySlot(exec
, Identifier(exec
, UString::from(i
)), slot
);
123 bool Arguments::getOwnPropertySlot(ExecState
* exec
, const Identifier
& propertyName
, PropertySlot
& slot
)
126 unsigned i
= propertyName
.toArrayIndex(&isArrayIndex
);
127 if (isArrayIndex
&& i
< d
->numArguments
&& (!d
->deletedArguments
|| !d
->deletedArguments
[i
])) {
128 if (i
< d
->numParameters
) {
129 slot
.setRegisterSlot(&d
->registers
[d
->firstParameterIndex
+ i
]);
131 slot
.setValue(d
->extraArguments
[i
- d
->numParameters
].jsValue(exec
));
135 if (propertyName
== exec
->propertyNames().length
&& LIKELY(!d
->overrodeLength
)) {
136 slot
.setValue(jsNumber(exec
, d
->numArguments
));
140 if (propertyName
== exec
->propertyNames().callee
&& LIKELY(!d
->overrodeCallee
)) {
141 slot
.setValue(d
->callee
);
145 return JSObject::getOwnPropertySlot(exec
, propertyName
, slot
);
148 void Arguments::put(ExecState
* exec
, unsigned i
, JSValuePtr value
, PutPropertySlot
& slot
)
150 if (i
< d
->numArguments
&& (!d
->deletedArguments
|| !d
->deletedArguments
[i
])) {
151 if (i
< d
->numParameters
)
152 d
->registers
[d
->firstParameterIndex
+ i
] = JSValuePtr(value
);
154 d
->extraArguments
[i
- d
->numParameters
] = JSValuePtr(value
);
158 JSObject::put(exec
, Identifier(exec
, UString::from(i
)), value
, slot
);
161 void Arguments::put(ExecState
* exec
, const Identifier
& propertyName
, JSValuePtr value
, PutPropertySlot
& slot
)
164 unsigned i
= propertyName
.toArrayIndex(&isArrayIndex
);
165 if (isArrayIndex
&& i
< d
->numArguments
&& (!d
->deletedArguments
|| !d
->deletedArguments
[i
])) {
166 if (i
< d
->numParameters
)
167 d
->registers
[d
->firstParameterIndex
+ i
] = JSValuePtr(value
);
169 d
->extraArguments
[i
- d
->numParameters
] = JSValuePtr(value
);
173 if (propertyName
== exec
->propertyNames().length
&& !d
->overrodeLength
) {
174 d
->overrodeLength
= true;
175 putDirect(propertyName
, value
, DontEnum
);
179 if (propertyName
== exec
->propertyNames().callee
&& !d
->overrodeCallee
) {
180 d
->overrodeCallee
= true;
181 putDirect(propertyName
, value
, DontEnum
);
185 JSObject::put(exec
, propertyName
, value
, slot
);
188 bool Arguments::deleteProperty(ExecState
* exec
, unsigned i
)
190 if (i
< d
->numArguments
) {
191 if (!d
->deletedArguments
) {
192 d
->deletedArguments
.set(new bool[d
->numArguments
]);
193 memset(d
->deletedArguments
.get(), 0, sizeof(bool) * d
->numArguments
);
195 if (!d
->deletedArguments
[i
]) {
196 d
->deletedArguments
[i
] = true;
201 return JSObject::deleteProperty(exec
, Identifier(exec
, UString::from(i
)));
204 bool Arguments::deleteProperty(ExecState
* exec
, const Identifier
& propertyName
)
207 unsigned i
= propertyName
.toArrayIndex(&isArrayIndex
);
208 if (isArrayIndex
&& i
< d
->numArguments
) {
209 if (!d
->deletedArguments
) {
210 d
->deletedArguments
.set(new bool[d
->numArguments
]);
211 memset(d
->deletedArguments
.get(), 0, sizeof(bool) * d
->numArguments
);
213 if (!d
->deletedArguments
[i
]) {
214 d
->deletedArguments
[i
] = true;
219 if (propertyName
== exec
->propertyNames().length
&& !d
->overrodeLength
) {
220 d
->overrodeLength
= true;
224 if (propertyName
== exec
->propertyNames().callee
&& !d
->overrodeCallee
) {
225 d
->overrodeCallee
= true;
229 return JSObject::deleteProperty(exec
, propertyName
);