JSValue RegExpObject::matchGlobal(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { RegExp* regExp = this->regExp(); ASSERT(regExp->global()); VM* vm = &globalObject->vm(); setLastIndex(exec, 0); if (exec->hadException()) return jsUndefined(); String s = string->value(exec); RegExpConstructor* regExpConstructor = globalObject->regExpConstructor(); if (regExp->unicode()) { unsigned stringLength = s.length(); return collectMatches( *vm, exec, string, s, regExpConstructor, regExp, [&] (size_t end) -> size_t { return advanceStringUnicode(s, stringLength, end); }); } return collectMatches( *vm, exec, string, s, regExpConstructor, regExp, [&] (size_t end) -> size_t { return end + 1; }); }
JSValue RegExpObject::matchGlobal(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { VM& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); RegExp* regExp = this->regExp(); ASSERT(regExp->global()); setLastIndex(exec, 0); RETURN_IF_EXCEPTION(scope, { }); String s = string->value(exec); RegExpConstructor* regExpConstructor = globalObject->regExpConstructor(); if (regExp->unicode()) { unsigned stringLength = s.length(); scope.release(); return collectMatches( vm, exec, string, s, regExpConstructor, regExp, [&] (size_t end) -> size_t { return advanceStringUnicode(s, stringLength, end); }); } scope.release(); return collectMatches( vm, exec, string, s, regExpConstructor, regExp, [&] (size_t end) -> size_t { return end + 1; }); }
JSValue RegExpObject::matchGlobal(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { RegExp* regExp = this->regExp(); ASSERT(regExp->global()); VM* vm = &globalObject->vm(); setLastIndex(exec, 0); if (exec->hadException()) return jsUndefined(); String s = string->value(exec); RegExpConstructor* regExpConstructor = globalObject->regExpConstructor(); MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, s, 0); // return array of matches MarkedArgumentBuffer list; // We defend ourselves from crazy. const size_t maximumReasonableMatchSize = 1000000000; if (regExp->unicode()) { unsigned stringLength = s.length(); while (result) { if (list.size() > maximumReasonableMatchSize) { throwOutOfMemoryError(exec); return jsUndefined(); } size_t end = result.end; size_t length = end - result.start; list.append(jsSubstring(exec, s, result.start, length)); if (!length) end = advanceStringUnicode(s, stringLength, end); result = regExpConstructor->performMatch(*vm, regExp, string, s, end); } } else { while (result) { if (list.size() > maximumReasonableMatchSize) { throwOutOfMemoryError(exec); return jsUndefined(); } size_t end = result.end; size_t length = end - result.start; list.append(jsSubstring(exec, s, result.start, length)); if (!length) ++end; result = regExpConstructor->performMatch(*vm, regExp, string, s, end); } } if (list.isEmpty()) { // if there are no matches at all, it's important to return // Null instead of an empty array, because this matches // other browsers and because Null is a false value. return jsNull(); } return constructArray(exec, static_cast<ArrayAllocationProfile*>(0), list); }