bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSFunction* thisObject = jsCast<JSFunction*>(cell); if (thisObject->isHostFunction()) return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (propertyName == exec->propertyNames().prototype) { JSGlobalData& globalData = exec->globalData(); PropertyOffset offset = thisObject->getDirectOffset(globalData, propertyName); if (!isValidOffset(offset)) { JSObject* prototype = constructEmptyObject(exec); prototype->putDirect(globalData, exec->propertyNames().constructor, thisObject, DontEnum); thisObject->putDirect(globalData, exec->propertyNames().prototype, prototype, DontDelete | DontEnum); offset = thisObject->getDirectOffset(globalData, exec->propertyNames().prototype); ASSERT(isValidOffset(offset)); } slot.setValue(thisObject, thisObject->getDirect(offset), offset); } if (propertyName == exec->propertyNames().arguments) { if (thisObject->jsExecutable()->isStrictMode()) { bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (!result) { thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); 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().name) { slot.setCacheableCustom(thisObject, nameGetter); return true; } if (propertyName == exec->propertyNames().caller) { if (thisObject->jsExecutable()->isStrictMode()) { bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (!result) { thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor); 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::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSFunction* thisObject = jsCast<JSFunction*>(object); if (thisObject->isHostOrBuiltinFunction()) return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (propertyName == exec->propertyNames().prototype) { VM& vm = exec->vm(); unsigned attributes; PropertyOffset offset = thisObject->getDirectOffset(vm, propertyName, attributes); if (!isValidOffset(offset)) { JSObject* prototype = constructEmptyObject(exec); prototype->putDirect(vm, exec->propertyNames().constructor, thisObject, DontEnum); thisObject->putDirect(vm, exec->propertyNames().prototype, prototype, DontDelete | DontEnum); offset = thisObject->getDirectOffset(vm, exec->propertyNames().prototype, attributes); ASSERT(isValidOffset(offset)); } slot.setValue(thisObject, attributes, thisObject->getDirect(offset), offset); } if (propertyName == exec->propertyNames().arguments) { if (thisObject->jsExecutable()->isStrictMode()) { bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (!result) { thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec->vm()), DontDelete | DontEnum | Accessor); result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); ASSERT(result); } return result; } slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, argumentsGetter); return true; } if (propertyName == exec->propertyNames().length) { slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, lengthGetter); return true; } if (propertyName == exec->propertyNames().name) { slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, nameGetter); return true; } if (propertyName == exec->propertyNames().caller) { if (thisObject->jsExecutable()->isStrictMode()) { bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); if (!result) { thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec->vm()), DontDelete | DontEnum | Accessor); result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); ASSERT(result); } return result; } slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, callerGetter); return true; } return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); }