+ return Base::deleteProperty(thisObject, exec, propertyName);
+}
+
+bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool throwException)
+{
+ JSFunction* thisObject = jsCast<JSFunction*>(object);
+ if (thisObject->isHostFunction())
+ 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->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
+ thisObject->m_allocationProfile.clear();
+ thisObject->m_allocationProfileWatchpoint.notifyWrite();
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+ }
+
+ bool valueCheck;
+ if (propertyName == exec->propertyNames().arguments) {
+ if (thisObject->jsExecutable()->isStrictMode()) {
+ if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor))
+ thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+ }
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject));
+ } else if (propertyName == exec->propertyNames().caller) {
+ if (thisObject->jsExecutable()->isStrictMode()) {
+ if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor))
+ thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+ }
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveCallerFromVMCode(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)
+ throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
+ return false;
+ }
+ if (descriptor.enumerablePresent() && descriptor.enumerable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
+ return false;
+ }
+ if (descriptor.isAccessorDescriptor()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
+ return false;
+ }
+ if (descriptor.writablePresent() && descriptor.writable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
+ return false;
+ }
+ if (!valueCheck) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
+ return false;
+ }
+ return true;