Changeset 64130 in webkit


Ignore:
Timestamp:
Jul 27, 2010 8:37:25 AM (14 years ago)
Author:
commit-queue@webkit.org
Message:

2010-07-27 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>

Reviewed by Kenneth Rohde Christiansen.

[Qt] Implement QScriptEngine::newFunction() parts that doesn't depend on QScriptContext
https://bugs.webkit.org/show_bug.cgi?id=42174

Since our function can be called in Javascript both as a function
and as a constructor, we couldn't use the existing
JSObjectMakeFunctionWithCallback() and JSObjectMakeConstructor().

Instead, a JSClassRef was created, implementing the needed
callbacks (the callAsConstructor is not there yet because its
behaviour depends on QScriptContext).

For the moment, QScriptContext is defined as a void type, since we
still don't use it.

The variant of newFunction() that also takes an external argument
was also implemented. The details of implementation were added to
the qscriptfunction{.c,_p.h} files.

This commit also adds tests, some of them from Qt's upstream.

  • api/QtScript.pro:
  • api/qscriptengine.cpp: (QScriptEngine::newFunction):
  • api/qscriptengine.h:
  • api/qscriptengine_p.cpp: (QScriptEnginePrivate::QScriptEnginePrivate): (QScriptEnginePrivate::~QScriptEnginePrivate): (QScriptEnginePrivate::newFunction):
  • api/qscriptengine_p.h:
  • api/qscriptfunction.cpp: Added. (qt_NativeFunction_finalize): (qt_NativeFunction_callAsFunction): (qt_NativeFunctionWithArg_finalize): (qt_NativeFunctionWithArg_callAsFunction):
  • api/qscriptfunction_p.h: Added. (QNativeFunctionData::QNativeFunctionData): (QNativeFunctionWithArgData::QNativeFunctionWithArgData):
  • api/qscriptoriginalglobalobject_p.h: (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject): (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject): (QScriptOriginalGlobalObject::functionPrototype):
  • tests/qscriptengine/tst_qscriptengine.cpp: (myFunction): (myFunctionWithArg): (myFunctionThatReturns): (myFunctionThatReturnsWithoutEngine): (myFunctionThatReturnsWrongEngine): (tst_QScriptEngine::newFunction):
Location:
trunk/JavaScriptCore/qt
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/qt/ChangeLog

    r63980 r64130  
     12010-07-27  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        [Qt] Implement QScriptEngine::newFunction() parts that doesn't depend on QScriptContext
     6        https://bugs.webkit.org/show_bug.cgi?id=42174
     7
     8        Since our function can be called in Javascript both as a function
     9        and as a constructor, we couldn't use the existing
     10        JSObjectMakeFunctionWithCallback() and JSObjectMakeConstructor().
     11
     12        Instead, a JSClassRef was created, implementing the needed
     13        callbacks (the callAsConstructor is not there yet because its
     14        behaviour depends on QScriptContext).
     15
     16        For the moment, QScriptContext is defined as a void type, since we
     17        still don't use it.
     18
     19        The variant of newFunction() that also takes an external argument
     20        was also implemented. The details of implementation were added to
     21        the qscriptfunction{.c,_p.h} files.
     22
     23        This commit also adds tests, some of them from Qt's upstream.
     24
     25        * api/QtScript.pro:
     26        * api/qscriptengine.cpp:
     27        (QScriptEngine::newFunction):
     28        * api/qscriptengine.h:
     29        * api/qscriptengine_p.cpp:
     30        (QScriptEnginePrivate::QScriptEnginePrivate):
     31        (QScriptEnginePrivate::~QScriptEnginePrivate):
     32        (QScriptEnginePrivate::newFunction):
     33        * api/qscriptengine_p.h:
     34        * api/qscriptfunction.cpp: Added.
     35        (qt_NativeFunction_finalize):
     36        (qt_NativeFunction_callAsFunction):
     37        (qt_NativeFunctionWithArg_finalize):
     38        (qt_NativeFunctionWithArg_callAsFunction):
     39        * api/qscriptfunction_p.h: Added.
     40        (QNativeFunctionData::QNativeFunctionData):
     41        (QNativeFunctionWithArgData::QNativeFunctionWithArgData):
     42        * api/qscriptoriginalglobalobject_p.h:
     43        (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject):
     44        (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject):
     45        (QScriptOriginalGlobalObject::functionPrototype):
     46        * tests/qscriptengine/tst_qscriptengine.cpp:
     47        (myFunction):
     48        (myFunctionWithArg):
     49        (myFunctionThatReturns):
     50        (myFunctionThatReturnsWithoutEngine):
     51        (myFunctionThatReturnsWrongEngine):
     52        (tst_QScriptEngine::newFunction):
     53
    1542010-07-23  Jedrzej Nowacki  <jedrzej.nowacki@nokia.com>
    255
  • trunk/JavaScriptCore/qt/api/QtScript.pro

    r63318 r64130  
    2929            $$PWD/qscriptprogram.cpp \
    3030            $$PWD/qscriptsyntaxcheckresult.cpp \
     31            $$PWD/qscriptfunction.cpp
    3132
    3233HEADERS +=  $$PWD/qtscriptglobal.h \
     
    4445            $$PWD/qscriptsyntaxcheckresult.h \
    4546            $$PWD/qscriptoriginalglobalobject_p.h \
    46 
     47            $$PWD/qscriptfunction_p.h
    4748
    4849!static: DEFINES += QT_MAKEDLL
  • trunk/JavaScriptCore/qt/api/qscriptengine.cpp

    r62377 r64130  
    259259
    260260/*!
     261    Creates a QScriptValue that wraps a native (C++) function. \a fun
     262    must be a C++ function with signature QScriptEngine::FunctionSignature.
     263    \a length is the number of arguments that \a fun expects; this becomes
     264    the \c{length} property of the created QScriptValue.
     265
     266    Note that \a length only gives an indication of the number of
     267    arguments that the function expects; an actual invocation of a
     268    function can include any number of arguments. You can check the
     269    \l{QScriptContext::argumentCount()}{argumentCount()} of the
     270    QScriptContext associated with the invocation to determine the
     271    actual number of arguments passed.
     272
     273    A \c{prototype} property is automatically created for the resulting
     274    function object, to provide for the possibility that the function
     275    will be used as a constructor.
     276
     277    By combining newFunction() and the property flags
     278    QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
     279    can create script object properties that behave like normal
     280    properties in script code, but are in fact accessed through
     281    functions (analogous to how properties work in \l{Qt's Property
     282    System}). Example:
     283
     284    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11
     285
     286    When the property \c{foo} of the script object is subsequently
     287    accessed in script code, \c{getSetFoo()} will be invoked to handle
     288    the access.  In this particular case, we chose to store the "real"
     289    value of \c{foo} as a property of the accessor function itself; you
     290    are of course free to do whatever you like in this function.
     291
     292    In the above example, a single native function was used to handle
     293    both reads and writes to the property; the argument count is used to
     294    determine if we are handling a read or write. You can also use two
     295    separate functions; just specify the relevant flag
     296    (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
     297    setting the property, e.g.:
     298
     299    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12
     300
     301    \sa QScriptValue::call()
     302*/
     303QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
     304{
     305    return QScriptValuePrivate::get(d_ptr->newFunction(fun, 0, length));
     306}
     307
     308/*!
     309    Creates a constructor function from \a fun, with the given \a length.
     310    The \c{prototype} property of the resulting function is set to be the
     311    given \a prototype. The \c{constructor} property of \a prototype is
     312    set to be the resulting function.
     313
     314    When a function is called as a constructor (e.g. \c{new Foo()}), the
     315    `this' object associated with the function call is the new object
     316    that the function is expected to initialize; the prototype of this
     317    default constructed object will be the function's public
     318    \c{prototype} property. If you always want the function to behave as
     319    a constructor (e.g. \c{Foo()} should also create a new object), or
     320    if you need to create your own object rather than using the default
     321    `this' object, you should make sure that the prototype of your
     322    object is set correctly; either by setting it manually, or, when
     323    wrapping a custom type, by having registered the defaultPrototype()
     324    of that type. Example:
     325
     326    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9
     327
     328    To wrap a custom type and provide a constructor for it, you'd typically
     329    do something like this:
     330
     331    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
     332*/
     333QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, const QScriptValue& prototype, int length)
     334{
     335    return QScriptValuePrivate::get(d_ptr->newFunction(fun, QScriptValuePrivate::get(prototype), length));
     336}
     337
     338/*!
     339    \internal
     340    \since 4.4
     341*/
     342QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg)
     343{
     344    return QScriptValuePrivate::get(d_ptr->newFunction(fun, arg));
     345}
     346
     347/*!
    261348  Creates a QtScript object of class Object.
    262349
     
    295382    return QScriptValuePrivate::get(d_ptr->globalObject());
    296383}
     384
     385/*!
     386    \typedef QScriptEngine::FunctionSignature
     387    \relates QScriptEngine
     388
     389    The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}.
     390
     391    A function with such a signature can be passed to
     392    QScriptEngine::newFunction() to wrap the function.
     393*/
     394
     395/*!
     396    \typedef QScriptEngine::FunctionWithArgSignature
     397    \relates QScriptEngine
     398
     399    The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}.
     400
     401    A function with such a signature can be passed to
     402    QScriptEngine::newFunction() to wrap the function.
     403*/
  • trunk/JavaScriptCore/qt/api/qscriptengine.h

    r62377 r64130  
    3131class QScriptEnginePrivate;
    3232
     33// FIXME: Remove this once QScriptContext is properly defined.
     34typedef void QScriptContext;
     35
    3336// Internal typedef
    3437typedef QExplicitlySharedDataPointer<QScriptEnginePrivate> QScriptEnginePtr;
     
    5760    QScriptValue nullValue();
    5861    QScriptValue undefinedValue();
     62
     63    typedef QScriptValue (*FunctionSignature)(QScriptContext *, QScriptEngine *);
     64    typedef QScriptValue (*FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *);
     65
     66    QScriptValue newFunction(FunctionSignature fun, int length = 0);
     67    QScriptValue newFunction(FunctionSignature fun, const QScriptValue& prototype, int length = 0);
     68    QScriptValue newFunction(FunctionWithArgSignature fun, void* arg);
     69
    5970    QScriptValue newObject();
    6071    QScriptValue newArray(uint length = 0);
  • trunk/JavaScriptCore/qt/api/qscriptengine_p.cpp

    r63318 r64130  
    2222#include "qscriptengine_p.h"
    2323
     24#include "qscriptfunction_p.h"
    2425#include "qscriptprogram_p.h"
    2526#include "qscriptvalue_p.h"
     
    3435    , m_exception(0)
    3536    , m_originalGlobalObject(m_context)
     37    , m_nativeFunctionClass(JSClassCreate(&qt_NativeFunctionClass))
     38    , m_nativeFunctionWithArgClass(JSClassCreate(&qt_NativeFunctionWithArgClass))
    3639{
    3740}
     
    3942QScriptEnginePrivate::~QScriptEnginePrivate()
    4043{
     44    JSClassRelease(m_nativeFunctionClass);
     45    JSClassRelease(m_nativeFunctionWithArgClass);
    4146    if (m_exception)
    4247        JSValueUnprotect(m_context, m_exception);
     
    8792}
    8893
     94QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length)
     95{
     96    // Note that this private data will be deleted in the object finalize function.
     97    QNativeFunctionData* data = new QNativeFunctionData(this, fun);
     98    JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionClass, reinterpret_cast<void*>(data));
     99    QScriptValuePrivate* proto = prototype ? prototype : newObject();
     100    return newFunction(funJS, proto);
     101}
     102
     103QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg)
     104{
     105    // Note that this private data will be deleted in the object finalize function.
     106    QNativeFunctionWithArgData* data = new QNativeFunctionWithArgData(this, fun, arg);
     107    JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionWithArgClass, reinterpret_cast<void*>(data));
     108    QScriptValuePrivate* proto = newObject();
     109    return newFunction(funJS, proto);
     110}
     111
     112QScriptValuePrivate* QScriptEnginePrivate::newFunction(JSObjectRef funJS, QScriptValuePrivate* prototype)
     113{
     114    JSObjectSetPrototype(m_context, funJS, m_originalGlobalObject.functionPrototype());
     115
     116    QScriptValuePrivate* result = new QScriptValuePrivate(this, funJS);
     117    static JSStringRef protoName = QScriptConverter::toString("prototype");
     118    static JSStringRef constructorName = QScriptConverter::toString("constructor");
     119    result->setProperty(protoName, prototype, QScriptValue::Undeletable);
     120    prototype->setProperty(constructorName, result, QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
     121
     122    return result;
     123}
     124
    89125QScriptValuePrivate* QScriptEnginePrivate::newObject() const
    90126{
  • trunk/JavaScriptCore/qt/api/qscriptengine_p.h

    r63318 r64130  
    7272    inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const;
    7373
     74    QScriptValuePrivate* newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length);
     75    QScriptValuePrivate* newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg);
     76    QScriptValuePrivate* newFunction(JSObjectRef funObject, QScriptValuePrivate* prototype);
     77
    7478    QScriptValuePrivate* newObject() const;
    7579    QScriptValuePrivate* newArray(uint length);
     
    9094
    9195    QScriptOriginalGlobalObject m_originalGlobalObject;
     96
     97    JSClassRef m_nativeFunctionClass;
     98    JSClassRef m_nativeFunctionWithArgClass;
    9299};
    93100
  • trunk/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h

    r63318 r64130  
    4646    inline bool isArray(JSValueRef value) const;
    4747    inline bool isError(JSValueRef value) const;
     48
     49    inline JSValueRef functionPrototype() const;
    4850private:
    4951    inline bool isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const;
     
    5860    JSObjectRef m_errorConstructor;
    5961    JSValueRef m_errorPrototype;
     62    JSObjectRef m_functionConstructor;
     63    JSValueRef m_functionPrototype;
    6064
    6165    // Reference to standard JS functions that are not exposed by JSC C API.
     
    7478    initializeMember(globalObject, propertyName.get(), "Array", m_arrayConstructor, m_arrayPrototype);
    7579    initializeMember(globalObject, propertyName.get(), "Error", m_errorConstructor, m_errorPrototype);
     80    initializeMember(globalObject, propertyName.get(), "Function", m_functionConstructor, m_functionPrototype);
    7681
    7782    propertyName.adopt(JSStringCreateWithUTF8CString("hasOwnProperty"));
     
    120125    JSValueUnprotect(m_context, m_errorConstructor);
    121126    JSValueUnprotect(m_context, m_errorPrototype);
     127    JSValueUnprotect(m_context, m_functionConstructor);
     128    JSValueUnprotect(m_context, m_functionPrototype);
    122129    JSValueUnprotect(m_context, m_hasOwnPropertyFunction);
    123130    JSValueUnprotect(m_context, m_getOwnPropertyNamesFunction);
     
    174181}
    175182
     183inline JSValueRef QScriptOriginalGlobalObject::functionPrototype() const
     184{
     185    return m_functionPrototype;
     186}
     187
    176188inline bool QScriptOriginalGlobalObject::isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const
    177189{
  • trunk/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp

    r62661 r64130  
    3636
    3737private slots:
     38    void newFunction();
    3839    void newObject();
    3940    void globalObject();
     
    5859    QVERIFY2(engine.evaluate("1+1").isValid(), "the expression should be evaluated and an valid result should be returned");
    5960    QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value");
     61}
     62
     63static QScriptValue myFunction(QScriptContext*, QScriptEngine* eng)
     64{
     65    return eng->nullValue();
     66}
     67
     68static QScriptValue myFunctionWithArg(QScriptContext*, QScriptEngine* eng, void* arg)
     69{
     70    int* result = reinterpret_cast<int*>(arg);
     71    return QScriptValue(eng, *result);
     72}
     73
     74static QScriptValue myFunctionThatReturns(QScriptContext*, QScriptEngine* eng)
     75{
     76    return QScriptValue(eng, 42);
     77}
     78
     79static QScriptValue myFunctionThatReturnsWithoutEngine(QScriptContext*, QScriptEngine*)
     80{
     81    return QScriptValue(1024);
     82}
     83
     84static QScriptValue myFunctionThatReturnsWrongEngine(QScriptContext*, QScriptEngine*, void* arg)
     85{
     86    QScriptEngine* wrongEngine = reinterpret_cast<QScriptEngine*>(arg);
     87    return QScriptValue(wrongEngine, 42);
     88}
     89
     90void tst_QScriptEngine::newFunction()
     91{
     92    QScriptEngine eng;
     93    {
     94        QScriptValue fun = eng.newFunction(myFunction);
     95        QCOMPARE(fun.isValid(), true);
     96        QCOMPARE(fun.isFunction(), true);
     97        QCOMPARE(fun.isObject(), true);
     98        // QCOMPARE(fun.scriptClass(), (QScriptClass*)0);
     99        // a prototype property is automatically constructed
     100        {
     101            QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal);
     102            QVERIFY(prot.isObject());
     103            QVERIFY(prot.property("constructor").strictlyEquals(fun));
     104            QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
     105            QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
     106            QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
     107            QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
     108        }
     109        // prototype should be Function.prototype
     110        QCOMPARE(fun.prototype().isValid(), true);
     111        QCOMPARE(fun.prototype().isFunction(), true);
     112        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
     113
     114        QCOMPARE(fun.call().isNull(), true);
     115        // QCOMPARE(fun.construct().isObject(), true);
     116    }
     117    // the overload that takes an extra argument
     118    {
     119        int expectedResult = 42;
     120        QScriptValue fun = eng.newFunction(myFunctionWithArg, reinterpret_cast<void*>(&expectedResult));
     121        QVERIFY(fun.isFunction());
     122        // QCOMPARE(fun.scriptClass(), (QScriptClass*)0);
     123        // a prototype property is automatically constructed
     124        {
     125            QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal);
     126            QVERIFY(prot.isObject());
     127            QVERIFY(prot.property("constructor").strictlyEquals(fun));
     128            QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
     129            QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
     130            QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
     131            QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
     132        }
     133        // prototype should be Function.prototype
     134        QCOMPARE(fun.prototype().isValid(), true);
     135        QCOMPARE(fun.prototype().isFunction(), true);
     136        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
     137
     138        QScriptValue result = fun.call();
     139        QCOMPARE(result.isNumber(), true);
     140        QCOMPARE(result.toInt32(), expectedResult);
     141    }
     142    // the overload that takes a prototype
     143    {
     144        QScriptValue proto = eng.newObject();
     145        QScriptValue fun = eng.newFunction(myFunction, proto);
     146        QCOMPARE(fun.isValid(), true);
     147        QCOMPARE(fun.isFunction(), true);
     148        QCOMPARE(fun.isObject(), true);
     149        // internal prototype should be Function.prototype
     150        QCOMPARE(fun.prototype().isValid(), true);
     151        QCOMPARE(fun.prototype().isFunction(), true);
     152        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
     153        // public prototype should be the one we passed
     154        QCOMPARE(fun.property("prototype").strictlyEquals(proto), true);
     155        QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
     156        QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
     157        QCOMPARE(proto.property("constructor").strictlyEquals(fun), true);
     158        QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
     159        QCOMPARE(proto.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
     160
     161        QCOMPARE(fun.call().isNull(), true);
     162        // QCOMPARE(fun.construct().isObject(), true);
     163    }
     164    // whether the return value is correct
     165    {
     166        QScriptValue fun = eng.newFunction(myFunctionThatReturns);
     167        QCOMPARE(fun.isValid(), true);
     168        QCOMPARE(fun.isFunction(), true);
     169        QCOMPARE(fun.isObject(), true);
     170
     171        QScriptValue result = fun.call();
     172        QCOMPARE(result.isNumber(), true);
     173        QCOMPARE(result.toInt32(), 42);
     174    }
     175    // whether the return value is assigned to the correct engine
     176    {
     177        QScriptValue fun = eng.newFunction(myFunctionThatReturnsWithoutEngine);
     178        QCOMPARE(fun.isValid(), true);
     179        QCOMPARE(fun.isFunction(), true);
     180        QCOMPARE(fun.isObject(), true);
     181
     182        QScriptValue result = fun.call();
     183        QCOMPARE(result.engine(), &eng);
     184        QCOMPARE(result.isNumber(), true);
     185        QCOMPARE(result.toInt32(), 1024);
     186    }
     187    // whether the return value is undefined when returning a value with wrong engine
     188    {
     189        QScriptEngine wrongEngine;
     190
     191        QScriptValue fun = eng.newFunction(myFunctionThatReturnsWrongEngine, reinterpret_cast<void*>(&wrongEngine));
     192        QCOMPARE(fun.isValid(), true);
     193        QCOMPARE(fun.isFunction(), true);
     194        QCOMPARE(fun.isObject(), true);
     195
     196        QTest::ignoreMessage(QtWarningMsg, "Value from different engine returned from native function, returning undefined value instead.");
     197        QScriptValue result = fun.call();
     198        QCOMPARE(result.isValid(), true);
     199        QCOMPARE(result.isUndefined(), true);
     200    }
    60201}
    61202
Note: See TracChangeset for help on using the changeset viewer.