aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qmljs_objects.cpp24
-rw-r--r--qmljs_objects.h6
-rw-r--r--qv4ecmaobjects.cpp82
-rw-r--r--qv4ecmaobjects_p.h21
4 files changed, 130 insertions, 3 deletions
diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp
index eace571ae4..4f26d2e311 100644
--- a/qmljs_objects.cpp
+++ b/qmljs_objects.cpp
@@ -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();
diff --git a/qmljs_objects.h b/qmljs_objects.h
index 60829d23e0..562da2f81c 100644
--- a/qmljs_objects.h
+++ b/qmljs_objects.h
@@ -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);
diff --git a/qv4ecmaobjects.cpp b/qv4ecmaobjects.cpp
index 35ed781dbf..4744faa1a6 100644
--- a/qv4ecmaobjects.cpp
+++ b/qv4ecmaobjects.cpp
@@ -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)
diff --git a/qv4ecmaobjects_p.h b/qv4ecmaobjects_p.h
index 0aaeee8970..a1a55284a4 100644
--- a/qv4ecmaobjects_p.h
+++ b/qv4ecmaobjects_p.h
@@ -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);