github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/regexp_test.go (about) 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 // This is tc39's test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.js 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 // This is tc39's test/built-ins/RegExp/prototype/Symbol.matchAll/species-constuctor.js 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 // Note that normally vm.ToValue() would replace invalid UTF-8 sequences with RuneError 695 _, err := vm.New(vm.Get("RegExp"), asciiString([]byte{0xAD})) 696 if err == nil { 697 t.Fatal("Expected error") 698 } 699 } 700 701 // this should not cause data races when run with -race 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 }