⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 175365 in webkit


Ignore:
Timestamp:
Oct 29, 2014, 8:54:23 PM (12 years ago)
Author:
akling@apple.com
Message:

Use plain JSArray for RegExp matches instead of a lazily populated custom object.
<https://webkit.org/b/138191>

Reviewed by Geoffrey Garen.

We're already offering two RegExp matching APIs, one that collects subpattern
matches (exec), and one that simply tests for a match (test).
Given that, it was pretty overkill to lazily populate the resulting array of
matches, since the user could simply use test() if they didn't need them.

This allows the JIT to generate better code for RegExp match arrays, and also
enables some fast paths in the JSC runtime that check if an object isJSArray().

Looks like ~1.5% improvement on Octane/regexp according to run-jsc-benchmarks.

  • jit/Repatch.cpp:

(JSC::tryCacheGetByID):

  • runtime/JSArray.h:

(JSC::createArrayButterflyWithExactLength): Deleted.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/RegExpCachedResult.cpp:

(JSC::RegExpCachedResult::visitChildren):
(JSC::RegExpCachedResult::lastResult):
(JSC::RegExpCachedResult::leftContext):
(JSC::RegExpCachedResult::rightContext):

  • runtime/RegExpCachedResult.h:

(JSC::RegExpCachedResult::RegExpCachedResult):
(JSC::RegExpCachedResult::record):
(JSC::RegExpCachedResult::input):

  • runtime/RegExpConstructor.cpp:

(JSC::RegExpConstructor::getBackref):
(JSC::RegExpConstructor::getLastParen):
(JSC::RegExpConstructor::getLeftContext):
(JSC::RegExpConstructor::getRightContext):

  • runtime/RegExpMatchesArray.cpp:

(JSC::createRegExpMatchesArray):
(JSC::RegExpMatchesArray::RegExpMatchesArray): Deleted.
(JSC::RegExpMatchesArray::create): Deleted.
(JSC::RegExpMatchesArray::finishCreation): Deleted.
(JSC::RegExpMatchesArray::visitChildren): Deleted.
(JSC::RegExpMatchesArray::reifyAllProperties): Deleted.
(JSC::RegExpMatchesArray::reifyMatchProperty): Deleted.
(JSC::RegExpMatchesArray::leftContext): Deleted.
(JSC::RegExpMatchesArray::rightContext): Deleted.

  • runtime/RegExpMatchesArray.h:

(JSC::RegExpMatchesArray::createStructure): Deleted.
(JSC::RegExpMatchesArray::reifyAllPropertiesIfNecessary): Deleted.
(JSC::RegExpMatchesArray::reifyMatchPropertyIfNecessary): Deleted.
(JSC::RegExpMatchesArray::getOwnPropertySlot): Deleted.
(JSC::RegExpMatchesArray::getOwnPropertySlotByIndex): Deleted.
(JSC::RegExpMatchesArray::put): Deleted.
(JSC::RegExpMatchesArray::putByIndex): Deleted.
(JSC::RegExpMatchesArray::deleteProperty): Deleted.
(JSC::RegExpMatchesArray::deletePropertyByIndex): Deleted.
(JSC::RegExpMatchesArray::getOwnPropertyNames): Deleted.
(JSC::RegExpMatchesArray::defineOwnProperty): Deleted.
(JSC::isRegExpMatchesArray): Deleted.

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::exec):

  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncMatch):

Location:
trunk/Source/JavaScriptCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r175362 r175365  
     12014-10-29  Andreas Kling  <akling@apple.com>
     2
     3        Use plain JSArray for RegExp matches instead of a lazily populated custom object.
     4        <https://webkit.org/b/138191>
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        We're already offering two RegExp matching APIs, one that collects subpattern
     9        matches (exec), and one that simply tests for a match (test).
     10        Given that, it was pretty overkill to lazily populate the resulting array of
     11        matches, since the user could simply use test() if they didn't need them.
     12
     13        This allows the JIT to generate better code for RegExp match arrays, and also
     14        enables some fast paths in the JSC runtime that check if an object isJSArray().
     15
     16        Looks like ~1.5% improvement on Octane/regexp according to run-jsc-benchmarks.
     17
     18        * jit/Repatch.cpp:
     19        (JSC::tryCacheGetByID):
     20        * runtime/JSArray.h:
     21        (JSC::createArrayButterflyWithExactLength): Deleted.
     22        * runtime/JSGlobalObject.cpp:
     23        (JSC::JSGlobalObject::init):
     24        * runtime/RegExpCachedResult.cpp:
     25        (JSC::RegExpCachedResult::visitChildren):
     26        (JSC::RegExpCachedResult::lastResult):
     27        (JSC::RegExpCachedResult::leftContext):
     28        (JSC::RegExpCachedResult::rightContext):
     29        * runtime/RegExpCachedResult.h:
     30        (JSC::RegExpCachedResult::RegExpCachedResult):
     31        (JSC::RegExpCachedResult::record):
     32        (JSC::RegExpCachedResult::input):
     33        * runtime/RegExpConstructor.cpp:
     34        (JSC::RegExpConstructor::getBackref):
     35        (JSC::RegExpConstructor::getLastParen):
     36        (JSC::RegExpConstructor::getLeftContext):
     37        (JSC::RegExpConstructor::getRightContext):
     38        * runtime/RegExpMatchesArray.cpp:
     39        (JSC::createRegExpMatchesArray):
     40        (JSC::RegExpMatchesArray::RegExpMatchesArray): Deleted.
     41        (JSC::RegExpMatchesArray::create): Deleted.
     42        (JSC::RegExpMatchesArray::finishCreation): Deleted.
     43        (JSC::RegExpMatchesArray::visitChildren): Deleted.
     44        (JSC::RegExpMatchesArray::reifyAllProperties): Deleted.
     45        (JSC::RegExpMatchesArray::reifyMatchProperty): Deleted.
     46        (JSC::RegExpMatchesArray::leftContext): Deleted.
     47        (JSC::RegExpMatchesArray::rightContext): Deleted.
     48        * runtime/RegExpMatchesArray.h:
     49        (JSC::RegExpMatchesArray::createStructure): Deleted.
     50        (JSC::RegExpMatchesArray::reifyAllPropertiesIfNecessary): Deleted.
     51        (JSC::RegExpMatchesArray::reifyMatchPropertyIfNecessary): Deleted.
     52        (JSC::RegExpMatchesArray::getOwnPropertySlot): Deleted.
     53        (JSC::RegExpMatchesArray::getOwnPropertySlotByIndex): Deleted.
     54        (JSC::RegExpMatchesArray::put): Deleted.
     55        (JSC::RegExpMatchesArray::putByIndex): Deleted.
     56        (JSC::RegExpMatchesArray::deleteProperty): Deleted.
     57        (JSC::RegExpMatchesArray::deletePropertyByIndex): Deleted.
     58        (JSC::RegExpMatchesArray::getOwnPropertyNames): Deleted.
     59        (JSC::RegExpMatchesArray::defineOwnProperty): Deleted.
     60        (JSC::isRegExpMatchesArray): Deleted.
     61        * runtime/RegExpObject.cpp:
     62        (JSC::RegExpObject::exec):
     63        * runtime/StringPrototype.cpp:
     64        (JSC::stringProtoFuncMatch):
     65
    1662014-10-29  Joseph Pecoraro  <pecoraro@apple.com>
    267
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r172176 r175365  
    639639    VM* vm = &exec->vm();
    640640
    641     if ((isJSArray(baseValue) || isRegExpMatchesArray(baseValue) || isJSString(baseValue)) && propertyName == exec->propertyNames().length) {
     641    if ((isJSArray(baseValue) || isJSString(baseValue)) && propertyName == exec->propertyNames().length) {
    642642        GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.baseGPR);
    643643#if USE(JSVALUE32_64)
     
    648648        MacroAssembler stubJit;
    649649
    650         if (isJSArray(baseValue) || isRegExpMatchesArray(baseValue)) {
     650        if (isJSArray(baseValue)) {
    651651            GPRReg scratchGPR = TempRegisterSet(stubInfo.patch.usedRegisters).getFreeGPR();
    652652            bool needToRestoreScratch = false;
  • trunk/Source/JavaScriptCore/runtime/JSArray.h

    r172618 r175365  
    189189        vm, intendedOwner, 0, 0, true, header, vectorLength * sizeof(EncodedJSValue));
    190190    return result;
    191 }
    192 
    193 inline Butterfly* createArrayButterflyWithExactLength(VM& vm, JSCell* intendedOwner, unsigned initialLength)
    194 {
    195     Butterfly* butterfly = Butterfly::create(
    196         vm, intendedOwner, 0, 0, true, indexingHeaderForArray(initialLength, initialLength),
    197         ArrayStorage::sizeFor(initialLength));
    198     ArrayStorage* storage = butterfly->arrayStorage();
    199     storage->m_indexBias = 0;
    200     storage->m_sparseMap.clear();
    201     storage->m_numValuesInVector = 0;
    202     return butterfly;
    203191}
    204192
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r173706 r175365  
    289289    for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
    290290        m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i];
    291    
    292     m_regExpMatchesArrayStructure.set(vm, this, RegExpMatchesArray::createStructure(vm, this, m_arrayPrototype.get()));
     291
     292    m_regExpMatchesArrayStructure.set(vm, this, Structure::create(vm, this, m_arrayPrototype.get(), TypeInfo(ObjectType, StructureFlags), JSArray::info(), ArrayWithSlowPutArrayStorage));
    293293   
    294294    RegExp* emptyRegex = RegExp::create(vm, "", NoFlags);
  • trunk/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp

    r163844 r175365  
    3838    visitor.append(&m_reifiedInput);
    3939    visitor.append(&m_reifiedResult);
     40    visitor.append(&m_reifiedLeftContext);
     41    visitor.append(&m_reifiedRightContext);
    4042}
    4143
    42 RegExpMatchesArray* RegExpCachedResult::lastResult(ExecState* exec, JSObject* owner)
     44JSArray* RegExpCachedResult::lastResult(ExecState* exec, JSObject* owner)
    4345{
    44     if (m_result) {
     46    if (!m_reified) {
    4547        m_reifiedInput.set(exec->vm(), owner, m_lastInput.get());
    46         m_reifiedResult.set(exec->vm(), owner, RegExpMatchesArray::create(exec, m_lastInput.get(), m_lastRegExp.get(), m_result));
    47         m_result = MatchResult::failed();
     48        m_reifiedResult.set(exec->vm(), owner, createRegExpMatchesArray(exec, m_lastInput.get(), m_lastRegExp.get(), m_result));
     49        m_reified = true;
    4850    }
    4951    return m_reifiedResult.get();
     52}
     53
     54JSString* RegExpCachedResult::leftContext(ExecState* exec, JSObject* owner)
     55{
     56    // Make sure we're reified.
     57    lastResult(exec, owner);
     58    if (!m_reifiedLeftContext)
     59        m_reifiedLeftContext.set(exec->vm(), owner, m_result.start ? jsSubstring(exec, m_reifiedInput.get(), 0, m_result.start) : jsEmptyString(exec));
     60    return m_reifiedLeftContext.get();
     61}
     62
     63JSString* RegExpCachedResult::rightContext(ExecState* exec, JSObject* owner)
     64{
     65    // Make sure we're reified.
     66    lastResult(exec, owner);
     67    if (!m_reifiedRightContext) {
     68        unsigned length = m_reifiedInput->length();
     69        m_reifiedRightContext.set(exec->vm(), owner, m_result.end != length ? jsSubstring(exec, m_reifiedInput.get(), m_result.end, length - m_result.end) : jsEmptyString(exec));
     70    }
     71    return m_reifiedRightContext.get();
    5072}
    5173
  • trunk/Source/JavaScriptCore/runtime/RegExpCachedResult.h

    r173269 r175365  
    3131namespace JSC {
    3232
     33class JSArray;
    3334class JSString;
    34 class RegExpMatchesArray;
    3535
    3636// RegExpCachedResult is used to track the cached results of the last
     
    4747    RegExpCachedResult(VM& vm, JSObject* owner, RegExp* emptyRegExp)
    4848        : m_result(0, 0)
     49        , m_reified(false)
    4950    {
    5051        m_lastInput.set(vm, owner, jsEmptyString(&vm));
     
    5657        m_lastRegExp.set(vm, owner, regExp);
    5758        m_lastInput.set(vm, owner, input);
     59        m_reifiedLeftContext.clear();
     60        m_reifiedRightContext.clear();
    5861        m_result = result;
     62        m_reified = false;
    5963    }
    6064
    61     RegExpMatchesArray* lastResult(ExecState*, JSObject* owner);
     65    JSArray* lastResult(ExecState*, JSObject* owner);
    6266    void setInput(ExecState*, JSObject* owner, JSString*);
     67
     68    JSString* leftContext(ExecState*, JSObject* owner);
     69    JSString* rightContext(ExecState*, JSObject* owner);
    6370
    6471    JSString* input()
    6572    {
    66         // If m_result showas a match then we're in a lazy state, so m_lastInput
    67         // is the most recent value of the input property. If not then we have
    68         // reified, in which case m_reifiedInput will contain the correct value.
    69         return m_result ? m_lastInput.get() : m_reifiedInput.get();
     73        return m_reified ? m_reifiedInput.get() : m_lastInput.get();
    7074    }
    7175
     
    7478private:
    7579    MatchResult m_result;
     80    bool m_reified;
    7681    WriteBarrier<JSString> m_lastInput;
    7782    WriteBarrier<RegExp> m_lastRegExp;
    78     WriteBarrier<RegExpMatchesArray> m_reifiedResult;
     83    WriteBarrier<JSArray> m_reifiedResult;
    7984    WriteBarrier<JSString> m_reifiedInput;
     85    WriteBarrier<JSString> m_reifiedLeftContext;
     86    WriteBarrier<JSString> m_reifiedRightContext;
    8087};
    8188
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp

    r171939 r175365  
    117117JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i)
    118118{
    119     RegExpMatchesArray* array = m_cachedResult.lastResult(exec, this);
     119    JSArray* array = m_cachedResult.lastResult(exec, this);
    120120
    121121    if (i < array->length()) {
     
    130130JSValue RegExpConstructor::getLastParen(ExecState* exec)
    131131{
    132     RegExpMatchesArray* array = m_cachedResult.lastResult(exec, this);
     132    JSArray* array = m_cachedResult.lastResult(exec, this);
    133133    unsigned length = array->length();
    134134    if (length > 1) {
     
    143143JSValue RegExpConstructor::getLeftContext(ExecState* exec)
    144144{
    145     return m_cachedResult.lastResult(exec, this)->leftContext(exec);
     145    return m_cachedResult.leftContext(exec, this);
    146146}
    147147
    148148JSValue RegExpConstructor::getRightContext(ExecState* exec)
    149149{
    150     return m_cachedResult.lastResult(exec, this)->rightContext(exec);
     150    return m_cachedResult.rightContext(exec, this);
    151151}
    152152   
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp

    r172618 r175365  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3232namespace JSC {
    3333
    34 const ClassInfo RegExpMatchesArray::s_info = {"Array", &JSArray::s_info, 0, CREATE_METHOD_TABLE(RegExpMatchesArray)};
    35 
    36 RegExpMatchesArray::RegExpMatchesArray(VM& vm, Butterfly* butterfly, JSGlobalObject* globalObject, JSString* input, RegExp* regExp, MatchResult result)
    37     : JSArray(vm, globalObject->regExpMatchesArrayStructure(), butterfly)
    38     , m_result(result)
    39     , m_state(ReifiedNone)
    40 {
    41     m_input.set(vm, this, input);
    42     m_regExp.set(vm, this, regExp);
    43 }
    44 
    45 RegExpMatchesArray* RegExpMatchesArray::create(ExecState* exec, JSString* input, RegExp* regExp, MatchResult result)
     34JSArray* createRegExpMatchesArray(ExecState* exec, JSString* input, RegExp* regExp, MatchResult result)
    4635{
    4736    ASSERT(result);
    4837    VM& vm = exec->vm();
    49     Butterfly* butterfly = createArrayButterflyWithExactLength(vm, 0, regExp->numSubpatterns() + 1);
    50     RegExpMatchesArray* array = new (NotNull, allocateCell<RegExpMatchesArray>(vm.heap)) RegExpMatchesArray(vm, butterfly, exec->lexicalGlobalObject(), input, regExp, result);
    51     array->finishCreation(vm);
    52     return array;
    53 }
     38    JSArray* array = JSArray::tryCreateUninitialized(vm, exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
     39    RELEASE_ASSERT(array);
    5440
    55 void RegExpMatchesArray::finishCreation(VM& vm)
    56 {
    57     Base::finishCreation(vm);
    58 }
     41    SamplingRegion samplingRegion("Reifying substring properties");
    5942
    60 void RegExpMatchesArray::visitChildren(JSCell* cell, SlotVisitor& visitor)
    61 {
    62     RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    63     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    64     Base::visitChildren(thisObject, visitor);
    65     visitor.append(&thisObject->m_input);
    66     visitor.append(&thisObject->m_regExp);
    67 }
     43    array->putDirectIndex(exec, 0, jsSubstring(exec, input, result.start, result.end - result.start));
    6844
    69 void RegExpMatchesArray::reifyAllProperties(ExecState* exec)
    70 {
    71     ASSERT(m_state != ReifiedAll);
    72     ASSERT(m_result);
    73  
    74     SamplingRegion samplingRegion("Reifying substring properties");
    75    
    76     reifyMatchPropertyIfNecessary(exec);
    77 
    78     if (unsigned numSubpatterns = m_regExp->numSubpatterns()) {
     45    if (unsigned numSubpatterns = regExp->numSubpatterns()) {
    7946        Vector<int, 32> subpatternResults;
    80         int position = m_regExp->match(exec->vm(), m_input->value(exec), m_result.start, subpatternResults);
    81         ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == m_result.start);
    82         ASSERT(m_result.start == static_cast<size_t>(subpatternResults[0]));
    83         ASSERT(m_result.end == static_cast<size_t>(subpatternResults[1]));
     47        int position = regExp->match(exec->vm(), input->value(exec), result.start, subpatternResults);
     48        ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == result.start);
     49        ASSERT(result.start == static_cast<size_t>(subpatternResults[0]));
     50        ASSERT(result.end == static_cast<size_t>(subpatternResults[1]));
    8451
    8552        for (unsigned i = 1; i <= numSubpatterns; ++i) {
    8653            int start = subpatternResults[2 * i];
    8754            if (start >= 0)
    88                 putDirectIndex(exec, i, jsSubstring(exec, m_input.get(), start, subpatternResults[2 * i + 1] - start));
     55                array->putDirectIndex(exec, i, jsSubstring(exec, input, start, subpatternResults[2 * i + 1] - start));
    8956            else
    90                 putDirectIndex(exec, i, jsUndefined());
     57                array->putDirectIndex(exec, i, jsUndefined());
    9158        }
    9259    }
    9360
    94     putDirect(exec->vm(), exec->propertyNames().index, jsNumber(m_result.start));
    95     putDirect(exec->vm(), exec->propertyNames().input, m_input.get());
     61    array->putDirect(exec->vm(), exec->propertyNames().index, jsNumber(result.start));
     62    array->putDirect(exec->vm(), exec->propertyNames().input, input);
    9663
    97     m_state = ReifiedAll;
    98 }
    99 
    100 void RegExpMatchesArray::reifyMatchProperty(ExecState* exec)
    101 {
    102     ASSERT(m_state == ReifiedNone);
    103     ASSERT(m_result);
    104     putDirectIndex(exec, 0, jsSubstring(exec, m_input.get(), m_result.start, m_result.end - m_result.start));
    105     m_state = ReifiedMatch;
    106 }
    107 
    108 JSString* RegExpMatchesArray::leftContext(ExecState* exec)
    109 {
    110     if (!m_result.start)
    111         return jsEmptyString(exec);
    112     return jsSubstring(exec, m_input.get(), 0, m_result.start);
    113 }
    114 
    115 JSString* RegExpMatchesArray::rightContext(ExecState* exec)
    116 {
    117     unsigned length = m_input->length();
    118     if (m_result.end == length)
    119         return jsEmptyString(exec);
    120     return jsSubstring(exec, m_input.get(), m_result.end, length - m_result.end);
     64    return array;
    12165}
    12266
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.h

    r173269 r175365  
    2727namespace JSC {
    2828
    29 class RegExpMatchesArray : public JSArray {
    30 private:
    31     RegExpMatchesArray(VM&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult);
    32 
    33     enum ReifiedState { ReifiedNone, ReifiedMatch, ReifiedAll };
    34 
    35 public:
    36     typedef JSArray Base;
    37 
    38     static RegExpMatchesArray* create(ExecState*, JSString*, RegExp*, MatchResult);
    39 
    40     JSString* leftContext(ExecState*);
    41     JSString* rightContext(ExecState*);
    42 
    43     DECLARE_INFO;
    44 
    45     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    46     {
    47         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayWithSlowPutArrayStorage);
    48     }
    49 
    50     static void visitChildren(JSCell*, SlotVisitor&);
    51 
    52 protected:
    53     void finishCreation(VM&);
    54 
    55     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
    56 
    57 private:
    58     ALWAYS_INLINE void reifyAllPropertiesIfNecessary(ExecState* exec)
    59     {
    60         if (m_state != ReifiedAll)
    61             reifyAllProperties(exec);
    62     }
    63 
    64     ALWAYS_INLINE void reifyMatchPropertyIfNecessary(ExecState* exec)
    65     {
    66         if (m_state == ReifiedNone)
    67             reifyMatchProperty(exec);
    68     }
    69 
    70     static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
    71     {
    72         RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
    73         thisObject->reifyAllPropertiesIfNecessary(exec);
    74         return JSArray::getOwnPropertySlot(thisObject, exec, propertyName, slot);
    75     }
    76 
    77     static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
    78     {
    79         RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
    80         if (propertyName)
    81             thisObject->reifyAllPropertiesIfNecessary(exec);
    82         else
    83             thisObject->reifyMatchPropertyIfNecessary(exec);
    84         return JSArray::getOwnPropertySlotByIndex(thisObject, exec, propertyName, slot);
    85     }
    86 
    87     static void put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue v, PutPropertySlot& slot)
    88     {
    89         RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    90         thisObject->reifyAllPropertiesIfNecessary(exec);
    91         JSArray::put(thisObject, exec, propertyName, v, slot);
    92     }
    93 
    94     static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v, bool shouldThrow)
    95     {
    96         RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    97         thisObject->reifyAllPropertiesIfNecessary(exec);
    98         JSArray::putByIndex(thisObject, exec, propertyName, v, shouldThrow);
    99     }
    100 
    101     static bool deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
    102     {
    103         RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    104         thisObject->reifyAllPropertiesIfNecessary(exec);
    105         return JSArray::deleteProperty(thisObject, exec, propertyName);
    106     }
    107 
    108     static bool deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
    109     {
    110         RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    111         thisObject->reifyAllPropertiesIfNecessary(exec);
    112         return JSArray::deletePropertyByIndex(thisObject, exec, propertyName);
    113     }
    114 
    115     static void getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
    116     {
    117         RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
    118         thisObject->reifyAllPropertiesIfNecessary(exec);
    119         JSArray::getOwnPropertyNames(thisObject, exec, arr, mode);
    120     }
    121 
    122     static bool defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
    123     {
    124         RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
    125         thisObject->reifyAllPropertiesIfNecessary(exec);
    126         return JSArray::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
    127     }
    128 
    129     void reifyAllProperties(ExecState*);
    130     void reifyMatchProperty(ExecState*);
    131 
    132     WriteBarrier<JSString> m_input;
    133     WriteBarrier<RegExp> m_regExp;
    134     MatchResult m_result;
    135     ReifiedState m_state;
    136 };
    137 
    138 inline bool isRegExpMatchesArray(JSValue value)
    139 {
    140     return value.isCell() && value.asCell()->classInfo() == RegExpMatchesArray::info();
    141 }
     29JSArray* createRegExpMatchesArray(ExecState*, JSString*, RegExp*, MatchResult);
    14230
    14331}
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp

    r172176 r175365  
    303303{
    304304    if (MatchResult result = match(exec, string))
    305         return RegExpMatchesArray::create(exec, string, regExp(), result);
     305        return createRegExpMatchesArray(exec, string, regExp(), result);
    306306    return jsNull();
    307307}
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r173761 r175365  
    865865    // case without 'g' flag is handled like RegExp.prototype.exec
    866866    if (!global)
    867         return JSValue::encode(result ? RegExpMatchesArray::create(exec, string, regExp, result) : jsNull());
     867        return JSValue::encode(result ? createRegExpMatchesArray(exec, string, regExp, result) : jsNull());
    868868
    869869    // return array of matches
Note: See TracChangeset for help on using the changeset viewer.