Fix remaining test failures related to Arguments object
authorLars Knoll <lars.knoll@digia.com>
Tue, 22 Jan 2013 21:23:59 +0000 (22:23 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 22 Jan 2013 21:54:26 +0000 (22:54 +0100)
Change-Id: I294da46457858c14c6d438cfc022d3144d4385d0
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qv4argumentsobject.cpp
qv4argumentsobject.h
qv4managed.h
qv4object.cpp
qv4object.h
tests/TestExpectations

index 7453b7a..b803644 100644 (file)
@@ -58,23 +58,75 @@ ArgumentsObject::ArgumentsObject(ExecutionContext *context, int formalParameterC
         __defineOwnProperty__(context, QStringLiteral("callee"), &pd);
         __defineOwnProperty__(context, QStringLiteral("caller"), &pd);
     } else {
-        uint enumerableParams = qMin(formalParameterCount, actualParameterCount);
-        context->engine->requireArgumentsAccessors(enumerableParams);
-        for (uint i = 0; i < (uint)enumerableParams; ++i)
+        uint numAccessors = qMin(formalParameterCount, actualParameterCount);
+        context->engine->requireArgumentsAccessors(numAccessors);
+        for (uint i = 0; i < (uint)numAccessors; ++i) {
+            mappedArguments.append(context->argument(i));
             __defineOwnProperty__(context, i, &context->engine->argumentsAccessors.at(i));
+        }
         PropertyDescriptor pd;
         pd.type = PropertyDescriptor::Data;
         pd.writable = PropertyDescriptor::Enabled;
         pd.configurable = PropertyDescriptor::Enabled;
         pd.enumberable = PropertyDescriptor::Enabled;
-        for (uint i = enumerableParams; i < qMin((uint)actualParameterCount, context->argumentCount); ++i) {
+        for (uint i = numAccessors; i < qMin((uint)actualParameterCount, context->argumentCount); ++i) {
             pd.value = context->argument(i);
             __defineOwnProperty__(context, i, &pd);
         }
         defineDefaultProperty(context, QStringLiteral("callee"), Value::fromObject(context->function));
+        isArgumentsObject = true;
+    }
+}
+
+bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const PropertyDescriptor *desc)
+{
+    PropertyDescriptor *pd = array.at(index);
+    PropertyDescriptor map;
+    bool isMapped = false;
+    if (pd && index < (uint)mappedArguments.size())
+        isMapped = pd->isAccessor() && pd->get == context->engine->argumentsAccessors.at(index).get;
+
+    if (isMapped) {
+        map = *pd;
+        pd->type = PropertyDescriptor::Data;
+        pd->writable = PropertyDescriptor::Enabled;
+        pd->configurable = PropertyDescriptor::Enabled;
+        pd->enumberable = PropertyDescriptor::Enabled;
+        pd->value = mappedArguments.at(index);
+    }
+
+    isArgumentsObject = false;
+    bool strict = ctx->strictMode;
+    ctx->strictMode = false;
+    bool result = Object::__defineOwnProperty__(ctx, index, desc);
+    ctx->strictMode = strict;
+    isArgumentsObject = true;
+
+    if (isMapped && desc->isData()) {
+        if (desc->type != PropertyDescriptor::Generic) {
+            Value arg = desc->value;
+            map.set->call(ctx, Value::fromObject(this), &arg, 1);
+        }
+        if (desc->writable != PropertyDescriptor::Disabled)
+            *pd = map;
     }
+
+    if (ctx->strictMode && !result)
+        __qmljs_throw_type_error(ctx);
+    return result;
 }
 
+void ArgumentsObject::getCollectables(QVector<Object *> &objects)
+{
+    for (int i = 0; i < mappedArguments.size(); ++i) {
+        Object *o = mappedArguments.at(i).asObject();
+        if (o)
+            objects.append(o);
+    }
+    Object::getCollectables(objects);
+}
+
+
 Value ArgumentsGetterFunction::call(ExecutionContext *ctx, Value thisObject, Value *, int)
 {
     Object *that = thisObject.asObject();
@@ -102,5 +154,6 @@ Value ArgumentsSetterFunction::call(ExecutionContext *ctx, Value thisObject, Val
     return Value::undefinedValue();
 }
 
+
 }
 }
index 90af02f..398f5de 100644 (file)
@@ -70,9 +70,14 @@ struct ArgumentsSetterFunction: FunctionObject
 
 struct ArgumentsObject: Object {
     ExecutionContext *context;
+    QVector<Value> mappedArguments;
     ArgumentsObject(ExecutionContext *context, int formalParameterCount, int actualParameterCount);
     virtual QString className() { return QStringLiteral("Arguments"); }
     virtual ArgumentsObject *asArgumentsObject() { return this; }
+
+    bool defineOwnProperty(ExecutionContext *ctx, uint index, const PropertyDescriptor *desc);
+
+    virtual void getCollectables(QVector<Object *> &objects);
 };
 
 }
index c7a5959..51aa68a 100644 (file)
@@ -64,7 +64,7 @@ private:
     void operator = (const Managed &other);
 
 protected:
-    Managed() : markBit(0), inUse(1), extensible(true), isArray(false), isString(false), isBuiltinFunction(false), unused(0) { }
+    Managed() : markBit(0), inUse(1), extensible(true), isArray(false), isArgumentsObject(false), isString(false), isBuiltinFunction(false), unused(0) { }
     virtual ~Managed();
 
 public:
@@ -81,6 +81,7 @@ protected:
             quintptr inUse   :  1;
             quintptr extensible : 1; // used by Object
             quintptr isArray : 1; // used by Object & Array
+            quintptr isArgumentsObject : 1;
             quintptr isString : 1; // used by Object & StringObject
             quintptr isBuiltinFunction : 1; // used by FunctionObject
             quintptr needsActivation : 1; // used by FunctionObject
index 6c723f1..5fcb7fc 100644 (file)
@@ -44,6 +44,7 @@
 #include "qv4isel_p.h"
 #include "qv4objectproto.h"
 #include "qv4stringobject.h"
+#include "qv4argumentsobject.h"
 #include "qv4mm.h"
 
 #include <private/qqmljsengine_p.h>
@@ -548,6 +549,9 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop
     if (isArray && index >= array.length() && !array.getLengthProperty()->isWritable())
         goto reject;
 
+    if (isArgumentsObject)
+        return static_cast<ArgumentsObject *>(this)->defineOwnProperty(ctx, index, desc);
+
     // Clause 1
     current = __getOwnProperty__(ctx, index);
     if (!current) {
index 819b5d7..2747dff 100644 (file)
@@ -137,7 +137,7 @@ struct Object: Managed {
     virtual bool __delete__(ExecutionContext *ctx, String *name);
     virtual bool __delete__(ExecutionContext *ctx, uint index);
     bool __defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *current, const PropertyDescriptor *desc);
-    virtual bool __defineOwnProperty__(ExecutionContext *ctx, String *name, const PropertyDescriptor *desc);
+    bool __defineOwnProperty__(ExecutionContext *ctx, String *name, const PropertyDescriptor *desc);
     bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const PropertyDescriptor *desc);
     bool __defineOwnProperty__(ExecutionContext *ctx, const QString &name, const PropertyDescriptor *desc);
 
index ab76a42..914d19d 100644 (file)
@@ -2,6 +2,11 @@
 S15.1.3.1_A2.5_T1
 S15.1.3.2_A2.5_T1
 
+# wrong tests
+# uses octal number
+15.2.3.6-2-17-1 failing
+
+
 # Tests failing that are supposed to pass.
 10.4.2-1-1 failing
 10.4.2-1-2 failing
@@ -314,23 +319,8 @@ S15.12.2_A1 failing
 15.12.3_2-3-a-2 failing
 15.12.3_2-3-a-3 failing
 15.12.3_4-1-2 failing
-15.2.3.6-2-17-1 failing
-15.2.3.6-4-291-1 failing
-15.2.3.6-4-292-1 failing
-15.2.3.6-4-293-2 failing
-15.2.3.6-4-293-3 failing
-15.2.3.6-4-294-1 failing
-15.2.3.6-4-295-1 failing
-15.2.3.6-4-296-1 failing
-15.2.3.6-4-297-1 failing
-15.2.3.6-4-299-1 failing
-15.2.3.6-4-300-1 failing
 15.2.3.6-4-360-3 failing
 15.2.3.6-4-360-7 failing
-15.2.3.7-6-a-280 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.4.4.14-9-a-10 failing
 15.4.4.14-9-a-17 failing
 15.4.4.14-9-a-7 failing