Changeset 229514 in webkit for trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp
- Timestamp:
- Mar 10, 2018, 11:20:29 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp
r229410 r229514 178 178 } 179 179 180 template<typename FixEndFunc>181 JSValue collectMatches(VM& vm, ExecState* exec, JSString* string, const String& s, RegExpConstructor* constructor, RegExp* regExp, const FixEndFunc& fixEnd)182 {183 auto scope = DECLARE_THROW_SCOPE(vm);184 185 MatchResult result = constructor->performMatch(vm, regExp, string, s, 0);186 if (!result)187 return jsNull();188 189 static unsigned maxSizeForDirectPath = 100000;190 191 JSArray* array = constructEmptyArray(exec, nullptr);192 RETURN_IF_EXCEPTION(scope, { });193 194 bool hasException = false;195 auto iterate = [&] () {196 size_t end = result.end;197 size_t length = end - result.start;198 array->push(exec, JSRopeString::createSubstringOfResolved(vm, string, result.start, length));199 if (UNLIKELY(scope.exception())) {200 hasException = true;201 return;202 }203 if (!length)204 end = fixEnd(end);205 result = constructor->performMatch(vm, regExp, string, s, end);206 };207 208 do {209 if (array->length() >= maxSizeForDirectPath) {210 // First do a throw-away match to see how many matches we'll get.211 unsigned matchCount = 0;212 MatchResult savedResult = result;213 do {214 if (array->length() + matchCount > MAX_STORAGE_VECTOR_LENGTH) {215 throwOutOfMemoryError(exec, scope);216 return jsUndefined();217 }218 219 size_t end = result.end;220 matchCount++;221 if (result.empty())222 end = fixEnd(end);223 224 // Using RegExpConstructor::performMatch() instead of calling RegExp::match()225 // directly is a surprising but profitable choice: it means that when we do OOM, we226 // will leave the cached result in the state it ought to have had just before the227 // OOM! On the other hand, if this loop concludes that the result is small enough,228 // then the iterate() loop below will overwrite the cached result anyway.229 result = constructor->performMatch(vm, regExp, string, s, end);230 } while (result);231 232 // OK, we have a sensible number of matches. Now we can create them for reals.233 result = savedResult;234 do {235 iterate();236 EXCEPTION_ASSERT(!!scope.exception() == hasException);237 if (UNLIKELY(hasException))238 return { };239 } while (result);240 241 return array;242 }243 244 iterate();245 } while (result);246 247 return array;248 }249 250 180 JSValue RegExpObject::matchGlobal(ExecState* exec, JSGlobalObject* globalObject, JSString* string) 251 181 {
Note:
See TracChangeset
for help on using the changeset viewer.