Implement Object.keys and obj.proto.propertyIsEnumerable
authorLars Knoll <lars.knoll@digia.com>
Wed, 28 Nov 2012 22:26:26 +0000 (23:26 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 29 Nov 2012 07:03:20 +0000 (08:03 +0100)
Change-Id: I30df135ad95f24246e43553b2711ad1008319d56
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qmljs_engine.cpp
qmljs_engine.h
qv4ecmaobjects.cpp

index 7d12df5..ffecdf8 100644 (file)
@@ -276,14 +276,14 @@ Object *ExecutionEngine::newFunctionObject(ExecutionContext *ctx)
     return object;
 }
 
-Object *ExecutionEngine::newArrayObject()
+ArrayObject *ExecutionEngine::newArrayObject()
 {
     ArrayObject *object = new ArrayObject();
     object->prototype = arrayPrototype;
     return object;
 }
 
-Object *ExecutionEngine::newArrayObject(const Array &value)
+ArrayObject *ExecutionEngine::newArrayObject(const Array &value)
 {
     ArrayObject *object = new ArrayObject(value);
     object->prototype = arrayPrototype;
index 54e303c..4ecc1da 100644 (file)
@@ -166,8 +166,8 @@ struct ExecutionEngine
 
     Object *newFunctionObject(ExecutionContext *ctx);
 
-    Object *newArrayObject();
-    Object *newArrayObject(const Array &value);
+    ArrayObject *newArrayObject();
+    ArrayObject *newArrayObject(const Array &value);
     FunctionObject *newArrayCtor(ExecutionContext *ctx);
 
     Object *newDateObject(const Value &value);
index c51c55c..9fd95b9 100644 (file)
@@ -723,8 +723,23 @@ Value ObjectPrototype::method_isExtensible(ExecutionContext *ctx)
 
 Value ObjectPrototype::method_keys(ExecutionContext *ctx)
 {
-    ctx->throwUnimplemented(QStringLiteral("Object.keys"));
-    return Value::undefinedValue();
+    if (!ctx->argument(0).isObject())
+        __qmljs_throw_type_error(ctx);
+
+    Object *o = ctx->argument(0).objectValue();
+
+    ArrayObject *a = ctx->engine->newArrayObject();
+
+    if (o->members) {
+        PropertyTable::iterator it = o->members->begin();
+        while (it != o->members->end()) {
+            if ((*it)->descriptor.isEnumerable())
+                a->value.push(Value::fromString((*it)->name));
+            ++it;
+        }
+    }
+
+    return Value::fromObject(a);
 }
 
 Value ObjectPrototype::method_toString(ExecutionContext *ctx)
@@ -765,8 +780,11 @@ Value ObjectPrototype::method_isPrototypeOf(ExecutionContext *ctx)
 
 Value ObjectPrototype::method_propertyIsEnumerable(ExecutionContext *ctx)
 {
-    ctx->throwUnimplemented(QStringLiteral("Object.prototype.propertyIsEnumerable"));
-    return Value::undefinedValue();
+    String *p = ctx->argument(0).toString(ctx);
+
+    Object *o = ctx->thisObject.toObject(ctx).objectValue();
+    PropertyDescriptor *pd = o->__getOwnProperty__(ctx, p);
+    return Value::fromBoolean(pd && pd->enumberable);
 }
 
 Value ObjectPrototype::method_defineGetter(ExecutionContext *ctx)