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
);