From 22cf4de119a9c6079c3a58828009552f0a1ee1c9 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 16 Jan 2013 13:34:46 +0100 Subject: [PATCH] Fix index access on StringObjects Change-Id: I5dbbc59f383e2a1e6630d1e0f0ca631890d4c8e7 Reviewed-by: Simon Hausmann --- qmljs_objects.cpp | 21 +++++++++++++-------- qmljs_objects.h | 8 ++++---- qv4managed.h | 7 ++++--- tests/TestExpectations | 1 - 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index 0cec5ea..faf3a86 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -207,11 +207,14 @@ PropertyDescriptor *Object::__getOwnProperty__(ExecutionContext *ctx, String *na return 0; } -PropertyDescriptor *Object::__getOwnProperty__(ExecutionContext *, uint index) +PropertyDescriptor *Object::__getOwnProperty__(ExecutionContext *ctx, uint index) { PropertyDescriptor *p = array.at(index); if(p && p->type != PropertyDescriptor::Generic) return p; + if (isString) + return static_cast(this)->getIndex(ctx, index); + return 0; } @@ -234,13 +237,18 @@ PropertyDescriptor *Object::__getPropertyDescriptor__(ExecutionContext *ctx, Str return 0; } -PropertyDescriptor *Object::__getPropertyDescriptor__(ExecutionContext *, uint index) +PropertyDescriptor *Object::__getPropertyDescriptor__(ExecutionContext *ctx, uint index) { Object *o = this; while (o) { PropertyDescriptor *p = o->array.at(index); if(p && p->type != PropertyDescriptor::Generic) return p; + if (o->isString) { + p = static_cast(o)->getIndex(ctx, index); + if (p) + return p; + } o = o->prototype; } return 0; @@ -1320,6 +1328,8 @@ void BoundFunction::getCollectables(QVector &objects) StringObject::StringObject(ExecutionContext *ctx, const Value &value) : value(value) { + isString = true; + tmpProperty.type = PropertyDescriptor::Data; tmpProperty.enumberable = PropertyDescriptor::Enabled; tmpProperty.writable = PropertyDescriptor::Disabled; @@ -1330,12 +1340,8 @@ StringObject::StringObject(ExecutionContext *ctx, const Value &value) defineReadonlyProperty(ctx->engine->id_length, Value::fromUInt32(value.stringValue()->toQString().length())); } -PropertyDescriptor *StringObject::__getOwnProperty__(ExecutionContext *ctx, uint index) +PropertyDescriptor *StringObject::getIndex(ExecutionContext *ctx, uint index) { - PropertyDescriptor *pd = Object::__getOwnProperty__(ctx, index); - if (pd) - return pd; - assert(value.isString()); QString str = value.stringValue()->toQString(); if (index >= (uint)str.length()) return 0; @@ -1344,7 +1350,6 @@ PropertyDescriptor *StringObject::__getOwnProperty__(ExecutionContext *ctx, uint return &tmpProperty; } - EvalErrorObject::EvalErrorObject(ExecutionContext *ctx) : ErrorObject(ctx->argument(0)) { diff --git a/qmljs_objects.h b/qmljs_objects.h index 5a59f14..8fae05c 100644 --- a/qmljs_objects.h +++ b/qmljs_objects.h @@ -121,10 +121,10 @@ struct Object: Managed { virtual ErrorObject *asErrorObject() { return 0; } virtual ArgumentsObject *asArgumentsObject() { return 0; } - virtual PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, String *name); - virtual PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, uint index); + PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, String *name); + PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, uint index); PropertyDescriptor *__getPropertyDescriptor__(ExecutionContext *ctx, String *name); - PropertyDescriptor *__getPropertyDescriptor__(ExecutionContext *ctx, uint index); + virtual PropertyDescriptor *__getPropertyDescriptor__(ExecutionContext *ctx, uint index); virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty = 0); virtual Value __get__(ExecutionContext *ctx, uint index, bool *hasProperty = 0); @@ -204,7 +204,7 @@ struct StringObject: Object { virtual QString className() { return QStringLiteral("String"); } virtual StringObject *asStringObject() { return this; } - virtual PropertyDescriptor *__getOwnProperty__(ExecutionContext *ctx, uint index); + PropertyDescriptor *getIndex(ExecutionContext *ctx, uint index); }; struct DateObject: Object { diff --git a/qv4managed.h b/qv4managed.h index 3c7f04d..a0472cf 100644 --- a/qv4managed.h +++ b/qv4managed.h @@ -64,7 +64,7 @@ private: void operator = (const Managed &other); protected: - Managed() : markBit(0), inUse(1), extensible(true), isArray(false), unused(0) { } + Managed() : markBit(0), inUse(1), extensible(true), isArray(false), isString(false), unused(0) { } virtual ~Managed(); public: @@ -81,13 +81,14 @@ protected: quintptr inUse : 1; quintptr extensible : 1; // used by Object quintptr isArray : 1; // used by Object & Array + quintptr isString : 1; // used by Object & StringObject quintptr needsActivation : 1; // used by FunctionObject quintptr usesArgumentsObject : 1; // used by FunctionObject quintptr strictMode : 1; // used by FunctionObject #if CPU(X86_64) - quintptr unused : 57; + quintptr unused : 56; #elif CPU(X86) - quintptr unused : 25; + quintptr unused : 24; #else #error "implement me" #endif diff --git a/tests/TestExpectations b/tests/TestExpectations index 01b1d87..41f41a8 100644 --- a/tests/TestExpectations +++ b/tests/TestExpectations @@ -858,7 +858,6 @@ S15.1.3.2_A5.3 failing 15.2.3.7-6-a-286 failing 15.2.3.7-6-a-288 failing 15.2.3.7-6-a-289 failing -15.2.3.9-2-a-12 failing 15.2.4.2-1-1 failing 15.2.4.2-1-2 failing 15.2.4.2-2-1 failing -- 2.7.4