diff options
-rw-r--r-- | qmljs_objects.cpp | 24 | ||||
-rw-r--r-- | qmljs_objects.h | 6 | ||||
-rw-r--r-- | qv4ecmaobjects.cpp | 82 | ||||
-rw-r--r-- | qv4ecmaobjects_p.h | 21 |
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); |