Get rid of __get__ implementation in ErrorObject
authorSimon Hausmann <simon.hausmann@digia.com>
Fri, 18 Jan 2013 12:28:00 +0000 (13:28 +0100)
committerLars Knoll <lars.knoll@digia.com>
Fri, 18 Jan 2013 15:28:16 +0000 (16:28 +0100)
As a step towards making __get__ non-virtual we can implement the message
property instead using run-time initialization.

The Error.prototype object must also provide a message property with
the empty string as initial value (15.11.4.3).

Change-Id: If8a7fd828e6c6fa6e20607505b392d0bda71f90a
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
main.cpp
qmljs_engine.cpp
qmljs_objects.cpp
qmljs_objects.h
qv4ecmaobjects.cpp
qv4ecmaobjects_p.h
tests/TestExpectations

index a948544..eb3eb0f 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -146,7 +146,7 @@ static void showException(QQmlJS::VM::ExecutionContext *ctx)
             std::cerr << qPrintable(msg->buildFullMessage(ctx)->toQString()) << std::endl;
         }
     } else {
-        std::cerr << "Uncaught exception: " << qPrintable(e->value.toString(ctx)->toQString()) << std::endl;
+        std::cerr << "Uncaught exception: " << qPrintable(e->__get__(ctx, ctx->engine->identifier(QStringLiteral("message")), 0).toString(ctx)->toQString()) << std::endl;
     }
 }
 
index 8bbff13..8f0fa63 100644 (file)
@@ -106,7 +106,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     datePrototype = new (memoryManager) DatePrototype();
     functionPrototype = new (memoryManager) FunctionPrototype(rootContext);
     regExpPrototype = new (memoryManager) RegExpPrototype(this);
-    errorPrototype = new (memoryManager) ErrorPrototype();
+    errorPrototype = new (memoryManager) ErrorPrototype(this);
     evalErrorPrototype = new (memoryManager) EvalErrorPrototype(rootContext);
     rangeErrorPrototype = new (memoryManager) RangeErrorPrototype(rootContext);
     referenceErrorPrototype = new (memoryManager) ReferenceErrorPrototype(rootContext);
@@ -382,7 +382,7 @@ FunctionObject *ExecutionEngine::newRegExpCtor(ExecutionContext *ctx)
 
 Object *ExecutionEngine::newErrorObject(const Value &value)
 {
-    ErrorObject *object = new (memoryManager) ErrorObject(value);
+    ErrorObject *object = new (memoryManager) ErrorObject(this, value);
     object->prototype = errorPrototype;
     return object;
 }
index d6a0640..5351c3f 100644 (file)
@@ -1139,15 +1139,10 @@ Value RegExpObject::__get__(ExecutionContext *ctx, String *name, bool *hasProper
     return Object::__get__(ctx, name, hasProperty);
 }
 
-Value ErrorObject::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
+ErrorObject::ErrorObject(ExecutionEngine* engine, const Value &message)
 {
-    QString n = name->toQString();
-    if (n == QLatin1String("message")) {
-        if (hasProperty)
-            *hasProperty = true;
-        return value;
-    }
-    return Object::__get__(ctx, name, hasProperty);
+    if (message.type() != Value::Undefined_Type)
+        defineDefaultProperty(engine->identifier(QStringLiteral("message")), message);
 }
 
 void ErrorObject::setNameProperty(ExecutionContext *ctx)
@@ -1155,20 +1150,11 @@ void ErrorObject::setNameProperty(ExecutionContext *ctx)
     defineDefaultProperty(ctx, QLatin1String("name"), Value::fromString(ctx, className()));
 }
 
-void ErrorObject::getCollectables(QVector<Object *> &objects)
-{
-    Object::getCollectables(objects);
-    if (Object *o = value.asObject())
-        objects.append(o);
-}
-
 SyntaxErrorObject::SyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *message)
-    : ErrorObject(ctx->argument(0))
+    : ErrorObject(ctx->engine, message ? Value::fromString(message->buildFullMessage(ctx)) : ctx->argument(0))
     , msg(message)
 {
     prototype = ctx->engine->syntaxErrorPrototype;
-    if (message)
-        value = Value::fromString(message->buildFullMessage(ctx));
     setNameProperty(ctx);
 }
 
@@ -1280,56 +1266,56 @@ PropertyDescriptor *StringObject::getIndex(ExecutionContext *ctx, uint index)
 }
 
 EvalErrorObject::EvalErrorObject(ExecutionContext *ctx)
-    : ErrorObject(ctx->argument(0))
+    : ErrorObject(ctx->engine, ctx->argument(0))
 {
     setNameProperty(ctx);
     prototype = ctx->engine->evalErrorPrototype;
 }
 
 RangeErrorObject::RangeErrorObject(ExecutionContext *ctx)
-    : ErrorObject(ctx->argument(0))
+    : ErrorObject(ctx->engine, ctx->argument(0))
 {
     setNameProperty(ctx);
     prototype = ctx->engine->rangeErrorPrototype;
 }
 
 RangeErrorObject::RangeErrorObject(ExecutionContext *ctx, const QString &msg)
-    : ErrorObject(Value::fromString(ctx,msg))
+    : ErrorObject(ctx->engine, Value::fromString(ctx,msg))
 {
     setNameProperty(ctx);
     prototype = ctx->engine->rangeErrorPrototype;
 }
 
 ReferenceErrorObject::ReferenceErrorObject(ExecutionContext *ctx)
-    : ErrorObject(ctx->argument(0))
+    : ErrorObject(ctx->engine, ctx->argument(0))
 {
     setNameProperty(ctx);
     prototype = ctx->engine->referenceErrorPrototype;
 }
 
 ReferenceErrorObject::ReferenceErrorObject(ExecutionContext *ctx, const QString &msg)
-    : ErrorObject(Value::fromString(ctx,msg))
+    : ErrorObject(ctx->engine, Value::fromString(ctx,msg))
 {
     setNameProperty(ctx);
     prototype = ctx->engine->referenceErrorPrototype;
 }
 
 TypeErrorObject::TypeErrorObject(ExecutionContext *ctx)
-    : ErrorObject(ctx->argument(0))
+    : ErrorObject(ctx->engine, ctx->argument(0))
 {
     setNameProperty(ctx);
     prototype = ctx->engine->typeErrorPrototype;
 }
 
 TypeErrorObject::TypeErrorObject(ExecutionContext *ctx, const QString &msg)
-    : ErrorObject(Value::fromString(ctx,msg))
+    : ErrorObject(ctx->engine, Value::fromString(ctx,msg))
 {
     setNameProperty(ctx);
     prototype = ctx->engine->typeErrorPrototype;
 }
 
 URIErrorObject::URIErrorObject(ExecutionContext *ctx)
-    : ErrorObject(ctx->argument(0))
+    : ErrorObject(ctx->engine, ctx->argument(0))
 {
     setNameProperty(ctx);
     prototype = ctx->engine->uRIErrorPrototype;
index 9c40ada..54b826c 100644 (file)
@@ -370,17 +370,14 @@ struct RegExpObject: Object {
 };
 
 struct ErrorObject: Object {
-    Value value;
-    ErrorObject(const Value &message): value(message) {}
+    ErrorObject(ExecutionEngine* engine, const Value &message);
     virtual QString className() { return QStringLiteral("Error"); }
     virtual ErrorObject *asErrorObject() { return this; }
-    virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty);
 
     virtual struct SyntaxErrorObject *asSyntaxError() { return 0; }
 
 protected:
     void setNameProperty(ExecutionContext *ctx);
-    virtual void getCollectables(QVector<Object *> &objects);
 };
 
 struct EvalErrorObject: ErrorObject {
index 462678f..c3bd81c 100644 (file)
@@ -3198,6 +3198,7 @@ void ErrorPrototype::init(ExecutionContext *ctx, const Value &ctor, Object *obj)
     ctor.objectValue()->defineReadonlyProperty(ctx->engine->id_length, Value::fromInt32(1));
     obj->defineDefaultProperty(ctx, QStringLiteral("constructor"), ctor);
     obj->defineDefaultProperty(ctx, QStringLiteral("toString"), method_toString, 0);
+    obj->defineDefaultProperty(ctx, QStringLiteral("message"), Value::fromString(ctx, QString()));
 }
 
 Value ErrorPrototype::method_toString(ExecutionContext *ctx)
index 55890ef..ffaf803 100644 (file)
@@ -357,7 +357,7 @@ struct URIErrorCtor: ErrorCtor
 struct ErrorPrototype: ErrorObject
 {
     // ### shouldn't be undefined
-    ErrorPrototype(): ErrorObject(Value::undefinedValue()) {}
+    ErrorPrototype(ExecutionEngine* engine): ErrorObject(engine, Value::undefinedValue()) {}
     void init(ExecutionContext *ctx, const Value &ctor) { init(ctx, ctor, this); }
 
     static void init(ExecutionContext *ctx, const Value &ctor, Object *obj);
index 48ae47a..1b6d87d 100644 (file)
@@ -331,8 +331,6 @@ S15.10.7.4_A8 failing
 S15.10.7.4_A9 failing
 S15.11.4.2_A1 failing
 S15.11.4.2_A2 failing
-S15.11.4.3_A1 failing
-S15.11.4.3_A2 failing
 15.12-0-1 failing
 15.12-0-2 failing
 15.12-0-3 failing