source: webkit/trunk/JavaScriptCore/kjs/JSActivation.cpp@ 34659

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

Reviewed by Darin.

Prepare JavaScript heap for being per-thread.

File size: 6.3 KB
Line 
1/*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "config.h"
30#include "JSActivation.h"
31
32#include "CodeBlock.h"
33#include "Machine.h"
34#include "Register.h"
35#include "JSFunction.h"
36
37namespace KJS {
38
39const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
40
41JSActivation::JSActivation(PassRefPtr<FunctionBodyNode> functionBody, Register** registerBase, int registerOffset)
42 : Base(new JSActivationData(functionBody, registerBase, registerOffset))
43{
44}
45
46JSActivation::~JSActivation()
47{
48 delete d()->registerArray;
49 delete d();
50}
51
52void JSActivation::copyRegisters()
53{
54 int numRegisters = d()->functionBody->generatedCode().numLocals;
55 if (!numRegisters)
56 return;
57
58 Register* registerArray = static_cast<Register*>(fastMalloc(numRegisters * sizeof(Register)));
59
60 Register* end = registers();
61 Register* src = end - numRegisters;
62 Register* dst = registerArray;
63 while (src != end)
64 *dst++ = *src++;
65
66 d()->registerArray = registerArray;
67 d()->registerBase = &d()->registerArray;
68 d()->registerOffset = numRegisters;
69}
70
71bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
72{
73 if (symbolTableGet(propertyName, slot))
74 return true;
75
76 if (JSValue** location = getDirectLocation(propertyName)) {
77 slot.setValueSlot(location);
78 return true;
79 }
80
81 // Only return the built-in arguments object if it wasn't overridden above.
82 if (propertyName == exec->propertyNames().arguments) {
83 slot.setCustom(this, getArgumentsGetter());
84 return true;
85 }
86
87 // We don't call through to JSObject because there's no way to give an
88 // activation object getter properties or a prototype.
89 ASSERT(!_prop.hasGetterSetterProperties());
90 ASSERT(prototype() == jsNull());
91 return false;
92}
93
94void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* value)
95{
96 if (symbolTablePut(propertyName, value))
97 return;
98
99 // We don't call through to JSObject because __proto__ and getter/setter
100 // properties are non-standard extensions that other implementations do not
101 // expose in the activation object.
102 ASSERT(!_prop.hasGetterSetterProperties());
103 _prop.put(propertyName, value, 0, true);
104}
105
106// FIXME: Make this function honor ReadOnly (const) and DontEnum
107void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
108{
109 if (symbolTablePutWithAttributes(propertyName, value, attributes))
110 return;
111
112 // We don't call through to JSObject because __proto__ and getter/setter
113 // properties are non-standard extensions that other implementations do not
114 // expose in the activation object.
115 ASSERT(!_prop.hasGetterSetterProperties());
116 _prop.put(propertyName, value, attributes, true);
117}
118
119bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName)
120{
121 if (propertyName == exec->propertyNames().arguments)
122 return false;
123
124 return Base::deleteProperty(exec, propertyName);
125}
126
127JSObject* JSActivation::toThisObject(ExecState* exec) const
128{
129 return exec->globalThisValue();
130}
131
132void JSActivation::mark()
133{
134 Base::mark();
135
136 if (d()->argumentsObject)
137 d()->argumentsObject->mark();
138
139 // No need to mark our values if they're still in the regsiter file, since
140 // the register file gets marked independently.
141 if(!d()->registerArray)
142 return;
143
144 int numRegisters = d()->functionBody->generatedCode().numLocals;
145 Register* end = d()->registerArray + numRegisters;
146 for (Register* it = d()->registerArray; it != end; ++it) {
147 JSValue* v = (*it).u.jsValue;
148 if (!v->marked())
149 v->mark();
150 }
151}
152
153bool JSActivation::isActivationObject() const
154{
155 return true;
156}
157
158bool JSActivation::isDynamicScope() const
159{
160 return d()->functionBody->usesEval();
161}
162
163JSValue* JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
164{
165 JSActivation* thisObj = static_cast<JSActivation*>(slot.slotBase());
166 if (!thisObj->d()->argumentsObject)
167 thisObj->d()->argumentsObject = thisObj->createArgumentsObject(exec);
168
169 return thisObj->d()->argumentsObject;
170}
171
172// These two functions serve the purpose of isolating the common case from a
173// PIC branch.
174
175PropertySlot::GetValueFunc JSActivation::getArgumentsGetter()
176{
177 return argumentsGetter;
178}
179
180JSObject* JSActivation::createArgumentsObject(ExecState* exec)
181{
182 Register* callFrame = registers() - d()->functionBody->generatedCode().numLocals - Machine::CallFrameHeaderSize;
183
184 JSFunction* function;
185 Register* argv;
186 int argc;
187 exec->machine()->getFunctionAndArguments(registerBase(), callFrame, function, argv, argc);
188 ArgList args(reinterpret_cast<JSValue***>(registerBase()), argv - *registerBase(), argc);
189 return new (exec) Arguments(exec, function, args, this);
190}
191
192} // namespace KJS
Note: See TracBrowser for help on using the repository browser.