+ JSFunction* thisObject = jsCast<JSFunction*>(object);
+ if (thisObject->isHostOrBuiltinFunction())
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+
+ if (propertyName == exec->propertyNames().prototype) {
+ // Make sure prototype has been reified, such that it can only be overwritten
+ // following the rules set out in ECMA-262 8.12.9.
+ PropertySlot slot(thisObject);
+ thisObject->methodTable(exec->vm())->getOwnPropertySlot(thisObject, exec, propertyName, slot);
+ if (thisObject->m_rareData)
+ thisObject->m_rareData->clear("Store to prototype property of a function");
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+ }
+
+ bool valueCheck;
+ if (propertyName == exec->propertyNames().arguments) {
+ if (thisObject->jsExecutable()->isStrictMode()) {
+ PropertySlot slot(thisObject);
+ if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
+ thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec->vm()), DontDelete | DontEnum | Accessor);
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+ }
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveArguments(exec, thisObject));
+ } else if (propertyName == exec->propertyNames().caller) {
+ if (thisObject->jsExecutable()->isStrictMode()) {
+ PropertySlot slot(thisObject);
+ if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
+ thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec->vm()), DontDelete | DontEnum | Accessor);
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+ }
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveCallerFunction(exec, thisObject));
+ } else if (propertyName == exec->propertyNames().length)
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount()));
+ else if (propertyName == exec->propertyNames().name)
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), thisObject->jsExecutable()->nameValue());
+ else
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+
+ if (descriptor.configurablePresent() && descriptor.configurable()) {
+ if (throwException)
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change configurable attribute of unconfigurable property.")));
+ return false;
+ }
+ if (descriptor.enumerablePresent() && descriptor.enumerable()) {
+ if (throwException)
+ exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));