]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/JSFunction.cpp
JavaScriptCore-1218.33.tar.gz
[apple/javascriptcore.git] / runtime / JSFunction.cpp
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
f9bf01c6 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
9dae56ea
A
5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
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 "JSFunction.h"
27
28#include "CodeBlock.h"
29#include "CommonIdentifiers.h"
30#include "CallFrame.h"
14957cd0 31#include "ExceptionHelpers.h"
9dae56ea 32#include "FunctionPrototype.h"
6fe7ccc8
A
33#include "GetterSetter.h"
34#include "JSArray.h"
9dae56ea 35#include "JSGlobalObject.h"
14957cd0 36#include "JSNotAnObject.h"
9dae56ea 37#include "Interpreter.h"
93a37866 38#include "ObjectConstructor.h"
9dae56ea 39#include "ObjectPrototype.h"
93a37866 40#include "Operations.h"
9dae56ea
A
41#include "Parser.h"
42#include "PropertyNameArray.h"
9dae56ea
A
43
44using namespace WTF;
45using namespace Unicode;
46
47namespace JSC {
14957cd0
A
48EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec)
49{
50 return throwVMError(exec, createNotAConstructorError(exec, exec->callee()));
51}
9dae56ea 52
6fe7ccc8 53const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFunction) };
9dae56ea 54
f9bf01c6
A
55bool JSFunction::isHostFunctionNonInline() const
56{
57 return isHostFunction();
58}
59
93a37866 60JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
f9bf01c6 61{
6fe7ccc8
A
62 NativeExecutable* executable;
63#if !ENABLE(JIT)
64 UNUSED_PARAM(intrinsic);
65#else
93a37866 66 if (intrinsic != NoIntrinsic && exec->vm().canUseJIT()) {
6fe7ccc8 67 ASSERT(nativeConstructor == callHostFunctionAsConstructor);
93a37866 68 executable = exec->vm().getHostFunction(nativeFunction, intrinsic);
6fe7ccc8
A
69 } else
70#endif
93a37866 71 executable = exec->vm().getHostFunction(nativeFunction, nativeConstructor);
6fe7ccc8
A
72
73 JSFunction* function = new (NotNull, allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, globalObject->functionStructure());
74 // Can't do this during initialization because getHostFunction might do a GC allocation.
75 function->finishCreation(exec, executable, length, name);
76 return function;
f9bf01c6
A
77}
78
93a37866 79void JSFunction::destroy(JSCell* cell)
ba379fdc 80{
93a37866 81 static_cast<JSFunction*>(cell)->JSFunction::~JSFunction();
ba379fdc
A
82}
83
93a37866
A
84JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
85 : Base(exec->vm(), structure)
86 , m_executable()
87 , m_scope(exec->vm(), this, globalObject)
88 // We initialize blind so that changes to the prototype after function creation but before
89 // the optimizer kicks in don't disable optimizations. Once the optimizer kicks in, the
90 // watchpoint will start watching and any changes will both force deoptimization and disable
91 // future attempts to optimize. This is necessary because we are guaranteed that the
92 // allocation profile is changed exactly once prior to optimizations kicking in. We could be
93 // smarter and count the number of times the prototype is clobbered and only optimize if it
94 // was clobbered exactly once, but that seems like overkill. In almost all cases it will be
95 // clobbered once, and if it's clobbered more than once, that will probably only occur
96 // before we started optimizing, anyway.
97 , m_allocationProfileWatchpoint(InitializedBlind)
9dae56ea
A
98{
99}
100
93a37866 101void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const String& name)
9dae56ea 102{
93a37866 103 Base::finishCreation(exec->vm());
6fe7ccc8 104 ASSERT(inherits(&s_info));
93a37866
A
105 m_executable.set(exec->vm(), this, executable);
106 putDirect(exec->vm(), exec->vm().propertyNames->name, jsString(exec, name), DontDelete | ReadOnly | DontEnum);
107 putDirect(exec->vm(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
14957cd0 108}
f9bf01c6 109
93a37866 110ObjectAllocationProfile* JSFunction::createAllocationProfile(ExecState* exec, size_t inlineCapacity)
14957cd0 111{
93a37866
A
112 VM& vm = exec->vm();
113 JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype));
114 if (!prototype)
115 prototype = globalObject()->objectPrototype();
116 m_allocationProfile.initialize(globalObject()->vm(), this, prototype, inlineCapacity);
117 return &m_allocationProfile;
9dae56ea
A
118}
119
93a37866 120String JSFunction::name(ExecState* exec)
9dae56ea 121{
93a37866 122 return get(exec, exec->vm().propertyNames->name).toWTFString(exec);
14957cd0
A
123}
124
93a37866 125String JSFunction::displayName(ExecState* exec)
14957cd0 126{
93a37866 127 JSValue displayName = getDirect(exec->vm(), exec->vm().propertyNames->displayName);
14957cd0 128
6fe7ccc8 129 if (displayName && isJSString(displayName))
14957cd0
A
130 return asString(displayName)->tryGetValue();
131
93a37866 132 return String();
14957cd0
A
133}
134
93a37866 135const String JSFunction::calculatedDisplayName(ExecState* exec)
14957cd0 136{
93a37866 137 const String explicitName = displayName(exec);
14957cd0
A
138
139 if (!explicitName.isEmpty())
140 return explicitName;
141
93a37866 142 const String actualName = name(exec);
6fe7ccc8
A
143 if (!actualName.isEmpty() || isHostFunction())
144 return actualName;
145
93a37866 146 return jsExecutable()->inferredName().string();
6fe7ccc8
A
147}
148
149const SourceCode* JSFunction::sourceCode() const
150{
151 if (isHostFunction())
152 return 0;
153 return &jsExecutable()->source();
14957cd0
A
154}
155
6fe7ccc8 156void JSFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
14957cd0 157{
6fe7ccc8
A
158 JSFunction* thisObject = jsCast<JSFunction*>(cell);
159 ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
14957cd0 160 COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
6fe7ccc8
A
161 ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
162 Base::visitChildren(thisObject, visitor);
14957cd0 163
93a37866
A
164 visitor.append(&thisObject->m_scope);
165 visitor.append(&thisObject->m_executable);
166 thisObject->m_allocationProfile.visitAggregate(visitor);
9dae56ea
A
167}
168
6fe7ccc8 169CallType JSFunction::getCallData(JSCell* cell, CallData& callData)
9dae56ea 170{
6fe7ccc8
A
171 JSFunction* thisObject = jsCast<JSFunction*>(cell);
172 if (thisObject->isHostFunction()) {
173 callData.native.function = thisObject->nativeFunction();
ba379fdc
A
174 return CallTypeHost;
175 }
6fe7ccc8 176 callData.js.functionExecutable = thisObject->jsExecutable();
93a37866 177 callData.js.scope = thisObject->scope();
9dae56ea
A
178 return CallTypeJS;
179}
180
93a37866 181JSValue JSFunction::argumentsGetter(ExecState* exec, JSValue slotBase, PropertyName)
9dae56ea 182{
6fe7ccc8 183 JSFunction* thisObj = jsCast<JSFunction*>(slotBase);
ba379fdc 184 ASSERT(!thisObj->isHostFunction());
6fe7ccc8 185 return exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObj);
9dae56ea
A
186}
187
93a37866 188JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, PropertyName)
9dae56ea 189{
6fe7ccc8 190 JSFunction* thisObj = jsCast<JSFunction*>(slotBase);
ba379fdc 191 ASSERT(!thisObj->isHostFunction());
6fe7ccc8
A
192 JSValue caller = exec->interpreter()->retrieveCallerFromVMCode(exec, thisObj);
193
194 // See ES5.1 15.3.5.4 - Function.caller may not be used to retrieve a strict caller.
195 if (!caller.isObject() || !asObject(caller)->inherits(&JSFunction::s_info))
196 return caller;
197 JSFunction* function = jsCast<JSFunction*>(caller);
198 if (function->isHostFunction() || !function->jsExecutable()->isStrictMode())
199 return caller;
93a37866 200 return throwTypeError(exec, ASCIILiteral("Function.caller used to retrieve strict caller"));
9dae56ea
A
201}
202
93a37866 203JSValue JSFunction::lengthGetter(ExecState*, JSValue slotBase, PropertyName)
9dae56ea 204{
6fe7ccc8 205 JSFunction* thisObj = jsCast<JSFunction*>(slotBase);
ba379fdc 206 ASSERT(!thisObj->isHostFunction());
14957cd0
A
207 return jsNumber(thisObj->jsExecutable()->parameterCount());
208}
209
93a37866
A
210JSValue JSFunction::nameGetter(ExecState*, JSValue slotBase, PropertyName)
211{
212 JSFunction* thisObj = jsCast<JSFunction*>(slotBase);
213 ASSERT(!thisObj->isHostFunction());
214 return thisObj->jsExecutable()->nameValue();
215}
216
217bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
14957cd0 218{
6fe7ccc8
A
219 JSFunction* thisObject = jsCast<JSFunction*>(cell);
220 if (thisObject->isHostFunction())
221 return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
ba379fdc 222
9dae56ea 223 if (propertyName == exec->propertyNames().prototype) {
93a37866
A
224 VM& vm = exec->vm();
225 PropertyOffset offset = thisObject->getDirectOffset(vm, propertyName);
226 if (!isValidOffset(offset)) {
227 JSObject* prototype = constructEmptyObject(exec);
228 prototype->putDirect(vm, exec->propertyNames().constructor, thisObject, DontEnum);
229 thisObject->putDirect(vm, exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
230 offset = thisObject->getDirectOffset(vm, exec->propertyNames().prototype);
231 ASSERT(isValidOffset(offset));
6fe7ccc8 232 }
9dae56ea 233
93a37866 234 slot.setValue(thisObject, thisObject->getDirect(offset), offset);
9dae56ea
A
235 }
236
237 if (propertyName == exec->propertyNames().arguments) {
6fe7ccc8
A
238 if (thisObject->jsExecutable()->isStrictMode()) {
239 bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
240 if (!result) {
93a37866 241 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
6fe7ccc8
A
242 result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
243 ASSERT(result);
244 }
245 return result;
14957cd0 246 }
6fe7ccc8 247 slot.setCacheableCustom(thisObject, argumentsGetter);
9dae56ea
A
248 return true;
249 }
250
251 if (propertyName == exec->propertyNames().length) {
6fe7ccc8 252 slot.setCacheableCustom(thisObject, lengthGetter);
9dae56ea
A
253 return true;
254 }
255
93a37866
A
256 if (propertyName == exec->propertyNames().name) {
257 slot.setCacheableCustom(thisObject, nameGetter);
258 return true;
259 }
260
9dae56ea 261 if (propertyName == exec->propertyNames().caller) {
6fe7ccc8
A
262 if (thisObject->jsExecutable()->isStrictMode()) {
263 bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
264 if (!result) {
93a37866 265 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
6fe7ccc8
A
266 result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
267 ASSERT(result);
268 }
269 return result;
14957cd0 270 }
6fe7ccc8 271 slot.setCacheableCustom(thisObject, callerGetter);
9dae56ea
A
272 return true;
273 }
274
6fe7ccc8 275 return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
9dae56ea
A
276}
277
93a37866 278bool JSFunction::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
14957cd0 279{
6fe7ccc8
A
280 JSFunction* thisObject = jsCast<JSFunction*>(object);
281 if (thisObject->isHostFunction())
282 return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
14957cd0
A
283
284 if (propertyName == exec->propertyNames().prototype) {
285 PropertySlot slot;
6fe7ccc8
A
286 thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
287 return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
14957cd0
A
288 }
289
290 if (propertyName == exec->propertyNames().arguments) {
6fe7ccc8
A
291 if (thisObject->jsExecutable()->isStrictMode()) {
292 bool result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
293 if (!result) {
93a37866 294 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
6fe7ccc8
A
295 result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
296 ASSERT(result);
297 }
298 return result;
299 }
300 descriptor.setDescriptor(exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject), ReadOnly | DontEnum | DontDelete);
14957cd0
A
301 return true;
302 }
303
304 if (propertyName == exec->propertyNames().length) {
6fe7ccc8 305 descriptor.setDescriptor(jsNumber(thisObject->jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
14957cd0
A
306 return true;
307 }
308
93a37866
A
309 if (propertyName == exec->propertyNames().name) {
310 descriptor.setDescriptor(thisObject->jsExecutable()->nameValue(), ReadOnly | DontEnum | DontDelete);
311 return true;
312 }
313
14957cd0 314 if (propertyName == exec->propertyNames().caller) {
6fe7ccc8
A
315 if (thisObject->jsExecutable()->isStrictMode()) {
316 bool result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
317 if (!result) {
93a37866 318 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
6fe7ccc8
A
319 result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
320 ASSERT(result);
321 }
322 return result;
323 }
324 descriptor.setDescriptor(exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject), ReadOnly | DontEnum | DontDelete);
14957cd0 325 return true;
f9bf01c6
A
326 }
327
6fe7ccc8 328 return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
14957cd0
A
329}
330
93a37866 331void JSFunction::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
f9bf01c6 332{
6fe7ccc8
A
333 JSFunction* thisObject = jsCast<JSFunction*>(object);
334 if (!thisObject->isHostFunction() && (mode == IncludeDontEnumProperties)) {
14957cd0
A
335 // Make sure prototype has been reified.
336 PropertySlot slot;
6fe7ccc8 337 thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, exec->propertyNames().prototype, slot);
14957cd0 338
f9bf01c6 339 propertyNames.add(exec->propertyNames().arguments);
f9bf01c6
A
340 propertyNames.add(exec->propertyNames().caller);
341 propertyNames.add(exec->propertyNames().length);
93a37866 342 propertyNames.add(exec->propertyNames().name);
f9bf01c6 343 }
93a37866 344 Base::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
f9bf01c6
A
345}
346
93a37866 347void JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
9dae56ea 348{
6fe7ccc8
A
349 JSFunction* thisObject = jsCast<JSFunction*>(cell);
350 if (thisObject->isHostFunction()) {
351 Base::put(thisObject, exec, propertyName, value, slot);
ba379fdc
A
352 return;
353 }
14957cd0
A
354 if (propertyName == exec->propertyNames().prototype) {
355 // Make sure prototype has been reified, such that it can only be overwritten
356 // following the rules set out in ECMA-262 8.12.9.
357 PropertySlot slot;
6fe7ccc8 358 thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
93a37866
A
359 thisObject->m_allocationProfile.clear();
360 thisObject->m_allocationProfileWatchpoint.notifyWrite();
361 // Don't allow this to be cached, since a [[Put]] must clear m_allocationProfile.
362 PutPropertySlot dontCache;
363 Base::put(thisObject, exec, propertyName, value, dontCache);
364 return;
14957cd0 365 }
6fe7ccc8
A
366 if (thisObject->jsExecutable()->isStrictMode() && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) {
367 // This will trigger the property to be reified, if this is not already the case!
368 bool okay = thisObject->hasProperty(exec, propertyName);
369 ASSERT_UNUSED(okay, okay);
370 Base::put(thisObject, exec, propertyName, value, slot);
371 return;
14957cd0 372 }
93a37866 373 if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().name || propertyName == exec->propertyNames().caller) {
6fe7ccc8
A
374 if (slot.isStrictMode())
375 throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
9dae56ea 376 return;
6fe7ccc8
A
377 }
378 Base::put(thisObject, exec, propertyName, value, slot);
9dae56ea
A
379}
380
93a37866 381bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
9dae56ea 382{
6fe7ccc8
A
383 JSFunction* thisObject = jsCast<JSFunction*>(cell);
384 // For non-host functions, don't let these properties by deleted - except by DefineOwnProperty.
93a37866 385 if (!thisObject->isHostFunction() && !exec->vm().isInDefineOwnProperty()
6fe7ccc8
A
386 && (propertyName == exec->propertyNames().arguments
387 || propertyName == exec->propertyNames().length
93a37866 388 || propertyName == exec->propertyNames().name
6fe7ccc8
A
389 || propertyName == exec->propertyNames().prototype
390 || propertyName == exec->propertyNames().caller))
391 return false;
392 return Base::deleteProperty(thisObject, exec, propertyName);
393}
394
93a37866 395bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool throwException)
6fe7ccc8
A
396{
397 JSFunction* thisObject = jsCast<JSFunction*>(object);
398 if (thisObject->isHostFunction())
399 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
400
401 if (propertyName == exec->propertyNames().prototype) {
402 // Make sure prototype has been reified, such that it can only be overwritten
403 // following the rules set out in ECMA-262 8.12.9.
404 PropertySlot slot;
405 thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
93a37866
A
406 thisObject->m_allocationProfile.clear();
407 thisObject->m_allocationProfileWatchpoint.notifyWrite();
6fe7ccc8
A
408 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
409 }
410
411 bool valueCheck;
412 if (propertyName == exec->propertyNames().arguments) {
413 if (thisObject->jsExecutable()->isStrictMode()) {
414 if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor))
93a37866 415 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
6fe7ccc8
A
416 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
417 }
418 valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject));
419 } else if (propertyName == exec->propertyNames().caller) {
420 if (thisObject->jsExecutable()->isStrictMode()) {
421 if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor))
93a37866 422 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
6fe7ccc8
A
423 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
424 }
425 valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject));
426 } else if (propertyName == exec->propertyNames().length)
427 valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount()));
93a37866
A
428 else if (propertyName == exec->propertyNames().name)
429 valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), thisObject->jsExecutable()->nameValue());
6fe7ccc8
A
430 else
431 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
432
433 if (descriptor.configurablePresent() && descriptor.configurable()) {
434 if (throwException)
93a37866 435 throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
6fe7ccc8
A
436 return false;
437 }
438 if (descriptor.enumerablePresent() && descriptor.enumerable()) {
439 if (throwException)
93a37866 440 throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
6fe7ccc8
A
441 return false;
442 }
443 if (descriptor.isAccessorDescriptor()) {
444 if (throwException)
93a37866 445 throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
6fe7ccc8
A
446 return false;
447 }
448 if (descriptor.writablePresent() && descriptor.writable()) {
449 if (throwException)
93a37866 450 throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
9dae56ea 451 return false;
6fe7ccc8
A
452 }
453 if (!valueCheck) {
454 if (throwException)
93a37866 455 throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
6fe7ccc8
A
456 return false;
457 }
458 return true;
9dae56ea
A
459}
460
461// ECMA 13.2.2 [[Construct]]
6fe7ccc8 462ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& constructData)
9dae56ea 463{
6fe7ccc8
A
464 JSFunction* thisObject = jsCast<JSFunction*>(cell);
465 if (thisObject->isHostFunction()) {
466 constructData.native.function = thisObject->nativeConstructor();
467 return ConstructTypeHost;
468 }
469 constructData.js.functionExecutable = thisObject->jsExecutable();
93a37866 470 constructData.js.scope = thisObject->scope();
9dae56ea
A
471 return ConstructTypeJS;
472}
6fe7ccc8 473
93a37866 474String getCalculatedDisplayName(CallFrame* callFrame, JSObject* object)
6fe7ccc8
A
475{
476 if (JSFunction* function = jsDynamicCast<JSFunction*>(object))
477 return function->calculatedDisplayName(callFrame);
478 if (InternalFunction* function = jsDynamicCast<InternalFunction*>(object))
479 return function->calculatedDisplayName(callFrame);
93a37866 480 return "";
6fe7ccc8 481}
9dae56ea 482
9dae56ea 483} // namespace JSC