2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2003, 2006, 2007, 2008 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 "JSActivation.h"
28 #include "JSFunction.h"
29 #include "JSGlobalObject.h"
34 struct ArgumentsData : Noncopyable {
35 JSActivation* activation;
37 unsigned numParameters;
38 ptrdiff_t firstParameterIndex;
39 unsigned numArguments;
42 OwnArrayPtr<Register> registerArray;
44 Register* extraArguments;
45 OwnArrayPtr<bool> deletedArguments;
46 Register extraArgumentsFixedBuffer[4];
49 bool overrodeLength : 1;
50 bool overrodeCallee : 1;
54 class Arguments : public JSObject {
56 Arguments(CallFrame*);
59 static const ClassInfo info;
63 void fillArgList(ExecState*, ArgList&);
66 bool isTornOff() const { return d->registerArray; }
67 void setActivation(JSActivation* activation)
69 d->activation = activation;
70 d->registers = &activation->registerAt(0);
74 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
75 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
76 virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
77 virtual void put(ExecState*, unsigned propertyName, JSValue*, PutPropertySlot&);
78 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
79 virtual bool deleteProperty(ExecState*, unsigned propertyName);
81 virtual const ClassInfo* classInfo() const { return &info; }
83 void init(CallFrame*);
85 OwnPtr<ArgumentsData> d;
88 inline Arguments::Arguments(CallFrame* callFrame)
89 : JSObject(callFrame->lexicalGlobalObject()->argumentsStructure())
90 , d(new ArgumentsData)
93 ptrdiff_t firstParameterIndex;
96 callFrame->machine()->getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments);
98 d->numParameters = callee->m_body->parameterCount();
99 d->firstParameterIndex = firstParameterIndex;
100 d->numArguments = numArguments;
103 d->registers = callFrame->registers();
105 Register* extraArguments;
106 if (d->numArguments <= d->numParameters)
109 unsigned numExtraArguments = d->numArguments - d->numParameters;
110 if (numExtraArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(Register))
111 extraArguments = new Register[numExtraArguments];
113 extraArguments = d->extraArgumentsFixedBuffer;
114 for (unsigned i = 0; i < numExtraArguments; ++i)
115 extraArguments[i] = argv[d->numParameters + i];
118 d->extraArguments = extraArguments;
121 d->overrodeLength = false;
122 d->overrodeCallee = false;
125 inline void Arguments::copyRegisters()
127 ASSERT(!isTornOff());
129 if (!d->numParameters)
132 int registerOffset = d->numParameters + RegisterFile::CallFrameHeaderSize;
133 size_t registerArraySize = d->numParameters;
135 Register* registerArray = new Register[registerArraySize];
136 memcpy(registerArray, d->registers - registerOffset, registerArraySize * sizeof(Register));
137 d->registerArray.set(registerArray);
138 d->registers = registerArray + registerOffset;
141 // This JSActivation function is defined here so it can get at Arguments::setRegisters.
142 inline void JSActivation::copyRegisters(Arguments* arguments)
144 ASSERT(!d()->registerArray);
146 size_t numParametersMinusThis = d()->functionBody->generatedByteCode().numParameters - 1;
147 size_t numVars = d()->functionBody->generatedByteCode().numVars;
148 size_t numLocals = numVars + numParametersMinusThis;
153 int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
154 size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
156 Register* registerArray = copyRegisterArray(d()->registers - registerOffset, registerArraySize);
157 setRegisters(registerArray + registerOffset, registerArray);
158 if (arguments && !arguments->isTornOff())
159 static_cast<Arguments*>(arguments)->setActivation(this);
164 #endif // Arguments_h