1 package goja
2
3 import (
4 "testing"
5 )
6
7 func TestRegexp1(t *testing.T) {
8 const SCRIPT = `
9 var r = new RegExp("(['\"])(.*?)\\1");
10 var m = r.exec("'test'");
11 m !== null && m.length == 3 && m[2] === "test";
12 `
13
14 testScript(SCRIPT, valueTrue, t)
15 }
16
17 func TestRegexp2(t *testing.T) {
18 const SCRIPT = `
19 var r = new RegExp("(['\"])(.*?)['\"]");
20 var m = r.exec("'test'");
21 m !== null && m.length == 3 && m[2] === "test";
22 `
23
24 testScript(SCRIPT, valueTrue, t)
25 }
26
27 func TestRegexpLiteral(t *testing.T) {
28 const SCRIPT = `
29 var r = /(['\"])(.*?)\1/;
30 var m = r.exec("'test'");
31 m !== null && m.length == 3 && m[2] === "test";
32 `
33
34 testScript(SCRIPT, valueTrue, t)
35 }
36
37 func TestRegexpRe2Unicode(t *testing.T) {
38 const SCRIPT = `
39 var r = /(тест)/i;
40 var m = r.exec("'Тест'");
41 m !== null && m.length == 2 && m[1] === "Тест";
42 `
43
44 testScript(SCRIPT, valueTrue, t)
45 }
46
47 func TestRegexpRe2UnicodeTarget(t *testing.T) {
48 const SCRIPT = `
49 var r = /(['\"])(.*?)['\"]/i;
50 var m = r.exec("'Тест'");
51 m !== null && m.length == 3 && m[2] === "Тест";
52 `
53
54 testScript(SCRIPT, valueTrue, t)
55 }
56
57 func TestRegexpRegexp2Unicode(t *testing.T) {
58 const SCRIPT = `
59 var r = /(['\"])(тест)\1/i;
60 var m = r.exec("'Тест'");
61 m !== null && m.length == 3 && m[2] === "Тест";
62 `
63
64 testScript(SCRIPT, valueTrue, t)
65 }
66
67 func TestRegexpRegexp2UnicodeTarget(t *testing.T) {
68 const SCRIPT = `
69 var r = /(['\"])(.*?)\1/;
70 var m = r.exec("'Тест'");
71 m !== null && m.length == 3 && m[2] === "Тест";
72 `
73
74 testScript(SCRIPT, valueTrue, t)
75 }
76
77 func TestRegexpRe2Whitespace(t *testing.T) {
78 const SCRIPT = `
79 "\u2000\u2001\u2002\u200b".replace(/\s+/g, "") === "\u200b";
80 `
81
82 testScript(SCRIPT, valueTrue, t)
83 }
84
85 func TestRegexpRegexp2Whitespace(t *testing.T) {
86 const SCRIPT = `
87 "A\u2000\u2001\u2002A\u200b".replace(/(A)\s+\1/g, "") === "\u200b"
88 `
89 testScript(SCRIPT, valueTrue, t)
90 }
91
92 func TestEmptyCharClassRe2(t *testing.T) {
93 const SCRIPT = `
94 /[]/.test("\u0000");
95 `
96
97 testScript(SCRIPT, valueFalse, t)
98 }
99
100 func TestNegatedEmptyCharClassRe2(t *testing.T) {
101 const SCRIPT = `
102 /[^]/.test("\u0000");
103 `
104
105 testScript(SCRIPT, valueTrue, t)
106 }
107
108 func TestEmptyCharClassRegexp2(t *testing.T) {
109 const SCRIPT = `
110 /([])\1/.test("\u0000\u0000");
111 `
112
113 testScript(SCRIPT, valueFalse, t)
114 }
115
116 func TestRegexp2Negate(t *testing.T) {
117 const SCRIPT = `
118 /([\D1])\1/.test("aa");
119 `
120
121 testScript(SCRIPT, valueTrue, t)
122 }
123
124 func TestAlternativeRe2(t *testing.T) {
125 const SCRIPT = `
126 /()|/.exec("") !== null;
127 `
128
129 testScript(SCRIPT, valueTrue, t)
130 }
131
132 func TestRegexpReplaceGlobal(t *testing.T) {
133 const SCRIPT = `
134 "QBZPbage\ny_cynprubyqre".replace(/^\s*|\s*$/g, '')
135 `
136
137 testScript(SCRIPT, asciiString("QBZPbage\ny_cynprubyqre"), t)
138 }
139
140 func TestRegexpNumCaptures(t *testing.T) {
141 const SCRIPT = `
142 "Fubpxjnir Synfu 9.0 e115".replace(/([a-zA-Z]|\s)+/, '')
143 `
144 testScript(SCRIPT, asciiString("9.0 e115"), t)
145 }
146
147 func TestRegexpNumCaptures1(t *testing.T) {
148 const SCRIPT = `
149 "Fubpxjnir Sy\tfu 9.0 e115".replace(/^.*\s+(\S+\s+\S+$)/, '')
150 `
151 testScript(SCRIPT, asciiString(""), t)
152 }
153
154 func TestRegexpSInClass(t *testing.T) {
155 const SCRIPT = `
156 /[\S]/.test("\u2028");
157 `
158 testScript(SCRIPT, valueFalse, t)
159 }
160
161 func TestRegexpDotMatchCR(t *testing.T) {
162 const SCRIPT = `
163 /./.test("\r");
164 `
165
166 testScript(SCRIPT, valueFalse, t)
167 }
168
169 func TestRegexpDotMatchCRInGroup(t *testing.T) {
170 const SCRIPT = `
171 /(.)/.test("\r");
172 `
173
174 testScript(SCRIPT, valueFalse, t)
175 }
176
177 func TestRegexpDotMatchLF(t *testing.T) {
178 const SCRIPT = `
179 /./.test("\n");
180 `
181
182 testScript(SCRIPT, valueFalse, t)
183 }
184
185 func TestRegexpSplitWithBackRef(t *testing.T) {
186 const SCRIPT = `
187 "a++b+-c".split(/([+-])\1/).join(" $$ ")
188 `
189
190 testScript(SCRIPT, asciiString("a $$ + $$ b+-c"), t)
191 }
192
193 func TestEscapeNonASCII(t *testing.T) {
194 const SCRIPT = `
195 /\⩓/.test("⩓")
196 `
197
198 testScript(SCRIPT, valueTrue, t)
199 }
200
201 func TestRegexpUTF16(t *testing.T) {
202 const SCRIPT = `
203 var str = "\uD800\uDC00";
204
205 assert(/\uD800/g.test(str), "#1");
206 assert(/\uD800/.test(str), "#2");
207 assert(/𐀀/.test(str), "#3");
208
209 var re = /\uD800/;
210
211 assert(compareArray(str.replace(re, "X"), ["X", "\uDC00"]), "#4");
212 assert(compareArray(str.split(re), ["", "\uDC00"]), "#5");
213 assert(compareArray("a\uD800\uDC00b".split(/\uD800/g), ["a", "\uDC00b"]), "#6");
214 assert(compareArray("a\uD800\uDC00b".split(/(?:)/g), ["a", "\uD800", "\uDC00", "b"]), "#7");
215 assert(compareArray("0\x80".split(/(0){0}/g), ["0", undefined, "\x80"]), "#7+");
216
217 re = /(?=)a/; // a hack to use regexp2
218 assert.sameValue(re.exec('\ud83d\ude02a').index, 2, "#8");
219
220 assert.sameValue(/./.exec('\ud83d\ude02')[0], '\ud83d', "#9");
221
222 assert(RegExp("\uD800").test("\uD800"), "#10");
223
224 var cu = 0xD800;
225 var xx = "a\\" + String.fromCharCode(cu);
226 var pattern = eval("/" + xx + "/");
227 assert.sameValue(pattern.source, "a\\\\\\ud800", "Code unit: " + cu.toString(16), "#11");
228 assert(pattern.test("a\\\uD800"), "#12");
229 `
230
231 testScriptWithTestLib(SCRIPT, _undefined, t)
232 }
233
234 func TestRegexpUnicode(t *testing.T) {
235 const SCRIPT = `
236
237 assert(!/\uD800/u.test("\uD800\uDC00"), "#1");
238 assert(!/\uFFFD/u.test("\uD800\uDC00"), "#2");
239
240 assert(/\uD800\uDC00/u.test("\uD800\uDC00"), "#3");
241
242 assert(/\uD800/u.test("\uD800"), "#4");
243
244 assert(compareArray("a\uD800\uDC00b".split(/\uD800/gu), ["a\uD800\uDC00b"]), "#5");
245
246 assert(compareArray("a\uD800\uDC00b".split(/(?:)/gu), ["a", "𐀀", "b"]), "#6");
247
248 assert(compareArray("0\x80".split(/(0){0}/gu), ["0", undefined, "\x80"]), "#7");
249
250 var re = eval('/' + /\ud834\udf06/u.source + '/u');
251 assert(re.test('\ud834\udf06'), "#9");
252
253 /*re = RegExp("\\p{L}", "u");
254 if (!re.test("A")) {
255 throw new Error("Test 9 failed");
256 }*/
257 `
258
259 testScriptWithTestLib(SCRIPT, _undefined, t)
260 }
261
262 func TestConvertRegexpToUnicode(t *testing.T) {
263 if s := convertRegexpToUnicode(`test\uD800\u0C00passed`); s != `test\uD800\u0C00passed` {
264 t.Fatal(s)
265 }
266 if s := convertRegexpToUnicode(`test\uD800\uDC00passed`); s != `test𐀀passed` {
267 t.Fatal(s)
268 }
269 if s := convertRegexpToUnicode(`test\u0023passed`); s != `test\u0023passed` {
270 t.Fatal(s)
271 }
272 if s := convertRegexpToUnicode(`test\u0passed`); s != `test\u0passed` {
273 t.Fatal(s)
274 }
275 if s := convertRegexpToUnicode(`test\uD800passed`); s != `test\uD800passed` {
276 t.Fatal(s)
277 }
278 if s := convertRegexpToUnicode(`test\uD800`); s != `test\uD800` {
279 t.Fatal(s)
280 }
281 if s := convertRegexpToUnicode(`test\uD80`); s != `test\uD80` {
282 t.Fatal(s)
283 }
284 if s := convertRegexpToUnicode(`\\uD800\uDC00passed`); s != `\\uD800\uDC00passed` {
285 t.Fatal(s)
286 }
287 if s := convertRegexpToUnicode(`testpassed`); s != `testpassed` {
288 t.Fatal(s)
289 }
290 }
291
292 func TestConvertRegexpToUtf16(t *testing.T) {
293 if s := convertRegexpToUtf16(`𐀀`); s != `\ud800\udc00` {
294 t.Fatal(s)
295 }
296 if s := convertRegexpToUtf16(`\𐀀`); s != `\\\ud800\udc00` {
297 t.Fatal(s)
298 }
299 }
300
301 func TestEscapeInvalidUtf16(t *testing.T) {
302 if s := escapeInvalidUtf16(asciiString("test")); s != "test" {
303 t.Fatal(s)
304 }
305 if s := escapeInvalidUtf16(newStringValue("test\U00010000")); s != "test\U00010000" {
306 t.Fatal(s)
307 }
308 if s := escapeInvalidUtf16(unicodeStringFromRunes([]rune{'t', 0xD800})); s != "t\\ud800" {
309 t.Fatal(s)
310 }
311 if s := escapeInvalidUtf16(unicodeStringFromRunes([]rune{'t', 0xD800, 'p'})); s != "t\\ud800p" {
312 t.Fatal(s)
313 }
314 if s := escapeInvalidUtf16(unicodeStringFromRunes([]rune{0xD800, 'p'})); s != "\\ud800p" {
315 t.Fatal(s)
316 }
317 if s := escapeInvalidUtf16(unicodeStringFromRunes([]rune{'t', '\\', 0xD800, 'p'})); s != `t\\\ud800p` {
318 t.Fatal(s)
319 }
320 }
321
322 func TestRegexpAssertion(t *testing.T) {
323 const SCRIPT = `
324 var res = 'aaa'.match(/^a/g);
325 res.length === 1 || res[0] === 'a';
326 `
327 testScript(SCRIPT, valueTrue, t)
328 }
329
330 func TestRegexpUnicodeAdvanceStringIndex(t *testing.T) {
331 const SCRIPT = `
332 // deoptimise RegExp
333 var origExec = RegExp.prototype.exec;
334 RegExp.prototype.exec = function(s) {
335 return origExec.call(this, s);
336 };
337
338 var re = /(?:)/gu;
339 var str = "a\uD800\uDC00b";
340 assert(compareArray(str.split(re), ["a", "𐀀", "b"]), "#1");
341
342 re.lastIndex = 3;
343 assert.sameValue(re.exec(str).index, 3, "#2");
344
345 re.lastIndex = 2;
346 assert.sameValue(re.exec(str).index, 1, "#3");
347
348 re.lastIndex = 4;
349 assert.sameValue(re.exec(str).index, 4, "#4");
350
351 re.lastIndex = 5;
352 assert.sameValue(re.exec(str), null, "#5");
353
354 var iterator = str.matchAll(re); // regexp is copied by matchAll, but resets lastIndex
355 var matches = [];
356 for (var v of iterator) {matches.push(v);}
357 assert.sameValue(matches.length, 4, "#6");
358 assert.sameValue(matches[0].index, 0, "#7 index");
359 assert.sameValue(matches[0][0], "", "#7 value");
360 assert.sameValue(matches[1].index, 1, "#8 index");
361 assert.sameValue(matches[1][0], "", "#8 value");
362 assert.sameValue(matches[2].index, 3, "#9 index");
363 assert.sameValue(matches[2][0], "", "#9 value");
364 assert.sameValue(matches[3].index, 4, "#10 index");
365 assert.sameValue(matches[3][0], "", "#10 value");
366 `
367 testScriptWithTestLib(SCRIPT, _undefined, t)
368 }
369
370 func TestRegexpInit(t *testing.T) {
371 const SCRIPT = `
372 RegExp(".").lastIndex;
373 `
374 testScript(SCRIPT, intToValue(0), t)
375 }
376
377 func TestRegexpToString(t *testing.T) {
378 const SCRIPT = `
379 RegExp.prototype.toString.call({
380 source: 'foo',
381 flags: 'bar'});
382 `
383 testScript(SCRIPT, asciiString("/foo/bar"), t)
384 }
385
386 func TestRegexpEscapeSource(t *testing.T) {
387 const SCRIPT = `
388 /href="(.+?)(\/.*\/\S+?)\/"/.source;
389 `
390 testScript(SCRIPT, asciiString(`href="(.+?)(\/.*\/\S+?)\/"`), t)
391 }
392
393 func TestRegexpConsecutiveMatchCache(t *testing.T) {
394 const SCRIPT = `
395 (function test(unicode) {
396 var regex = new RegExp('t(e)(st(\\d?))', unicode?'gu':'g');
397 var string = 'test1test2';
398 var match;
399 var matches = [];
400 while (match = regex.exec(string)) {
401 matches.push(match);
402 }
403 var expectedMatches = [
404 [
405 'test1',
406 'e',
407 'st1',
408 '1'
409 ],
410 [
411 'test2',
412 'e',
413 'st2',
414 '2'
415 ]
416 ];
417 expectedMatches[0].index = 0;
418 expectedMatches[0].input = 'test1test2';
419 expectedMatches[1].index = 5;
420 expectedMatches[1].input = 'test1test2';
421
422 assert(deepEqual(matches, expectedMatches), "#1");
423
424 // try the same regexp with a different string
425 regex.lastIndex = 0;
426 match = regex.exec(' test5');
427 var expectedMatch = [
428 'test5',
429 'e',
430 'st5',
431 '5'
432 ];
433 expectedMatch.index = 1;
434 expectedMatch.input = ' test5';
435 assert(deepEqual(match, expectedMatch), "#2");
436 assert.sameValue(regex.lastIndex, 6, "#3");
437
438 // continue matching with a different string
439 match = regex.exec(' test5test6');
440 expectedMatch = [
441 'test6',
442 'e',
443 'st6',
444 '6'
445 ];
446 expectedMatch.index = 6;
447 expectedMatch.input = ' test5test6';
448 assert(deepEqual(match, expectedMatch), "#4");
449 assert.sameValue(regex.lastIndex, 11, "#5");
450
451 match = regex.exec(' test5test6');
452 assert.sameValue(match, null, "#6");
453 return regex;
454 });
455 `
456 vm := New()
457 _, _ = vm.RunProgram(testLib())
458 _, _ = vm.RunProgram(testLibX())
459 v, err := vm.RunString(SCRIPT)
460 if err != nil {
461 t.Fatal(err)
462 }
463 var f func(bool) (*Object, error)
464 err = vm.ExportTo(v, &f)
465 if err != nil {
466 t.Fatal(err)
467 }
468
469 regex, err := f(false)
470 if err != nil {
471 t.Fatal(err)
472 }
473 if regex.self.(*regexpObject).pattern.regexp2Wrapper.cache != nil {
474 t.Fatal("Cache is not nil (non-unicode)")
475 }
476
477 regex, err = f(true)
478 if err != nil {
479 t.Fatal(err)
480 }
481 if regex.self.(*regexpObject).pattern.regexp2Wrapper.cache != nil {
482 t.Fatal("Cache is not nil (unicode)")
483 }
484 }
485
486 func TestRegexpMatchAll(t *testing.T) {
487 const SCRIPT = `
488 (function test(unicode) {
489 var regex = new RegExp('t(e)(st(\\d?))', unicode?'gu':'g');
490 var string = 'test1test2';
491 var matches = [];
492 for (var match of string.matchAll(regex)) {
493 matches.push(match);
494 }
495 var expectedMatches = [
496 [
497 'test1',
498 'e',
499 'st1',
500 '1'
501 ],
502 [
503 'test2',
504 'e',
505 'st2',
506 '2'
507 ]
508 ];
509 expectedMatches[0].index = 0;
510 expectedMatches[0].input = 'test1test2';
511 expectedMatches[1].index = 5;
512 expectedMatches[1].input = 'test1test2';
513
514 assert(deepEqual(matches, expectedMatches), "#1");
515 assert.sameValue(regex.lastIndex, 0, "#1 lastIndex");
516
517 // try the same regexp with a different string
518 string = ' test5';
519 matches = [];
520 for (var match of string.matchAll(regex)) {
521 matches.push(match);
522 }
523 expectedMatches = [
524 [
525 'test5',
526 'e',
527 'st5',
528 '5'
529 ]
530 ];
531 expectedMatches[0].index = 1;
532 expectedMatches[0].input = ' test5';
533 assert(deepEqual(matches, expectedMatches), "#2");
534 assert.sameValue(regex.lastIndex, 0, "#2 lastIndex");
535
536 // continue matching with a different string
537 string = ' test5test6';
538 matches = [];
539 for (var match of string.matchAll(regex)) {
540 matches.push(match);
541 }
542 var expectedMatches = [
543 [
544 'test5',
545 'e',
546 'st5',
547 '5'
548 ],
549 [
550 'test6',
551 'e',
552 'st6',
553 '6'
554 ]
555 ];
556 expectedMatches[0].index = 1;
557 expectedMatches[0].input = ' test5test6';
558 expectedMatches[1].index = 6;
559 expectedMatches[1].input = ' test5test6';
560 assert(deepEqual(matches, expectedMatches), "#3");
561 assert.sameValue(regex.lastIndex, 0, "#3 lastindex");
562 });
563 `
564 vm := New()
565 _, _ = vm.RunProgram(testLib())
566 _, _ = vm.RunProgram(testLibX())
567 v, err := vm.RunString(SCRIPT)
568 if err != nil {
569 t.Fatal(err)
570 }
571 var f func(bool) (*Object, error)
572 err = vm.ExportTo(v, &f)
573 if err != nil {
574 t.Fatal(err)
575 }
576
577 _, err = f(false)
578 if err != nil {
579 t.Fatal(err)
580 }
581
582 _, err = f(true)
583 if err != nil {
584 t.Fatal(err)
585 }
586 }
587
588 func TestRegexpOverrideSpecies(t *testing.T) {
589 const SCRIPT = `
590 Object.defineProperty(RegExp, Symbol.species, {
591 configurable: true,
592 value: function() {
593 throw "passed";
594 }
595 });
596 try {
597 "ab".split(/a/);
598 throw new Error("Expected error");
599 } catch(e) {
600 if (e !== "passed") {
601 throw e;
602 }
603 }
604 `
605 testScript(SCRIPT, _undefined, t)
606 }
607
608 func TestRegexpSymbolMatchAllCallsIsRegexp(t *testing.T) {
609
610 const SCRIPT = `
611 var a = new Object();
612 Object.defineProperty(a, Symbol.match, {
613 get: function() {
614 throw "passed";
615 }
616 });
617 try {
618 RegExp.prototype[Symbol.matchAll].call(a, '');
619 throw new Error("Expected error");
620 } catch(e) {
621 if (e !== "passed") {
622 throw e;
623 }
624 }
625 `
626 testScript(SCRIPT, _undefined, t)
627 }
628
629 func TestRegexpMatchAllConstructor(t *testing.T) {
630
631 const SCRIPT = `
632 var callCount = 0;
633 var callArgs;
634 var regexp = /\d/u;
635 var obj = {}
636 Object.defineProperty(obj, Symbol.species, {
637 value: function() {
638 callCount++;
639 callArgs = arguments;
640 return /\w/g;
641 }
642 });
643 regexp.constructor = obj;
644 var str = 'a*b';
645 var iter = regexp[Symbol.matchAll](str);
646
647 assert.sameValue(callCount, 1);
648 assert.sameValue(callArgs.length, 2);
649 assert.sameValue(callArgs[0], regexp);
650 assert.sameValue(callArgs[1], 'u');
651
652 var first = iter.next()
653 assert.sameValue(first.done, false);
654 assert.sameValue(first.value.length, 1);
655 assert.sameValue(first.value[0], "a");
656 var second = iter.next()
657 assert.sameValue(second.done, true);
658 `
659 testScriptWithTestLib(SCRIPT, _undefined, t)
660 }
661
662 func TestRegexp2InvalidEscape(t *testing.T) {
663 testScript(`/(?=)\x0/.test("x0")`, valueTrue, t)
664 }
665
666 func TestRegexpUnicodeEmptyMatch(t *testing.T) {
667 testScript(`/(0)0|/gu.exec("0\xef").length === 2`, valueTrue, t)
668 }
669
670 func TestRegexpInvalidGroup(t *testing.T) {
671 const SCRIPT = `
672 ["?", "(?)"].forEach(function(s) {
673 assert.throws(SyntaxError, function() {new RegExp(s)}, s);
674 });
675 `
676 testScriptWithTestLib(SCRIPT, _undefined, t)
677 }
678
679 func TestRegexpLookbehindAssertion(t *testing.T) {
680 const SCRIPT = `
681 var re = /(?<=Jack|Tom)Sprat/;
682 assert(re.test("JackSprat"), "#1");
683 assert(!re.test("JohnSprat"), "#2");
684
685 re = /(?<!-)\d+/;
686 assert(re.test("3"), "#3");
687 assert(!re.test("-3"), "#4");
688 `
689 testScriptWithTestLib(SCRIPT, _undefined, t)
690 }
691
692 func TestRegexpInvalidUTF8(t *testing.T) {
693 vm := New()
694
695 _, err := vm.New(vm.Get("RegExp"), asciiString([]byte{0xAD}))
696 if err == nil {
697 t.Fatal("Expected error")
698 }
699 }
700
701
702 func TestRegexpConcurrentLiterals(t *testing.T) {
703 prg := MustCompile("test.js", `var r = /(?<!-)\d+/; r.test("");`, false)
704 go func() {
705 vm := New()
706 _, err := vm.RunProgram(prg)
707 if err != nil {
708 panic(err)
709 }
710 }()
711 vm := New()
712 _, _ = vm.RunProgram(prg)
713 }
714
715 func BenchmarkRegexpSplitWithBackRef(b *testing.B) {
716 const SCRIPT = `
717 "aaaaaaaaaaaaaaaaaaaaaaaaa++bbbbbbbbbbbbbbbbbbbbbb+-ccccccccccccccccccccccc".split(/([+-])\1/)
718 `
719 b.StopTimer()
720 prg, err := Compile("test.js", SCRIPT, false)
721 if err != nil {
722 b.Fatal(err)
723 }
724 vm := New()
725 b.StartTimer()
726 for i := 0; i < b.N; i++ {
727 vm.RunProgram(prg)
728 }
729 }
730
731 func BenchmarkRegexpMatch(b *testing.B) {
732 const SCRIPT = `
733 "a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
734 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
735 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
736 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
737 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
738 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
739 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
740 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
741 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
742 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
743 ".match(/[^\r\n]+/g)
744 `
745 b.StopTimer()
746 prg, err := Compile("test.js", SCRIPT, false)
747 if err != nil {
748 b.Fatal(err)
749 }
750 vm := New()
751 b.StartTimer()
752 for i := 0; i < b.N; i++ {
753 vm.RunProgram(prg)
754 }
755 }
756
757 func BenchmarkRegexpMatchCache(b *testing.B) {
758 const SCRIPT = `
759 (function() {
760 var s = "a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
761 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
762 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
763 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
764 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
765 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
766 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
767 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
768 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
769 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
770 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
771 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
772 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
773 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
774 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
775 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
776 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
777 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
778 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
779 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
780 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
781 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
782 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
783 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
784 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
785 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
786 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
787 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
788 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
789 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
790 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
791 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
792 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
793 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
794 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
795 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
796 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
797 "
798 var r = /[^\r\n]+/g
799 while(r.exec(s)) {};
800 });
801 `
802 vm := New()
803 v, err := vm.RunString(SCRIPT)
804 if err != nil {
805 b.Fatal(err)
806 }
807 if fn, ok := AssertFunction(v); ok {
808 b.ResetTimer()
809 b.ReportAllocs()
810 for i := 0; i < b.N; i++ {
811 fn(_undefined)
812 }
813 } else {
814 b.Fatal("not a function")
815 }
816 }
817
818 func BenchmarkRegexpMatchAll(b *testing.B) {
819 const SCRIPT = `
820 (function() {
821 var s = "a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
822 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
823 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
824 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
825 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
826 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
827 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
828 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
829 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
830 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
831 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
832 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
833 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
834 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
835 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
836 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
837 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
838 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
839 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
840 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
841 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
842 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
843 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
844 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
845 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
846 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
847 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
848 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
849 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
850 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
851 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
852 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
853 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
854 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
855 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
856 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
857 a\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\ra\nb\r\c\nd\r\e\n\f\rg\nh\r\
858 "
859 var r = /[^\r\n]+/g
860 for (var v of s.matchAll(r)) {}
861 });
862 `
863 vm := New()
864 v, err := vm.RunString(SCRIPT)
865 if err != nil {
866 b.Fatal(err)
867 }
868 if fn, ok := AssertFunction(v); ok {
869 b.ResetTimer()
870 b.ReportAllocs()
871 for i := 0; i < b.N; i++ {
872 fn(_undefined)
873 }
874 } else {
875 b.Fatal("not a function")
876 }
877 }
878
879 func BenchmarkRegexpSingleExec(b *testing.B) {
880 vm := New()
881 regexp := vm.Get("RegExp")
882 f := func(reStr, str string, b *testing.B) {
883 r, err := vm.New(regexp, vm.ToValue(reStr))
884 if err != nil {
885 b.Fatal(err)
886 }
887 exec, ok := AssertFunction(r.Get("exec"))
888 if !ok {
889 b.Fatal("RegExp.exec is not a function")
890 }
891 arg := vm.ToValue(str)
892 b.ResetTimer()
893 b.ReportAllocs()
894 for i := 0; i < b.N; i++ {
895 _, err := exec(r, arg)
896 if err != nil {
897 b.Fatal(err)
898 }
899 }
900 }
901
902 b.Run("Re-ASCII", func(b *testing.B) {
903 f("test", "aaaaaaaaaaaaaaaaaaaaaaaaa testing", b)
904 })
905
906 b.Run("Re2-ASCII", func(b *testing.B) {
907 f("(?=)test", "aaaaaaaaaaaaaaaaaaaaaaaaa testing", b)
908 })
909
910 b.Run("Re-Unicode", func(b *testing.B) {
911 f("test", "aaaaaaaaaaaaaaaaaaaaaaaaa testing 😀", b)
912 })
913
914 b.Run("Re2-Unicode", func(b *testing.B) {
915 f("(?=)test", "aaaaaaaaaaaaaaaaaaaaaaaaa testing 😀", b)
916 })
917
918 }
919
View as plain text