if (__qmljs_string_equal(formals()[i], name))
return arguments[i];
}
- if (activation && activation->__hasProperty__(this, name))
- return activation->__get__(scope, name);
+ if (activation) {
+ bool hasProperty = false;
+ Value v = activation->__get__(scope, name, &hasProperty);
+ if (hasProperty)
+ return v;
+ }
assert(false);
}
if (ctx->withObject) {
With *w = ctx->withObject;
while (w) {
- if (w->object->__hasProperty__(ctx, name))
- return w->object->__get__(ctx, name);
+ bool hasProperty = false;
+ Value v = w->object->__get__(ctx, name, &hasProperty);
+ if (hasProperty)
+ return v;
w = w->next;
}
}
for (unsigned int i = 0; i < ctx->formalCount(); ++i)
if (__qmljs_string_equal(ctx->formals()[i], name))
return ctx->arguments[i];
- if (ctx->activation && ctx->activation->__hasProperty__(ctx, name))
- return ctx->activation->__get__(ctx, name);
+ if (ctx->activation) {
+ bool hasProperty = false;
+ Value v = ctx->activation->__get__(ctx, name, &hasProperty);
+ if (hasProperty)
+ return v;
+ }
if (name->isEqualTo(ctx->engine->id_arguments)) {
Value arguments = Value::fromObject(new (engine->memoryManager) ArgumentsObject(this));
createMutableBinding(ctx->engine->id_arguments, false);
if (ctx->withObject) {
With *w = ctx->withObject;
while (w) {
- if (w->object->__hasProperty__(ctx, name))
- return w->object->__get__(ctx, name);
+ bool hasProperty = false;
+ Value v = w->object->__get__(ctx, name, &hasProperty);
+ if (hasProperty)
+ return v;
w = w->next;
}
}
for (unsigned int i = 0; i < ctx->formalCount(); ++i)
if (__qmljs_string_equal(ctx->formals()[i], name))
return ctx->arguments[i];
- if (ctx->activation && ctx->activation->__hasProperty__(ctx, name))
- return ctx->activation->__get__(ctx, name);
+ if (ctx->activation) {
+ bool hasProperty = false;
+ Value v = ctx->activation->__get__(ctx, name, &hasProperty);
+ if (hasProperty)
+ return v;
+ }
if (name->isEqualTo(ctx->engine->id_arguments)) {
Value arguments = Value::fromObject(new (engine->memoryManager) ArgumentsObject(this));
createMutableBinding(ctx->engine->id_arguments, false);
// Section 8.12.2
PropertyDescriptor *Object::__getPropertyDescriptor__(ExecutionContext *ctx, String *name, PropertyDescriptor *to_fill)
{
- if (PropertyDescriptor *p = __getOwnProperty__(ctx, name))
- return p;
+ if (members)
+ if (PropertyDescriptor *p = members->find(name))
+ return p;
if (prototype)
return prototype->__getPropertyDescriptor__(ctx, name, to_fill);
}
// Section 8.12.3
-Value Object::__get__(ExecutionContext *ctx, String *name)
+Value Object::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
{
- if (name->isEqualTo(ctx->engine->id___proto__))
+ if (name->isEqualTo(ctx->engine->id___proto__)) {
+ if (hasProperty)
+ *hasProperty = true;
return Value::fromObject(prototype);
+ }
PropertyDescriptor tmp;
- if (PropertyDescriptor *p = __getPropertyDescriptor__(ctx, name, &tmp))
+ if (PropertyDescriptor *p = __getPropertyDescriptor__(ctx, name, &tmp)) {
+ if (hasProperty)
+ *hasProperty = true;
return getValue(ctx, p);
+ }
+ if (hasProperty)
+ *hasProperty = false;
return Value::undefinedValue();
}
objects.append(current);
}
-Value ArrayObject::__get__(ExecutionContext *ctx, String *name)
+Value ArrayObject::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
{
- if (name->isEqualTo(ctx->engine->id_length))
+ if (name->isEqualTo(ctx->engine->id_length)) {
+ if (hasProperty)
+ *hasProperty = true;
return Value::fromDouble(value.size());
- return Object::__get__(ctx, name);
+ }
+ return Object::__get__(ctx, name, hasProperty);
}
bool ArrayObject::inplaceBinOp(Value rhs, Value index, BinOp op, ExecutionContext *ctx)
}
-Value RegExpObject::__get__(ExecutionContext *ctx, String *name)
+Value RegExpObject::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
{
QString n = name->toQString();
+ Value v = Value::undefinedValue();
if (n == QLatin1String("source"))
- return Value::fromString(ctx, value.pattern());
+ v = Value::fromString(ctx, value.pattern());
else if (n == QLatin1String("global"))
- return Value::fromBoolean(global);
+ v = Value::fromBoolean(global);
else if (n == QLatin1String("ignoreCase"))
- return Value::fromBoolean(value.patternOptions() & QRegularExpression::CaseInsensitiveOption);
+ v = Value::fromBoolean(value.patternOptions() & QRegularExpression::CaseInsensitiveOption);
else if (n == QLatin1String("multiline"))
- return Value::fromBoolean(value.patternOptions() & QRegularExpression::MultilineOption);
+ v = Value::fromBoolean(value.patternOptions() & QRegularExpression::MultilineOption);
else if (n == QLatin1String("lastIndex"))
- return lastIndex;
- return Object::__get__(ctx, name);
+ v = lastIndex;
+ if (v.type() != Value::Undefined_Type) {
+ if (hasProperty)
+ *hasProperty = true;
+ return v;
+ }
+
+ return Object::__get__(ctx, name, hasProperty);
}
-Value ErrorObject::__get__(ExecutionContext *ctx, String *name)
+Value ErrorObject::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
{
QString n = name->toQString();
- if (n == QLatin1String("message"))
+ if (n == QLatin1String("message")) {
+ if (hasProperty)
+ *hasProperty = true;
return value;
- return Object::__get__(ctx, name);
+ }
+ return Object::__get__(ctx, name, hasProperty);
}
void ErrorObject::setNameProperty(ExecutionContext *ctx)
return ctx->thisObject;
}
-Value ArgumentsObject::__get__(ExecutionContext *ctx, String *name)
+Value ArgumentsObject::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
{
- if (name->isEqualTo(ctx->engine->id_length))
+ if (name->isEqualTo(ctx->engine->id_length)) {
+ if (hasProperty)
+ *hasProperty = true;
return Value::fromInt32(context->argumentCount);
- return Object::__get__(ctx, name);
+ }
+ return Object::__get__(ctx, name, hasProperty);
}
PropertyDescriptor *ArgumentsObject::__getPropertyDescriptor__(ExecutionContext *ctx, String *name, PropertyDescriptor *to_fill)
virtual ErrorObject *asErrorObject() { return 0; }
virtual ArgumentsObject *asArgumentsObject() { return 0; }
- virtual Value __get__(ExecutionContext *ctx, String *name);
+ virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty = 0);
virtual PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, String *name);
virtual PropertyDescriptor *__getPropertyDescriptor__(ExecutionContext *ctx, String *name, PropertyDescriptor *to_fill);
virtual void __put__(ExecutionContext *ctx, String *name, Value value);
ArrayObject(const Array &value): value(value) {}
virtual QString className() { return QStringLiteral("Array"); }
virtual ArrayObject *asArrayObject() { return this; }
- virtual Value __get__(ExecutionContext *ctx, String *name);
+ virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty);
virtual bool inplaceBinOp(Value rhs, Value index, BinOp op, ExecutionContext *ctx);
RegExpObject(const QRegularExpression &value, bool global): value(value), lastIndex(Value::fromInt32(0)), global(global) {}
virtual QString className() { return QStringLiteral("RegExp"); }
virtual RegExpObject *asRegExpObject() { return this; }
- virtual Value __get__(ExecutionContext *ctx, String *name);
+ virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty);
};
struct ErrorObject: Object {
ErrorObject(const Value &message): value(message) {}
virtual QString className() { return QStringLiteral("Error"); }
virtual ErrorObject *asErrorObject() { return this; }
- virtual Value __get__(ExecutionContext *ctx, String *name);
+ virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty);
virtual struct SyntaxErrorObject *asSyntaxError() { return 0; }
ArgumentsObject(ExecutionContext *context): context(context) {}
virtual QString className() { return QStringLiteral("Arguments"); }
virtual ArgumentsObject *asArgumentsObject() { return this; }
- virtual Value __get__(ExecutionContext *ctx, String *name);
+ virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty);
virtual PropertyDescriptor *__getPropertyDescriptor__(ExecutionContext *ctx, String *name, PropertyDescriptor *to_fill);
};
return __qmljs_to_object(ctx->argument(0), ctx);
}
-Value ObjectCtor::__get__(ExecutionContext *ctx, String *name)
+Value ObjectCtor::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
{
- if (name == ctx->engine->id_length)
+ if (name == ctx->engine->id_length) {
+ if (hasProperty)
+ *hasProperty = true;
return Value::fromDouble(1);
- return Object::__get__(ctx, name);
+ }
+ return Object::__get__(ctx, name, hasProperty);
}
void ObjectPrototype::init(ExecutionContext *ctx, const Value &ctor)
virtual Value construct(ExecutionContext *ctx);
virtual Value call(ExecutionContext *ctx);
- virtual Value __get__(ExecutionContext *ctx, String *name);
+ virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty);
};
struct ObjectPrototype: Object