Changeset 283874 in webkit


Ignore:
Timestamp:
Oct 10, 2021 1:49:45 AM (9 months ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Refine RegExp#compile based on regexp-legacy-features proposal
https://bugs.webkit.org/show_bug.cgi?id=231486

Reviewed by Alexey Shvayka.

JSTests:

  • stress/regexp-recompile.js: Added.

(shouldBe):
(recompile):
(target):

  • test262/expectations.yaml:

Source/JavaScriptCore:

This patch refines RegExp#compile based regexp-legacy-features proposal[1].
We add legacyFeaturesDisabledFlag flag to RegExpObject so that we can
detect LegacyFeaturesEnabled?.

We also add regExpRecompiledWatchpoint to JSGlobalObject. We have strength
reduction in DFG / FTL, but we should recompile DFG / FTL code when RegExp
is recompiled. Since it is rare, instead of having this watchpoint per
RegExpObject, we hold it in JSGlobalObject.

[1]: https://github.com/tc39/proposal-regexp-legacy-features

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileNewRegexp):
(JSC::DFG::SpeculativeJIT::compileSetRegExpObjectLastIndex):

  • dfg/DFGStrengthReductionPhase.cpp:

(JSC::DFG::StrengthReductionPhase::handleNode):

  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):

  • ftl/FTLOperations.cpp:

(JSC::FTL::JSC_DEFINE_JIT_OPERATION):

  • jit/JITOperations.cpp:

(JSC::JSC_DEFINE_JIT_OPERATION):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::JSGlobalObject):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::regExpRecompiledWatchpoint):
(JSC::JSGlobalObject::isRegExpRecompiled const):

  • runtime/RegExpConstructor.cpp:

(JSC::areLegacyFeaturesEnabled):
(JSC::regExpCreate):
(JSC::constructRegExp):

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::RegExpObject):

  • runtime/RegExpObject.h:
  • runtime/RegExpPrototype.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

Location:
trunk
Files:
1 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r283852 r283874  
     12021-10-09  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Refine RegExp#compile based on regexp-legacy-features proposal
     4        https://bugs.webkit.org/show_bug.cgi?id=231486
     5
     6        Reviewed by Alexey Shvayka.
     7
     8        * stress/regexp-recompile.js: Added.
     9        (shouldBe):
     10        (recompile):
     11        (target):
     12        * test262/expectations.yaml:
     13
    1142021-10-08  Tadeu Zagallo  <tzagallo@apple.com>
    215
  • trunk/JSTests/test262/expectations.yaml

    r283705 r283874  
    66  default: "SyntaxError: Unexpected token '}'. Expected a parameter pattern or a ')' in parameter list."
    77  strict mode: "SyntaxError: Unexpected token '}'. Expected a parameter pattern or a ')' in parameter list."
    8 test/annexB/built-ins/RegExp/prototype/compile/this-cross-realm-instance.js:
    9   default: 'Test262Error: `RegExp.prototype.compile.call(otherRealm_regexp)` throws TypeError Expected a TypeError to be thrown but no exception was thrown at all'
    10   strict mode: 'Test262Error: `RegExp.prototype.compile.call(otherRealm_regexp)` throws TypeError Expected a TypeError to be thrown but no exception was thrown at all'
    11 test/annexB/built-ins/RegExp/prototype/compile/this-subclass-instance.js:
    12   default: 'Test262Error: `subclass_regexp.compile()` throws TypeError Expected a TypeError to be thrown but no exception was thrown at all'
    13   strict mode: 'Test262Error: `subclass_regexp.compile()` throws TypeError Expected a TypeError to be thrown but no exception was thrown at all'
    148test/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js:
    159  default: 'Test262Error: An initialized binding is not created prior to evaluation Expected a ReferenceError to be thrown but no exception was thrown at all'
  • trunk/Source/JavaScriptCore/ChangeLog

    r283862 r283874  
     12021-10-09  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Refine RegExp#compile based on regexp-legacy-features proposal
     4        https://bugs.webkit.org/show_bug.cgi?id=231486
     5
     6        Reviewed by Alexey Shvayka.
     7
     8        This patch refines RegExp#compile based regexp-legacy-features proposal[1].
     9        We add legacyFeaturesDisabledFlag flag to RegExpObject so that we can
     10        detect [[LegacyFeaturesEnabled]].
     11
     12        We also add regExpRecompiledWatchpoint to JSGlobalObject. We have strength
     13        reduction in DFG / FTL, but we should recompile DFG / FTL code when RegExp
     14        is recompiled. Since it is rare, instead of having this watchpoint per
     15        RegExpObject, we hold it in JSGlobalObject.
     16
     17        [1]: https://github.com/tc39/proposal-regexp-legacy-features
     18
     19        * dfg/DFGSpeculativeJIT.cpp:
     20        (JSC::DFG::SpeculativeJIT::compileNewRegexp):
     21        (JSC::DFG::SpeculativeJIT::compileSetRegExpObjectLastIndex):
     22        * dfg/DFGStrengthReductionPhase.cpp:
     23        (JSC::DFG::StrengthReductionPhase::handleNode):
     24        * ftl/FTLAbstractHeapRepository.h:
     25        * ftl/FTLLowerDFGToB3.cpp:
     26        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
     27        * ftl/FTLOperations.cpp:
     28        (JSC::FTL::JSC_DEFINE_JIT_OPERATION):
     29        * jit/JITOperations.cpp:
     30        (JSC::JSC_DEFINE_JIT_OPERATION):
     31        * llint/LLIntSlowPaths.cpp:
     32        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     33        * runtime/JSGlobalObject.cpp:
     34        (JSC::JSGlobalObject::JSGlobalObject):
     35        * runtime/JSGlobalObject.h:
     36        (JSC::JSGlobalObject::regExpRecompiledWatchpoint):
     37        (JSC::JSGlobalObject::isRegExpRecompiled const):
     38        * runtime/RegExpConstructor.cpp:
     39        (JSC::areLegacyFeaturesEnabled):
     40        (JSC::regExpCreate):
     41        (JSC::constructRegExp):
     42        * runtime/RegExpObject.cpp:
     43        (JSC::RegExpObject::RegExpObject):
     44        * runtime/RegExpObject.h:
     45        * runtime/RegExpPrototype.cpp:
     46        (JSC::JSC_DEFINE_HOST_FUNCTION):
     47
    1482021-10-08  Saam Barati  <sbarati@apple.com>
    249
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r283556 r283874  
    1122411224    m_jit.storePtr(
    1122511225        TrustedImmPtr(node->cellOperand()),
    11226         CCallHelpers::Address(resultGPR, RegExpObject::offsetOfRegExpAndLastIndexIsNotWritableFlag()));
     11226        CCallHelpers::Address(resultGPR, RegExpObject::offsetOfRegExpAndFlags()));
    1122711227    m_jit.storeValue(lastIndexRegs, CCallHelpers::Address(resultGPR, RegExpObject::offsetOfLastIndex()));
    1122811228    m_jit.mutatorFence(vm());
     
    1277412774            m_jit.branchTestPtr(
    1277512775                JITCompiler::NonZero,
    12776                 JITCompiler::Address(regExpGPR, RegExpObject::offsetOfRegExpAndLastIndexIsNotWritableFlag()),
     12776                JITCompiler::Address(regExpGPR, RegExpObject::offsetOfRegExpAndFlags()),
    1277712777                JITCompiler::TrustedImm32(RegExpObject::lastIndexIsNotWritableFlag)));
    1277812778    }
  • trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp

    r283300 r283874  
    503503                regExpObjectNode = m_node->child2().node();
    504504                if (RegExpObject* regExpObject = regExpObjectNode->dynamicCastConstant<RegExpObject*>(vm())) {
     505                    JSGlobalObject* globalObject = regExpObject->globalObject(vm());
     506                    if (globalObject->isRegExpRecompiled()) {
     507                        if (verbose)
     508                            dataLog("Giving up because RegExp recompile happens.\n");
     509                        break;
     510                    }
     511                    m_graph.watchpoints().addLazily(globalObject->regExpRecompiledWatchpoint());
    505512                    regExp = regExpObject->regExp();
    506513                    regExpObjectNodeIsConstant = true;
    507                 } else if (regExpObjectNode->op() == NewRegexp)
     514                } else if (regExpObjectNode->op() == NewRegexp) {
     515                    JSGlobalObject* globalObject = m_graph.globalObjectFor(regExpObjectNode->origin.semantic);
     516                    if (globalObject->isRegExpRecompiled()) {
     517                        if (verbose)
     518                            dataLog("Giving up because RegExp recompile happens.\n");
     519                        break;
     520                    }
     521                    m_graph.watchpoints().addLazily(globalObject->regExpRecompiledWatchpoint());
    508522                    regExp = regExpObjectNode->castOperand<RegExp*>();
    509                 else {
     523                } else {
    510524                    if (verbose)
    511525                        dataLog("Giving up because the regexp is unknown.\n");
     
    836850            Node* regExpObjectNode = m_node->child2().node();
    837851            RegExp* regExp;
    838             if (RegExpObject* regExpObject = regExpObjectNode->dynamicCastConstant<RegExpObject*>(vm()))
     852            if (RegExpObject* regExpObject = regExpObjectNode->dynamicCastConstant<RegExpObject*>(vm())) {
     853                JSGlobalObject* globalObject = regExpObject->globalObject(vm());
     854                if (globalObject->isRegExpRecompiled()) {
     855                    if (verbose)
     856                        dataLog("Giving up because RegExp recompile happens.\n");
     857                    break;
     858                }
     859                m_graph.watchpoints().addLazily(globalObject->regExpRecompiledWatchpoint());
    839860                regExp = regExpObject->regExp();
    840             else if (regExpObjectNode->op() == NewRegexp)
     861            } else if (regExpObjectNode->op() == NewRegexp) {
     862                JSGlobalObject* globalObject = m_graph.globalObjectFor(regExpObjectNode->origin.semantic);
     863                if (globalObject->isRegExpRecompiled()) {
     864                    if (verbose)
     865                        dataLog("Giving up because RegExp recompile happens.\n");
     866                    break;
     867                }
     868                m_graph.watchpoints().addLazily(globalObject->regExpRecompiledWatchpoint());
    841869                regExp = regExpObjectNode->castOperand<RegExp*>();
    842             else {
     870            } else {
    843871                if (verbose)
    844872                    dataLog("Giving up because the regexp is unknown.\n");
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

    r283556 r283874  
    124124    macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \
    125125    macro(NativeExecutable_asString, NativeExecutable::offsetOfAsString()) \
    126     macro(RegExpObject_regExpAndLastIndexIsNotWritableFlag, RegExpObject::offsetOfRegExpAndLastIndexIsNotWritableFlag()) \
     126    macro(RegExpObject_regExpAndFlags, RegExpObject::offsetOfRegExpAndFlags()) \
    127127    macro(RegExpObject_lastIndex, RegExpObject::offsetOfLastIndex()) \
    128128    macro(ShadowChicken_Packet_callee, OBJECT_OFFSETOF(ShadowChicken::Packet, callee)) \
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r283556 r283874  
    1429114291        auto structure = m_graph.registerStructure(globalObject->regExpStructure());
    1429214292        LValue fastResultValue = allocateObject<RegExpObject>(structure, m_out.intPtrZero, slowCase);
    14293         m_out.storePtr(frozenPointer(regexp), fastResultValue, m_heaps.RegExpObject_regExpAndLastIndexIsNotWritableFlag);
     14293        m_out.storePtr(frozenPointer(regexp), fastResultValue, m_heaps.RegExpObject_regExpAndFlags);
    1429414294        m_out.store64(lastIndex, fastResultValue, m_heaps.RegExpObject_lastIndex);
    1429514295        mutatorFence();
     
    1437814378                ExoticObjectMode, noValue(), nullptr,
    1437914379                m_out.testNonZeroPtr(
    14380                     m_out.loadPtr(regExp, m_heaps.RegExpObject_regExpAndLastIndexIsNotWritableFlag),
     14380                    m_out.loadPtr(regExp, m_heaps.RegExpObject_regExpAndFlags),
    1438114381                    m_out.constIntPtr(RegExpObject::lastIndexIsNotWritableFlag)));
    1438214382
  • trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp

    r278875 r283874  
    690690        CodeBlock* codeBlock = baselineCodeBlockForOriginAndBaselineCodeBlock(materialization->origin(), callFrame->codeBlock()->baselineAlternative());
    691691        Structure* structure = codeBlock->globalObject()->regExpStructure();
    692         return RegExpObject::create(vm, structure, regExp);
     692        static constexpr bool areLegacyFeaturesEnabled = true;
     693        return RegExpObject::create(vm, structure, regExp, areLegacyFeaturesEnabled);
    693694    }
    694695
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r283139 r283874  
    18911891    RegExp* regexp = static_cast<RegExp*>(regexpPtr);
    18921892    ASSERT(regexp->isValid());
    1893     return RegExpObject::create(vm, globalObject->regExpStructure(), regexp);
     1893    static constexpr bool areLegacyFeaturesEnabled = true;
     1894    return RegExpObject::create(vm, globalObject->regExpStructure(), regexp, areLegacyFeaturesEnabled);
    18941895}
    18951896
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r283556 r283874  
    613613    RegExp* regExp = jsCast<RegExp*>(getOperand(callFrame, bytecode.m_regexp));
    614614    ASSERT(regExp->isValid());
    615     LLINT_RETURN(RegExpObject::create(vm, globalObject->regExpStructure(), regExp));
     615    static constexpr bool areLegacyFeaturesEnabled = true;
     616    LLINT_RETURN(RegExpObject::create(vm, globalObject->regExpStructure(), regExp, areLegacyFeaturesEnabled));
    616617}
    617618
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r283852 r283874  
    609609    , m_varInjectionWatchpoint(WatchpointSet::create(IsWatched))
    610610    , m_varReadOnlyWatchpoint(WatchpointSet::create(IsWatched))
     611    , m_regExpRecompiledWatchpoint(WatchpointSet::create(IsWatched))
    611612    , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
    612613    , m_arrayIteratorProtocolWatchpointSet(IsWatched)
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r283852 r283874  
    488488    RefPtr<WatchpointSet> m_varInjectionWatchpoint;
    489489    RefPtr<WatchpointSet> m_varReadOnlyWatchpoint;
     490    RefPtr<WatchpointSet> m_regExpRecompiledWatchpoint;
    490491
    491492    std::unique_ptr<JSGlobalObjectRareData> m_rareData;
     
    10261027    WatchpointSet* varInjectionWatchpoint() { return m_varInjectionWatchpoint.get(); }
    10271028    WatchpointSet* varReadOnlyWatchpoint() { return m_varReadOnlyWatchpoint.get(); }
     1029    WatchpointSet* regExpRecompiledWatchpoint() { return m_regExpRecompiledWatchpoint.get(); }
    10281030       
    10291031    bool isHavingABadTime() const
     
    10371039    bool arrayPrototypeChainIsSane();
    10381040    bool stringPrototypeChainIsSane();
     1041
     1042    bool isRegExpRecompiled() const
     1043    {
     1044        return m_regExpRecompiledWatchpoint->hasBeenInvalidated();
     1045    }
    10391046
    10401047    void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; }
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp

    r280489 r283874  
    188188}
    189189
     190static inline bool areLegacyFeaturesEnabled(JSGlobalObject* globalObject, JSValue newTarget)
     191{
     192    if (!newTarget)
     193        return true;
     194    return newTarget == globalObject->regExpConstructor();
     195}
     196
    190197inline Structure* getRegExpStructure(JSGlobalObject* globalObject, JSValue newTarget)
    191198{
     
    233240    Structure* structure = getRegExpStructure(globalObject, newTarget);
    234241    RETURN_IF_EXCEPTION(scope, nullptr);
    235     return RegExpObject::create(vm, structure, regExp);
     242    return RegExpObject::create(vm, structure, regExp, areLegacyFeaturesEnabled(globalObject, newTarget));
    236243}
    237244
     
    272279        }
    273280
    274         return RegExpObject::create(vm, structure, regExp);
     281        return RegExpObject::create(vm, structure, regExp, areLegacyFeaturesEnabled(globalObject, newTarget));
    275282    }
    276283
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp

    r278589 r283874  
    3333static JSC_DECLARE_CUSTOM_SETTER(regExpObjectSetLastIndexNonStrict);
    3434
    35 RegExpObject::RegExpObject(VM& vm, Structure* structure, RegExp* regExp)
     35RegExpObject::RegExpObject(VM& vm, Structure* structure, RegExp* regExp, bool areLegacyFeaturesEnabled)
    3636    : JSNonFinalObject(vm, structure)
    37     , m_regExpAndLastIndexIsNotWritableFlag(bitwise_cast<uintptr_t>(regExp)) // lastIndexIsNotWritableFlag is not set.
     37    , m_regExpAndFlags(bitwise_cast<uintptr_t>(regExp) | (areLegacyFeaturesEnabled ? 0 : legacyFeaturesDisabledFlag)) // lastIndexIsNotWritableFlag is not set.
    3838{
    3939    m_lastIndex.setWithoutWriteBarrier(jsNumber(0));
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.h

    r278589 r283874  
    4040    }
    4141
    42     static constexpr uintptr_t lastIndexIsNotWritableFlag = 1;
     42    static constexpr uintptr_t lastIndexIsNotWritableFlag = 0b01;
     43    static constexpr uintptr_t legacyFeaturesDisabledFlag = 0b10;
     44    static constexpr uintptr_t flagsMask = lastIndexIsNotWritableFlag | legacyFeaturesDisabledFlag;
     45    static constexpr uintptr_t regExpMask = ~flagsMask;
    4346
    44     static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
     47    static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp, bool areLegacyFeaturesEnabled = true)
    4548    {
    46         RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp);
     49        RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp, areLegacyFeaturesEnabled);
    4750        object->finishCreation(vm);
    4851        return object;
     
    5154    static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp, JSValue lastIndex)
    5255    {
    53         auto* object = create(vm, structure, regExp);
     56        static constexpr bool areLegacyFeaturesEnabled = true;
     57        auto* object = create(vm, structure, regExp, areLegacyFeaturesEnabled);
    5458        object->m_lastIndex.set(vm, object, lastIndex);
    5559        return object;
     
    5862    void setRegExp(VM& vm, RegExp* regExp)
    5963    {
    60         uintptr_t result = (m_regExpAndLastIndexIsNotWritableFlag & lastIndexIsNotWritableFlag) | bitwise_cast<uintptr_t>(regExp);
    61         m_regExpAndLastIndexIsNotWritableFlag = result;
     64        uintptr_t result = (m_regExpAndFlags & flagsMask) | bitwise_cast<uintptr_t>(regExp);
     65        m_regExpAndFlags = result;
    6266        vm.heap.writeBarrier(this, regExp);
    6367    }
     
    6569    RegExp* regExp() const
    6670    {
    67         return bitwise_cast<RegExp*>(m_regExpAndLastIndexIsNotWritableFlag & (~lastIndexIsNotWritableFlag));
     71        return bitwise_cast<RegExp*>(m_regExpAndFlags & regExpMask);
    6872    }
    6973
     
    113117    }
    114118
    115     static ptrdiff_t offsetOfRegExpAndLastIndexIsNotWritableFlag()
     119    static ptrdiff_t offsetOfRegExpAndFlags()
    116120    {
    117         return OBJECT_OFFSETOF(RegExpObject, m_regExpAndLastIndexIsNotWritableFlag);
     121        return OBJECT_OFFSETOF(RegExpObject, m_regExpAndFlags);
    118122    }
    119123
     
    129133    }
    130134
     135    bool areLegacyFeaturesEnabled() const { return !(m_regExpAndFlags & legacyFeaturesDisabledFlag); }
     136
    131137private:
    132     JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
     138    JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*, bool areLegacyFeaturesEnabled);
    133139    JS_EXPORT_PRIVATE void finishCreation(VM&);
    134140
     
    137143    bool lastIndexIsWritable() const
    138144    {
    139         return !(m_regExpAndLastIndexIsNotWritableFlag & lastIndexIsNotWritableFlag);
     145        return !(m_regExpAndFlags & lastIndexIsNotWritableFlag);
    140146    }
    141147
    142148    void setLastIndexIsNotWritable()
    143149    {
    144         m_regExpAndLastIndexIsNotWritableFlag = (m_regExpAndLastIndexIsNotWritableFlag | lastIndexIsNotWritableFlag);
     150        m_regExpAndFlags = (m_regExpAndFlags | lastIndexIsNotWritableFlag);
    145151    }
    146152
     
    151157    MatchResult matchInline(JSGlobalObject*, JSString*);
    152158
    153     uintptr_t m_regExpAndLastIndexIsNotWritableFlag { 0 };
     159    uintptr_t m_regExpAndFlags { 0 };
    154160    WriteBarrier<Unknown> m_lastIndex;
    155161};
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp

    r279976 r283874  
    133133        return throwVMTypeError(globalObject, scope);
    134134
     135    if (thisRegExp->globalObject(vm) != globalObject)
     136        return throwVMTypeError(globalObject, scope, "RegExp.prototype.compile function's Realm must be the same to |this| RegExp object"_s);
     137
     138    if (!thisRegExp->areLegacyFeaturesEnabled())
     139        return throwVMTypeError(globalObject, scope, "|this| RegExp object's legacy features are not enabled"_s);
     140
    135141    RegExp* regExp;
    136142    JSValue arg0 = callFrame->argument(0);
     
    155161    if (!regExp->isValid())
    156162        return throwVMError(globalObject, scope, regExp->errorToThrow(globalObject));
     163
     164    globalObject->regExpRecompiledWatchpoint()->fireAll(vm, "RegExp is recompiled");
    157165
    158166    thisRegExp->setRegExp(vm, regExp);
Note: See TracChangeset for help on using the changeset viewer.