Initial work on the Function prototype.
authorRoberto Raggi <roberto.raggi@nokia.com>
Mon, 21 May 2012 12:57:02 +0000 (14:57 +0200)
committerRoberto Raggi <roberto.raggi@nokia.com>
Mon, 21 May 2012 12:58:23 +0000 (14:58 +0200)
qmljs_objects.cpp
qmljs_objects.h
qv4ecmaobjects.cpp
qv4ecmaobjects_p.h

index eace571..4f26d2e 100644 (file)
@@ -218,6 +218,9 @@ ExecutionEngine::ExecutionEngine()
     objectCtor = ObjectCtor::create(this);
     objectCtor.objectValue->get(prototype, &objectPrototype);
 
+    functionCtor = FunctionCtor::create(this);
+    functionCtor.objectValue->get(prototype, &functionPrototype);
+
     stringCtor = StringCtor::create(this);
     numberCtor = NumberCtor::create(this);
     booleanCtor = BooleanCtor::create(this);
@@ -234,6 +237,7 @@ ExecutionEngine::ExecutionEngine()
     glo->put(identifier(QLatin1String("String")), stringCtor);
     glo->put(identifier(QLatin1String("Number")), numberCtor);
     glo->put(identifier(QLatin1String("Array")), arrayCtor);
+    glo->put(identifier(QLatin1String("Function")), functionCtor);
     glo->put(identifier(QLatin1String("Date")), dateCtor);
     glo->put(identifier(QLatin1String("Math")), Value::fromObject(newMathObject(rootContext)));
 }
@@ -344,6 +348,26 @@ Object *ExecutionEngine::newBooleanPrototype(Context *ctx, FunctionObject *proto
     return booleanProto;
 }
 
+Object *ExecutionEngine::newFunctionObject(Context *ctx)
+{
+    Object *object = new FunctionObject(ctx);
+    if (functionPrototype.isObject())
+        object->prototype = functionPrototype.objectValue;
+    return object;
+}
+
+FunctionObject *ExecutionEngine::newFunctionCtor(Context *ctx)
+{
+    return new FunctionCtor(ctx);
+}
+
+Object *ExecutionEngine::newFunctionPrototype(Context *ctx, FunctionObject *proto)
+{
+    Object *functionProto = new FunctionPrototype(ctx, proto);
+    functionProto->prototype = objectPrototype.objectValue;
+    return functionProto;
+}
+
 Object *ExecutionEngine::newArrayObject()
 {
     ArrayObject *object = new ArrayObject();
index 60829d2..562da2f 100644 (file)
@@ -385,6 +385,7 @@ struct ExecutionEngine
     Value numberCtor;
     Value booleanCtor;
     Value arrayCtor;
+    Value functionCtor;
     Value dateCtor;
 
     Value objectPrototype;
@@ -392,6 +393,7 @@ struct ExecutionEngine
     Value numberPrototype;
     Value booleanPrototype;
     Value arrayPrototype;
+    Value functionPrototype;
     Value datePrototype;
 
     QHash<QString, String *> identifiers;
@@ -422,6 +424,10 @@ struct ExecutionEngine
     FunctionObject *newBooleanCtor(Context *ctx);
     Object *newBooleanPrototype(Context *ctx, FunctionObject *proto);
 
+    Object *newFunctionObject(Context *ctx);
+    FunctionObject *newFunctionCtor(Context *ctx);
+    Object *newFunctionPrototype(Context *ctx, FunctionObject *proto);
+
     Object *newArrayObject();
     Object *newArrayObject(const Array &value);
     FunctionObject *newArrayCtor(Context *ctx);
index 35ed781..4744faa 100644 (file)
@@ -1076,9 +1076,6 @@ void BooleanPrototype::method_valueOf(Context *ctx)
 //
 // Array object
 //
-//
-// Number object
-//
 Value ArrayCtor::create(ExecutionEngine *engine)
 {
     Context *ctx = engine->rootContext;
@@ -1376,6 +1373,85 @@ void ArrayPrototype::method_unshift(Context *ctx)
 }
 
 //
+// Function object
+//
+//
+// Array object
+//
+Value FunctionCtor::create(ExecutionEngine *engine)
+{
+    Context *ctx = engine->rootContext;
+    FunctionObject *ctor = ctx->engine->newFunctionCtor(ctx);
+    ctor->setProperty(ctx, QLatin1String("prototype"), Value::fromObject(ctx->engine->newFunctionPrototype(ctx, ctor)));
+    return Value::fromObject(ctor);
+}
+
+FunctionCtor::FunctionCtor(Context *scope)
+    : FunctionObject(scope)
+{
+}
+
+void FunctionCtor::construct(Context *ctx)
+{
+    Q_UNIMPLEMENTED();
+}
+
+void FunctionCtor::call(Context *ctx)
+{
+    Q_UNIMPLEMENTED();
+}
+
+FunctionPrototype::FunctionPrototype(Context *ctx, FunctionObject *ctor)
+    : FunctionObject(ctx)
+{
+    setProperty(ctx, QLatin1String("constructor"), Value::fromObject(ctor));
+    setProperty(ctx, QLatin1String("toString"), method_toString, 0);
+    setProperty(ctx, QLatin1String("apply"), method_apply, 0);
+    setProperty(ctx, QLatin1String("call"), method_call, 0);
+    setProperty(ctx, QLatin1String("bind"), method_bind, 0);
+}
+
+void FunctionPrototype::method_toString(Context *ctx)
+{
+    if (FunctionObject *fun = ctx->thisObject.asFunctionObject()) {
+        ctx->result = Value::fromString(ctx, QLatin1String("function() { [code] }"));
+    } else {
+        assert(!"type error");
+    }
+}
+
+void FunctionPrototype::method_apply(Context *ctx)
+{
+    if (FunctionObject *fun = ctx->thisObject.asFunctionObject()) {
+        Q_UNIMPLEMENTED();
+    } else {
+        assert(!"type error");
+    }
+}
+
+void FunctionPrototype::method_call(Context *ctx)
+{
+    if (FunctionObject *fun = ctx->thisObject.asFunctionObject()) {
+        Value thisArg = ctx->argument(0);
+        QVector<Value> args(ctx->argumentCount ? ctx->argumentCount - 1 : 0);
+        if (ctx->argumentCount)
+            qCopy(ctx->arguments + 1, ctx->arguments + ctx->argumentCount, args.begin());
+        __qmljs_call_value(ctx, &ctx->result, &thisArg, &ctx->thisObject, args.data(), args.size());
+    } else {
+        assert(!"type error");
+    }
+}
+
+void FunctionPrototype::method_bind(Context *ctx)
+{
+    if (FunctionObject *fun = ctx->thisObject.asFunctionObject()) {
+        Q_UNIMPLEMENTED();
+    } else {
+        assert(!"type error");
+    }
+}
+
+//
 // Date object
 //
 Value DateCtor::create(ExecutionEngine *engine)
index 0aaeee8..a1a5528 100644 (file)
@@ -134,6 +134,27 @@ protected:
     static void method_unshift(Context *ctx);
 };
 
+struct FunctionCtor: FunctionObject
+{
+    static Value create(ExecutionEngine *engine);
+
+    FunctionCtor(Context *scope);
+
+    virtual void construct(Context *ctx);
+    virtual void call(Context *ctx);
+};
+
+struct FunctionPrototype: FunctionObject
+{
+    FunctionPrototype(Context *ctx, FunctionObject *ctor);
+
+protected:
+    static void method_toString(Context *ctx);
+    static void method_apply(Context *ctx);
+    static void method_call(Context *ctx);
+    static void method_bind(Context *ctx);
+};
+
 struct DateCtor: FunctionObject
 {
     static Value create(ExecutionEngine *engine);