return false;
d_ptr->currentName = d_ptr->nextName;
d_ptr->currentIndex = d_ptr->nextIndex;
- d_ptr->currentProperty.copy(d_ptr->nextProperty, d_ptr->nextAttributes);
+ d_ptr->currentProperty.copy(&d_ptr->nextProperty, d_ptr->nextAttributes);
d_ptr->currentAttributes = d_ptr->nextAttributes;
QV4::ExecutionEngine *v4 = d_ptr->iterator.engine();
QJSValue value;
QV4::PersistentValue iterator;
+ // ### GC
QV4::Property currentProperty;
QV4::PropertyAttributes currentAttributes;
QV4::StringValue currentName;
uint currentIndex;
+ // ### GC
QV4::Property nextProperty;
QV4::PropertyAttributes nextAttributes;
QV4::StringValue nextName;
d()->mappedArguments = md->reallocate(engine(), d()->mappedArguments, numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
mappedArguments()->data[i] = context()->callData->args[i];
- arraySet(i, context()->engine->argumentsAccessors[i], Attr_Accessor);
+ arraySet(i, context()->engine->argumentsAccessors + i, Attr_Accessor);
}
arrayPut(numAccessors, context()->callData->args + numAccessors, argCount - numAccessors);
for (uint i = numAccessors; i < argCount; ++i)
d()->fullyCreated = true;
}
-bool ArgumentsObject::defineOwnProperty(ExecutionEngine *engine, uint index, const Property &desc, PropertyAttributes attrs)
+bool ArgumentsObject::defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs)
{
fullyCreate();
Scope scope(engine);
Property *pd = arrayData() ? arrayData()->getProperty(index) : 0;
- Property map;
+ ScopedProperty map(scope);
PropertyAttributes mapAttrs;
bool isMapped = false;
uint numAccessors = qMin((int)context()->function->formalParameterCount(), context()->realArgumentCount);
if (isMapped) {
Q_ASSERT(arrayData());
mapAttrs = arrayData()->attributes(index);
- map.copy(*pd, mapAttrs);
+ map->copy(pd, mapAttrs);
setArrayAttributes(index, Attr_Data);
pd = arrayData()->getProperty(index);
pd->value = mappedArguments()->data[index];
if (isMapped && attrs.isData()) {
Q_ASSERT(arrayData());
- ScopedFunctionObject setter(scope, map.setter());
+ ScopedFunctionObject setter(scope, map->setter());
ScopedCallData callData(scope, 1);
callData->thisObject = this->asReturnedValue();
- callData->args[0] = desc.value;
+ callData->args[0] = desc->value;
setter->call(callData);
if (attrs.isWritable()) {
!static_cast<ArgumentsObject *>(m)->context()->strictMode;
}
- bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property &desc, PropertyAttributes attrs);
+ bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void putIndexed(Managed *m, uint index, const ValueRef value);
static bool deleteIndexedProperty(Managed *m, uint index);
thisObject->initSparseArray();
while (n != sparse->sparse()->end()) {
PropertyAttributes a = sparse->attrs() ? sparse->attrs()[n->value] : Attr_Data;
- thisObject->arraySet(n->value, *reinterpret_cast<Property *>(sparse->arrayData() + n->value), a);
+ thisObject->arraySet(n->value, reinterpret_cast<Property *>(sparse->arrayData() + n->value), a);
n = n->nextNode();
}
if (activation->hasProperty(name))
return;
- Property desc(Primitive::undefinedValue());
+ ScopedProperty desc(scope);
PropertyAttributes attrs(Attr_Data);
attrs.setConfigurable(deletable);
activation->__defineOwnProperty__(scope.engine, name, desc, attrs);
f->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(f->formalParameterCount()));
if (scope->d()->strictMode) {
- Property pd(s.engine->thrower, s.engine->thrower);
+ ScopedProperty pd(s);
+ pd->value = s.engine->thrower;
+ pd->set = s.engine->thrower;
f->insertMember(scope->d()->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
f->insertMember(scope->d()->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
len = 0;
f->defineReadonlyProperty(s.engine->id_length, Primitive::fromInt32(len));
- ExecutionEngine *v4 = s.engine;
-
- Property pd(v4->thrower, v4->thrower);
+ ScopedProperty pd(s);
+ pd->value = s.engine->thrower;
+ pd->set = s.engine->thrower;
f->insertMember(s.engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
f->insertMember(s.engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
d()->memberData = MemberData::reallocate(engine(), d()->memberData, idx);
}
-void Object::insertMember(String *s, const Property &p, PropertyAttributes attributes)
+void Object::insertMember(String *s, const Property *p, PropertyAttributes attributes)
{
uint idx;
InternalClass::addMember(this, s, attributes, &idx);
if (attributes.isAccessor()) {
setHasAccessorProperty();
Property *pp = propertyAt(idx);
- pp->value = p.value;
- pp->set = p.set;
+ pp->value = p->value;
+ pp->set = p->set;
} else {
- d()->memberData->data[idx] = p.value;
+ d()->memberData->data[idx] = p->value;
}
}
it->arrayIndex = k + 1;
*index = k;
*attrs = a;
- pd->copy(*p, a);
+ pd->copy(p, a);
return;
}
}
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
*name = m->engine()->newString(n->string);
*attrs = a;
- pd->copy(*p, a);
+ pd->copy(p, a);
return;
}
}
}
// Section 8.12.9
-bool Object::__defineOwnProperty__(ExecutionEngine *engine, String *name, const Property &p, PropertyAttributes attrs)
+bool Object::__defineOwnProperty__(ExecutionEngine *engine, String *name, const Property *p, PropertyAttributes attrs)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
Q_ASSERT(Heap::ArrayObject::LengthPropertyIndex == internalClass()->find(engine->id_length));
Property *lp = propertyAt(Heap::ArrayObject::LengthPropertyIndex);
cattrs = internalClass()->propertyData.constData() + Heap::ArrayObject::LengthPropertyIndex;
- if (attrs.isEmpty() || p.isSubset(attrs, *lp, *cattrs))
+ if (attrs.isEmpty() || p->isSubset(attrs, lp, *cattrs))
return true;
if (!cattrs->isWritable() || attrs.type() == PropertyAttributes::Accessor || attrs.isConfigurable() || attrs.isEnumerable())
goto reject;
bool succeeded = true;
if (attrs.type() == PropertyAttributes::Data) {
bool ok;
- uint l = p.value.asArrayLength(&ok);
+ uint l = p->value.asArrayLength(&ok);
if (!ok) {
- ScopedValue v(scope, p.value);
+ ScopedValue v(scope, p->value);
engine->throwRangeError(v);
return false;
}
if (!isExtensible())
goto reject;
// clause 4
- Property pd;
- pd.copy(p, attrs);
- pd.fullyPopulated(&attrs);
+ ScopedProperty pd(scope);
+ pd->copy(p, attrs);
+ pd->fullyPopulated(&attrs);
insertMember(name, pd, attrs);
return true;
}
return false;
}
-bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, const Property &p, PropertyAttributes attrs)
+bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, const Property *p, PropertyAttributes attrs)
{
// 15.4.5.1, 4b
if (isArrayObject() && index >= getLength() && !internalClass()->propertyData[Heap::ArrayObject::LengthPropertyIndex].isWritable())
return false;
}
-bool Object::defineOwnProperty2(ExecutionEngine *engine, uint index, const Property &p, PropertyAttributes attrs)
+bool Object::defineOwnProperty2(ExecutionEngine *engine, uint index, const Property *p, PropertyAttributes attrs)
{
Property *current = 0;
if (!isExtensible())
goto reject;
// clause 4
- Property pp;
- pp.copy(p, attrs);
- pp.fullyPopulated(&attrs);
+ Scope scope(engine);
+ ScopedProperty pp(scope);
+ pp->copy(p, attrs);
+ pp->fullyPopulated(&attrs);
if (attrs == Attr_Data) {
- Scope scope(engine);
- ScopedValue v(scope, pp.value);
+ ScopedValue v(scope, pp->value);
arraySet(index, v);
} else {
arraySet(index, pp, attrs);
return false;
}
-bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *member, const Property &p, PropertyAttributes attrs)
+bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *member, const Property *p, PropertyAttributes attrs)
{
// clause 5
if (attrs.isEmpty())
}
// clause 6
- if (p.isSubset(attrs, *current, cattrs))
+ if (p->isSubset(attrs, current, cattrs))
return true;
// clause 7
}
} else if (cattrs.isData() && attrs.isData()) { // clause 10
if (!cattrs.isConfigurable() && !cattrs.isWritable()) {
- if (attrs.isWritable() || !current->value.sameValue(p.value))
+ if (attrs.isWritable() || !current->value.sameValue(p->value))
goto reject;
}
} else { // clause 10
Q_ASSERT(cattrs.isAccessor() && attrs.isAccessor());
if (!cattrs.isConfigurable()) {
- if (!p.value.isEmpty() && current->value.val != p.value.val)
+ if (!p->value.isEmpty() && current->value.val != p->value.val)
goto reject;
- if (!p.set.isEmpty() && current->set.val != p.set.val)
+ if (!p->set.isEmpty() && current->set.val != p->set.val)
goto reject;
}
}
}
-bool Object::__defineOwnProperty__(ExecutionEngine *engine, const QString &name, const Property &p, PropertyAttributes attrs)
+bool Object::__defineOwnProperty__(ExecutionEngine *engine, const QString &name, const Property *p, PropertyAttributes attrs)
{
Scope scope(engine);
ScopedString s(scope, engine->newString(name));
bool hasOwnProperty(String *name) const;
bool hasOwnProperty(uint index) const;
- bool __defineOwnProperty__(ExecutionEngine *engine, uint index, String *member, const Property &p, PropertyAttributes attrs);
- bool __defineOwnProperty__(ExecutionEngine *engine, String *name, const Property &p, PropertyAttributes attrs);
- bool __defineOwnProperty__(ExecutionEngine *engine, uint index, const Property &p, PropertyAttributes attrs);
- bool __defineOwnProperty__(ExecutionEngine *engine, const QString &name, const Property &p, PropertyAttributes attrs);
- bool defineOwnProperty2(ExecutionEngine *engine, uint index, const Property &p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionEngine *engine, uint index, String *member, const Property *p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionEngine *engine, String *name, const Property *p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionEngine *engine, uint index, const Property *p, PropertyAttributes attrs);
+ bool __defineOwnProperty__(ExecutionEngine *engine, const QString &name, const Property *p, PropertyAttributes attrs);
+ bool defineOwnProperty2(ExecutionEngine *engine, uint index, const Property *p, PropertyAttributes attrs);
//
// helpers
}
void insertMember(String *s, const ValueRef v, PropertyAttributes attributes = Attr_Data) {
- Property p(*v);
+ Scope scope(engine());
+ ScopedProperty p(scope);
+ p->value = *v;
insertMember(s, p, attributes);
}
- void insertMember(String *s, const Property &p, PropertyAttributes attributes);
+ void insertMember(String *s, const Property *p, PropertyAttributes attributes);
inline ExecutionEngine *engine() const { return internalClass()->engine; }
bool setArrayLength(uint newLen);
void setArrayLengthUnchecked(uint l);
- void arraySet(uint index, const Property &p, PropertyAttributes attributes = Attr_Data);
+ void arraySet(uint index, const Property *p, PropertyAttributes attributes = Attr_Data);
void arraySet(uint index, ValueRef value);
bool arrayPut(uint index, ValueRef value) {
setArrayLengthUnchecked(idx + 1);
}
-inline void Object::arraySet(uint index, const Property &p, PropertyAttributes attributes)
+inline void Object::arraySet(uint index, const Property *p, PropertyAttributes attributes)
{
// ### Clean up
arrayCreate();
}
setArrayAttributes(index, attributes);
Property *pd = ArrayData::insert(this, index, attributes.isAccessor());
- pd->value = p.value;
+ pd->value = p->value;
if (attributes.isAccessor())
- pd->set = p.set;
+ pd->set = p->set;
if (isArrayObject() && index >= getLength())
setArrayLengthUnchecked(index + 1);
}
return Encode::null();
PropertyAttributes attrs;
- Property p;
uint index;
Scope scope(object->engine());
+ ScopedProperty p(scope);
ScopedString name(scope);
- next(name.getRef(), &index, &p, &attrs);
+ next(name.getRef(), &index, p, &attrs);
if (attrs.isEmpty())
return Encode::null();
- value = object->objectValue()->getValue(&p, attrs);
+ value = object->objectValue()->getValue(p, attrs);
if (!!name)
return name->asReturnedValue();
return Encode::null();
PropertyAttributes attrs;
- Property p;
uint index;
Scope scope(object->engine());
+ ScopedProperty p(scope);
ScopedString name(scope);
- next(name.getRef(), &index, &p, &attrs);
+ next(name.getRef(), &index, p, &attrs);
if (attrs.isEmpty())
return Encode::null();
- value = object->objectValue()->getValue(&p, attrs);
+ value = object->objectValue()->getValue(p, attrs);
if (!!name)
return name->asReturnedValue();
return Encode::null();
PropertyAttributes attrs;
- // ### GC
- Property p;
uint index;
Scope scope(object->engine());
+ ScopedProperty p(scope);
ScopedString name(scope);
- next(name.getRef(), &index, &p, &attrs);
+ next(name.getRef(), &index, p, &attrs);
if (attrs.isEmpty())
return Encode::null();
defineDefaultProperty(QStringLiteral("__defineSetter__"), method_defineSetter, 2);
ScopedContext global(scope, scope.engine->rootContext());
- Property p(ScopedFunctionObject(scope, BuiltinFunction::create(global, v4->id___proto__, method_get_proto)),
- ScopedFunctionObject(scope, BuiltinFunction::create(global, v4->id___proto__, method_set_proto)));
+ ScopedProperty p(scope);
+ p->value = BuiltinFunction::create(global, v4->id___proto__, method_get_proto);
+ p->set = BuiltinFunction::create(global, v4->id___proto__, method_set_proto);
insertMember(v4->id___proto__, p, Attr_Accessor|Attr_NotEnumerable);
}
return Encode::undefined();
ScopedValue attributes(scope, ctx->argument(2));
- Property pd;
+ ScopedProperty pd(scope);
PropertyAttributes attrs;
- toPropertyDescriptor(scope.engine, attributes, &pd, &attrs);
+ toPropertyDescriptor(scope.engine, attributes, pd, &attrs);
if (scope.engine->hasException)
return Encode::undefined();
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
ScopedString name(scope);
+ ScopedProperty pd(scope);
+ ScopedProperty n(scope);
while (1) {
uint index;
PropertyAttributes attrs;
- Property pd;
- it.next(name.getRef(), &index, &pd, &attrs);
+ it.next(name.getRef(), &index, pd, &attrs);
if (attrs.isEmpty())
break;
- Property n;
PropertyAttributes nattrs;
- val = o->getValue(&pd, attrs);
- toPropertyDescriptor(scope.engine, val, &n, &nattrs);
+ val = o->getValue(pd, attrs);
+ toPropertyDescriptor(scope.engine, val, n, &nattrs);
if (scope.engine->hasException)
return Encode::undefined();
bool ok;
o = ctx->d()->engine->globalObject();
}
- Property pd;
- pd.value = f;
- pd.set = Primitive::emptyValue();
+ ScopedProperty pd(scope);
+ pd->value = f;
+ pd->set = Primitive::emptyValue();
o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
return Encode::undefined();
}
o = ctx->d()->engine->globalObject();
}
- Property pd;
- pd.value = Primitive::emptyValue();
- pd.set = f;
+ ScopedProperty pd(scope);
+ pd->value = Primitive::emptyValue();
+ pd->set = f;
o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
return Encode::undefined();
}
ScopedObject o(scope, engine->newObject());
ScopedString s(scope);
- Property pd;
+ ScopedProperty pd(scope);
if (attrs.isData()) {
- pd.value = desc->value;
+ pd->value = desc->value;
s = engine->newString(QStringLiteral("value"));
o->__defineOwnProperty__(scope.engine, s, pd, Attr_Data);
- pd.value = Primitive::fromBoolean(attrs.isWritable());
+ pd->value = Primitive::fromBoolean(attrs.isWritable());
s = engine->newString(QStringLiteral("writable"));
o->__defineOwnProperty__(scope.engine, s, pd, Attr_Data);
} else {
- pd.value = desc->getter() ? desc->getter()->asReturnedValue() : Encode::undefined();
+ pd->value = desc->getter() ? desc->getter()->asReturnedValue() : Encode::undefined();
s = engine->newString(QStringLiteral("get"));
o->__defineOwnProperty__(scope.engine, s, pd, Attr_Data);
- pd.value = desc->setter() ? desc->setter()->asReturnedValue() : Encode::undefined();
+ pd->value = desc->setter() ? desc->setter()->asReturnedValue() : Encode::undefined();
s = engine->newString(QStringLiteral("set"));
o->__defineOwnProperty__(scope.engine, s, pd, Attr_Data);
}
- pd.value = Primitive::fromBoolean(attrs.isEnumerable());
+ pd->value = Primitive::fromBoolean(attrs.isEnumerable());
s = engine->newString(QStringLiteral("enumerable"));
o->__defineOwnProperty__(scope.engine, s, pd, Attr_Data);
- pd.value = Primitive::fromBoolean(attrs.isConfigurable());
+ pd->value = Primitive::fromBoolean(attrs.isConfigurable());
s = engine->newString(QStringLiteral("configurable"));
o->__defineOwnProperty__(scope.engine, s, pd, Attr_Data);
return pd;
}
- inline bool isSubset(const PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs) const;
- inline void merge(PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs);
+ inline bool isSubset(const PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs) const;
+ inline void merge(PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs);
inline Heap::FunctionObject *getter() const { return value.isManaged() ? reinterpret_cast<Heap::FunctionObject *>(value.heapObject()) : 0; }
inline Heap::FunctionObject *setter() const { return set.isManaged() ? reinterpret_cast<Heap::FunctionObject *>(set.heapObject()) : 0; }
inline void setGetter(FunctionObject *g) { value = Primitive::fromManaged(reinterpret_cast<Managed *>(g)); }
inline void setSetter(FunctionObject *s) { set = s ? Primitive::fromManaged(reinterpret_cast<Managed *>(s)) : Value::fromHeapObject(0); }
- void copy(const Property &other, PropertyAttributes attrs) {
- value = other.value;
+ void copy(const Property *other, PropertyAttributes attrs) {
+ value = other->value;
if (attrs.isAccessor())
- set = other.set;
+ set = other->set;
}
explicit Property() { value = Encode::undefined(); set = Value::fromHeapObject(0); }
Property &operator=(const Property &);
};
-inline bool Property::isSubset(const PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs) const
+inline bool Property::isSubset(const PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs) const
{
if (attrs.type() != PropertyAttributes::Generic && attrs.type() != otherAttrs.type())
return false;
return false;
if (attrs.hasWritable() && attrs.isWritable() != otherAttrs.isWritable())
return false;
- if (attrs.type() == PropertyAttributes::Data && !value.sameValue(other.value))
+ if (attrs.type() == PropertyAttributes::Data && !value.sameValue(other->value))
return false;
if (attrs.type() == PropertyAttributes::Accessor) {
- if (value.heapObject() != other.value.heapObject())
+ if (value.heapObject() != other->value.heapObject())
return false;
- if (set.heapObject() != other.set.heapObject())
+ if (set.heapObject() != other->set.heapObject())
return false;
}
return true;
}
-inline void Property::merge(PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs)
+inline void Property::merge(PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs)
{
if (otherAttrs.hasEnumerable())
attrs.setEnumerable(otherAttrs.isEnumerable());
attrs.setWritable(otherAttrs.isWritable());
if (otherAttrs.type() == PropertyAttributes::Accessor) {
attrs.setType(PropertyAttributes::Accessor);
- if (!other.value.isEmpty())
- value = other.value;
- if (!other.set.isEmpty())
- set = other.set;
+ if (!other->value.isEmpty())
+ value = other->value;
+ if (!other->set.isEmpty())
+ set = other->set;
} else if (otherAttrs.type() == PropertyAttributes::Data){
attrs.setType(PropertyAttributes::Data);
- value = other.value;
+ value = other->value;
}
}
ScopedProperty(Scope &scope)
{
property = reinterpret_cast<Property*>(scope.alloc(sizeof(Property) / sizeof(Value)));
+ property->value = Encode::undefined();
+ property->set = Encode::undefined();
}
Property *operator->() { return property; }
- operator const Property &() { return *property; }
+ operator const Property *() const { return property; }
+ operator Property *() { return property; }
Property *property;
};
Property *pd = s->__getOwnProperty__(*index, &a);
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
*attrs = a;
- p->copy(*pd, a);
+ p->copy(pd, a);
return;
}
}