return false;
d_ptr->currentName = d_ptr->nextName;
d_ptr->currentIndex = d_ptr->nextIndex;
- d_ptr->currentProperty = d_ptr->nextProperty;
+ d_ptr->currentProperty.copy(d_ptr->nextProperty, d_ptr->nextAttributes);
d_ptr->currentAttributes = d_ptr->nextAttributes;
QV4::ExecutionEngine *v4 = d_ptr->iterator.engine();
setArrayType(ArrayData::Complex);
if (context->strictMode) {
- Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
Q_ASSERT(CallerPropertyIndex == internalClass->find(context->engine->id_caller));
- *propertyAt(CalleePropertyIndex) = pd;
- *propertyAt(CallerPropertyIndex) = pd;
+ propertyAt(CalleePropertyIndex)->value = v4->thrower;
+ propertyAt(CalleePropertyIndex)->set = v4->thrower;
+ propertyAt(CallerPropertyIndex)->value = v4->thrower;
+ propertyAt(CallerPropertyIndex)->set = v4->thrower;
arrayReserve(context->callData->argc);
arrayPut(0, context->callData->args, context->callData->argc);
context->engine->requireArgumentsAccessors(numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
mappedArguments.append(context->callData->args[i]);
- arraySet(i, context->engine->argumentsAccessors.at(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)
PropertyAttributes mapAttrs;
bool isMapped = false;
if (pd && index < (uint)mappedArguments.size())
- isMapped = arrayData->attributes(index).isAccessor() && pd->getter() == context->engine->argumentsAccessors.at(index).getter();
+ isMapped = arrayData->attributes(index).isAccessor() && pd->getter() == context->engine->argumentsAccessors[index].getter();
if (isMapped) {
- map = *pd;
mapAttrs = arrayData->attributes(index);
+ map.copy(*pd, mapAttrs);
setArrayAttributes(index, Attr_Data);
pd = arrayData->getProperty(index);
pd->value = mappedArguments.at(index);
if (attrs.isWritable()) {
setArrayAttributes(index, mapAttrs);
pd = arrayData->getProperty(index);
- *pd = map;
+ pd->copy(map, mapAttrs);
}
}
} else {
for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse->begin();
it != static_cast<const SparseArrayData *>(other)->sparse->end(); it = it->nextNode())
- obj->arraySet(oldSize + it->key(), other->data[it->value]);
+ obj->arraySet(oldSize + it->key(), ValueRef(other->data[it->value]));
}
} else {
obj->arrayPut(oldSize, other->data, n);
result->putIndexed(startIndex + i, entry);
}
} else {
- result->arraySet(result->getLength(), ctx->callData->args[i]);
+ result->arraySet(result->getLength(), ValueRef(ctx->callData->args[i]));
}
}
if (activation->hasProperty(name))
return;
- Property desc = Property::fromValue(Primitive::undefinedValue());
+ Property desc(Primitive::undefinedValue());
PropertyAttributes attrs(Attr_Data);
attrs.setConfigurable(deletable);
activation->__defineOwnProperty__(this, name, desc, attrs);
, globalObject(0)
, globalCode(0)
, v8Engine(0)
+ , argumentsAccessors(0)
+ , nArgumentsAccessors(0)
, m_engineId(engineSerial.fetchAndAddOrdered(1))
, regExpCache(0)
, m_multiplyWrappedQObjects(0)
delete executableAllocator;
jsStack->deallocate();
delete jsStack;
+ delete [] argumentsAccessors;
}
void ExecutionEngine::enableDebugger()
void ExecutionEngine::requireArgumentsAccessors(int n)
{
- if (n <= argumentsAccessors.size())
+ if (n <= nArgumentsAccessors)
return;
Scope scope(this);
ScopedFunctionObject get(scope);
ScopedFunctionObject set(scope);
- uint oldSize = argumentsAccessors.size();
- argumentsAccessors.resize(n);
- for (int i = oldSize; i < n; ++i) {
- get = new (memoryManager) ArgumentsGetterFunction(rootContext, i);
- set = new (memoryManager) ArgumentsSetterFunction(rootContext, i);
- Property pd = Property::fromAccessor(get.getPointer(), set.getPointer());
- argumentsAccessors[i] = pd;
+ if (n >= nArgumentsAccessors) {
+ Property *oldAccessors = argumentsAccessors;
+ int oldSize = nArgumentsAccessors;
+ nArgumentsAccessors = qMax(8, n);
+ argumentsAccessors = new Property[nArgumentsAccessors];
+ if (oldAccessors) {
+ memcpy(argumentsAccessors, oldAccessors, oldSize*sizeof(Property));
+ delete [] oldAccessors;
+ }
+ for (int i = oldSize; i < nArgumentsAccessors; ++i) {
+ argumentsAccessors[i].value = Value::fromManaged(new (memoryManager) ArgumentsGetterFunction(rootContext, i));
+ argumentsAccessors[i].set = Value::fromManaged(new (memoryManager) ArgumentsSetterFunction(rootContext, i));
+ }
}
}
globalObject->mark(this);
- for (int i = 0; i < argumentsAccessors.size(); ++i) {
- const Property &pd = argumentsAccessors.at(i);
+ for (int i = 0; i < nArgumentsAccessors; ++i) {
+ const Property &pd = argumentsAccessors[i];
if (FunctionObject *getter = pd.getter())
getter->mark(this);
if (FunctionObject *setter = pd.setter())
EvalFunction *evalFunction;
FunctionObject *thrower;
- QVector<Property> argumentsAccessors;
+ Property *argumentsAccessors;
+ int nArgumentsAccessors;
StringValue id_undefined;
StringValue id_null;
defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount()));
if (scope->strictMode) {
- Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
+ Property pd(v4->thrower, v4->thrower);
insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(formalParameterCount()));
if (scope->strictMode) {
- Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
+ Property pd(v4->thrower, v4->thrower);
insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
ExecutionEngine *v4 = scope->engine;
- Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
+ Property pd(v4->thrower, v4->thrower);
insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
if (attributes.isAccessor()) {
hasAccessorProperty = 1;
- *propertyAt(idx) = p;
+ Property *pp = propertyAt(idx);
+ pp->value = p.value;
+ pp->set = p.set;
} else {
memberData[idx] = p.value;
}
it->arrayIndex = k + 1;
*index = k;
*attrs = a;
- *pd = *p;
+ pd->copy(*p, a);
return;
}
}
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
name = n;
*attrs = a;
- *pd = *p;
+ pd->copy(*p, a);
return;
}
}
if (!extensible)
goto reject;
// clause 4
- Property pd = p;
+ Property pd;
+ pd.copy(p, attrs);
pd.fullyPopulated(&attrs);
insertMember(name, pd, attrs);
return true;
if (!extensible)
goto reject;
// clause 4
- Property pp(p);
+ Property pp;
+ pp.copy(p, attrs);
pp.fullyPopulated(&attrs);
if (attrs == Attr_Data) {
Scope scope(ctx);
void defineReadonlyProperty(const StringRef name, ValueRef value);
void insertMember(const StringRef s, const ValueRef v, PropertyAttributes attributes = Attr_Data) {
- insertMember(s, Property::fromValue(*v), attributes);
+ insertMember(s, Property(*v), attributes);
}
void insertMember(const StringRef s, const Property &p, PropertyAttributes attributes);
defineDefaultProperty(QStringLiteral("__defineSetter__"), method_defineSetter, 2);
Scoped<String> id_proto(scope, v4->id___proto__);
- Property p = Property::fromAccessor(v4->newBuiltinFunction(v4->rootContext, id_proto, method_get_proto)->getPointer(),
- v4->newBuiltinFunction(v4->rootContext, id_proto, method_set_proto)->getPointer());
+ Property p(v4->newBuiltinFunction(v4->rootContext, id_proto, method_get_proto)->getPointer(),
+ v4->newBuiltinFunction(v4->rootContext, id_proto, method_set_proto)->getPointer());
insertMember(StringRef(v4->id___proto__), p, Attr_Accessor|Attr_NotEnumerable);
}
attrs->resolve();
}
- static inline Property fromValue(Value v) {
- Property pd;
- pd.value = v;
- return pd;
- }
- static inline Property fromAccessor(FunctionObject *getter, FunctionObject *setter) {
- Property pd;
- pd.value = Primitive::fromManaged(reinterpret_cast<Managed *>(getter));
- pd.set = Primitive::fromManaged(reinterpret_cast<Managed *>(setter));
- return pd;
- }
-
static Property genericDescriptor() {
Property pd;
pd.value = Primitive::emptyValue();
inline FunctionObject *setter() const { return reinterpret_cast<FunctionObject *>(set.asManaged()); }
inline void setGetter(FunctionObject *g) { value = Primitive::fromManaged(reinterpret_cast<Managed *>(g)); }
inline void setSetter(FunctionObject *s) { set = Primitive::fromManaged(reinterpret_cast<Managed *>(s)); }
+
+ void copy(const Property &other, PropertyAttributes attrs) {
+ value = other.value;
+ if (attrs.isAccessor())
+ set = other.set;
+ }
+
+ explicit Property() { value = Encode::undefined(); set = Encode::undefined(); }
+ explicit Property(Value v) : value(v) { set = Encode::undefined(); }
+ Property(FunctionObject *getter, FunctionObject *setter) {
+ value = Primitive::fromManaged(reinterpret_cast<Managed *>(getter));
+ set = Primitive::fromManaged(reinterpret_cast<Managed *>(setter));
+ }
+ Property &operator=(Value v) { value = v; return *this; }
+private:
+ Property(const Property &);
+ Property &operator=(const Property &);
};
inline bool Property::isSubset(const PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs) const
}
+Q_DECLARE_TYPEINFO(QV4::Property, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
#endif
Property *pd = s->__getOwnProperty__(*index, &a);
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
*attrs = a;
- *p = *pd;
+ p->copy(*pd, a);
return;
}
}