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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.