First part of moving get/put etc. into the Managed vtbl.

Change-Id: I6fe14b02205901dbffa25c6c1b4883fb99586417
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Lars Knoll 2013-03-07 12:25:59 +01:00 committed by Simon Hausmann
parent d9f1831917
commit 1196824e7a
23 changed files with 286 additions and 126 deletions

View File

@ -416,7 +416,7 @@ void ExecutionEngine::requireArgumentsAccessors(int n)
set->prototype = functionPrototype;
PropertyDescriptor pd = PropertyDescriptor::fromAccessor(get, set);
pd.configurable = PropertyDescriptor::Enabled;
pd.enumberable = PropertyDescriptor::Enabled;
pd.enumerable = PropertyDescriptor::Enabled;
argumentsAccessors[i] = pd;
}
}

View File

@ -109,7 +109,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
desc.type = PropertyDescriptor::Data;
desc.configurable = deletable ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled;
desc.writable = PropertyDescriptor::Enabled;
desc.enumberable = PropertyDescriptor::Enabled;
desc.enumerable = PropertyDescriptor::Enabled;
activation->__defineOwnProperty__(this, name, &desc);
}
@ -153,7 +153,7 @@ Value ExecutionContext::getBindingValue(ExecutionContext *scope, String *name, b
if (activation) {
bool hasProperty = false;
Value v = activation->__get__(scope, name, &hasProperty);
Value v = activation->get(scope, name, &hasProperty);
if (hasProperty)
return v;
}
@ -370,7 +370,7 @@ Value ExecutionContext::getProperty(String *name)
hasWith = true;
// qDebug() << ctx << "hasWith";
bool hasProperty = false;
Value v = w->__get__(ctx, name, &hasProperty);
Value v = w->get(ctx, name, &hasProperty);
if (hasProperty) {
// qDebug() << " withHasProp";
return v;
@ -396,7 +396,7 @@ Value ExecutionContext::getProperty(String *name)
}
if (ctx->activation) {
bool hasProperty = false;
Value v = ctx->activation->__get__(ctx, name, &hasProperty);
Value v = ctx->activation->get(ctx, name, &hasProperty);
if (hasProperty)
return v;
}
@ -418,7 +418,7 @@ Value ExecutionContext::getPropertyNoThrow(String *name)
if (Object *w = ctx->withObject) {
hasWith = true;
bool hasProperty = false;
Value v = w->__get__(ctx, name, &hasProperty);
Value v = w->get(ctx, name, &hasProperty);
if (hasProperty)
return v;
continue;
@ -442,7 +442,7 @@ Value ExecutionContext::getPropertyNoThrow(String *name)
}
if (ctx->activation) {
bool hasProperty = false;
Value v = ctx->activation->__get__(ctx, name, &hasProperty);
Value v = ctx->activation->get(ctx, name, &hasProperty);
if (hasProperty)
return v;
}
@ -464,7 +464,7 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
if (Object *w = ctx->withObject) {
hasWith = true;
bool hasProperty = false;
Value v = w->__get__(ctx, name, &hasProperty);
Value v = w->get(ctx, name, &hasProperty);
if (hasProperty) {
*base = w;
return v;
@ -490,7 +490,7 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
}
if (ctx->activation) {
bool hasProperty = false;
Value v = ctx->activation->__get__(ctx, name, &hasProperty);
Value v = ctx->activation->get(ctx, name, &hasProperty);
if (hasProperty)
return v;
}
@ -614,7 +614,7 @@ void ExecutionContext::wireUpPrototype()
{
assert(thisObject.isObject());
Value proto = function->__get__(this, engine->id_prototype);
Value proto = function->get(this, engine->id_prototype);
if (proto.isObject())
thisObject.objectValue()->prototype = proto.objectValue();
else

View File

@ -510,14 +510,14 @@ Value __qmljs_object_default_value(ExecutionContext *ctx, Value object, int type
assert(object.isObject());
Object *oo = object.objectValue();
Value conv = oo->__get__(ctx, meth1);
Value conv = oo->get(ctx, meth1);
if (FunctionObject *o = conv.asFunctionObject()) {
Value r = o->call(ctx, object, 0, 0);
if (r.isPrimitive())
return r;
}
conv = oo->__get__(ctx, meth2);
conv = oo->get(ctx, meth2);
if (FunctionObject *o = conv.asFunctionObject()) {
Value r = o->call(ctx, object, 0, 0);
if (r.isPrimitive())
@ -619,14 +619,14 @@ void __qmljs_get_element(ExecutionContext *ctx, Value *result, const Value &obje
return;
}
Value res = o->__get__(ctx, idx);
Value res = o->getIndexed(ctx, idx);
if (result)
*result = res;
return;
}
String *name = index.toString(ctx);
Value res = o->__get__(ctx, name);
Value res = o->get(ctx, name);
if (result)
*result = res;
}
@ -680,12 +680,12 @@ void __qmljs_get_property(ExecutionContext *ctx, Value *result, const Value &obj
Value res;
Object *o = object.asObject();
if (o) {
res = o->__get__(ctx, name);
res = o->get(ctx, name);
} else if (object.isString() && name->isEqualTo(ctx->engine->id_length)) {
res = Value::fromInt32(object.stringValue()->toQString().length());
} else {
o = __qmljs_convert_to_object(ctx, object);
res = o->__get__(ctx, name);
res = o->get(ctx, name);
}
if (result)
*result = res;
@ -731,13 +731,13 @@ void __qmljs_get_property_lookup(ExecutionContext *ctx, Value *result, const Val
if (p)
res = p->type == PropertyDescriptor::Data ? p->value : o->getValue(ctx, p);
else
res = o->__get__(ctx, l->name);
res = o->get(ctx, l->name);
} else {
if (object.isString() && l->name->isEqualTo(ctx->engine->id_length)) {
res = Value::fromInt32(object.stringValue()->toQString().length());
} else {
o = __qmljs_convert_to_object(ctx, object);
res = o->__get__(ctx, l->name);
res = o->get(ctx, l->name);
}
}
if (result)
@ -879,7 +879,7 @@ void __qmljs_call_property(ExecutionContext *context, Value *result, const Value
baseObject = thisObject.objectValue();
}
Value func = baseObject->__get__(context, name);
Value func = baseObject->get(context, name);
FunctionObject *o = func.asFunctionObject();
if (!o)
context->throwTypeError();
@ -936,7 +936,7 @@ void __qmljs_call_property_lookup(ExecutionContext *context, Value *result, cons
if (p)
func = p->type == PropertyDescriptor::Data ? p->value : baseObject->getValue(context, p);
else
func = baseObject->__get__(context, l->name);
func = baseObject->get(context, l->name);
FunctionObject *o = func.asFunctionObject();
if (!o)
@ -952,7 +952,7 @@ void __qmljs_call_element(ExecutionContext *context, Value *result, const Value
Object *baseObject = that.toObject(context);
Value thisObject = Value::fromObject(baseObject);
Value func = baseObject->__get__(context, index.toString(context));
Value func = baseObject->get(context, index.toString(context));
Object *o = func.asObject();
if (!o)
context->throwTypeError();
@ -994,7 +994,7 @@ void __qmljs_construct_property(ExecutionContext *context, Value *result, const
{
Object *thisObject = base.toObject(context);
Value func = thisObject->__get__(context, name);
Value func = thisObject->get(context, name);
if (Object *f = func.asObject()) {
Value res = f->construct(context, args, argc);
if (result)
@ -1056,7 +1056,7 @@ void __qmljs_builtin_typeof_member(ExecutionContext *context, Value *result, con
{
Object *obj = base.toObject(context);
Value res;
__qmljs_builtin_typeof(context, &res, obj->__get__(context, name));
__qmljs_builtin_typeof(context, &res, obj->get(context, name));
if (result)
*result = res;
}
@ -1066,7 +1066,7 @@ void __qmljs_builtin_typeof_element(ExecutionContext *context, Value *result, co
String *name = index.toString(context);
Object *obj = base.toObject(context);
Value res;
__qmljs_builtin_typeof(context, &res, obj->__get__(context, name));
__qmljs_builtin_typeof(context, &res, obj->get(context, name));
if (result)
*result = res;
}
@ -1108,7 +1108,7 @@ void __qmljs_builtin_post_increment_member(ExecutionContext *context, Value *res
{
Object *o = base.toObject(context);
Value v = o->__get__(context, name);
Value v = o->get(context, name);
if (v.isInteger() && v.integerValue() < INT_MAX) {
if (result)
@ -1135,7 +1135,7 @@ void __qmljs_builtin_post_increment_element(ExecutionContext *context, Value *re
return __qmljs_builtin_post_increment_member(context, result, base, s);
}
Value v = o->__get__(context, idx);
Value v = o->getIndexed(context, idx);
if (v.isInteger() && v.integerValue() < INT_MAX) {
if (result)
@ -1188,7 +1188,7 @@ void __qmljs_builtin_post_decrement_member(ExecutionContext *context, Value *res
{
Object *o = base.toObject(context);
Value v = o->__get__(context, name);
Value v = o->get(context, name);
if (v.isInteger() && v.integerValue() > INT_MIN) {
if (result)
@ -1215,7 +1215,7 @@ void __qmljs_builtin_post_decrement_element(ExecutionContext *context, Value *re
return __qmljs_builtin_post_decrement_member(context, result, base, s);
}
Value v = o->__get__(context, idx);
Value v = o->getIndexed(context, idx);
if (v.isInteger() && v.integerValue() > INT_MIN) {
if (result)
@ -1267,7 +1267,7 @@ void __qmljs_builtin_define_property(ExecutionContext *ctx, const Value &object,
pd->value = val ? *val : Value::undefinedValue();
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Enabled;
pd->enumerable = PropertyDescriptor::Enabled;
pd->configurable = PropertyDescriptor::Enabled;
}
@ -1285,13 +1285,13 @@ void __qmljs_builtin_define_array(ExecutionContext *ctx, Value *array, Value *va
pd->value = Value::undefinedValue();
pd->type = PropertyDescriptor::Generic;
pd->writable = PropertyDescriptor::Undefined;
pd->enumberable = PropertyDescriptor::Undefined;
pd->enumerable = PropertyDescriptor::Undefined;
pd->configurable = PropertyDescriptor::Undefined;
} else {
pd->value = values[i];
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Enabled;
pd->enumerable = PropertyDescriptor::Enabled;
pd->configurable = PropertyDescriptor::Enabled;
}
++pd;
@ -1313,7 +1313,7 @@ void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const Value &ob
pd->set = setter ? setter->asFunctionObject() : 0;
pd->type = PropertyDescriptor::Accessor;
pd->writable = PropertyDescriptor::Undefined;
pd->enumberable = PropertyDescriptor::Enabled;
pd->enumerable = PropertyDescriptor::Enabled;
pd->configurable = PropertyDescriptor::Enabled;
}

View File

@ -164,7 +164,7 @@ double Value::toInteger(double number)
Value Value::property(ExecutionContext *ctx, String *name) const
{
return isObject() ? objectValue()->__get__(ctx, name) : undefinedValue();
return isObject() ? objectValue()->get(ctx, name) : undefinedValue();
}
PersistentValue::PersistentValue()

View File

@ -65,7 +65,7 @@ ArgumentsObject::ArgumentsObject(ExecutionContext *context, int formalParameterC
FunctionObject *thrower = context->engine->newBuiltinFunction(context, 0, throwTypeError);
PropertyDescriptor pd = PropertyDescriptor::fromAccessor(thrower, thrower);
pd.configurable = PropertyDescriptor::Disabled;
pd.enumberable = PropertyDescriptor::Disabled;
pd.enumerable = PropertyDescriptor::Disabled;
__defineOwnProperty__(context, QStringLiteral("callee"), &pd);
__defineOwnProperty__(context, QStringLiteral("caller"), &pd);
} else {
@ -79,7 +79,7 @@ ArgumentsObject::ArgumentsObject(ExecutionContext *context, int formalParameterC
pd.type = PropertyDescriptor::Data;
pd.writable = PropertyDescriptor::Enabled;
pd.configurable = PropertyDescriptor::Enabled;
pd.enumberable = PropertyDescriptor::Enabled;
pd.enumerable = PropertyDescriptor::Enabled;
for (uint i = numAccessors; i < qMin((uint)actualParameterCount, context->argumentCount); ++i) {
pd.value = context->argument(i);
__defineOwnProperty__(context, i, &pd);
@ -107,7 +107,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->configurable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Enabled;
pd->enumerable = PropertyDescriptor::Enabled;
pd->value = mappedArguments.at(index);
}

View File

@ -115,7 +115,7 @@ uint ArrayPrototype::getLength(ExecutionContext *ctx, Object *o)
{
if (o->isArrayObject())
return o->arrayLength();
return o->__get__(ctx, ctx->engine->id_length).toUInt32(ctx);
return o->get(ctx, ctx->engine->id_length).toUInt32(ctx);
}
Value ArrayPrototype::method_isArray(ExecutionContext *ctx)
@ -189,7 +189,7 @@ Value ArrayPrototype::method_join(ExecutionContext *ctx)
if (i)
R += r4;
Value e = a->__get__(ctx, i);
Value e = a->getIndexed(ctx, i);
if (! (e.isUndefined() || e.isNull()))
R += e.toString(ctx)->toQString();
}
@ -227,7 +227,7 @@ Value ArrayPrototype::method_pop(ExecutionContext *ctx)
return Value::undefinedValue();
}
Value result = instance->__get__(ctx, len - 1);
Value result = instance->getIndexed(ctx, len - 1);
instance->__delete__(ctx, len - 1);
if (instance->isArrayObject())
@ -303,8 +303,8 @@ Value ArrayPrototype::method_reverse(ExecutionContext *ctx)
for (; lo < hi; ++lo, --hi) {
bool loExists, hiExists;
Value lval = instance->__get__(ctx, lo, &loExists);
Value hval = instance->__get__(ctx, hi, &hiExists);
Value lval = instance->getIndexed(ctx, lo, &loExists);
Value hval = instance->getIndexed(ctx, hi, &hiExists);
if (hiExists)
instance->__put__(ctx, lo, hval);
else
@ -364,7 +364,7 @@ Value ArrayPrototype::method_shift(ExecutionContext *ctx)
// do it the slow way
for (uint k = 1; k < len; ++k) {
bool exists;
Value v = instance->__get__(ctx, k, &exists);
Value v = instance->getIndexed(ctx, k, &exists);
if (exists)
instance->__put__(ctx, k - 1, v);
else
@ -385,7 +385,7 @@ Value ArrayPrototype::method_slice(ExecutionContext *ctx)
Object *o = ctx->thisObject.toObject(ctx);
ArrayObject *result = ctx->engine->newArrayObject(ctx);
uint len = o->__get__(ctx, ctx->engine->id_length).toUInt32(ctx);
uint len = o->get(ctx, ctx->engine->id_length).toUInt32(ctx);
double s = ctx->argument(0).toInteger(ctx);
uint start;
if (s < 0)
@ -408,7 +408,7 @@ Value ArrayPrototype::method_slice(ExecutionContext *ctx)
uint n = 0;
for (uint i = start; i < end; ++i) {
bool exists;
Value v = o->__get__(ctx, i, &exists);
Value v = o->getIndexed(ctx, i, &exists);
if (exists) {
result->arraySet(n, v);
}
@ -449,9 +449,9 @@ Value ArrayPrototype::method_splice(ExecutionContext *ctx)
for (uint i = 0; i < deleteCount; ++i) {
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Enabled;
pd->enumerable = PropertyDescriptor::Enabled;
pd->configurable = PropertyDescriptor::Enabled;
pd->value = instance->__get__(ctx, start + i);
pd->value = instance->getIndexed(ctx, start + i);
++pd;
}
newArray->arrayDataLen = deleteCount;
@ -462,7 +462,7 @@ Value ArrayPrototype::method_splice(ExecutionContext *ctx)
if (itemCount < deleteCount) {
for (uint k = start; k < len - deleteCount; ++k) {
bool exists;
Value v = instance->__get__(ctx, k + deleteCount, &exists);
Value v = instance->getIndexed(ctx, k + deleteCount, &exists);
if (exists)
instance->arraySet(k + itemCount, v);
else
@ -474,7 +474,7 @@ Value ArrayPrototype::method_splice(ExecutionContext *ctx)
uint k = len - deleteCount;
while (k > start) {
bool exists;
Value v = instance->__get__(ctx, k + deleteCount - 1, &exists);
Value v = instance->getIndexed(ctx, k + deleteCount - 1, &exists);
if (exists)
instance->arraySet(k + itemCount - 1, v);
else
@ -523,7 +523,7 @@ Value ArrayPrototype::method_unshift(ExecutionContext *ctx)
} else {
for (uint k = len; k > 0; --k) {
bool exists;
Value v = instance->__get__(ctx, k - 1, &exists);
Value v = instance->getIndexed(ctx, k - 1, &exists);
if (exists)
instance->__put__(ctx, k + ctx->argumentCount - 1, v);
else
@ -571,7 +571,7 @@ Value ArrayPrototype::method_indexOf(ExecutionContext *ctx)
if (instance->isStringObject()) {
for (uint k = fromIndex; k < len; ++k) {
bool exists;
Value v = instance->__get__(ctx, k, &exists);
Value v = instance->getIndexed(ctx, k, &exists);
if (exists && __qmljs_strict_equal(v, searchValue, ctx))
return Value::fromDouble(k);
}
@ -611,7 +611,7 @@ Value ArrayPrototype::method_lastIndexOf(ExecutionContext *ctx)
for (uint k = fromIndex; k > 0;) {
--k;
bool exists;
Value v = instance->__get__(ctx, k, &exists);
Value v = instance->getIndexed(ctx, k, &exists);
if (exists && __qmljs_strict_equal(v, searchValue, ctx))
return Value::fromDouble(k);
}
@ -633,7 +633,7 @@ Value ArrayPrototype::method_every(ExecutionContext *ctx)
bool ok = true;
for (uint k = 0; ok && k < len; ++k) {
bool exists;
Value v = instance->__get__(ctx, k, &exists);
Value v = instance->getIndexed(ctx, k, &exists);
if (!exists)
continue;
@ -661,7 +661,7 @@ Value ArrayPrototype::method_some(ExecutionContext *ctx)
for (uint k = 0; k < len; ++k) {
bool exists;
Value v = instance->__get__(ctx, k, &exists);
Value v = instance->getIndexed(ctx, k, &exists);
if (!exists)
continue;
@ -690,7 +690,7 @@ Value ArrayPrototype::method_forEach(ExecutionContext *ctx)
for (uint k = 0; k < len; ++k) {
bool exists;
Value v = instance->__get__(ctx, k, &exists);
Value v = instance->getIndexed(ctx, k, &exists);
if (!exists)
continue;
@ -721,7 +721,7 @@ Value ArrayPrototype::method_map(ExecutionContext *ctx)
for (uint k = 0; k < len; ++k) {
bool exists;
Value v = instance->__get__(ctx, k, &exists);
Value v = instance->getIndexed(ctx, k, &exists);
if (!exists)
continue;
@ -753,7 +753,7 @@ Value ArrayPrototype::method_filter(ExecutionContext *ctx)
uint to = 0;
for (uint k = 0; k < len; ++k) {
bool exists;
Value v = instance->__get__(ctx, k, &exists);
Value v = instance->getIndexed(ctx, k, &exists);
if (!exists)
continue;
@ -787,7 +787,7 @@ Value ArrayPrototype::method_reduce(ExecutionContext *ctx)
} else {
bool kPresent = false;
while (k < len && !kPresent) {
Value v = instance->__get__(ctx, k, &kPresent);
Value v = instance->getIndexed(ctx, k, &kPresent);
if (kPresent)
acc = v;
++k;
@ -798,7 +798,7 @@ Value ArrayPrototype::method_reduce(ExecutionContext *ctx)
while (k < len) {
bool kPresent;
Value v = instance->__get__(ctx, k, &kPresent);
Value v = instance->getIndexed(ctx, k, &kPresent);
if (kPresent) {
Value args[4];
args[0] = acc;
@ -835,7 +835,7 @@ Value ArrayPrototype::method_reduceRight(ExecutionContext *ctx)
} else {
bool kPresent = false;
while (k > 0 && !kPresent) {
Value v = instance->__get__(ctx, k - 1, &kPresent);
Value v = instance->getIndexed(ctx, k - 1, &kPresent);
if (kPresent)
acc = v;
--k;
@ -846,7 +846,7 @@ Value ArrayPrototype::method_reduceRight(ExecutionContext *ctx)
while (k > 0) {
bool kPresent;
Value v = instance->__get__(ctx, k - 1, &kPresent);
Value v = instance->getIndexed(ctx, k - 1, &kPresent);
if (kPresent) {
Value args[4];
args[0] = acc;

View File

@ -1307,7 +1307,7 @@ Value DatePrototype::method_toJSON(ExecutionContext *ctx)
if (tv.isNumber() && !isfinite(tv.toNumber(ctx)))
return Value::nullValue();
FunctionObject *toIso = O.objectValue()->__get__(ctx, ctx->engine->newString(QStringLiteral("toISOString"))).asFunctionObject();
FunctionObject *toIso = O.objectValue()->get(ctx, ctx->engine->newString(QStringLiteral("toISOString"))).asFunctionObject();
if (!toIso)
ctx->throwTypeError();

View File

@ -236,14 +236,14 @@ Value ErrorPrototype::method_toString(ExecutionContext *ctx)
if (!o)
ctx->throwTypeError();
Value name = o->__get__(ctx, ctx->engine->newString(QString::fromLatin1("name")));
Value name = o->get(ctx, ctx->engine->newString(QString::fromLatin1("name")));
QString qname;
if (name.isUndefined())
qname = QString::fromLatin1("Error");
else
qname = __qmljs_to_string(name, ctx).stringValue()->toQString();
Value message = o->__get__(ctx, ctx->engine->newString(QString::fromLatin1("message")));
Value message = o->get(ctx, ctx->engine->newString(QString::fromLatin1("message")));
QString qmessage;
if (!message.isUndefined())
qmessage = __qmljs_to_string(message, ctx).stringValue()->toQString();

View File

@ -113,7 +113,7 @@ bool FunctionObject::hasInstance(Managed *that, ExecutionContext *ctx, const Val
if (!v)
return false;
Object *o = f->__get__(ctx, ctx->engine->id_prototype).asObject();
Object *o = f->get(ctx, ctx->engine->id_prototype).asObject();
if (!o)
ctx->throwTypeError();
@ -134,7 +134,7 @@ Value FunctionObject::construct(Managed *that, ExecutionContext *context, Value
FunctionObject *f = static_cast<FunctionObject *>(that);
Object *obj = context->engine->newObject();
Value proto = f->__get__(context, context->engine->id_prototype);
Value proto = f->get(context, context->engine->id_prototype);
if (proto.isObject())
obj->prototype = proto.objectValue();
return Value::fromObject(obj);
@ -253,9 +253,9 @@ Value FunctionPrototype::method_apply(ExecutionContext *ctx)
QVector<Value> args;
if (Object *arr = arg.asObject()) {
quint32 len = arr->__get__(ctx, ctx->engine->id_length).toUInt32(ctx);
quint32 len = arr->get(ctx, ctx->engine->id_length).toUInt32(ctx);
for (quint32 i = 0; i < len; ++i) {
Value a = arr->__get__(ctx, i);
Value a = arr->getIndexed(ctx, i);
args.append(a);
}
} else if (!(arg.isUndefined() || arg.isNull())) {
@ -341,7 +341,7 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
PropertyDescriptor *pd = insertMember(scope->engine->id_prototype);
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Disabled;
pd->enumerable = PropertyDescriptor::Disabled;
pd->configurable = PropertyDescriptor::Disabled;
pd->value = Value::fromObject(proto);
@ -349,7 +349,7 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
FunctionObject *thrower = scope->engine->newBuiltinFunction(scope, 0, throwTypeError);
PropertyDescriptor pd = PropertyDescriptor::fromAccessor(thrower, thrower);
pd.configurable = PropertyDescriptor::Disabled;
pd.enumberable = PropertyDescriptor::Disabled;
pd.enumerable = PropertyDescriptor::Disabled;
__defineOwnProperty__(scope, QStringLiteral("caller"), &pd);
__defineOwnProperty__(scope, QStringLiteral("arguments"), &pd);
}
@ -360,7 +360,7 @@ Value ScriptFunction::construct(Managed *that, ExecutionContext *context, Value
ScriptFunction *f = static_cast<ScriptFunction *>(that);
assert(f->function->code);
Object *obj = context->engine->newObject();
Value proto = f->__get__(context, context->engine->id_prototype);
Value proto = f->get(context, context->engine->id_prototype);
if (proto.isObject())
obj->prototype = proto.objectValue();
@ -503,7 +503,7 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va
, boundArgs(boundArgs)
{
vtbl = &static_vtbl;
int len = target->__get__(scope, scope->engine->id_length).toUInt32(scope);
int len = target->get(scope, scope->engine->id_length).toUInt32(scope);
len -= boundArgs.size();
if (len < 0)
len = 0;
@ -512,7 +512,7 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va
FunctionObject *thrower = scope->engine->newBuiltinFunction(scope, 0, throwTypeError);
PropertyDescriptor pd = PropertyDescriptor::fromAccessor(thrower, thrower);
pd.configurable = PropertyDescriptor::Disabled;
pd.enumberable = PropertyDescriptor::Disabled;
pd.enumerable = PropertyDescriptor::Disabled;
*insertMember(scope->engine->id_arguments) = pd;
*insertMember(scope->engine->id_caller) = pd;
}

View File

@ -44,6 +44,18 @@ QT_BEGIN_NAMESPACE
# define Q_V4_EXPORT
#endif
namespace QQmlJS {
namespace VM {
enum PropertyFlags {
Writable = 0x1,
Enumerable = 0x2,
Configurable = 0x4
};
}
}
QT_END_NAMESPACE
#endif // QV4GLOBAL_H

View File

@ -284,7 +284,7 @@ bool Parser::parseMember(Object *o)
PropertyDescriptor *p = o->insertMember(context->engine->newIdentifier(key));
p->type = PropertyDescriptor::Data;
p->writable = PropertyDescriptor::Enabled;
p->enumberable = PropertyDescriptor::Enabled;
p->enumerable = PropertyDescriptor::Enabled;
p->configurable = PropertyDescriptor::Enabled;
p->value = val;
@ -705,7 +705,7 @@ QString Stringify::Str(const QString &key, Value value)
QString result;
if (Object *o = value.asObject()) {
FunctionObject *toJSON = o->__get__(ctx, ctx->engine->newString(QStringLiteral("toJSON"))).asFunctionObject();
FunctionObject *toJSON = o->get(ctx, ctx->engine->newString(QStringLiteral("toJSON"))).asFunctionObject();
if (toJSON) {
Value arg = Value::fromString(ctx, key);
value = toJSON->call(ctx, value, &arg, 1);
@ -801,7 +801,7 @@ QString Stringify::JO(Object *o)
} else {
for (int i = 0; i < propertyList.size(); ++i) {
bool exists;
Value v = o->__get__(ctx, propertyList.at(i), &exists);
Value v = o->get(ctx, propertyList.at(i), &exists);
if (!exists)
continue;
QString member = makeMember(propertyList.at(i)->toQString(), v);
@ -838,7 +838,7 @@ QString Stringify::JA(ArrayObject *a)
uint len = a->arrayLength();
for (uint i = 0; i < len; ++i) {
bool exists;
Value v = a->__get__(ctx, i, &exists);
Value v = a->getIndexed(ctx, i, &exists);
if (!exists) {
partial += QStringLiteral("null");
continue;
@ -902,7 +902,7 @@ Value JsonObject::method_stringify(ExecutionContext *ctx)
if (o->isArrayObject()) {
uint arrayLen = o->arrayLength();
for (uint i = 0; i < arrayLen; ++i) {
Value v = o->__get__(ctx, i);
Value v = o->getIndexed(ctx, i);
if (v.asNumberObject() || v.asStringObject() || v.isNumber())
v = __qmljs_to_string(v, ctx);
if (v.isString()) {

View File

@ -52,6 +52,14 @@ const ManagedVTable Managed::static_vtbl =
0 /*markObjects*/,
destroy,
hasInstance,
0,
0,
0,
0,
0,
0,
0,
0,
"Managed",
};
@ -165,3 +173,13 @@ Value Managed::call(Managed *, ExecutionContext *context, const Value &, Value *
{
context->throwTypeError();
}
Value Managed::get(ExecutionContext *ctx, String *name, bool *hasProperty)
{
return vtbl->get(this, ctx, name, hasProperty);
}
Value Managed::getIndexed(ExecutionContext *ctx, uint index, bool *hasProperty)
{
return vtbl->getIndexed(this, ctx, index, hasProperty);
}

View File

@ -72,7 +72,6 @@ struct ForeachIteratorObject;
struct Managed;
struct Value;
struct ManagedVTable
{
Value (*call)(Managed *, ExecutionContext *context, const Value &thisObject, Value *args, int argc);
@ -80,6 +79,14 @@ struct ManagedVTable
void (*markObjects)(Managed *);
void (*destroy)(Managed *);
bool (*hasInstance)(Managed *, ExecutionContext *ctx, const Value &value);
Value (*get)(Managed *, ExecutionContext *ctx, String *name, bool *hasProperty);
Value (*getIndexed)(Managed *, ExecutionContext *ctx, uint index, bool *hasProperty);
void (*put)(Managed *, ExecutionContext *ctx, String *name, const Value &value);
void (*putIndexed)(Managed *, ExecutionContext *ctx, uint index, const Value &value);
PropertyFlags (*query)(Managed *, ExecutionContext *ctx, String *name);
PropertyFlags (*queryIndexed)(Managed *, ExecutionContext *ctx, uint index);
bool (*deleteProperty)(Managed *m, ExecutionContext *ctx, String *name);
bool (*deleteIndexedProperty)(Managed *m, ExecutionContext *ctx, uint index);
const char *className;
};
@ -91,6 +98,14 @@ const ManagedVTable classname::static_vtbl = \
markObjects, \
destroy, \
hasInstance, \
get, \
getIndexed, \
put, \
putIndexed, \
query, \
queryIndexed, \
deleteProperty, \
deleteIndexedProperty, \
#classname \
}
@ -170,8 +185,10 @@ public:
inline bool hasInstance(ExecutionContext *ctx, const Value &v) {
return vtbl->hasInstance(this, ctx, v);
}
inline Value construct(ExecutionContext *context, Value *args, int argc);
inline Value call(ExecutionContext *context, const Value &thisObject, Value *args, int argc);
Value construct(ExecutionContext *context, Value *args, int argc);
Value call(ExecutionContext *context, const Value &thisObject, Value *args, int argc);
Value get(ExecutionContext *ctx, String *name, bool *hasProperty = 0);
Value getIndexed(ExecutionContext *ctx, uint index, bool *hasProperty = 0);
static void destroy(Managed *that) { that->_data = 0; }
static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value &value);

View File

@ -115,6 +115,18 @@ Value Object::getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p
return getValue(ctx, p);
}
Value Object::getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p, const Value &thisObject) const
{
if (!p || p->type == PropertyDescriptor::Generic)
return Value::undefinedValue();
if (p->isData())
return p->value;
if (!p->get)
return Value::undefinedValue();
return p->get->call(ctx, thisObject, 0, 0);
}
Value Object::getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p, bool *exists) const
{
*exists = p && p->type != PropertyDescriptor::Generic;
@ -150,7 +162,7 @@ void Object::putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value
void Object::inplaceBinOp(ExecutionContext *ctx, BinOp op, String *name, const Value &rhs)
{
bool hasProperty = false;
Value v = __get__(ctx, name, &hasProperty);
Value v = get(ctx, name, &hasProperty);
Value result;
op(ctx, &result, v, rhs);
__put__(ctx, name, result);
@ -161,7 +173,7 @@ void Object::inplaceBinOp(ExecutionContext *ctx, BinOp op, const Value &index, c
uint idx = index.asArrayIndex();
if (idx < UINT_MAX) {
bool hasProperty = false;
Value v = __get__(ctx, idx, &hasProperty);
Value v = getIndexed(ctx, idx, &hasProperty);
Value result;
op(ctx, &result, v, rhs);
__put__(ctx, idx, result);
@ -177,7 +189,7 @@ void Object::defineDefaultProperty(String *name, Value value)
PropertyDescriptor *pd = insertMember(name);
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Disabled;
pd->enumerable = PropertyDescriptor::Disabled;
pd->configurable = PropertyDescriptor::Enabled;
pd->value = value;
}
@ -215,7 +227,7 @@ void Object::defineReadonlyProperty(String *name, Value value)
PropertyDescriptor *pd = insertMember(name);
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Disabled;
pd->enumberable = PropertyDescriptor::Disabled;
pd->enumerable = PropertyDescriptor::Disabled;
pd->configurable = PropertyDescriptor::Disabled;
pd->value = value;
}
@ -317,11 +329,11 @@ PropertyDescriptor *Object::__getPropertyDescriptor__(const ExecutionContext *ct
}
// Section 8.12.3
Value Object::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
Value Object::get(ExecutionContext *ctx, String *name, bool *hasProperty)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
return __get__(ctx, idx, hasProperty);
return getIndexed(ctx, idx, hasProperty);
name->makeIdentifier(ctx);
@ -348,7 +360,7 @@ Value Object::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
return Value::undefinedValue();
}
Value Object::__get__(ExecutionContext *ctx, uint index, bool *hasProperty)
Value Object::getIndexed(ExecutionContext *ctx, uint index, bool *hasProperty)
{
PropertyDescriptor *pd = 0;
Object *o = this;
@ -452,7 +464,7 @@ void Object::__put__(ExecutionContext *ctx, String *name, const Value &value)
p->type = PropertyDescriptor::Data;
p->value = value;
p->configurable = PropertyDescriptor::Enabled;
p->enumberable = PropertyDescriptor::Enabled;
p->enumerable = PropertyDescriptor::Enabled;
p->writable = PropertyDescriptor::Enabled;
return;
}
@ -673,7 +685,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *cu
if (!current->isConfigurable()) {
if (desc->isConfigurable())
goto reject;
if (desc->enumberable != PropertyDescriptor::Undefined && desc->enumberable != current->enumberable)
if (desc->enumerable != PropertyDescriptor::Undefined && desc->enumerable != current->enumerable)
goto reject;
}
@ -757,7 +769,7 @@ Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionCont
// lets be safe and slow
for (uint i = fromIndex; i < endIndex; ++i) {
bool exists;
Value value = o->__get__(ctx, i, &exists);
Value value = o->getIndexed(ctx, i, &exists);
if (exists && __qmljs_strict_equal(value, v, ctx))
return Value::fromDouble(i);
}
@ -981,7 +993,7 @@ void ArrayObject::init(ExecutionContext *context)
PropertyDescriptor *pd = memberData + LengthPropertyIndex;
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Disabled;
pd->enumerable = PropertyDescriptor::Disabled;
pd->configurable = PropertyDescriptor::Disabled;
pd->value = Value::fromInt32(0);
}

View File

@ -129,12 +129,11 @@ struct Q_V4_EXPORT Object: Managed {
PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, String *name);
PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, uint index);
// -> vtable
PropertyDescriptor *__getPropertyDescriptor__(const ExecutionContext *ctx, String *name) const;
PropertyDescriptor *__getPropertyDescriptor__(const ExecutionContext *ctx, uint index) const;
Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty = 0);
Value __get__(ExecutionContext *ctx, uint index, bool *hasProperty = 0);
Value get(ExecutionContext *ctx, String *name, bool *hasProperty = 0);
Value getIndexed(ExecutionContext *ctx, uint index, bool *hasProperty = 0);
// -> vtable
void __put__(ExecutionContext *ctx, String *name, const Value &value);
@ -148,6 +147,8 @@ struct Q_V4_EXPORT Object: Managed {
PropertyDescriptor *pd = __getPropertyDescriptor__(ctx, index);
return pd && pd->type != PropertyDescriptor::Generic;
}
// -> vtable
bool __delete__(ExecutionContext *ctx, String *name);
bool __delete__(ExecutionContext *ctx, uint index);
bool __defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *current, const PropertyDescriptor *desc);
@ -162,6 +163,7 @@ struct Q_V4_EXPORT Object: Managed {
Value getValue(ExecutionContext *ctx, const PropertyDescriptor *p) const;
Value getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p) const;
Value getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p, const Value &thisObject) const;
Value getValueChecked(ExecutionContext *ctx, const PropertyDescriptor *p, bool *exists) const;
void putValue(ExecutionContext *ctx, PropertyDescriptor *pd, const Value &value);
@ -186,7 +188,7 @@ struct Q_V4_EXPORT Object: Managed {
{
pd->type = PropertyDescriptor::Data;
pd->writable = PropertyDescriptor::Enabled;
pd->enumberable = PropertyDescriptor::Enabled;
pd->enumerable = PropertyDescriptor::Enabled;
pd->configurable = PropertyDescriptor::Enabled;
pd->value = v;
}
@ -323,6 +325,22 @@ protected:
static const ManagedVTable static_vtbl;
static void destroy(Managed *that);
static void markObjects(Managed *that);
static Value get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty)
{ return static_cast<Object *>(m)->get(ctx, name, hasProperty); }
static Value getIndexed(Managed *m, ExecutionContext *ctx, uint index, bool *hasProperty)
{ return static_cast<Object *>(m)->getIndexed(ctx, index, hasProperty); }
static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value)
{ static_cast<Object *>(m)->__put__(ctx, name, value); }
static void putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Value &value)
{ static_cast<Object *>(m)->__put__(ctx, index, value); }
static PropertyFlags query(Managed *m, ExecutionContext *ctx, String *name)
{ return PropertyFlags(0); /* ### */ }
static PropertyFlags queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
{ return PropertyFlags(0); /* ### */ }
static bool deleteProperty(Managed *m, ExecutionContext *ctx, String *name)
{ return static_cast<Object *>(m)->__delete__(ctx, name); }
static bool deleteIndexedProperty(Managed *m, ExecutionContext *ctx, uint index)
{ return static_cast<Object *>(m)->__delete__(ctx, index); }
friend struct ObjectIterator;
friend struct ObjectPrototype;

View File

@ -84,7 +84,7 @@ Value ObjectCtor::construct(Managed *that, ExecutionContext *ctx, Value *args, i
ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
if (!argc || args[0].isUndefined() || args[0].isNull()) {
Object *obj = ctx->engine->newObject();
Value proto = ctor->__get__(ctx, ctx->engine->id_prototype);
Value proto = ctor->get(ctx, ctx->engine->id_prototype);
if (proto.isObject())
obj->prototype = proto.objectValue();
return Value::fromObject(obj);
@ -381,7 +381,7 @@ Value ObjectPrototype::method_toString(ExecutionContext *ctx)
Value ObjectPrototype::method_toLocaleString(ExecutionContext *ctx)
{
Object *o = ctx->thisObject.toObject(ctx);
Value ts = o->__get__(ctx, ctx->engine->newString(QStringLiteral("toString")));
Value ts = o->get(ctx, ctx->engine->newString(QStringLiteral("toString")));
FunctionObject *f = ts.asFunctionObject();
if (!f)
ctx->throwTypeError();
@ -440,7 +440,7 @@ Value ObjectPrototype::method_defineGetter(ExecutionContext *ctx)
PropertyDescriptor pd = PropertyDescriptor::fromAccessor(f, 0);
pd.configurable = PropertyDescriptor::Enabled;
pd.enumberable = PropertyDescriptor::Enabled;
pd.enumerable = PropertyDescriptor::Enabled;
o->__defineOwnProperty__(ctx, prop, &pd);
return Value::undefinedValue();
}
@ -459,7 +459,7 @@ Value ObjectPrototype::method_defineSetter(ExecutionContext *ctx)
PropertyDescriptor pd = PropertyDescriptor::fromAccessor(0, f);
pd.configurable = PropertyDescriptor::Enabled;
pd.enumberable = PropertyDescriptor::Enabled;
pd.enumerable = PropertyDescriptor::Enabled;
o->__defineOwnProperty__(ctx, prop, &pd);
return Value::undefinedValue();
}
@ -473,17 +473,17 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
desc->type = PropertyDescriptor::Generic;
desc->enumberable = PropertyDescriptor::Undefined;
desc->enumerable = PropertyDescriptor::Undefined;
if (o->__hasProperty__(ctx, ctx->engine->id_enumerable))
desc->enumberable = o->__get__(ctx, ctx->engine->id_enumerable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled;
desc->enumerable = o->get(ctx, ctx->engine->id_enumerable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled;
desc->configurable = PropertyDescriptor::Undefined;
if (o->__hasProperty__(ctx, ctx->engine->id_configurable))
desc->configurable = o->__get__(ctx, ctx->engine->id_configurable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled;
desc->configurable = o->get(ctx, ctx->engine->id_configurable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled;
desc->get = 0;
if (o->__hasProperty__(ctx, ctx->engine->id_get)) {
Value get = o->__get__(ctx, ctx->engine->id_get);
Value get = o->get(ctx, ctx->engine->id_get);
FunctionObject *f = get.asFunctionObject();
if (f) {
desc->get = f;
@ -497,7 +497,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
desc->set = 0;
if (o->__hasProperty__(ctx, ctx->engine->id_set)) {
Value set = o->__get__(ctx, ctx->engine->id_set);
Value set = o->get(ctx, ctx->engine->id_set);
FunctionObject *f = set.asFunctionObject();
if (f) {
desc->set = f;
@ -513,7 +513,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (o->__hasProperty__(ctx, ctx->engine->id_writable)) {
if (desc->isAccessor())
ctx->throwTypeError();
desc->writable = o->__get__(ctx, ctx->engine->id_writable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled;
desc->writable = o->get(ctx, ctx->engine->id_writable).toBoolean() ? PropertyDescriptor::Enabled : PropertyDescriptor::Disabled;
// writable forces it to be a data descriptor
desc->value = Value::undefinedValue();
}
@ -521,7 +521,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (o->__hasProperty__(ctx, ctx->engine->id_value)) {
if (desc->isAccessor())
ctx->throwTypeError();
desc->value = o->__get__(ctx, ctx->engine->id_value);
desc->value = o->get(ctx, ctx->engine->id_value);
desc->type = PropertyDescriptor::Data;
}
@ -540,7 +540,7 @@ Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Prope
PropertyDescriptor pd;
pd.type = PropertyDescriptor::Data;
pd.writable = PropertyDescriptor::Enabled;
pd.enumberable = PropertyDescriptor::Enabled;
pd.enumerable = PropertyDescriptor::Enabled;
pd.configurable = PropertyDescriptor::Enabled;
if (desc->isData()) {
@ -554,7 +554,7 @@ Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Prope
pd.value = desc->set ? Value::fromObject(desc->set) : Value::undefinedValue();
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("set")), &pd);
}
pd.value = Value::fromBoolean(desc->enumberable == PropertyDescriptor::Enabled ? true : false);
pd.value = Value::fromBoolean(desc->enumerable == PropertyDescriptor::Enabled ? true : false);
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("enumerable")), &pd);
pd.value = Value::fromBoolean(desc->configurable == PropertyDescriptor::Enabled ? true : false);
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("configurable")), &pd);

View File

@ -41,6 +41,7 @@
#ifndef QV4PROPERTYDESCRIPTOR_H
#define QV4PROPERTYDESCRIPTOR_H
#include "qv4global.h"
#include "qmljs_value.h"
QT_BEGIN_NAMESPACE
@ -70,15 +71,26 @@ struct PropertyDescriptor {
};
uint type : 8;
uint writable : 8;
uint enumberable : 8;
uint enumerable : 8;
uint configurable : 8;
PropertyFlags propertyFlags() {
int f = 0;
if (writable == Enabled)
f |= Writable;
if (configurable == Enabled)
f |= Configurable;
if (enumerable == Enabled)
f |= Enumerable;
return PropertyFlags(f);
}
static inline PropertyDescriptor fromValue(Value v) {
PropertyDescriptor pd;
pd.value = v;
pd.type = Data;
pd.writable = Undefined;
pd.enumberable = Undefined;
pd.enumerable = Undefined;
pd.configurable = Undefined;
return pd;
}
@ -88,7 +100,7 @@ struct PropertyDescriptor {
pd.set = setter;
pd.type = Accessor;
pd.writable = Undefined;
pd.enumberable = Undefined;
pd.enumerable = Undefined;
pd.configurable = Undefined;
return pd;
}
@ -109,8 +121,8 @@ struct PropertyDescriptor {
if ((quintptr)set == 0x1)
set = 0;
}
if (enumberable == Undefined)
enumberable = Disabled;
if (enumerable == Undefined)
enumerable = Disabled;
if (configurable == Undefined)
configurable = Disabled;
}
@ -120,16 +132,16 @@ struct PropertyDescriptor {
inline bool isGeneric() const { return type == Generic && writable == Undefined; }
inline bool isWritable() const { return writable == Enabled; }
inline bool isEnumerable() const { return enumberable == Enabled; }
inline bool isEnumerable() const { return enumerable == Enabled; }
inline bool isConfigurable() const { return configurable == Enabled; }
inline bool isEmpty() const {
return type == Generic && writable == Undefined && enumberable == Undefined && configurable == Undefined;
return type == Generic && writable == Undefined && enumerable == Undefined && configurable == Undefined;
}
inline bool isSubset(PropertyDescriptor *other) const {
if (type != Generic && type != other->type)
return false;
if (enumberable != Undefined && enumberable != other->enumberable)
if (enumerable != Undefined && enumerable != other->enumerable)
return false;
if (configurable != Undefined && configurable != other->configurable)
return false;
@ -146,8 +158,8 @@ struct PropertyDescriptor {
return true;
}
inline void operator+=(const PropertyDescriptor &other) {
if (other.enumberable != Undefined)
enumberable = other.enumberable;
if (other.enumerable != Undefined)
enumerable = other.enumerable;
if (other.configurable != Undefined)
configurable = other.configurable;
if (other.writable != Undefined)

View File

@ -75,7 +75,7 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, PassRefPtr<RegExp> value, bo
PropertyDescriptor *lastIndexProperty = insertMember(engine->newIdentifier(QStringLiteral("lastIndex")));
lastIndexProperty->type = PropertyDescriptor::Data;
lastIndexProperty->writable = PropertyDescriptor::Enabled;
lastIndexProperty->enumberable = PropertyDescriptor::Disabled;
lastIndexProperty->enumerable = PropertyDescriptor::Disabled;
lastIndexProperty->configurable = PropertyDescriptor::Disabled;
lastIndexProperty->value = Value::fromInt32(0);
if (!this->value.get())

View File

@ -42,6 +42,7 @@
#include "qv4string.h"
#include "qv4identifier.h"
#include "qmljs_runtime.h"
#include "qv4objectproto.h"
#include <QtCore/QHash>
namespace QQmlJS {
@ -80,6 +81,14 @@ const ManagedVTable String::static_vtbl =
0 /*markObjects*/,
destroy,
hasInstance,
get,
getIndexed,
put,
putIndexed,
query,
queryIndexed,
deleteProperty,
deleteIndexedProperty,
"String",
};
@ -88,6 +97,59 @@ void String::destroy(Managed *that)
static_cast<String*>(that)->~String();
}
Value String::get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty)
{
String *that = static_cast<String *>(m);
if (name == ctx->engine->id_length)
return Value::fromInt32(that->_text.length());
PropertyDescriptor *pd = ctx->engine->objectPrototype->__getPropertyDescriptor__(ctx, name);
return ctx->engine->objectPrototype->getValueChecked(ctx, pd, Value::fromString(that));
}
Value String::getIndexed(Managed *m, ExecutionContext *ctx, uint index, bool *hasProperty)
{
String *that = static_cast<String *>(m);
if (index < that->_text.length()) {
if (hasProperty)
*hasProperty = true;
return Value::fromString(ctx, that->toQString().mid(index, 1));
}
if (hasProperty)
*hasProperty = false;
return Value::undefinedValue();
}
void String::put(Managed *m, ExecutionContext *ctx, String *name, const Value &value)
{
/* ### */
}
void String::putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Value &value)
{
/* ### */
}
PropertyFlags String::query(Managed *m, ExecutionContext *ctx, String *name)
{
return PropertyFlags(0);
}
PropertyFlags String::queryIndexed(Managed *m, ExecutionContext *ctx, uint index)
{
String *that = static_cast<String *>(m);
return (index < that->_text.length()) ? PropertyFlags(Enumerable) : PropertyFlags(0);
}
bool String::deleteProperty(Managed *m, ExecutionContext *ctx, String *name)
{
return false;
}
bool String::deleteIndexedProperty(Managed *m, ExecutionContext *ctx, uint index)
{
return false;
}
uint String::toUInt(bool *ok) const
{
*ok = true;

View File

@ -112,6 +112,15 @@ struct String : public Managed {
protected:
static void destroy(Managed *);
static Value get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty);
static Value getIndexed(Managed *m, ExecutionContext *ctx, uint index, bool *hasProperty);
static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value);
static void putIndexed(Managed *m, ExecutionContext *ctx, uint index, const Value &value);
static PropertyFlags query(Managed *m, ExecutionContext *ctx, String *name);
static PropertyFlags queryIndexed(Managed *m, ExecutionContext *ctx, uint index);
static bool deleteProperty(Managed *m, ExecutionContext *ctx, String *name);
static bool deleteIndexedProperty(Managed *m, ExecutionContext *ctx, uint index);
static const ManagedVTable static_vtbl;
};

View File

@ -84,7 +84,7 @@ StringObject::StringObject(ExecutionContext *ctx, const Value &value)
type = Type_StringObject;
tmpProperty.type = PropertyDescriptor::Data;
tmpProperty.enumberable = PropertyDescriptor::Enabled;
tmpProperty.enumerable = PropertyDescriptor::Enabled;
tmpProperty.writable = PropertyDescriptor::Disabled;
tmpProperty.configurable = PropertyDescriptor::Disabled;
tmpProperty.value = Value::undefinedValue();
@ -318,7 +318,7 @@ Value StringPrototype::method_match(ExecutionContext *parentCtx, Value thisObjec
bool global = rx->global;
// ### use the standard builtin function, not the one that might be redefined in the proto
FunctionObject *exec = parentCtx->engine->regExpPrototype->__get__(parentCtx, parentCtx->engine->newString(QStringLiteral("exec")), 0).asFunctionObject();
FunctionObject *exec = parentCtx->engine->regExpPrototype->get(parentCtx, parentCtx->engine->newString(QStringLiteral("exec")), 0).asFunctionObject();
Value arg = Value::fromString(s);
if (!global)
@ -335,14 +335,14 @@ Value StringPrototype::method_match(ExecutionContext *parentCtx, Value thisObjec
if (result.isNull())
break;
assert(result.isObject());
double thisIndex = rx->__get__(parentCtx, lastIndex, 0).toInteger(parentCtx);
double thisIndex = rx->get(parentCtx, lastIndex, 0).toInteger(parentCtx);
if (previousLastIndex == thisIndex) {
previousLastIndex = thisIndex + 1;
rx->__put__(parentCtx, lastIndex, Value::fromDouble(previousLastIndex));
} else {
previousLastIndex = thisIndex;
}
Value matchStr = result.objectValue()->__get__(parentCtx, (uint)0, (bool *)0);
Value matchStr = result.objectValue()->getIndexed(parentCtx, 0, (bool *)0);
a->arraySet(n, matchStr);
++n;
}

View File

@ -658,7 +658,7 @@ Local<Value> Object::Get(Handle<Value> key)
QQmlJS::VM::Object *o = ConstValuePtr(this)->asObject();
assert(o);
QQmlJS::VM::ExecutionContext *ctx = currentEngine()->current;
QQmlJS::VM::Value prop = o->__get__(ctx, ValuePtr(&key)->toString(ctx));
QQmlJS::VM::Value prop = o->get(ctx, ValuePtr(&key)->toString(ctx));
return Local<Value>::New(Value::fromVmValue(prop));
}
@ -667,7 +667,7 @@ Local<Value> Object::Get(uint32_t key)
QQmlJS::VM::Object *o = ConstValuePtr(this)->asObject();
assert(o);
QQmlJS::VM::ExecutionContext *ctx = currentEngine()->current;
QQmlJS::VM::Value prop = o->__get__(ctx, key);
QQmlJS::VM::Value prop = o->getIndexed(ctx, key);
return Local<Value>::New(Value::fromVmValue(prop));
}

View File

@ -135,7 +135,7 @@ static void showException(QQmlJS::VM::ExecutionContext *ctx, const QQmlJS::VM::V
std::cerr << qPrintable(msg->buildFullMessage(ctx)->toQString()) << std::endl;
}
} else {
std::cerr << "Uncaught exception: " << qPrintable(e->__get__(ctx, ctx->engine->newString(QStringLiteral("message")), 0).toString(ctx)->toQString()) << std::endl;
std::cerr << "Uncaught exception: " << qPrintable(e->get(ctx, ctx->engine->newString(QStringLiteral("message")), 0).toString(ctx)->toQString()) << std::endl;
}
}