[webkit-changes] cvs commit: JavaScriptCore/kjs create_hash_table regexp.cpp regexp_object.cpp regexp_object.h string_object.cpp

Geoffrey ggaren at opensource.apple.com
Tue Oct 11 13:43:51 PDT 2005


ggaren      05/10/11 13:43:51

  Modified:    .        ChangeLog
               JavaScriptCore.xcodeproj project.pbxproj
               kjs      create_hash_table regexp.cpp regexp_object.cpp
                        regexp_object.h string_object.cpp
  Log:
          - 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):
  
  Revision  Changes    Path
  1.860     +51 -0     JavaScriptCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/ChangeLog,v
  retrieving revision 1.859
  retrieving revision 1.860
  diff -u -r1.859 -r1.860
  --- ChangeLog	9 Oct 2005 22:57:59 -0000	1.859
  +++ ChangeLog	11 Oct 2005 20:43:46 -0000	1.860
  @@ -1,3 +1,54 @@
  +2005-10-10  Geoffrey Garen  <ggaren at apple.com>
  +
  +        - 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):
  +
   2005-10-09  Darin Adler  <darin at apple.com>
   
           Reviewed by Maciej; some changes done after review.
  
  
  
  1.19      +18 -0     JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
  
  Index: project.pbxproj
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- project.pbxproj	5 Oct 2005 08:05:36 -0000	1.18
  +++ project.pbxproj	11 Oct 2005 20:43:48 -0000	1.19
  @@ -1129,6 +1129,7 @@
   				93F197EC08245819001E9ABC /* lexer.lut.h */,
   				93F1983308245BA1001E9ABC /* math_object.lut.h */,
   				93F1983108245B9E001E9ABC /* number_object.lut.h */,
  +				14F6037308FB039300E9E573 /* regexp_object.lut.h */,
   				93F1983508245BA6001E9ABC /* string_object.lut.h */,
   				932F5B3F0822A1C700736975 /* Headers */,
   				932F5B910822A1C700736975 /* Sources */,
  @@ -1356,6 +1357,23 @@
   /* End PBXProject section */
   
   /* Begin PBXShellScriptBuildPhase section */
  +		14F6037308FB039300E9E573 /* regexp_object.lut.h */ = {
  +			isa = PBXShellScriptBuildPhase;
  +			buildActionMask = 2147483647;
  +			files = (
  +			);
  +			inputPaths = (
  +				"kjs/create_hash_table\nkjs/create_hash_table",
  +				kjs/regexp_object.cpp,
  +			);
  +			name = regexp_object.lut.h;
  +			outputPaths = (
  +				"$(DERIVED_FILE_DIR)/regexp_object.lut.h",
  +			);
  +			runOnlyForDeploymentPostprocessing = 0;
  +			shellPath = /bin/sh;
  +			shellScript = "kjs/create_hash_table kjs/regexp_object.cpp -i > \"$DERIVED_FILE_DIR/regexp_object.lut.h\"";
  +		};
   		93396BB50824516200AB803D /* chartables.c */ = {
   			isa = PBXShellScriptBuildPhase;
   			buildActionMask = 2147483647;
  
  
  
  1.6       +2 -2      JavaScriptCore/kjs/create_hash_table
  
  Index: create_hash_table
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/create_hash_table,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- create_hash_table	1 Jul 2005 09:48:20 -0000	1.5
  +++ create_hash_table	11 Oct 2005 20:43:49 -0000	1.6
  @@ -64,7 +64,7 @@
         @attrs = ();
         @params = ();
         $inside = 0;
  -	} elsif (/^([-:\@\w\[\=\]]+)\s*([\w\:-]+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) {
  +    } elsif (/^(\S+)\s*(\S+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) {
         my $key = $1;
         my $val = $2;
         my $att = $3;
  @@ -76,7 +76,7 @@
         push(@attrs, length($att) > 0 ? $att : "0");
         push(@params, length($param) > 0 ? $param : "0");
       } elsif ($inside) {
  -      die "invalid data";
  +      die "invalid data {" . $_ . "}";
       }
   }
   
  
  
  
  1.14      +1 -0      JavaScriptCore/kjs/regexp.cpp
  
  Index: regexp.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/regexp.cpp,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- regexp.cpp	3 Oct 2005 21:11:51 -0000	1.13
  +++ regexp.cpp	11 Oct 2005 20:43:49 -0000	1.14
  @@ -36,6 +36,7 @@
   
     int options = PCRE_UTF8;
     // Note: the Global flag is already handled by RegExpProtoFunc::execute.
  +  // FIXME: That last comment is dubious. Not all RegExps get run through RegExpProtoFunc::execute.
     if (flags & IgnoreCase)
       options |= PCRE_CASELESS;
     if (flags & Multiline)
  
  
  
  1.26      +203 -71   JavaScriptCore/kjs/regexp_object.cpp
  
  Index: regexp_object.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/regexp_object.cpp,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- regexp_object.cpp	3 Oct 2005 21:11:51 -0000	1.25
  +++ regexp_object.cpp	11 Oct 2005 20:43:49 -0000	1.26
  @@ -23,6 +23,8 @@
   #include "config.h"
   #include "regexp_object.h"
   
  +#include "regexp_object.lut.h"
  +
   #include <stdio.h>
   #include "value.h"
   #include "object.h"
  @@ -32,6 +34,7 @@
   #include "internal.h"
   #include "regexp.h"
   #include "error_object.h"
  +#include "lookup.h"
   
   using namespace KJS;
   
  @@ -79,69 +82,64 @@
           case ToString: return String("//");
         }
       }
  +    
       return throwError(exec, TypeError);
     }
   
  -  RegExpImp *reimp = static_cast<RegExpImp*>(thisObj);
  -  RegExp *re = reimp->regExp();
  -  UString s;
  -  UString str;
     switch (id) {
  -  case Exec:      // 15.10.6.2
  -  case Test:
  +  case Test:      // 15.10.6.2
  +  case Exec:
     {
  -    s = args[0]->toString(exec);
  -    int length = s.size();
  -    ValueImp *lastIndex = thisObj->get(exec,"lastIndex");
  -    int i = lastIndex->toInt32(exec);
  -    bool globalFlag = thisObj->get(exec,"global")->toBoolean(exec);
  +    RegExp *regExp = static_cast<RegExpImp*>(thisObj)->regExp();
  +    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
  +
  +    UString input;
  +    if (args.isEmpty())
  +      input = regExpObj->get(exec, "input")->toString(exec);
  +    else
  +      input = args[0]->toString(exec);
  +
  +    double lastIndex = thisObj->get(exec, "lastIndex")->toInteger(exec);
  +
  +    bool globalFlag = thisObj->get(exec, "global")->toBoolean(exec);
       if (!globalFlag)
  -      i = 0;
  -    if (i < 0 || i > length) {
  -      thisObj->put(exec,"lastIndex", Number(0), DontDelete | DontEnum);
  -      if (id == Test)
  -        return Boolean(false);
  -      else
  -        return Null();
  +      lastIndex = 0;
  +    if (lastIndex < 0 || lastIndex > input.size()) {
  +      thisObj->put(exec, "lastIndex", jsZero(), DontDelete | DontEnum);
  +      return Null();
       }
  -    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
  -    int **ovector = regExpObj->registerRegexp( re, s );
   
  -    str = re->match(s, i, 0L, ovector);
  -    regExpObj->setSubPatterns(re->subPatterns());
  +    UString match = regExpObj->performMatch(regExp, input, static_cast<int>(lastIndex));
  +    bool didMatch = !match.isNull();
   
  +    // Test
       if (id == Test)
  -      return Boolean(!str.isNull());
  +      return Boolean(didMatch);
   
  -    if (str.isNull()) // no match
  -    {
  +    // Exec
  +    if (didMatch) {
         if (globalFlag)
  -        thisObj->put(exec,"lastIndex",Number(0), DontDelete | DontEnum);
  -      return Null();
  -    }
  -    else // success
  -    {
  +        thisObj->put(exec, "lastIndex", Number(lastIndex + match.size()), DontDelete | DontEnum);
  +      return regExpObj->arrayOfMatches(exec, match);
  +    } else {
         if (globalFlag)
  -        thisObj->put(exec,"lastIndex",Number( (*ovector)[1] ), DontDelete | DontEnum);
  -      return regExpObj->arrayOfMatches(exec,str);
  +        thisObj->put(exec, "lastIndex", jsZero(), DontDelete | DontEnum);
  +      return Null();
       }
     }
     break;
     case ToString:
  -    s = thisObj->get(exec,"source")->toString(exec);
  -    str = "/";
  -    str += s;
  -    str += "/";
  -    if (thisObj->get(exec,"global")->toBoolean(exec)) {
  -      str += "g";
  +    UString result = "/" + thisObj->get(exec, "source")->toString(exec) + "/";
  +    if (thisObj->get(exec, "global")->toBoolean(exec)) {
  +      result += "g";
       }
  -    if (thisObj->get(exec,"ignoreCase")->toBoolean(exec)) {
  -      str += "i";
  +    if (thisObj->get(exec, "ignoreCase")->toBoolean(exec)) {
  +      result += "i";
       }
  -    if (thisObj->get(exec,"multiline")->toBoolean(exec)) {
  -      str += "m";
  +    if (thisObj->get(exec, "multiline")->toBoolean(exec)) {
  +      result += "m";
       }
  -    return String(str);
  +    return String(result);
     }
   
     return Undefined();
  @@ -163,11 +161,39 @@
   
   // ------------------------------ RegExpObjectImp ------------------------------
   
  +const ClassInfo RegExpObjectImp::info = {"RegExp", &InternalFunctionImp::info, &RegExpTable, 0};
  +
  +/* Source for regexp_object.lut.h
  + at begin RegExpTable 20
  +  input           RegExpObjectImp::Input          None
  +  $_              RegExpObjectImp::Input          DontEnum
  +  multiline       RegExpObjectImp::Multiline      None
  +  $*              RegExpObjectImp::Multiline      DontEnum
  +  lastMatch       RegExpObjectImp::LastMatch      DontDelete|ReadOnly
  +  $&              RegExpObjectImp::LastMatch      DontDelete|ReadOnly|DontEnum
  +  lastParen       RegExpObjectImp::LastParen      DontDelete|ReadOnly
  +  $+              RegExpObjectImp::LastParen      DontDelete|ReadOnly|DontEnum
  +  leftContext     RegExpObjectImp::LeftContext    DontDelete|ReadOnly
  +  $`              RegExpObjectImp::LeftContext    DontDelete|ReadOnly|DontEnum
  +  rightContext    RegExpObjectImp::RightContext   DontDelete|ReadOnly
  +  $'              RegExpObjectImp::RightContext   DontDelete|ReadOnly|DontEnum
  +  $1              RegExpObjectImp::Dollar1        DontDelete|ReadOnly
  +  $2              RegExpObjectImp::Dollar2        DontDelete|ReadOnly
  +  $3              RegExpObjectImp::Dollar3        DontDelete|ReadOnly
  +  $4              RegExpObjectImp::Dollar4        DontDelete|ReadOnly
  +  $5              RegExpObjectImp::Dollar5        DontDelete|ReadOnly
  +  $6              RegExpObjectImp::Dollar6        DontDelete|ReadOnly
  +  $7              RegExpObjectImp::Dollar7        DontDelete|ReadOnly
  +  $8              RegExpObjectImp::Dollar8        DontDelete|ReadOnly
  +  $9              RegExpObjectImp::Dollar9        DontDelete|ReadOnly
  + at end
  +*/
  +
   RegExpObjectImp::RegExpObjectImp(ExecState *exec,
                                    FunctionPrototypeImp *funcProto,
                                    RegExpPrototypeImp *regProto)
   
  -  : InternalFunctionImp(funcProto), lastOvector(0L), lastNrSubPatterns(0)
  +  : InternalFunctionImp(funcProto), multiline(false), lastInput(""), lastOvector(0), lastNumSubPatterns(0)
   {
     // ECMA 15.10.5.1 RegExp.prototype
     putDirect(prototypePropertyName, regProto, DontEnum|DontDelete|ReadOnly);
  @@ -181,13 +207,32 @@
     delete [] lastOvector;
   }
   
  -int **RegExpObjectImp::registerRegexp( const RegExp* re, const UString& s )
  -{
  -  lastString = s;
  -  delete [] lastOvector;
  -  lastOvector = 0;
  -  lastNrSubPatterns = re->subPatterns();
  -  return &lastOvector;
  +/* 
  +  To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
  +  expression matching through the performMatch function. We use cached results to calculate, 
  +  e.g., RegExp.lastMatch and RegExp.leftParen.
  +*/
  +UString RegExpObjectImp::performMatch(RegExp* r, const UString& s, int startOffset, int *endOffset, int **ovector)
  +{
  +  int tmpOffset;
  +  int *tmpOvector;
  +  UString match = r->match(s, startOffset, &tmpOffset, &tmpOvector);
  +
  +  if (endOffset)
  +    *endOffset = tmpOffset;
  +  if (ovector)
  +    *ovector = tmpOvector;
  +  
  +  if (!match.isNull()) {
  +    assert(tmpOvector);
  +    
  +    lastInput = s;
  +    delete [] lastOvector;
  +    lastOvector = tmpOvector;
  +    lastNumSubPatterns = r->subPatterns();
  +  }
  +  
  +  return match;
   }
   
   ObjectImp *RegExpObjectImp::arrayOfMatches(ExecState *exec, const UString &result) const
  @@ -196,52 +241,139 @@
     // The returned array contains 'result' as first item, followed by the list of matches
     list.append(String(result));
     if ( lastOvector )
  -    for ( unsigned i = 1 ; i < lastNrSubPatterns + 1 ; ++i )
  +    for ( unsigned i = 1 ; i < lastNumSubPatterns + 1 ; ++i )
       {
         int start = lastOvector[2*i];
         if (start == -1)
           list.append(jsUndefined());
         else {
  -        UString substring = lastString.substr( start, lastOvector[2*i+1] - start );
  +        UString substring = lastInput.substr( start, lastOvector[2*i+1] - start );
           list.append(String(substring));
         }
       }
     ObjectImp *arr = exec->lexicalInterpreter()->builtinArray()->construct(exec, list);
     arr->put(exec, "index", Number(lastOvector[0]));
  -  arr->put(exec, "input", String(lastString));
  +  arr->put(exec, "input", String(lastInput));
     return arr;
   }
   
  -ValueImp *RegExpObjectImp::backrefGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
  +ValueImp *RegExpObjectImp::getBackref(unsigned i) const
   {
  -  RegExpObjectImp *thisObj = static_cast<RegExpObjectImp *>(slot.slotBase());
  -  unsigned i = slot.index();
  -
  -  if (i < thisObj->lastNrSubPatterns + 1) {
  -    int *lastOvector = thisObj->lastOvector;
  -    UString substring = thisObj->lastString.substr(lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
  +  if (lastOvector && i < lastNumSubPatterns + 1) {
  +    UString substring = lastInput.substr(lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
       return String(substring);
     } 
   
     return String("");
   }
   
  +ValueImp *RegExpObjectImp::getLastMatch() const
  +{
  +  if (lastOvector) {
  +    UString substring = lastInput.substr(lastOvector[0], lastOvector[1] - lastOvector[0]);
  +    return String(substring);
  +  }
  +  
  +  return String("");
  +}
  +
  +ValueImp *RegExpObjectImp::getLastParen() const
  +{
  +  int i = lastNumSubPatterns;
  +  if (i > 0) {
  +    assert(lastOvector);
  +    UString substring = lastInput.substr(lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i]);
  +    return String(substring);
  +  }
  +    
  +  return String("");
  +}
  +
  +ValueImp *RegExpObjectImp::getLeftContext() const
  +{
  +  if (lastOvector) {
  +    UString substring = lastInput.substr(0, lastOvector[0]);
  +    return String(substring);
  +  }
  +  
  +  return String("");
  +}
  +
  +ValueImp *RegExpObjectImp::getRightContext() const
  +{
  +  if (lastOvector) {
  +    UString s = lastInput;
  +    UString substring = s.substr(lastOvector[1], s.size() - lastOvector[1]);
  +    return String(substring);
  +  }
  +  
  +  return String("");
  +}
  +
   bool RegExpObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
   {
  -  UString s = propertyName.ustring();
  -  if (s[0] == '$' && lastOvector)
  -  {
  -    bool ok;
  -    unsigned i = s.substr(1).toUInt32(&ok);
  -    if (ok) {
  -      slot.setCustomIndex(this, i, backrefGetter);
  -      return true;
  -    }
  +  return getStaticValueSlot<RegExpObjectImp, InternalFunctionImp>(exec, &RegExpTable, this, propertyName, slot);
  +}
  +
  +ValueImp *RegExpObjectImp::getValueProperty(ExecState *exec, int token) const
  +{
  +  switch (token) {
  +    case Dollar1:
  +      return getBackref(1);
  +    case Dollar2:
  +      return getBackref(2);
  +    case Dollar3:
  +      return getBackref(3);
  +    case Dollar4:
  +      return getBackref(4);
  +    case Dollar5:
  +      return getBackref(5);
  +    case Dollar6:
  +      return getBackref(6);
  +    case Dollar7:
  +      return getBackref(7);
  +    case Dollar8:
  +      return getBackref(8);
  +    case Dollar9:
  +      return getBackref(9);
  +    case Input:
  +      return jsString(lastInput);
  +    case Multiline:
  +      return jsBoolean(multiline);
  +    case LastMatch:
  +      return getLastMatch();
  +    case LastParen:
  +      return getLastParen();
  +    case LeftContext:
  +      return getLeftContext();
  +    case RightContext:
  +      return getRightContext();
  +    default:
  +      assert(0);
     }
   
  -  return InternalFunctionImp::getOwnPropertySlot(exec, propertyName, slot);
  +  return String("");
   }
   
  +void RegExpObjectImp::put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr)
  +{
  +  lookupPut<RegExpObjectImp, InternalFunctionImp>(exec, propertyName, value, attr, &RegExpTable, this);
  +}
  +
  +void RegExpObjectImp::putValueProperty(ExecState *exec, int token, ValueImp *value, int attr)
  +{
  +  switch (token) {
  +    case Input:
  +      lastInput = value->toString(exec);
  +      break;
  +    case Multiline:
  +      multiline = value->toBoolean(exec);
  +      break;
  +    default:
  +      assert(0);
  +  }
  +}
  +  
   bool RegExpObjectImp::implementsConstruct() const
   {
     return true;
  
  
  
  1.13      +21 -6     JavaScriptCore/kjs/regexp_object.h
  
  Index: regexp_object.h
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/regexp_object.h,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- regexp_object.h	4 Sep 2005 01:18:13 -0000	1.12
  +++ regexp_object.h	11 Oct 2005 20:43:49 -0000	1.13
  @@ -65,6 +65,9 @@
   
     class RegExpObjectImp : public InternalFunctionImp {
     public:
  +    enum { Dollar1, Dollar2, Dollar3, Dollar4, Dollar5, Dollar6, Dollar7, Dollar8, Dollar9, 
  +           Input, Multiline, LastMatch, LastParen, LeftContext, RightContext };
  +    
       RegExpObjectImp(ExecState *exec,
                       FunctionPrototypeImp *funcProto,
                       RegExpPrototypeImp *regProto);
  @@ -74,16 +77,28 @@
       virtual bool implementsCall() const;
       virtual ValueImp *callAsFunction(ExecState *exec, ObjectImp *thisObj, const List &args);
   
  +    virtual void put(ExecState *, const Identifier &, ValueImp *, int attr = None);
  +    void putValueProperty(ExecState *, int token, ValueImp *, int attr);
       virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
  -    int ** registerRegexp( const RegExp* re, const UString& s );
  -    void setSubPatterns(int num) { lastNrSubPatterns = num; }
  +    ValueImp *getValueProperty(ExecState *, int token) const;
  +    UString performMatch(RegExp *, const UString&, int startOffset = 0, int *endOffset = 0, int **ovector = 0);
       ObjectImp *arrayOfMatches(ExecState *exec, const UString &result) const;
  +    
  +    virtual const ClassInfo *classInfo() const { return &info; }
     private:
  -    static ValueImp *backrefGetter(ExecState *exec, const Identifier&, const PropertySlot& slot);
  -  
  -    UString lastString;
  +    ValueImp *getBackref(unsigned) const;
  +    ValueImp *getLastMatch() const;
  +    ValueImp *getLastParen() const;
  +    ValueImp *getLeftContext() const;
  +    ValueImp *getRightContext() const;
  +
  +    // Global search cache / settings
  +    bool multiline;
  +    UString lastInput;
       int *lastOvector;
  -    unsigned lastNrSubPatterns;
  +    unsigned lastNumSubPatterns;
  +    
  +    static const ClassInfo info;
     };
   
   } // namespace
  
  
  
  1.49      +14 -20    JavaScriptCore/kjs/string_object.cpp
  
  Index: string_object.cpp
  ===================================================================
  RCS file: /cvs/root/JavaScriptCore/kjs/string_object.cpp,v
  retrieving revision 1.48
  retrieving revision 1.49
  diff -u -r1.48 -r1.49
  --- string_object.cpp	6 Oct 2005 01:13:18 -0000	1.48
  +++ string_object.cpp	11 Oct 2005 20:43:49 -0000	1.49
  @@ -232,7 +232,7 @@
     count++;
   }
   
  -static inline UString substituteBackreferences(const UString &replacement, const UString &source, int **ovector, RegExp *reg)
  +static inline UString substituteBackreferences(const UString &replacement, const UString &source, int *ovector, RegExp *reg)
   {
     UString substitutedReplacement = replacement;
   
  @@ -246,8 +246,8 @@
       // Assume number part is one char exactly
       unsigned backrefIndex = substitutedReplacement.substr(i+1,1).toUInt32(&converted, false /* tolerate empty string */);
       if (converted && backrefIndex <= (unsigned)reg->subPatterns()) {
  -      int backrefStart = (*ovector)[2*backrefIndex];
  -      int backrefLength = (*ovector)[2*backrefIndex+1] - backrefStart;
  +      int backrefStart = ovector[2*backrefIndex];
  +      int backrefLength = ovector[2*backrefIndex+1] - backrefStart;
         substitutedReplacement = substitutedReplacement.substr(0,i)
           + source.substr(backrefStart, backrefLength)
           + substitutedReplacement.substr(i+2);
  @@ -288,9 +288,8 @@
   
       // This is either a loop (if global is set) or a one-way (if not).
       do {
  -      int **ovector = regExpObj->registerRegexp( reg, source );
  -      UString matchString = reg->match(source, startPosition, &matchIndex, ovector);
  -      regExpObj->setSubPatterns(reg->subPatterns());
  +      int *ovector;
  +      UString matchString = regExpObj->performMatch(reg, source, startPosition, &matchIndex, &ovector);
         if (matchIndex == -1)
           break;
         int matchLen = matchString.size();
  @@ -298,14 +297,14 @@
         pushSourceRange(sourceRanges, sourceRangeCount, sourceRangeCapacity, UString::Range(lastIndex, matchIndex - lastIndex));
   
         if (replacementFunction) {
  -          int completeMatchStart = (*ovector)[0];
  +          int completeMatchStart = ovector[0];
             List args;
   
             args.append(jsString(matchString));
             
             for (unsigned i = 0; i < reg->subPatterns(); i++) {
  -              int matchStart = (*ovector)[(i + 1) * 2];
  -              int matchLen = (*ovector)[(i + 1) * 2 + 1] - matchStart;
  +              int matchStart = ovector[(i + 1) * 2];
  +              int matchLen = ovector[(i + 1) * 2 + 1] - matchStart;
                 
                 args.append(jsString(source.substr(matchStart, matchLen)));
             }
  @@ -454,13 +453,11 @@
       u = s;
       RegExp *reg, *tmpReg = 0;
       RegExpImp *imp = 0;
  -    if (a0->isObject() && a0->getObject()->inherits(&RegExpImp::info))
  -    {
  +    if (a0->isObject() && a0->getObject()->inherits(&RegExpImp::info)) {
         imp = static_cast<RegExpImp *>(a0);
         reg = imp->regExp();
  -    }
  -    else
  -    { /*
  +    } else { 
  +      /*
          *  ECMA 15.5.4.12 String.prototype.search (regexp)
          *  If regexp is not an object whose [[Class]] property is "RegExp", it is
          *  replaced with the result of the expression new RegExp(regexp).
  @@ -468,8 +465,7 @@
         reg = tmpReg = new RegExp(a0->toString(exec), RegExp::None);
       }
       RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
  -    int **ovector = regExpObj->registerRegexp(reg, u);
  -    UString mstr = reg->match(u, -1, &pos, ovector);
  +    UString mstr = regExpObj->performMatch(reg, u, 0, &pos);
       if (id == Search) {
         result = Number(pos);
       } else {
  @@ -479,7 +475,6 @@
   	if (mstr.isNull()) {
   	  result = Null();
   	} else {
  -	  regExpObj->setSubPatterns(reg->subPatterns());
   	  result = regExpObj->arrayOfMatches(exec,mstr);
   	}
         } else {
  @@ -493,8 +488,7 @@
   	    list.append(String(mstr));
   	  lastIndex = pos;
   	  pos += mstr.isEmpty() ? 1 : mstr.size();
  -	  delete [] *ovector;
  -	  mstr = reg->match(u, pos, &pos, ovector);
  +	  mstr = regExpObj->performMatch(reg, u, pos, &pos);
   	}
   	if (imp)
   	  imp->put(exec, "lastIndex", Number(lastIndex), DontDelete|DontEnum);
  @@ -514,7 +508,7 @@
     case Replace:
       result = replace(exec, s, a0, a1);
       break;
  -  case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/string.htm#1194366
  +  case Slice:
       {
           // The arg processing is very much like ArrayProtoFunc::Slice
           double begin = args[0]->toInteger(exec);
  
  
  



More information about the webkit-changes mailing list