Changeset 171390 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Jul 22, 2014, 9:18:35 PM (11 years ago)
Author:
[email protected]
Message:

Array.concat() should work on runtime arrays too.
<https://webkit.org/b/135179>

Reviewed by Geoffrey Garen.

  • jsc.cpp:

(WTF::RuntimeArray::create):
(WTF::RuntimeArray::~RuntimeArray):
(WTF::RuntimeArray::destroy):
(WTF::RuntimeArray::getOwnPropertySlot):
(WTF::RuntimeArray::getOwnPropertySlotByIndex):
(WTF::RuntimeArray::put):
(WTF::RuntimeArray::deleteProperty):
(WTF::RuntimeArray::getLength):
(WTF::RuntimeArray::createPrototype):
(WTF::RuntimeArray::createStructure):
(WTF::RuntimeArray::finishCreation):
(WTF::RuntimeArray::RuntimeArray):
(WTF::RuntimeArray::lengthGetter):
(GlobalObject::finishCreation):
(functionCreateRuntimeArray):

  • Added support to create a runtime array for testing purpose.
  • runtime/ArrayPrototype.cpp:

(JSC::getLength):

  • Added fast case for when the array object is a JSArray.

(JSC::arrayProtoFuncJoin):

  • Added a needed but missing exception check.

(JSC::arrayProtoFuncConcat):

  • Use getLength() to compute the array length instead of assuming that the array is a JSArray instance.
  • tests/stress/regexp-matches-array.js: Added.

(testArrayConcat):

  • tests/stress/runtime-array.js: Added.

(testArrayConcat):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r171387 r171390  
     12014-07-22  Mark Lam  <[email protected]>
     2
     3        Array.concat() should work on runtime arrays too.
     4        <https://webkit.org/b/135179>
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * jsc.cpp:
     9        (WTF::RuntimeArray::create):
     10        (WTF::RuntimeArray::~RuntimeArray):
     11        (WTF::RuntimeArray::destroy):
     12        (WTF::RuntimeArray::getOwnPropertySlot):
     13        (WTF::RuntimeArray::getOwnPropertySlotByIndex):
     14        (WTF::RuntimeArray::put):
     15        (WTF::RuntimeArray::deleteProperty):
     16        (WTF::RuntimeArray::getLength):
     17        (WTF::RuntimeArray::createPrototype):
     18        (WTF::RuntimeArray::createStructure):
     19        (WTF::RuntimeArray::finishCreation):
     20        (WTF::RuntimeArray::RuntimeArray):
     21        (WTF::RuntimeArray::lengthGetter):
     22        (GlobalObject::finishCreation):
     23        (functionCreateRuntimeArray):
     24        - Added support to create a runtime array for testing purpose.
     25        * runtime/ArrayPrototype.cpp:
     26        (JSC::getLength):
     27        - Added fast case for when the array object is a JSArray.
     28        (JSC::arrayProtoFuncJoin):
     29        - Added a needed but missing exception check.
     30        (JSC::arrayProtoFuncConcat):
     31        - Use getLength() to compute the array length instead of assuming that
     32          the array is a JSArray instance.
     33        * tests/stress/regexp-matches-array.js: Added.
     34        (testArrayConcat):
     35        * tests/stress/runtime-array.js: Added.
     36        (testArrayConcat):
     37
    1382014-07-22  Brent Fulgham  <[email protected]>
    239
  • trunk/Source/JavaScriptCore/jsc.cpp

    r171387 r171390  
    2323#include "config.h"
    2424
     25#include "ArrayPrototype.h"
    2526#include "ButterflyInlines.h"
    2627#include "BytecodeGenerator.h"
     
    115116class Masuqerader;
    116117class Root;
     118class RuntimeArray;
    117119
    118120class Element : public JSNonFinalObject {
     
    294296};
    295297
     298class RuntimeArray : public JSArray {
     299public:
     300    typedef JSArray Base;
     301
     302    static RuntimeArray* create(ExecState* exec)
     303    {
     304        VM& vm = exec->vm();
     305        JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     306        Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));
     307        RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(*exec->heap())) RuntimeArray(exec, structure);
     308        runtimeArray->finishCreation(exec);
     309        vm.heap.addFinalizer(runtimeArray, destroy);
     310        return runtimeArray;
     311    }
     312
     313    ~RuntimeArray() { }
     314
     315    static void destroy(JSCell* cell)
     316    {
     317        static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
     318    }
     319
     320    static const bool needsDestruction = false;
     321
     322    static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
     323    {
     324        RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
     325        if (propertyName == exec->propertyNames().length) {
     326            slot.setCacheableCustom(thisObject, DontDelete | ReadOnly | DontEnum, thisObject->lengthGetter);
     327            return true;
     328        }
     329
     330        unsigned index = propertyName.asIndex();
     331        if (index < thisObject->getLength()) {
     332            ASSERT(index != PropertyName::NotAnIndex);
     333            slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index]));
     334            return true;
     335        }
     336
     337        return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
     338    }
     339
     340    static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
     341    {
     342        RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
     343        if (index < thisObject->getLength()) {
     344            slot.setValue(thisObject, DontDelete | DontEnum, jsNumber(thisObject->m_vector[index]));
     345            return true;
     346        }
     347
     348        return JSObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
     349    }
     350
     351    static NO_RETURN_DUE_TO_CRASH void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&)
     352    {
     353        RELEASE_ASSERT_NOT_REACHED();
     354    }
     355
     356    static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, ExecState*, PropertyName)
     357    {
     358        RELEASE_ASSERT_NOT_REACHED();
     359    }
     360
     361    unsigned getLength() const { return m_vector.size(); }
     362
     363    DECLARE_INFO;
     364
     365    static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)
     366    {
     367        return globalObject->arrayPrototype();
     368    }
     369
     370    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     371    {
     372        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass);
     373    }
     374
     375protected:
     376    void finishCreation(ExecState* exec)
     377    {
     378        Base::finishCreation(exec->vm());
     379        ASSERT(inherits(info()));
     380
     381        for (size_t i = 0; i < exec->argumentCount(); i++)
     382            m_vector.append(exec->argument(i).toInt32(exec));
     383    }
     384
     385    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSArray::StructureFlags;
     386
     387private:
     388    RuntimeArray(ExecState* exec, Structure* structure)
     389        : JSArray(exec->vm(), structure, 0)
     390    {
     391    }
     392
     393    static EncodedJSValue lengthGetter(ExecState* exec, JSObject*, EncodedJSValue thisValue, PropertyName)
     394    {
     395        RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(JSValue::decode(thisValue));
     396        if (!thisObject)
     397            return throwVMTypeError(exec);
     398        return JSValue::encode(jsNumber(thisObject->getLength()));
     399    }
     400
     401    Vector<int> m_vector;
     402};
     403
    296404const ClassInfo Element::s_info = { "Element", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Element) };
    297405const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Masquerader) };
    298406const ClassInfo Root::s_info = { "Root", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Root) };
    299407const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ImpureGetter) };
     408const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeArray) };
    300409
    301410ElementHandleOwner* Element::handleOwner()
     
    318427
    319428static EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState*);
     429static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState*);
    320430static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*);
    321431static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*);
     
    503613
    504614        addFunction(vm, "createProxy", functionCreateProxy, 1);
     615        addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
    505616
    506617        addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
     
    674785    JSProxy* proxy = JSProxy::create(exec->vm(), structure, jsTarget);
    675786    return JSValue::encode(proxy);
     787}
     788
     789EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState* exec)
     790{
     791    JSLockHolder lock(exec);
     792    RuntimeArray* array = RuntimeArray::create(exec);
     793    return JSValue::encode(array);
    676794}
    677795
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r171328 r171390  
    160160static ALWAYS_INLINE unsigned getLength(ExecState* exec, JSObject* obj)
    161161{
     162    if (isJSArray(obj))
     163        return jsCast<JSArray*>(obj)->length();
    162164    return obj->get(exec, exec->propertyNames().length).toUInt32(exec);
    163165}
     
    413415    for (; k < length; k++) {
    414416        JSValue element = thisObj->get(exec, k);
     417        if (exec->hadException())
     418            return JSValue::encode(jsUndefined());
    415419        if (!element.isUndefinedOrNull())
    416420            stringJoiner.append(element.toWTFStringInline(exec));
     
    430434
    431435    for (size_t i = 0;;) {
    432         if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg))
    433             finalArraySize += currentArray->length();
    434         else
     436        if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
     437            finalArraySize += getLength(exec, currentArray);
     438            if (exec->hadException())
     439                return JSValue::encode(jsUndefined());
     440        } else
    435441            finalArraySize++;
    436442        if (i == argCount)
     
    451457    for (size_t i = 0;;) {
    452458        if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
    453             unsigned length = currentArray->length();
     459            unsigned length = getLength(exec, currentArray);
     460            if (exec->hadException())
     461                return JSValue::encode(jsUndefined());
    454462            for (unsigned k = 0; k < length; ++k) {
    455463                JSValue v = getProperty(exec, currentArray, k);
Note: See TracChangeset for help on using the changeset viewer.