Ignore:
Timestamp:
Oct 11, 2005, 1:43:49 PM (20 years ago)
Author:
ggaren
Message:
  • Implemented caching of match state inside the global RegExp object (lastParen, leftContext, rightContext, lastMatch, input).

exec(), test(), match(), search(), and replace() now dipatch regular
expression matching through the RegExp object's performMatch function,
to facilitate caching. This replaces registerRegexp and
setSubPatterns.

  • Implemented the special '$' aliases (e.g. RegExp.input aliases to RegExp.$_).
  • Moved support for backreferences into the new static hash table used for other special RegExp properties. Truncated backreferences at $9 to match IE, FF, and the "What's New in Netscape 1.2?" doc. (String.replace still supports double-digit backreferences.)
  • Tweaked RegExp.prototype.exec to handle ginormous values in lastIndex.

Fixes 11 -- count em, 11 -- JavaScriptCore tests.

Reviewed by NOBODY (OOPS!).

  • JavaScriptCore.xcodeproj/project.pbxproj: Added regexp_object.lut.h
  • kjs/create_hash_table: Tweaked to allow for more exotic characters.

We now rely on the compiler to catch illegal
identifiers.

  • kjs/regexp.cpp: (KJS::RegExp::RegExp):
  • kjs/regexp_object.cpp: (RegExpProtoFuncImp::callAsFunction): (RegExpObjectImp::RegExpObjectImp): (RegExpObjectImp::performMatch): (RegExpObjectImp::arrayOfMatches): (RegExpObjectImp::backrefGetter): (RegExpObjectImp::getLastMatch): (RegExpObjectImp::getLastParen): (RegExpObjectImp::getLeftContext): (RegExpObjectImp::getRightContext): (RegExpObjectImp::getOwnPropertySlot): (RegExpObjectImp::getValueProperty): (RegExpObjectImp::put): (RegExpObjectImp::putValueProperty):
  • kjs/regexp_object.h: (KJS::RegExpObjectImp::):
  • kjs/string_object.cpp: (substituteBackreferences): (replace): (StringProtoFuncImp::callAsFunction):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/string_object.cpp

    r10757 r10818  
    233233}
    234234
    235 static inline UString substituteBackreferences(const UString &replacement, const UString &source, int **ovector, RegExp *reg)
     235static inline UString substituteBackreferences(const UString &replacement, const UString &source, int *ovector, RegExp *reg)
    236236{
    237237  UString substitutedReplacement = replacement;
     
    247247    unsigned backrefIndex = substitutedReplacement.substr(i+1,1).toUInt32(&converted, false /* tolerate empty string */);
    248248    if (converted && backrefIndex <= (unsigned)reg->subPatterns()) {
    249       int backrefStart = (*ovector)[2*backrefIndex];
    250       int backrefLength = (*ovector)[2*backrefIndex+1] - backrefStart;
     249      int backrefStart = ovector[2*backrefIndex];
     250      int backrefLength = ovector[2*backrefIndex+1] - backrefStart;
    251251      substitutedReplacement = substitutedReplacement.substr(0,i)
    252252        + source.substr(backrefStart, backrefLength)
     
    289289    // This is either a loop (if global is set) or a one-way (if not).
    290290    do {
    291       int **ovector = regExpObj->registerRegexp( reg, source );
    292       UString matchString = reg->match(source, startPosition, &matchIndex, ovector);
    293       regExpObj->setSubPatterns(reg->subPatterns());
     291      int *ovector;
     292      UString matchString = regExpObj->performMatch(reg, source, startPosition, &matchIndex, &ovector);
    294293      if (matchIndex == -1)
    295294        break;
     
    299298
    300299      if (replacementFunction) {
    301           int completeMatchStart = (*ovector)[0];
     300          int completeMatchStart = ovector[0];
    302301          List args;
    303302
     
    305304         
    306305          for (unsigned i = 0; i < reg->subPatterns(); i++) {
    307               int matchStart = (*ovector)[(i + 1) * 2];
    308               int matchLen = (*ovector)[(i + 1) * 2 + 1] - matchStart;
     306              int matchStart = ovector[(i + 1) * 2];
     307              int matchLen = ovector[(i + 1) * 2 + 1] - matchStart;
    309308             
    310309              args.append(jsString(source.substr(matchStart, matchLen)));
     
    455454    RegExp *reg, *tmpReg = 0;
    456455    RegExpImp *imp = 0;
    457     if (a0->isObject() && a0->getObject()->inherits(&RegExpImp::info))
    458     {
     456    if (a0->isObject() && a0->getObject()->inherits(&RegExpImp::info)) {
    459457      imp = static_cast<RegExpImp *>(a0);
    460458      reg = imp->regExp();
    461     }
    462     else
    463     { /*
     459    } else {
     460      /*
    464461       *  ECMA 15.5.4.12 String.prototype.search (regexp)
    465462       *  If regexp is not an object whose [[Class]] property is "RegExp", it is
     
    469466    }
    470467    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
    471     int **ovector = regExpObj->registerRegexp(reg, u);
    472     UString mstr = reg->match(u, -1, &pos, ovector);
     468    UString mstr = regExpObj->performMatch(reg, u, 0, &pos);
    473469    if (id == Search) {
    474470      result = Number(pos);
     
    480476          result = Null();
    481477        } else {
    482           regExpObj->setSubPatterns(reg->subPatterns());
    483478          result = regExpObj->arrayOfMatches(exec,mstr);
    484479        }
     
    494489          lastIndex = pos;
    495490          pos += mstr.isEmpty() ? 1 : mstr.size();
    496           delete [] *ovector;
    497           mstr = reg->match(u, pos, &pos, ovector);
     491          mstr = regExpObj->performMatch(reg, u, pos, &pos);
    498492        }
    499493        if (imp)
     
    515509    result = replace(exec, s, a0, a1);
    516510    break;
    517   case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/string.htm#1194366
     511  case Slice:
    518512    {
    519513        // The arg processing is very much like ArrayProtoFunc::Slice
Note: See TracChangeset for help on using the changeset viewer.