Some more fixes for defineOwnProperty
authorLars Knoll <lars.knoll@digia.com>
Mon, 14 Jan 2013 22:32:57 +0000 (23:32 +0100)
committerLars Knoll <lars.knoll@digia.com>
Tue, 15 Jan 2013 14:16:37 +0000 (15:16 +0100)
Change-Id: If130677591bb7f655bcc5d35f1797ced08cd17f3
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qmljs_objects.cpp
qmljs_objects.h
tests/TestExpectations

index 04107d0..eacf40b 100644 (file)
@@ -518,72 +518,23 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, Property
         return true;
     }
 
-    // clause 5
-    if (desc->isEmpty())
-        return true;
-
-    // clause 6
-    if (desc->isSubset(current))
-        return true;
-
-    // clause 7
-    if (!current->isConfigurable()) {
-        if (desc->isConfigurable())
-            goto reject;
-        if (desc->enumberable != PropertyDescriptor::Undefined && desc->enumberable != current->enumberable)
-            goto reject;
-    }
-
-    // clause 8
-    if (desc->isGeneric())
-        goto accept;
-
-    // clause 9
-    if (current->isData() != desc->isData()) {
-        // 9a
-        if (!current->isConfigurable())
-            goto reject;
-        if (current->isData()) {
-            // 9b
-            current->type = PropertyDescriptor::Accessor;
-            current->writable = PropertyDescriptor::Undefined;
-            current->get = 0;
-            current->set = 0;
-        } else {
-            // 9c
-            current->type = PropertyDescriptor::Data;
-            current->writable = PropertyDescriptor::Disabled;
-            current->value = Value::undefinedValue();
-        }
-    } else if (current->isData() && desc->isData()) { // clause 10
-        if (!current->isConfigurable() && !current->isWritable()) {
-            if (desc->isWritable() || !current->value.sameValue(desc->value))
-                goto reject;
-        }
-    } else { // clause 10
-        assert(current->isAccessor() && desc->isAccessor());
-        if (!current->isConfigurable()) {
-            if (((quintptr)desc->get > 0x1 && current->get != desc->get) ||
-                ((quintptr)desc->set > 0x1 && current->set != desc->set))
-                goto reject;
-        }
-    }
-
-  accept:
-
-    *current += *desc;
-    return true;
-  reject:
-    qDebug() << "___put__ rejected" << name->toQString();
-    if (ctx->strictMode)
-        __qmljs_throw_type_error(ctx);
-    return false;
+    return __defineOwnProperty__(ctx, current, desc);
+reject:
+  if (ctx->strictMode)
+      __qmljs_throw_type_error(ctx);
+  return false;
 }
 
 bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, PropertyDescriptor *desc)
 {
+    PropertyDescriptor *current;
+
+    // 15.4.5.1, 4b
+    if (isArray && index >= array.length() && !array.getLengthProperty()->isWritable())
+        goto reject;
+
     // Clause 1
-    PropertyDescriptor *current = __getOwnProperty__(ctx, index);
+    current = __getOwnProperty__(ctx, index);
     if (!current) {
         // clause 3
         if (!extensible)
@@ -595,6 +546,15 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, PropertyDe
         return true;
     }
 
+    return __defineOwnProperty__(ctx, current, desc);
+reject:
+  if (ctx->strictMode)
+      __qmljs_throw_type_error(ctx);
+  return false;
+}
+
+bool Object::__defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *current, PropertyDescriptor *desc)
+{
     // clause 5
     if (desc->isEmpty())
         return true;
@@ -640,8 +600,10 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, PropertyDe
     } else { // clause 10
         assert(current->isAccessor() && desc->isAccessor());
         if (!current->isConfigurable()) {
-            if (((quintptr)desc->get > 0x1 && current->get != desc->get) ||
-                ((quintptr)desc->set > 0x1 && current->set != desc->set))
+            if ((!current->get && (quintptr)desc->get > 0x1) ||
+                (current->get && current->get != desc->get) ||
+                (!current->set && (quintptr)desc->set > 0x1) ||
+                (current->set && current->set != desc->set))
                 goto reject;
         }
     }
@@ -651,12 +613,12 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, PropertyDe
     *current += *desc;
     return true;
   reject:
-    qDebug() << "___put__ rejected index=" << index;
     if (ctx->strictMode)
         __qmljs_throw_type_error(ctx);
     return false;
 }
 
+
 bool Object::__defineOwnProperty__(ExecutionContext *ctx, const QString &name, PropertyDescriptor *desc)
 {
     return __defineOwnProperty__(ctx, ctx->engine->identifier(name), desc);
index 19fa492..5a59f14 100644 (file)
@@ -138,6 +138,7 @@ struct Object: Managed {
     virtual bool __hasProperty__(const ExecutionContext *ctx, uint index) const;
     virtual bool __delete__(ExecutionContext *ctx, String *name);
     virtual bool __delete__(ExecutionContext *ctx, uint index);
+    bool __defineOwnProperty__(ExecutionContext *ctx, PropertyDescriptor *current, PropertyDescriptor *desc);
     virtual bool __defineOwnProperty__(ExecutionContext *ctx, String *name, PropertyDescriptor *desc);
     bool __defineOwnProperty__(ExecutionContext *ctx, uint index, PropertyDescriptor *desc);
     bool __defineOwnProperty__(ExecutionContext *ctx, const QString &name, PropertyDescriptor *desc);
index f030ff5..1341803 100644 (file)
@@ -823,10 +823,6 @@ S15.1.3.2_A5.3 failing
 15.2.3.6-3-66 failing
 15.2.3.6-3-94-1 failing
 15.2.3.6-3-94 failing
-15.2.3.6-4-188 failing
-15.2.3.6-4-189 failing
-15.2.3.6-4-20 failing
-15.2.3.6-4-256 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
@@ -841,14 +837,6 @@ S15.1.3.2_A5.3 failing
 15.2.3.6-4-360-7 failing
 15.2.3.6-4-41 failing
 15.2.3.6-4-410 failing
-15.2.3.6-4-472 failing
-15.2.3.6-4-490 failing
-15.2.3.6-4-507 failing
-15.2.3.6-4-525 failing
-15.2.3.6-4-543 failing
-15.2.3.6-4-544 failing
-15.2.3.6-4-561 failing
-15.2.3.6-4-562 failing
 15.2.3.6-4-586 failing
 15.2.3.6-4-593 failing
 15.2.3.6-4-594 failing