// Section 8.12.5 bool Object::internalPut(String *name, const Value &value) { ExecutionEngine *engine = this->engine(); if (engine->hasException) return false; uint idx = name->asArrayIndex(); if (idx != UINT_MAX) return putIndexed(idx, value); name->makeIdentifier(); Identifier *id = name->identifier(); MemberData::Index memberIndex{0, 0}; uint member = internalClass()->find(id); PropertyAttributes attrs; if (member < UINT_MAX) { attrs = internalClass()->propertyData[member]; memberIndex = d()->writablePropertyData(attrs.isAccessor() ? member + SetterOffset : member); } // clause 1 if (!memberIndex.isNull()) { if (attrs.isAccessor()) { if (memberIndex->as<FunctionObject>()) goto cont; goto reject; } else if (!attrs.isWritable()) goto reject; else if (isArrayObject() && name->equals(engine->id_length())) { bool ok; uint l = value.asArrayLength(&ok); if (!ok) { engine->throwRangeError(value); return false; } ok = setArrayLength(l); if (!ok) goto reject; } else { memberIndex.set(engine, value); } return true; } else if (!prototype()) { if (!isExtensible()) goto reject; } else { // clause 4 Scope scope(engine); memberIndex = ScopedObject(scope, prototype())->getValueOrSetter(name, &attrs); if (!memberIndex.isNull()) { if (attrs.isAccessor()) { if (!memberIndex->as<FunctionObject>()) goto reject; } else if (!isExtensible() || !attrs.isWritable()) { goto reject; } } else if (!isExtensible()) { goto reject; } } cont: // Clause 5 if (!memberIndex.isNull() && attrs.isAccessor()) { Q_ASSERT(memberIndex->as<FunctionObject>()); Scope scope(engine); ScopedFunctionObject setter(scope, *memberIndex); ScopedCallData callData(scope, 1); callData->args[0] = value; callData->thisObject = this; setter->call(scope, callData); return !internalClass()->engine->hasException; } insertMember(name, value); return true; reject: // ### this should be removed once everything is ported to use Object::set() if (engine->current->strictMode) { QString message = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"'); engine->throwTypeError(message); } return false; }