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:
parent
d9f1831917
commit
1196824e7a
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue