1 /* 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 */ 20 21 #ifndef RegExpConstructor_h 22 #define RegExpConstructor_h 23 24 #include "InternalFunction.h" 25 #include "RegExp.h" 26 #include <wtf/OwnPtr.h> 27 28 namespace JSC { 29 30 class RegExp; 31 class RegExpPrototype; 32 struct RegExpConstructorPrivate; 33 34 struct RegExpConstructorPrivate { 35 WTF_MAKE_FAST_ALLOCATED; 36 public: 37 // Global search cache / settings RegExpConstructorPrivateRegExpConstructorPrivate38 RegExpConstructorPrivate() 39 : lastNumSubPatterns(0) 40 , multiline(false) 41 , lastOvectorIndex(0) 42 { 43 } 44 lastOvectorRegExpConstructorPrivate45 const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; } lastOvectorRegExpConstructorPrivate46 Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; } tempOvectorRegExpConstructorPrivate47 Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; } changeLastOvectorRegExpConstructorPrivate48 void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; } 49 50 UString input; 51 UString lastInput; 52 Vector<int, 32> ovector[2]; 53 unsigned lastNumSubPatterns : 30; 54 bool multiline : 1; 55 unsigned lastOvectorIndex : 1; 56 }; 57 58 class RegExpConstructor : public InternalFunction { 59 public: 60 RegExpConstructor(ExecState*, JSGlobalObject*, Structure*, RegExpPrototype*); 61 createStructure(JSGlobalData & globalData,JSValue prototype)62 static Structure* createStructure(JSGlobalData& globalData, JSValue prototype) 63 { 64 return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); 65 } 66 67 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 68 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 69 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 70 71 static const ClassInfo s_info; 72 73 void performMatch(RegExp*, const UString&, int startOffset, int& position, int& length, int** ovector = 0); 74 JSObject* arrayOfMatches(ExecState*) const; 75 76 void setInput(const UString&); 77 const UString& input() const; 78 79 void setMultiline(bool); 80 bool multiline() const; 81 82 JSValue getBackref(ExecState*, unsigned) const; 83 JSValue getLastParen(ExecState*) const; 84 JSValue getLeftContext(ExecState*) const; 85 JSValue getRightContext(ExecState*) const; 86 87 protected: 88 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; 89 90 private: 91 virtual ConstructType getConstructData(ConstructData&); 92 virtual CallType getCallData(CallData&); 93 94 OwnPtr<RegExpConstructorPrivate> d; 95 }; 96 97 RegExpConstructor* asRegExpConstructor(JSValue); 98 99 JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&); 100 asRegExpConstructor(JSValue value)101 inline RegExpConstructor* asRegExpConstructor(JSValue value) 102 { 103 ASSERT(asObject(value)->inherits(&RegExpConstructor::s_info)); 104 return static_cast<RegExpConstructor*>(asObject(value)); 105 } 106 107 /* 108 To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular 109 expression matching through the performMatch function. We use cached results to calculate, 110 e.g., RegExp.lastMatch and RegExp.leftParen. 111 */ performMatch(RegExp * r,const UString & s,int startOffset,int & position,int & length,int ** ovector)112 ALWAYS_INLINE void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector) 113 { 114 position = r->match(s, startOffset, &d->tempOvector()); 115 116 if (ovector) 117 *ovector = d->tempOvector().data(); 118 119 if (position != -1) { 120 ASSERT(!d->tempOvector().isEmpty()); 121 122 length = d->tempOvector()[1] - d->tempOvector()[0]; 123 124 d->input = s; 125 d->lastInput = s; 126 d->changeLastOvector(); 127 d->lastNumSubPatterns = r->numSubpatterns(); 128 } 129 } 130 131 } // namespace JSC 132 133 #endif // RegExpConstructor_h 134