2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003-2009, 2015-2016 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 * Copyright (C) 2007 Maks Orlovich
7 * Copyright (C) 2015 Canon Inc. All rights reserved.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
27 #include "JSFunction.h"
29 #include "ClonedArguments.h"
30 #include "CodeBlock.h"
31 #include "CommonIdentifiers.h"
32 #include "CallFrame.h"
33 #include "ExceptionHelpers.h"
34 #include "FunctionPrototype.h"
35 #include "GeneratorPrototype.h"
36 #include "GetterSetter.h"
38 #include "JSBoundFunction.h"
39 #include "JSCInlines.h"
40 #include "JSFunctionInlines.h"
41 #include "JSGlobalObject.h"
42 #include "Interpreter.h"
43 #include "ObjectConstructor.h"
44 #include "ObjectPrototype.h"
46 #include "PropertyNameArray.h"
47 #include "StackVisitor.h"
51 EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec)
53 return throwVMError(exec, createNotAConstructorError(exec, exec->callee()));
56 const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(JSFunction) };
58 bool JSFunction::isHostFunctionNonInline() const
60 return isHostFunction();
63 JSFunction* JSFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope)
65 return create(vm, executable, scope, scope->globalObject()->functionStructure());
68 JSFunction* JSFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope, Structure* structure)
70 JSFunction* result = createImpl(vm, executable, scope, structure);
71 executable->singletonFunction()->notifyWrite(vm, result, "Allocating a function");
75 #if ENABLE(WEBASSEMBLY)
76 JSFunction* JSFunction::create(VM& vm, WebAssemblyExecutable* executable, JSScope* scope)
78 JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
79 ASSERT(function->structure()->globalObject());
80 function->finishCreation(vm);
85 NativeExecutable* JSFunction::lookUpOrCreateNativeExecutable(VM& vm, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor, const String& name)
87 return vm.getHostFunction(nativeFunction, intrinsic, nativeConstructor, name);
90 JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
92 NativeExecutable* executable = lookUpOrCreateNativeExecutable(vm, nativeFunction, intrinsic, nativeConstructor, name);
93 JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, globalObject, globalObject->functionStructure());
94 // Can't do this during initialization because getHostFunction might do a GC allocation.
95 function->finishCreation(vm, executable, length, name);
99 JSFunction::JSFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure)
100 : Base(vm, globalObject, structure)
105 void JSFunction::finishCreation(VM& vm, NativeExecutable* executable, int length, const String& name)
107 Base::finishCreation(vm);
108 ASSERT(inherits(info()));
109 m_executable.set(vm, this, executable);
110 putDirect(vm, vm.propertyNames->name, jsString(&vm, name), ReadOnly | DontEnum);
111 putDirect(vm, vm.propertyNames->length, jsNumber(length), ReadOnly | DontEnum);
114 JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject)
116 JSFunction* function = create(vm, executable, globalObject);
117 function->putDirect(vm, vm.propertyNames->name, jsString(&vm, executable->name().string()), ReadOnly | DontEnum);
118 function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), ReadOnly | DontEnum);
122 JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject, const String& name)
124 JSFunction* function = create(vm, executable, globalObject);
125 function->putDirect(vm, vm.propertyNames->name, jsString(&vm, name), ReadOnly | DontEnum);
126 function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), ReadOnly | DontEnum);
130 FunctionRareData* JSFunction::allocateRareData(VM& vm)
133 FunctionRareData* rareData = FunctionRareData::create(vm);
135 // A DFG compilation thread may be trying to read the rare data
136 // We want to ensure that it sees it properly allocated
137 WTF::storeStoreFence();
139 m_rareData.set(vm, this, rareData);
140 return m_rareData.get();
143 FunctionRareData* JSFunction::allocateAndInitializeRareData(ExecState* exec, size_t inlineCapacity)
147 JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype));
149 prototype = globalObject()->objectPrototype();
150 FunctionRareData* rareData = FunctionRareData::create(vm);
151 rareData->initializeObjectAllocationProfile(globalObject()->vm(), prototype, inlineCapacity);
153 // A DFG compilation thread may be trying to read the rare data
154 // We want to ensure that it sees it properly allocated
155 WTF::storeStoreFence();
157 m_rareData.set(vm, this, rareData);
158 return m_rareData.get();
161 FunctionRareData* JSFunction::initializeRareData(ExecState* exec, size_t inlineCapacity)
163 ASSERT(!!m_rareData);
165 JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype));
167 prototype = globalObject()->objectPrototype();
168 m_rareData->initializeObjectAllocationProfile(globalObject()->vm(), prototype, inlineCapacity);
169 return m_rareData.get();
172 String JSFunction::name()
174 if (isHostFunction()) {
175 NativeExecutable* executable = jsCast<NativeExecutable*>(this->executable());
176 return executable->name();
178 return jsExecutable()->name().string();
181 String JSFunction::displayName(ExecState* exec)
183 JSValue displayName = getDirect(exec->vm(), exec->vm().propertyNames->displayName);
185 if (displayName && isJSString(displayName))
186 return asString(displayName)->tryGetValue();
191 const String JSFunction::calculatedDisplayName(ExecState* exec)
193 const String explicitName = displayName(exec);
195 if (!explicitName.isEmpty())
198 const String actualName = name();
199 if (!actualName.isEmpty() || isHostOrBuiltinFunction())
202 return jsExecutable()->inferredName().string();
205 const SourceCode* JSFunction::sourceCode() const
207 if (isHostOrBuiltinFunction())
209 return &jsExecutable()->source();
212 void JSFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
214 JSFunction* thisObject = jsCast<JSFunction*>(cell);
215 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
216 Base::visitChildren(thisObject, visitor);
218 visitor.append(&thisObject->m_executable);
219 if (thisObject->m_rareData)
220 visitor.append(&thisObject->m_rareData);
223 CallType JSFunction::getCallData(JSCell* cell, CallData& callData)
225 JSFunction* thisObject = jsCast<JSFunction*>(cell);
226 if (thisObject->isHostFunction()) {
227 callData.native.function = thisObject->nativeFunction();
228 return CallType::Host;
230 callData.js.functionExecutable = thisObject->jsExecutable();
231 callData.js.scope = thisObject->scope();
235 class RetrieveArgumentsFunctor {
237 RetrieveArgumentsFunctor(JSFunction* functionObj)
238 : m_targetCallee(jsDynamicCast<JSObject*>(functionObj))
243 JSValue result() const { return m_result; }
245 StackVisitor::Status operator()(StackVisitor& visitor) const
247 JSObject* callee = visitor->callee();
248 if (callee != m_targetCallee)
249 return StackVisitor::Continue;
251 m_result = JSValue(visitor->createArguments());
252 return StackVisitor::Done;
256 JSObject* m_targetCallee;
257 mutable JSValue m_result;
260 static JSValue retrieveArguments(ExecState* exec, JSFunction* functionObj)
262 RetrieveArgumentsFunctor functor(functionObj);
263 exec->iterate(functor);
264 return functor.result();
267 EncodedJSValue JSFunction::argumentsGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
269 JSFunction* thisObj = jsCast<JSFunction*>(JSValue::decode(thisValue));
270 ASSERT(!thisObj->isHostFunction());
272 return JSValue::encode(retrieveArguments(exec, thisObj));
275 class RetrieveCallerFunctionFunctor {
277 RetrieveCallerFunctionFunctor(JSFunction* functionObj)
278 : m_targetCallee(jsDynamicCast<JSObject*>(functionObj))
279 , m_hasFoundFrame(false)
280 , m_hasSkippedToCallerFrame(false)
285 JSValue result() const { return m_result; }
287 StackVisitor::Status operator()(StackVisitor& visitor) const
289 JSObject* callee = visitor->callee();
291 if (callee && callee->inherits(JSBoundFunction::info()))
292 return StackVisitor::Continue;
294 if (!m_hasFoundFrame && (callee != m_targetCallee))
295 return StackVisitor::Continue;
297 m_hasFoundFrame = true;
298 if (!m_hasSkippedToCallerFrame) {
299 m_hasSkippedToCallerFrame = true;
300 return StackVisitor::Continue;
305 return StackVisitor::Done;
309 JSObject* m_targetCallee;
310 mutable bool m_hasFoundFrame;
311 mutable bool m_hasSkippedToCallerFrame;
312 mutable JSValue m_result;
315 static JSValue retrieveCallerFunction(ExecState* exec, JSFunction* functionObj)
317 RetrieveCallerFunctionFunctor functor(functionObj);
318 exec->iterate(functor);
319 return functor.result();
322 static GetterSetter* getThrowTypeErrorGetterSetter(JSFunction* function)
324 return function->jsExecutable()->isClassConstructorFunction() || function->jsExecutable()->parseMode() == SourceParseMode::MethodMode
325 ? function->globalObject()->throwTypeErrorArgumentsAndCallerGetterSetter()
326 : function->globalObject()->throwTypeErrorGetterSetter();
329 EncodedJSValue JSFunction::callerGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
331 JSFunction* thisObj = jsCast<JSFunction*>(JSValue::decode(thisValue));
332 ASSERT(!thisObj->isHostFunction());
333 JSValue caller = retrieveCallerFunction(exec, thisObj);
335 // See ES5.1 15.3.5.4 - Function.caller may not be used to retrieve a strict caller.
336 if (!caller.isObject() || !asObject(caller)->inherits(JSFunction::info())) {
337 // It isn't a JSFunction, but if it is a JSCallee from a program or call eval, return null.
338 if (jsDynamicCast<JSCallee*>(caller))
339 return JSValue::encode(jsNull());
340 return JSValue::encode(caller);
342 JSFunction* function = jsCast<JSFunction*>(caller);
343 if (function->isHostOrBuiltinFunction() || !function->jsExecutable()->isStrictMode())
344 return JSValue::encode(caller);
345 return JSValue::encode(throwTypeError(exec, ASCIILiteral("Function.caller used to retrieve strict caller")));
348 bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
350 JSFunction* thisObject = jsCast<JSFunction*>(object);
351 if (thisObject->isHostOrBuiltinFunction())
352 return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
354 if (propertyName == exec->propertyNames().prototype && !thisObject->jsExecutable()->isArrowFunction()) {
357 PropertyOffset offset = thisObject->getDirectOffset(vm, propertyName, attributes);
358 if (!isValidOffset(offset)) {
359 JSObject* prototype = nullptr;
360 if (thisObject->jsExecutable()->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode)
361 prototype = constructEmptyObject(exec, thisObject->globalObject()->generatorPrototype());
363 prototype = constructEmptyObject(exec);
365 prototype->putDirect(vm, exec->propertyNames().constructor, thisObject, DontEnum);
366 thisObject->putDirect(vm, exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
367 offset = thisObject->getDirectOffset(vm, exec->propertyNames().prototype, attributes);
368 ASSERT(isValidOffset(offset));
371 slot.setValue(thisObject, attributes, thisObject->getDirect(offset), offset);
374 if (propertyName == exec->propertyNames().arguments) {
375 if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isClassConstructorFunction()) {
376 bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
378 GetterSetter* errorGetterSetter = getThrowTypeErrorGetterSetter(thisObject);
379 thisObject->putDirectAccessor(exec, propertyName, errorGetterSetter, DontDelete | DontEnum | Accessor);
380 result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
385 slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, argumentsGetter);
389 if (propertyName == exec->propertyNames().caller) {
390 if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isClassConstructorFunction()) {
391 bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
393 GetterSetter* errorGetterSetter = getThrowTypeErrorGetterSetter(thisObject);
394 thisObject->putDirectAccessor(exec, propertyName, errorGetterSetter, DontDelete | DontEnum | Accessor);
395 result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
400 slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, callerGetter);
404 thisObject->reifyLazyPropertyIfNeeded(exec, propertyName);
406 return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
409 void JSFunction::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
411 JSFunction* thisObject = jsCast<JSFunction*>(object);
412 if (!thisObject->isHostOrBuiltinFunction() && mode.includeDontEnumProperties()) {
414 // Make sure prototype has been reified.
415 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
416 thisObject->methodTable(vm)->getOwnPropertySlot(thisObject, exec, vm.propertyNames->prototype, slot);
418 propertyNames.add(vm.propertyNames->arguments);
419 propertyNames.add(vm.propertyNames->caller);
420 if (!thisObject->hasReifiedLength())
421 propertyNames.add(vm.propertyNames->length);
422 if (!thisObject->hasReifiedName())
423 propertyNames.add(vm.propertyNames->name);
425 Base::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
428 bool JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
430 JSFunction* thisObject = jsCast<JSFunction*>(cell);
432 if (UNLIKELY(isThisValueAltered(slot, thisObject)))
433 return ordinarySetSlow(exec, thisObject, propertyName, value, slot.thisValue(), slot.isStrictMode());
435 if (thisObject->isHostOrBuiltinFunction())
436 return Base::put(thisObject, exec, propertyName, value, slot);
438 if (propertyName == exec->propertyNames().prototype) {
439 // Make sure prototype has been reified, such that it can only be overwritten
440 // following the rules set out in ECMA-262 8.12.9.
441 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
442 thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot);
443 if (thisObject->m_rareData)
444 thisObject->m_rareData->clear("Store to prototype property of a function");
445 // Don't allow this to be cached, since a [[Put]] must clear m_rareData.
446 PutPropertySlot dontCache(thisObject);
447 return Base::put(thisObject, exec, propertyName, value, dontCache);
449 if (thisObject->jsExecutable()->isStrictMode() && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) {
450 // This will trigger the property to be reified, if this is not already the case!
451 bool okay = thisObject->hasProperty(exec, propertyName);
452 ASSERT_UNUSED(okay, okay);
453 return Base::put(thisObject, exec, propertyName, value, slot);
455 if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller) {
456 if (slot.isStrictMode())
457 throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
460 thisObject->reifyLazyPropertyIfNeeded(exec, propertyName);
461 return Base::put(thisObject, exec, propertyName, value, slot);
464 bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
466 JSFunction* thisObject = jsCast<JSFunction*>(cell);
467 // For non-host functions, don't let these properties by deleted - except by DefineOwnProperty.
468 if (!thisObject->isHostOrBuiltinFunction() && !exec->vm().isInDefineOwnProperty()) {
469 FunctionExecutable* executable = thisObject->jsExecutable();
470 if (propertyName == exec->propertyNames().arguments
471 || (propertyName == exec->propertyNames().prototype && !executable->isArrowFunction())
472 || propertyName == exec->propertyNames().caller)
475 thisObject->reifyLazyPropertyIfNeeded(exec, propertyName);
478 return Base::deleteProperty(thisObject, exec, propertyName);
481 bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool throwException)
483 JSFunction* thisObject = jsCast<JSFunction*>(object);
484 if (thisObject->isHostOrBuiltinFunction())
485 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
487 if (propertyName == exec->propertyNames().prototype) {
488 // Make sure prototype has been reified, such that it can only be overwritten
489 // following the rules set out in ECMA-262 8.12.9.
490 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
491 thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot);
492 if (thisObject->m_rareData)
493 thisObject->m_rareData->clear("Store to prototype property of a function");
494 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
498 if (propertyName == exec->propertyNames().arguments) {
499 if (thisObject->jsExecutable()->isStrictMode()) {
500 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
501 if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
502 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(), DontDelete | DontEnum | Accessor);
503 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
505 valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveArguments(exec, thisObject));
506 } else if (propertyName == exec->propertyNames().caller) {
507 if (thisObject->jsExecutable()->isStrictMode()) {
508 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
509 if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
510 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(), DontDelete | DontEnum | Accessor);
511 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
513 valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveCallerFunction(exec, thisObject));
515 thisObject->reifyLazyPropertyIfNeeded(exec, propertyName);
516 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
519 if (descriptor.configurablePresent() && descriptor.configurable()) {
521 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property.")));
524 if (descriptor.enumerablePresent() && descriptor.enumerable()) {
526 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
529 if (descriptor.isAccessorDescriptor()) {
531 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral(UnconfigurablePropertyChangeAccessMechanismError)));
534 if (descriptor.writablePresent() && descriptor.writable()) {
536 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
541 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
547 // ECMA 13.2.2 [[Construct]]
548 ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& constructData)
550 JSFunction* thisObject = jsCast<JSFunction*>(cell);
552 if (thisObject->isHostFunction()) {
553 constructData.native.function = thisObject->nativeConstructor();
554 return ConstructType::Host;
557 FunctionExecutable* functionExecutable = thisObject->jsExecutable();
558 if (functionExecutable->constructAbility() == ConstructAbility::CannotConstruct)
559 return ConstructType::None;
561 constructData.js.functionExecutable = functionExecutable;
562 constructData.js.scope = thisObject->scope();
563 return ConstructType::JS;
566 String getCalculatedDisplayName(CallFrame* callFrame, JSObject* object)
568 if (JSFunction* function = jsDynamicCast<JSFunction*>(object))
569 return function->calculatedDisplayName(callFrame);
570 if (InternalFunction* function = jsDynamicCast<InternalFunction*>(object))
571 return function->calculatedDisplayName(callFrame);
572 return emptyString();
575 void JSFunction::setFunctionName(ExecState* exec, JSValue value)
577 // The "name" property may have been already been defined as part of a property list in an
578 // object literal (and therefore reified).
579 if (hasReifiedName())
582 ASSERT(!isHostFunction());
583 ASSERT(jsExecutable()->ecmaName().isNull());
585 if (value.isSymbol()) {
586 SymbolImpl* uid = asSymbol(value)->privateName().uid();
587 if (uid->isNullSymbol())
588 name = emptyString();
590 name = makeString("[", String(asSymbol(value)->privateName().uid()), ']');
593 JSString* jsStr = value.toString(exec);
596 name = jsStr->value(exec);
600 reifyName(exec, name);
603 void JSFunction::reifyLength(ExecState* exec)
606 FunctionRareData* rareData = this->rareData(vm);
608 ASSERT(!hasReifiedLength());
609 ASSERT(!isHostFunction());
610 JSValue initialValue = jsNumber(jsExecutable()->parameterCount());
611 unsigned initialAttributes = DontEnum | ReadOnly;
612 const Identifier& identifier = exec->propertyNames().length;
613 putDirect(vm, identifier, initialValue, initialAttributes);
615 rareData->setHasReifiedLength();
618 void JSFunction::reifyName(ExecState* exec)
620 String name = jsExecutable()->ecmaName().string();
621 reifyName(exec, name);
624 void JSFunction::reifyName(ExecState* exec, String name)
627 FunctionRareData* rareData = this->rareData(vm);
629 ASSERT(!hasReifiedName());
630 ASSERT(!isHostFunction());
631 unsigned initialAttributes = DontEnum | ReadOnly;
632 const Identifier& propID = exec->propertyNames().name;
634 if (jsExecutable()->isGetter())
635 name = makeString("get ", name);
636 else if (jsExecutable()->isSetter())
637 name = makeString("set ", name);
639 putDirect(vm, propID, jsString(exec, name), initialAttributes);
640 rareData->setHasReifiedName();
643 void JSFunction::reifyLazyPropertyIfNeeded(ExecState* exec, PropertyName propertyName)
645 if (propertyName == exec->propertyNames().length) {
646 if (!hasReifiedLength())
648 } else if (propertyName == exec->propertyNames().name) {
649 if (!hasReifiedName())