Changeset 27405 in webkit for trunk/JavaScriptCore/kjs/regexp_object.cpp
- Timestamp:
- Nov 3, 2007, 9:28:51 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/regexp_object.cpp
r27393 r27405 1 // -*- c-basic-offset: 2 -*-2 1 /* 3 2 * Copyright (C) 1999-2000 Harri Porten ([email protected]) … … 36 35 #include <stdio.h> 37 36 38 using namespace KJS; 37 namespace KJS { 39 38 40 39 // ------------------------------ RegExpPrototype --------------------------- … … 79 78 } 80 79 81 switch (id) { 82 case Test: // 15.10.6.2 83 case Exec: 84 { 85 RegExp *regExp = static_cast<RegExpImp*>(thisObj)->regExp(); 86 RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp()); 87 88 UString input; 89 if (args.isEmpty()) 90 input = regExpObj->get(exec, exec->propertyNames().input)->toString(exec); 91 else 92 input = args[0]->toString(exec); 93 94 double lastIndex = thisObj->get(exec, exec->propertyNames().lastIndex)->toInteger(exec); 95 96 bool globalFlag = thisObj->get(exec, exec->propertyNames().global)->toBoolean(exec); 97 if (!globalFlag) 98 lastIndex = 0; 99 if (lastIndex < 0 || lastIndex > input.size()) { 100 thisObj->put(exec, exec->propertyNames().lastIndex, jsNumber(0), DontDelete | DontEnum); 101 return jsNull(); 102 } 103 104 int foundIndex; 105 int foundLength; 106 regExpObj->performMatch(regExp, input, static_cast<int>(lastIndex), foundIndex, foundLength); 107 108 // Test 109 if (id == Test) 110 return jsBoolean(foundIndex >= 0); 111 112 // Exec 113 if (foundIndex < 0) { 114 if (globalFlag) 115 thisObj->put(exec, exec->propertyNames().lastIndex, jsNumber(0), DontDelete | DontEnum); 116 return jsNull(); 117 } 118 if (globalFlag) 119 thisObj->put(exec, exec->propertyNames().lastIndex, jsNumber(foundIndex + foundLength), DontDelete | DontEnum); 120 return regExpObj->arrayOfMatches(exec); 121 } 122 break; 80 switch (id) { 81 case Test: 82 return static_cast<RegExpImp*>(thisObj)->test(exec, args); 83 case Exec: 84 return static_cast<RegExpImp*>(thisObj)->exec(exec, args); 123 85 case Compile: 124 86 { … … 192 154 const ClassInfo RegExpImp::info = {"RegExp", 0, 0, 0}; 193 155 194 RegExpImp::RegExpImp(RegExpPrototype* regexpProto )156 RegExpImp::RegExpImp(RegExpPrototype* regexpProto, RegExp* exp) 195 157 : JSObject(regexpProto) 158 , m_regExp(exp) 196 159 { 197 160 } … … 199 162 RegExpImp::~RegExpImp() 200 163 { 164 } 165 166 bool RegExpImp::match(ExecState* exec, const List& args) 167 { 168 RegExpObjectImp* regExpObj = exec->lexicalInterpreter()->builtinRegExp(); 169 170 UString input; 171 if (!args.isEmpty()) 172 input = args[0]->toString(exec); 173 else { 174 input = regExpObj->input(); 175 if (input.isNull()) { 176 throwError(exec, GeneralError, "No input."); 177 return false; 178 } 179 } 180 181 bool global = get(exec, exec->propertyNames().global)->toBoolean(exec); 182 int lastIndex = 0; 183 if (global) { 184 double lastIndexDouble = get(exec, exec->propertyNames().lastIndex)->toInteger(exec); 185 if (lastIndexDouble < 0 || lastIndexDouble > input.size()) { 186 put(exec, exec->propertyNames().lastIndex, jsNumber(0), DontDelete | DontEnum); 187 return false; 188 } 189 lastIndex = static_cast<int>(lastIndexDouble); 190 } 191 192 int foundIndex; 193 int foundLength; 194 regExpObj->performMatch(m_regExp.get(), input, lastIndex, foundIndex, foundLength); 195 196 if (global) { 197 lastIndex = foundIndex < 0 ? 0 : foundIndex + foundLength; 198 put(exec, exec->propertyNames().lastIndex, jsNumber(lastIndex), DontDelete | DontEnum); 199 } 200 201 return foundIndex >= 0; 202 } 203 204 JSValue* RegExpImp::test(ExecState* exec, const List& args) 205 { 206 return jsBoolean(match(exec, args)); 207 } 208 209 JSValue* RegExpImp::exec(ExecState* exec, const List& args) 210 { 211 return match(exec, args) 212 ? exec->lexicalInterpreter()->builtinRegExp()->arrayOfMatches(exec) 213 : jsNull(); 214 } 215 216 bool RegExpImp::implementsCall() const 217 { 218 return true; 219 } 220 221 JSValue* RegExpImp::callAsFunction(ExecState* exec, JSObject*, const List& args) 222 { 223 return RegExpImp::exec(exec, args); 201 224 } 202 225 … … 231 254 */ 232 255 233 struct KJS::RegExpObjectImpPrivate {256 struct RegExpObjectImpPrivate { 234 257 // Global search cache / settings 235 RegExpObjectImpPrivate() : last Input(""), lastNumSubPatterns(0), multiline(false) { }258 RegExpObjectImpPrivate() : lastNumSubPatterns(0), multiline(false) { } 236 259 UString lastInput; 237 260 OwnArrayPtr<int> lastOvector; … … 404 427 UString flags = args[1]->isUndefined() ? UString("") : args[1]->toString(exec); 405 428 406 RegExpPrototype *proto = static_cast<RegExpPrototype*>(exec->lexicalInterpreter()->builtinRegExpPrototype()); 407 RegExpImp *dat = new RegExpImp(proto); 429 RegExpPrototype* proto = static_cast<RegExpPrototype*>(exec->lexicalInterpreter()->builtinRegExpPrototype()); 408 430 409 431 bool global = (flags.find("g") >= 0); 410 432 bool ignoreCase = (flags.find("i") >= 0); 411 433 bool multiline = (flags.find("m") >= 0); 412 413 dat->putDirect(exec->propertyNames().global, jsBoolean(global), DontDelete | ReadOnly | DontEnum);414 dat->putDirect(exec->propertyNames().ignoreCase, jsBoolean(ignoreCase), DontDelete | ReadOnly | DontEnum);415 dat->putDirect(exec->propertyNames().multiline, jsBoolean(multiline), DontDelete | ReadOnly | DontEnum);416 417 dat->putDirect(exec->propertyNames().source, jsString(p), DontDelete | ReadOnly | DontEnum);418 dat->putDirect(exec->propertyNames().lastIndex, jsNumber(0), DontDelete | DontEnum);419 434 420 435 int reflags = RegExp::None; … … 430 445 return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(re->errorMessage())); 431 446 432 dat->setRegExp(re.release()); 447 RegExpImp* dat = new RegExpImp(proto, re.release()); 448 449 dat->putDirect(exec->propertyNames().global, jsBoolean(global), DontDelete | ReadOnly | DontEnum); 450 dat->putDirect(exec->propertyNames().ignoreCase, jsBoolean(ignoreCase), DontDelete | ReadOnly | DontEnum); 451 dat->putDirect(exec->propertyNames().multiline, jsBoolean(multiline), DontDelete | ReadOnly | DontEnum); 452 453 dat->putDirect(exec->propertyNames().source, jsString(p), DontDelete | ReadOnly | DontEnum); 454 dat->putDirect(exec->propertyNames().lastIndex, jsNumber(0), DontDelete | DontEnum); 433 455 434 456 return dat; … … 440 462 return construct(exec, args); 441 463 } 464 465 const UString& RegExpObjectImp::input() const 466 { 467 // Can detect a distinct initial state that is invisible to JavaScript, by checking for null 468 // state (since jsString turns null strings to empty strings). 469 return d->lastInput; 470 } 471 472 }
Note:
See TracChangeset
for help on using the changeset viewer.