From ad255eac6aaba9ac1689145bbf47376c354996aa Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 29 Jul 2009 12:58:20 +0200 Subject: set calledAsConstructor to true when function is called as constructor --- src/script/api/qscriptcontext.cpp | 5 ++++ src/script/api/qscriptcontext_p.h | 1 + src/script/bridge/qscriptclassobject.cpp | 3 +++ src/script/bridge/qscriptfunction.cpp | 2 ++ tests/auto/qscriptcontext/tst_qscriptcontext.cpp | 32 ++++++++++++++++++++++++ 5 files changed, 43 insertions(+) diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp index f0f7b24..0efb037 100644 --- a/src/script/api/qscriptcontext.cpp +++ b/src/script/api/qscriptcontext.cpp @@ -189,6 +189,11 @@ const QScriptContextPrivate *QScriptContextPrivate::get(const QScriptContext *q) return q->d_func(); } +QScriptContextPrivate *QScriptContextPrivate::get(QScriptContext *q) +{ + return q->d_func(); +} + /*! \internal */ diff --git a/src/script/api/qscriptcontext_p.h b/src/script/api/qscriptcontext_p.h index 1aaf546..43efd06 100644 --- a/src/script/api/qscriptcontext_p.h +++ b/src/script/api/qscriptcontext_p.h @@ -81,6 +81,7 @@ public: static QScriptContext *create(JSC::ExecState *frame, QScriptEnginePrivate *engine); static const QScriptContextPrivate *get(const QScriptContext *q); + static QScriptContextPrivate *get(QScriptContext *q); JSC::ExecState *frame; bool calledAsConstructor; diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp index e173ebc..512c00e 100644 --- a/src/script/bridge/qscriptclassobject.cpp +++ b/src/script/bridge/qscriptclassobject.cpp @@ -45,6 +45,8 @@ #include "../api/qscriptengine.h" #include "../api/qscriptengine_p.h" +#include "../api/qscriptcontext.h" +#include "../api/qscriptcontext_p.h" #include "../api/qscriptclass.h" #include "../api/qscriptclasspropertyiterator.h" @@ -240,6 +242,7 @@ JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObjec QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); JSC::ExecState *previousFrame = eng_p->currentFrame; QScriptContext *ctx = eng_p->contextForFrame(exec); + QScriptContextPrivate::get(ctx)->calledAsConstructor = true; eng_p->currentFrame = exec; QScriptValue defaultObject = ctx->thisObject(); QScriptValue result = qvariant_cast(scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx))); diff --git a/src/script/bridge/qscriptfunction.cpp b/src/script/bridge/qscriptfunction.cpp index ef97f6f..777bd3b 100644 --- a/src/script/bridge/qscriptfunction.cpp +++ b/src/script/bridge/qscriptfunction.cpp @@ -143,6 +143,7 @@ JSC::JSObject* FunctionWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObje QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(self->data->engine); JSC::ExecState *previousFrame = eng_p->currentFrame; QScriptContext *ctx = eng_p->contextForFrame(exec); + QScriptContextPrivate::get(ctx)->calledAsConstructor = true; eng_p->currentFrame = exec; //We might have nested eval inside our function so we should create another scope @@ -213,6 +214,7 @@ JSC::JSObject* FunctionWithArgWrapper::proxyConstruct(JSC::ExecState *exec, JSC: QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(self->data->engine); JSC::ExecState *previousFrame = eng_p->currentFrame; QScriptContext *ctx = eng_p->contextForFrame(exec); + QScriptContextPrivate::get(ctx)->calledAsConstructor = true; eng_p->currentFrame = exec; //We might have nested eval inside our function so we should create another scope diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index 8b3d1d7..d9fb1ff 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -73,6 +73,7 @@ private slots: void pushAndPopScope(); void getSetActivationObject(); void toString(); + void calledAsConstructor(); void argumentsObjectInNative(); }; @@ -743,6 +744,37 @@ void tst_QScriptContext::toString() QCOMPARE(ret.toString(), QString::fromLatin1("foo (first=1, second=2, third=3) at script.qs:2")); } +static QScriptValue storeCalledAsConstructor(QScriptContext *ctx, QScriptEngine *eng) +{ + ctx->callee().setProperty("calledAsConstructor", ctx->isCalledAsConstructor()); + return eng->undefinedValue(); +} + +static QScriptValue storeCalledAsConstructorV2(QScriptContext *ctx, QScriptEngine *eng, void *) +{ + ctx->callee().setProperty("calledAsConstructor", ctx->isCalledAsConstructor()); + return eng->undefinedValue(); +} + +void tst_QScriptContext::calledAsConstructor() +{ + QScriptEngine eng; + { + QScriptValue fun = eng.newFunction(storeCalledAsConstructor); + fun.call(); + QVERIFY(!fun.property("calledAsConstructor").toBool()); + fun.construct(); + QVERIFY(fun.property("calledAsConstructor").toBool()); + } + { + QScriptValue fun = eng.newFunction(storeCalledAsConstructorV2, (void*)0); + fun.call(); + QVERIFY(!fun.property("calledAsConstructor").toBool()); + fun.construct(); + QVERIFY(fun.property("calledAsConstructor").toBool()); + } +} + static QScriptValue argumentsObjectInNative_test1(QScriptContext *ctx, QScriptEngine *) { #define VERIFY(statement) \ -- cgit v0.12