Changeset 62661 in webkit


Ignore:
Timestamp:
Jul 7, 2010 7:10:50 AM (14 years ago)
Author:
commit-queue@webkit.org
Message:

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

Reviewed by Kenneth Rohde Christiansen.

Implementation of QScriptValue::isArray()
https://bugs.webkit.org/show_bug.cgi?id=41713

Since we don't have access to the Class? internal property of
builtins (including Array), the solution was to keep the original 'Array'
(constructor) and 'Array.prototype' objects and use them to identify
if a given object is an Array.

Also uncomment some tests and add some tests of newArray() that
depended on isArray().

  • api/qscriptengine_p.cpp: (QScriptEnginePrivate::QScriptEnginePrivate): (QScriptEnginePrivate::~QScriptEnginePrivate):
  • api/qscriptengine_p.h: (QScriptEnginePrivate::isArray):
  • api/qscriptvalue.cpp: (QScriptValue::isArray):
  • api/qscriptvalue.h:
  • api/qscriptvalue_p.h: (QScriptValuePrivate::isArray):
  • tests/qscriptengine/tst_qscriptengine.cpp: (tst_QScriptEngine::newArray):
Location:
trunk/JavaScriptCore/qt
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/qt/ChangeLog

    r62547 r62661  
     12010-07-07  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
     2
     3        Reviewed by Kenneth Rohde Christiansen.
     4
     5        Implementation of QScriptValue::isArray()
     6        https://bugs.webkit.org/show_bug.cgi?id=41713
     7
     8        Since we don't have access to the [[Class]] internal property of
     9        builtins (including Array), the solution was to keep the original 'Array'
     10        (constructor) and 'Array.prototype' objects and use them to identify
     11        if a given object is an Array.
     12
     13        Also uncomment some tests and add some tests of newArray() that
     14        depended on isArray().
     15
     16        * api/qscriptengine_p.cpp:
     17        (QScriptEnginePrivate::QScriptEnginePrivate):
     18        (QScriptEnginePrivate::~QScriptEnginePrivate):
     19        * api/qscriptengine_p.h:
     20        (QScriptEnginePrivate::isArray):
     21        * api/qscriptvalue.cpp:
     22        (QScriptValue::isArray):
     23        * api/qscriptvalue.h:
     24        * api/qscriptvalue_p.h:
     25        (QScriptValuePrivate::isArray):
     26        * tests/qscriptengine/tst_qscriptengine.cpp:
     27        (tst_QScriptEngine::newArray):
     28
    1292010-07-06  Jedrzej Nowacki  <jedrzej.nowacki@nokia.com>
    230
  • trunk/JavaScriptCore/qt/api/qscriptengine_p.cpp

    r62382 r62661  
    3333    , m_context(JSGlobalContextCreate(0))
    3434    , m_exception(0)
     35    , m_arrayConstructor(0)
     36    , m_arrayPrototype(0)
    3537{
     38    JSObjectRef globalObject = JSContextGetGlobalObject(m_context);
     39
     40    // Save references to the Array constructor and prototype.
     41    JSRetainPtr<JSStringRef> arrayName(Adopt, JSStringCreateWithUTF8CString("Array"));
     42    JSValueRef arrayConstructor = JSObjectGetProperty(m_context, globalObject, arrayName.get(), /* exception */ 0);
     43    Q_ASSERT(JSValueIsObject(m_context, arrayConstructor));
     44    m_arrayConstructor = JSValueToObject(m_context, arrayConstructor, /* exception */ 0);
     45    JSValueProtect(m_context, m_arrayConstructor);
     46
     47    // Note that this is not the [[Prototype]] internal property (which we could
     48    // get via JSObjectGetPrototype), but the Array.prototype, that will be set
     49    // as [[Prototype]] of Array instances.
     50    JSRetainPtr<JSStringRef> prototypeName(Adopt, JSStringCreateWithUTF8CString("prototype"));
     51    JSValueRef arrayPrototype = JSObjectGetProperty(m_context, m_arrayConstructor, prototypeName.get(), /* exception */ 0);
     52    Q_ASSERT(JSValueIsObject(m_context, arrayPrototype));
     53    m_arrayPrototype = arrayPrototype;
     54    JSValueProtect(m_context, m_arrayPrototype);
    3655}
    3756
    3857QScriptEnginePrivate::~QScriptEnginePrivate()
    3958{
     59    JSValueUnprotect(m_context, m_arrayConstructor);
     60    JSValueUnprotect(m_context, m_arrayPrototype);
    4061    if (m_exception)
    4162        JSValueUnprotect(m_context, m_exception);
  • trunk/JavaScriptCore/qt/api/qscriptengine_p.h

    r62382 r62661  
    7878
    7979    inline operator JSGlobalContextRef() const;
     80
     81    inline bool isArray(JSValueRef value) const;
    8082private:
    8183    QScriptEngine* q_ptr;
    8284    JSGlobalContextRef m_context;
    8385    JSValueRef m_exception;
     86
     87    JSObjectRef m_arrayConstructor;
     88    JSValueRef m_arrayPrototype;
    8489};
    8590
     
    212217}
    213218
     219bool QScriptEnginePrivate::isArray(JSValueRef value) const
     220{
     221    // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value
     222    // is an array if it was created with the Array constructor or if it is the Array.prototype.
     223    return JSValueIsInstanceOfConstructor(m_context, value, m_arrayConstructor, /* exception */ 0) || JSValueIsStrictEqual(m_context, value, m_arrayPrototype);
     224}
     225
    214226#endif
  • trunk/JavaScriptCore/qt/api/qscriptvalue.cpp

    r62547 r62661  
    311311{
    312312    return d_ptr->isError();
     313}
     314
     315/*!
     316  Returns true if this QScriptValue is an object of the Array class;
     317  otherwise returns false.
     318
     319  \sa QScriptEngine::newArray()
     320*/
     321bool QScriptValue::isArray() const
     322{
     323    return d_ptr->isArray();
    313324}
    314325
  • trunk/JavaScriptCore/qt/api/qscriptvalue.h

    r62547 r62661  
    109109    bool isObject() const;
    110110    bool isError() const;
     111    bool isArray() const;
    111112
    112113    QString toString() const;
  • trunk/JavaScriptCore/qt/api/qscriptvalue_p.h

    r62547 r62661  
    102102    inline bool isObject();
    103103    inline bool isFunction();
     104    inline bool isArray();
    104105
    105106    inline QString toString() const;
     
    445446}
    446447
     448bool QScriptValuePrivate::isArray()
     449{
     450    switch (m_state) {
     451    case JSValue:
     452        if (refinedJSValue() != JSObject)
     453            return false;
     454        // Fall-through.
     455    case JSObject:
     456        return m_engine->isArray(*this);
     457    default:
     458        return false;
     459    }
     460}
     461
    447462QString QScriptValuePrivate::toString() const
    448463{
  • trunk/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp

    r62377 r62661  
    417417    QScriptValue array = eng.newArray();
    418418    QCOMPARE(array.isValid(), true);
    419     // QCOMPARE(array.isArray(), true);
     419    QCOMPARE(array.isArray(), true);
    420420    QCOMPARE(array.isObject(), true);
    421421    QVERIFY(!array.isFunction());
     
    424424    // Prototype should be Array.prototype.
    425425    QCOMPARE(array.prototype().isValid(), true);
    426     // QCOMPARE(array.prototype().isArray(), true);
     426    QCOMPARE(array.prototype().isArray(), true);
    427427    QCOMPARE(array.prototype().strictlyEquals(eng.evaluate("Array.prototype")), true);
    428428
    429429    QScriptValue arrayWithSize = eng.newArray(42);
    430430    QCOMPARE(arrayWithSize.isValid(), true);
    431     // QCOMPARE(arrayWithSize.isArray(), true);
     431    QCOMPARE(arrayWithSize.isArray(), true);
    432432    QCOMPARE(arrayWithSize.isObject(), true);
    433433    QCOMPARE(arrayWithSize.property("length").toInt32(), 42);
     434
     435    // task 218092
     436    {
     437        QScriptValue ret = eng.evaluate("[].splice(0, 0, 'a')");
     438        QVERIFY(ret.isArray());
     439        QCOMPARE(ret.property("length").toInt32(), 0);
     440    }
     441    {
     442        QScriptValue ret = eng.evaluate("['a'].splice(0, 1, 'b')");
     443        QVERIFY(ret.isArray());
     444        QCOMPARE(ret.property("length").toInt32(), 1);
     445    }
     446    {
     447        QScriptValue ret = eng.evaluate("['a', 'b'].splice(0, 1, 'c')");
     448        QVERIFY(ret.isArray());
     449        QCOMPARE(ret.property("length").toInt32(), 1);
     450    }
     451    {
     452        QScriptValue ret = eng.evaluate("['a', 'b', 'c'].splice(0, 2, 'd')");
     453        QVERIFY(ret.isArray());
     454        QCOMPARE(ret.property("length").toInt32(), 2);
     455    }
     456    {
     457        QScriptValue ret = eng.evaluate("['a', 'b', 'c'].splice(1, 2, 'd', 'e', 'f')");
     458        QVERIFY(ret.isArray());
     459        QCOMPARE(ret.property("length").toInt32(), 2);
     460    }
    434461}
    435462
Note: See TracChangeset for help on using the changeset viewer.