source: webkit/trunk/JavaScriptCore/kjs/Arguments.cpp@ 37337

Last change on this file since 37337 was 37324, checked in by [email protected], 17 years ago

2008-10-05 Cameron Zwarich <[email protected]>

Reviewed by Oliver Hunt.

Bug 21364: Remove the branch in op_ret for OptionalCalleeActivation and OptionalCalleeArguments
<https://bugs.webkit.org/show_bug.cgi?id=21364>

Use information from the parser to detect whether an activation is
needed or 'arguments' is used, and emit explicit instructions to tear
them off before op_ret. This allows a branch to be removed from op_ret
and simplifies some other code. This does cause a small change in the
behaviour of 'f.arguments'; it is no longer live when 'arguments' is not
mentioned in the lexical scope of the function.

It should now be easy to remove the OptionaCalleeActivation slot in the
call frame, but this will be done in a later patch.

JavaScriptCore:

  • VM/CTI.cpp: (JSC::CTI::privateCompileMainPass):
  • VM/CodeBlock.cpp: (JSC::CodeBlock::dump):
  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::emitReturn):
  • VM/CodeGenerator.h:
  • VM/Machine.cpp: (JSC::Machine::unwindCallFrame): (JSC::Machine::privateExecute): (JSC::Machine::retrieveArguments): (JSC::Machine::cti_op_create_arguments): (JSC::Machine::cti_op_tear_off_activation): (JSC::Machine::cti_op_tear_off_arguments):
  • VM/Machine.h:
  • VM/Opcode.h:
  • kjs/Arguments.cpp: (JSC::Arguments::mark):
  • kjs/Arguments.h: (JSC::Arguments::isTornOff): (JSC::Arguments::Arguments): (JSC::Arguments::copyRegisters): (JSC::JSActivation::copyRegisters):
  • kjs/JSActivation.cpp: (JSC::JSActivation::argumentsGetter):
  • kjs/JSActivation.h:

LayoutTests:

  • fast/js/function-dot-arguments-expected.txt:
  • fast/js/resources/function-dot-arguments.js:
  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1/*
2 * Copyright (C) 1999-2002 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich ([email protected])
6 * Copyright (C) 2007 Maks Orlovich
7 *
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.
12 *
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.
17 *
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.
22 *
23 */
24
25#include "config.h"
26#include "Arguments.h"
27
28#include "JSActivation.h"
29#include "JSFunction.h"
30#include "JSGlobalObject.h"
31
32using namespace std;
33
34namespace JSC {
35
36ASSERT_CLASS_FITS_IN_CELL(Arguments);
37
38const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
39
40Arguments::~Arguments()
41{
42 if (d->extraArguments != d->extraArgumentsFixedBuffer)
43 delete [] d->extraArguments;
44}
45
46void Arguments::mark()
47{
48 JSObject::mark();
49
50 if (d->registerArray) {
51 for (unsigned i = 0; i < d->numParameters; ++i) {
52 if (!d->registerArray[i].marked())
53 d->registerArray[i].mark();
54 }
55 }
56
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();
62 }
63 }
64
65 if (!d->callee->marked())
66 d->callee->mark();
67}
68
69void Arguments::fillArgList(ExecState* exec, ArgList& args)
70{
71 if (LIKELY(!d->deletedArguments)) {
72 if (LIKELY(!d->numParameters)) {
73 args.initialize(d->extraArguments, d->numArguments);
74 return;
75 }
76
77 if (d->numParameters == d->numArguments) {
78 args.initialize(&d->registers[d->firstParameterIndex], d->numArguments);
79 return;
80 }
81
82 unsigned parametersLength = min(d->numParameters, d->numArguments);
83 unsigned i = 0;
84 for (; i < parametersLength; ++i)
85 args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
86 for (; i < d->numArguments; ++i)
87 args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
88 return;
89 }
90
91 unsigned parametersLength = min(d->numParameters, d->numArguments);
92 unsigned i = 0;
93 for (; i < parametersLength; ++i) {
94 if (!d->deletedArguments[i])
95 args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
96 else
97 args.append(get(exec, i));
98 }
99 for (; i < d->numArguments; ++i) {
100 if (!d->deletedArguments[i])
101 args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
102 else
103 args.append(get(exec, i));
104 }
105}
106
107bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
108{
109 if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
110 if (i < d->numParameters) {
111 slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
112 } else
113 slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
114 return true;
115 }
116
117 return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::from(i)), slot);
118}
119
120bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
121{
122 bool isArrayIndex;
123 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
124 if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
125 if (i < d->numParameters) {
126 slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
127 } else
128 slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
129 return true;
130 }
131
132 if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) {
133 slot.setValue(jsNumber(exec, d->numArguments));
134 return true;
135 }
136
137 if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
138 slot.setValue(d->callee);
139 return true;
140 }
141
142 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
143}
144
145void Arguments::put(ExecState* exec, unsigned i, JSValue* value, PutPropertySlot& slot)
146{
147 if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
148 if (i < d->numParameters)
149 d->registers[d->firstParameterIndex + i] = value;
150 else
151 d->extraArguments[i - d->numParameters] = value;
152 return;
153 }
154
155 JSObject::put(exec, Identifier(exec, UString::from(i)), value, slot);
156}
157
158void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
159{
160 bool isArrayIndex;
161 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
162 if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
163 if (i < d->numParameters)
164 d->registers[d->firstParameterIndex + i] = value;
165 else
166 d->extraArguments[i - d->numParameters] = value;
167 return;
168 }
169
170 if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
171 d->overrodeLength = true;
172 putDirect(propertyName, value, DontEnum);
173 return;
174 }
175
176 if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
177 d->overrodeCallee = true;
178 putDirect(propertyName, value, DontEnum);
179 return;
180 }
181
182 JSObject::put(exec, propertyName, value, slot);
183}
184
185bool Arguments::deleteProperty(ExecState* exec, unsigned i)
186{
187 if (i < d->numArguments) {
188 if (!d->deletedArguments) {
189 d->deletedArguments.set(new bool[d->numArguments]);
190 memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
191 }
192 if (!d->deletedArguments[i]) {
193 d->deletedArguments[i] = true;
194 return true;
195 }
196 }
197
198 return JSObject::deleteProperty(exec, Identifier(exec, UString::from(i)));
199}
200
201bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
202{
203 bool isArrayIndex;
204 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
205 if (isArrayIndex && i < d->numArguments) {
206 if (!d->deletedArguments) {
207 d->deletedArguments.set(new bool[d->numArguments]);
208 memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
209 }
210 if (!d->deletedArguments[i]) {
211 d->deletedArguments[i] = true;
212 return true;
213 }
214 }
215
216 if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
217 d->overrodeLength = true;
218 return true;
219 }
220
221 if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
222 d->overrodeCallee = true;
223 return true;
224 }
225
226 return JSObject::deleteProperty(exec, propertyName);
227}
228
229} // namespace JSC
Note: See TracBrowser for help on using the repository browser.