bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { JSFunction* thisObject = static_cast<JSFunction*>(cell); if (thisObject->isHostFunction()) return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (propertyName == exec->propertyNames().prototype) { WriteBarrierBase<Unknown>* location = thisObject->getDirectLocation(exec->globalData(), propertyName); if (!location) { JSObject* prototype = constructEmptyObject(exec, thisObject->globalObject()->emptyObjectStructure()); prototype->putDirect(exec->globalData(), exec->propertyNames().constructor, thisObject, DontEnum); PutPropertySlot slot; thisObject->putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum, false, slot); location = thisObject->getDirectLocation(exec->globalData(), exec->propertyNames().prototype); } slot.setValue(thisObject, location->get(), thisObject->offsetForLocation(location)); } if (propertyName == exec->propertyNames().arguments) { if (thisObject->jsExecutable()->isStrictMode()) { bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (!result) { thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter); result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); ASSERT(result); } return result; } slot.setCacheableCustom(thisObject, argumentsGetter); return true; } if (propertyName == exec->propertyNames().length) { slot.setCacheableCustom(thisObject, lengthGetter); return true; } if (propertyName == exec->propertyNames().caller) { if (thisObject->jsExecutable()->isStrictMode()) { bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (!result) { thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter); result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); ASSERT(result); } return result; } slot.setCacheableCustom(thisObject, callerGetter); return true; } return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); }
bool JSFunction::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { JSFunction* thisObject = jsCast<JSFunction*>(object); if (thisObject->isHostFunction()) return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); if (propertyName == exec->propertyNames().prototype) { PropertySlot slot; thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot); return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); } if (propertyName == exec->propertyNames().arguments) { if (thisObject->jsExecutable()->isStrictMode()) { bool result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); if (!result) { thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); ASSERT(result); } return result; } descriptor.setDescriptor(exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject), ReadOnly | DontEnum | DontDelete); return true; } if (propertyName == exec->propertyNames().length) { descriptor.setDescriptor(jsNumber(thisObject->jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete); return true; } if (propertyName == exec->propertyNames().caller) { if (thisObject->jsExecutable()->isStrictMode()) { bool result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); if (!result) { thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); ASSERT(result); } return result; } descriptor.setDescriptor(exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject), ReadOnly | DontEnum | DontDelete); return true; } return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); }