Object *proto = scope->engine->newObject();
proto->defineDefaultProperty(scope->engine->id_constructor, Value::fromObject(this));
- PropertyDescriptor *pd = members->insert(scope->engine->id_prototype);
+ PropertyDescriptor *pd = insertMember(scope->engine->id_prototype);
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Disabled;
PropertyDescriptor pd = PropertyDescriptor::fromAccessor(thrower, thrower);
pd.configurable = PropertyDescriptor::Disabled;
pd.enumberable = PropertyDescriptor::Disabled;
- *members->insert(scope->engine->id_arguments) = pd;
- *members->insert(scope->engine->id_caller) = pd;
+ *insertMember(scope->engine->id_arguments) = pd;
+ *insertMember(scope->engine->id_caller) = pd;
}
Value BoundFunction::call(ExecutionContext *context, Value, Value *args, int argc)
{
if (!members)
members.reset(new PropertyTable());
- PropertyDescriptor *pd = members->insert(name);
+ PropertyDescriptor *pd = insertMember(name);
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Disabled;
{
if (!members)
members.reset(new PropertyTable());
- PropertyDescriptor *pd = members->insert(name);
+ PropertyDescriptor *pd = insertMember(name);
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Disabled;
pd->enumberable = PropertyDescriptor::Disabled;
continue;
(*it)->name->mark();
}
- for (int i = 0; i < (uint)members->values.size(); ++i) {
- const PropertyDescriptor &pd = members->values.at(i);
+ for (int i = 0; i < (uint)memberData.size(); ++i) {
+ const PropertyDescriptor &pd = memberData.at(i);
if (pd.isData()) {
if (Managed *m = pd.value.asManaged())
m->mark();
array.markObjects();
}
+PropertyDescriptor *Object::insertMember(String *s)
+{
+ if (!members)
+ members.reset(new PropertyTable);
+
+ PropertyTableEntry *e = members->insert(s);
+ if (e->valueIndex == UINT_MAX) {
+ e->valueIndex = memberData.size();
+ memberData.resize(memberData.size() + 1);
+ }
+ return memberData.data() + e->valueIndex;
+}
+
// Section 8.12.1
PropertyDescriptor *Object::__getOwnProperty__(ExecutionContext *ctx, String *name)
{
if (idx != String::InvalidArrayIndex)
return __getOwnProperty__(ctx, idx);
- if (members)
- return members->find(name);
+ if (members) {
+ uint idx = members->find(name);
+ if (idx < UINT_MAX)
+ return memberData.data() + idx;
+ }
return 0;
}
Object *o = this;
while (o) {
if (o->members) {
- if (PropertyDescriptor *p = o->members->find(name))
- return p;
+ uint idx = o->members->find(name);
+ if (idx < UINT_MAX)
+ return o->memberData.data() + idx;
}
o = o->prototype;
}
Object *o = this;
while (o) {
if (o->members) {
- if (PropertyDescriptor *p = o->members->find(name)) {
+ uint idx = o->members->find(name);
+ if (idx < UINT_MAX) {
if (hasProperty)
*hasProperty = true;
- return getValue(ctx, p);
+ return getValue(ctx, o->memberData.data() + idx);
}
}
o = o->prototype;
}
{
- PropertyDescriptor *p = members->insert(name);
+ PropertyDescriptor *p = insertMember(name);
p->type = PropertyDescriptor::Data;
p->value = value;
p->configurable = PropertyDescriptor::Enabled;
name->makeIdentifier(ctx);
- if (members && members->find(name) != 0)
+ if (members && members->find(name) != UINT_MAX)
return true;
return prototype ? prototype->__hasProperty__(ctx, name) : false;
if (members) {
if (PropertyTableEntry *entry = members->findEntry(name)) {
- if (members->values[entry->valueIndex].isConfigurable()) {
+ PropertyDescriptor &pd = memberData[entry->valueIndex];
+ if (pd.isConfigurable()) {
members->remove(entry);
+ // ### leaves a hole in memberData
+ pd.type = PropertyDescriptor::Generic;
+ pd.writable = PropertyDescriptor::Undefined;
return true;
}
if (ctx->strictMode)
PropertyDescriptor *current;
if (isArrayObject() && name->isEqualTo(ctx->engine->id_length)) {
- PropertyDescriptor *lp = members->values.data(); // length is always the first property
- assert(lp == members->find(ctx->engine->id_length));
+ PropertyDescriptor *lp = memberData.data() + ArrayObject::LengthPropertyIndex;
+ assert(0 == members->find(ctx->engine->id_length));
if (desc->isEmpty() || desc->isSubset(lp))
return true;
if (!lp->isWritable() || desc->type == PropertyDescriptor::Accessor || desc->isConfigurable() || desc->isEnumerable())
if (!extensible)
goto reject;
// clause 4
- PropertyDescriptor *pd = members->insert(name);
+ PropertyDescriptor *pd = insertMember(name);
*pd = *desc;
pd->fullyPopulated();
return true;
PropertyDescriptor *current;
// 15.4.5.1, 4b
- if (isArrayObject() && index >= array.length() && !members->values.at(0).isWritable())
+ if (isArrayObject() && index >= array.length() && !memberData.at(ArrayObject::LengthPropertyIndex).isWritable())
goto reject;
if (isNonStrictArgumentsObject)
if (!members)
members.reset(new PropertyTable());
- PropertyDescriptor *pd = members->insert(context->engine->id_length);
+ PropertyDescriptor *pd = insertMember(context->engine->id_length);
+ assert(pd == memberData.constData() + LengthPropertyIndex);
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Disabled;
pd->configurable = PropertyDescriptor::Disabled;
pd->value = Value::fromInt32(0);
array.setArrayObject(this);
- assert(pd = members->values.data());
}
_properties[prop->index] = 0;
prop->next = _freeList;
_freeList = prop;
- // ### empty space in value array
- values[prop->valueIndex].type = PropertyDescriptor::Generic;
- values[prop->valueIndex].writable = PropertyDescriptor::Undefined;
}
PropertyTableEntry *findEntry(String *name) const
return 0;
}
- PropertyDescriptor *find(String *name)
+ uint find(String *name)
{
if (_properties) {
for (PropertyTableEntry *prop = _buckets[name->hashValue() % _bucketCount]; prop; prop = prop->next) {
if (prop && prop->name->isEqualTo(name))
- return values.data() + prop->valueIndex;
+ return prop->valueIndex;
}
}
- return 0;
+ return UINT_MAX;
}
- PropertyDescriptor *insert(String *name)
+ PropertyTableEntry *insert(String *name)
{
if (PropertyTableEntry *prop = findEntry(name))
- return values.data() + prop->valueIndex;
+ return prop;
if (_propertyCount == _allocated) {
if (! _allocated)
bucket = prop;
}
- prop->valueIndex = values.size();
- values.resize(values.size() + 1);
- return values.data() + prop->valueIndex;
+ return prop;
+// prop->valueIndex = values.size();
+// values.resize(values.size() + 1);
+// return values.data() + prop->valueIndex;
}
private:
int _bucketCount;
int _primeIdx: 5;
int _allocated: 27;
- QVector<PropertyDescriptor> values;
};
} // namespace VM