1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdlib.h> 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ast.h" 34589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "char-predicates-inl.h" 35589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "cctest.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "jsregexp.h" 37589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "parser.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "regexp-macro-assembler.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "regexp-macro-assembler-irregexp.h" 40589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "string-stream.h" 41589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "zone-inl.h" 426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef V8_INTERPRETED_REGEXP 436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "interpreter-irregexp.h" 446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#else // V8_INTERPRETED_REGEXP 453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "macro-assembler.h" 463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "code.h" 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef V8_TARGET_ARCH_ARM 483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "arm/assembler-arm.h" 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/macro-assembler-arm.h" 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/regexp-macro-assembler-arm.h" 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef V8_TARGET_ARCH_MIPS 533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "mips/assembler-mips.h" 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "mips/macro-assembler-mips.h" 5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "mips/regexp-macro-assembler-mips.h" 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef V8_TARGET_ARCH_X64 583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "x64/assembler-x64.h" 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "x64/macro-assembler-x64.h" 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "x64/regexp-macro-assembler-x64.h" 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef V8_TARGET_ARCH_IA32 633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "ia32/assembler-ia32.h" 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ia32/macro-assembler-ia32.h" 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ia32/regexp-macro-assembler-ia32.h" 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif // V8_INTERPRETED_REGEXP 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8::internal; 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic bool CheckParse(const char* input) { 73e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V8::Initialize(NULL); 74e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::HandleScope scope; 75257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block FlatStringReader reader(Isolate::Current(), CStrVector(input)); 77e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke RegExpCompileData result; 783e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu return v8::internal::RegExpParser::ParseRegExp(&reader, false, &result); 79e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 80e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 81e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 82589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochstatic SmartArrayPointer<const char> Parse(const char* input) { 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 85257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block FlatStringReader reader(Isolate::Current(), CStrVector(input)); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpCompileData result; 883e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result)); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result.tree != NULL); 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result.error.is_null()); 91589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<const char> output = result.tree->ToString(); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return output; 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool CheckSimple(const char* input) { 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 98d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block unibrow::Utf8InputBuffer<> buffer(input, StrLength(input)); 99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block FlatStringReader reader(Isolate::Current(), CStrVector(input)); 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpCompileData result; 1023e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result)); 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result.tree != NULL); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result.error.is_null()); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result.simple; 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct MinMaxPair { 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int min_match; 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int max_match; 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic MinMaxPair CheckMinMaxMatch(const char* input) { 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block unibrow::Utf8InputBuffer<> buffer(input, StrLength(input)); 117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FlatStringReader reader(Isolate::Current(), CStrVector(input)); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpCompileData result; 1203e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result)); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result.tree != NULL); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result.error.is_null()); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int min_match = result.tree->min_match(); 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int max_match = result.tree->max_match(); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MinMaxPair pair = { min_match, max_match }; 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return pair; 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#define CHECK_PARSE_ERROR(input) CHECK(!CheckParse(input)) 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_PARSE_EQ(input, expected) CHECK_EQ(expected, *Parse(input)) 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_SIMPLE(input, simple) CHECK_EQ(simple, CheckSimple(input)); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_MIN_MAX(input, min, max) \ 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { MinMaxPair min_max = CheckMinMaxMatch(input); \ 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(min, min_max.min_match); \ 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(max, min_max.max_match); \ 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(Parser) { 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 142e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_ERROR("?"); 143e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("abc", "'abc'"); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("", "%"); 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("abc|def", "(| 'abc' 'def')"); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("abc|def|ghi", "(| 'abc' 'def' 'ghi')"); 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("^xxx$", "(: @^i 'xxx' @$i)"); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("ab\\b\\d\\bcd", "(: 'ab' @b [0-9] @b 'cd')"); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\w|\\d", "(| [0-9 A-Z _ a-z] [0-9])"); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a*", "(# 0 - g 'a')"); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a*?", "(# 0 - n 'a')"); 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("abc+", "(: 'ab' (# 1 - g 'c'))"); 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("abc+?", "(: 'ab' (# 1 - n 'c'))"); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz?", "(: 'xy' (# 0 1 g 'z'))"); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz??", "(: 'xy' (# 0 1 n 'z'))"); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz{0,1}", "(: 'xy' (# 0 1 g 'z'))"); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz{0,1}?", "(: 'xy' (# 0 1 n 'z'))"); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz{93}", "(: 'xy' (# 93 93 g 'z'))"); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz{93}?", "(: 'xy' (# 93 93 n 'z'))"); 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz{1,32}", "(: 'xy' (# 1 32 g 'z'))"); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz{1,32}?", "(: 'xy' (# 1 32 n 'z'))"); 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz{1,}", "(: 'xy' (# 1 - g 'z'))"); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("xyz{1,}?", "(: 'xy' (# 1 - n 'z'))"); 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a\\fb\\nc\\rd\\te\\vf", "'a\\x0cb\\x0ac\\x0dd\\x09e\\x0bf'"); 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a\\nb\\bc", "(: 'a\\x0ab' @b 'c')"); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?:foo)", "'foo'"); 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?: foo )", "' foo '"); 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(foo|bar|baz)", "(^ (| 'foo' 'bar' 'baz'))"); 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("foo|(bar|baz)|quux", "(| 'foo' (^ (| 'bar' 'baz')) 'quux')"); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("foo(?=bar)baz", "(: 'foo' (-> + 'bar') 'baz')"); 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("foo(?!bar)baz", "(: 'foo' (-> - 'bar') 'baz')"); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("()", "(^ %)"); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?=)", "(-> + %)"); 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[]", "^[\\x00-\\uffff]"); // Doesn't compile on windows 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[^]", "[\\x00-\\uffff]"); // \uffff isn't in codepage 1252 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[x]", "[x]"); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[xyz]", "[x y z]"); 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[a-zA-Z0-9]", "[a-z A-Z 0-9]"); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[-123]", "[- 1 2 3]"); 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[^123]", "^[1 2 3]"); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("]", "']'"); 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("}", "'}'"); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[a-b-c]", "[a-b - c]"); 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\d]", "[0-9]"); 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[x\\dz]", "[x 0-9 z]"); 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\d-z]", "[0-9 - z]"); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\d-\\d]", "[0-9 - 0-9]"); 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[z-\\d]", "[z - 0-9]"); 190086aeeaae12517475c22695a200be45495516549Ben Murdoch // Control character outside character class. 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\cj\\cJ\\ci\\cI\\ck\\cK", 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "'\\x0a\\x0a\\x09\\x09\\x0b\\x0b'"); 193086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("\\c!", "'\\c!'"); 194086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("\\c_", "'\\c_'"); 195086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("\\c~", "'\\c~'"); 196086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("\\c1", "'\\c1'"); 197086aeeaae12517475c22695a200be45495516549Ben Murdoch // Control character inside character class. 198086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("[\\c!]", "[\\ c !]"); 199086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("[\\c_]", "[\\x1f]"); 200086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("[\\c~]", "[\\ c ~]"); 201086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("[\\ca]", "[\\x01]"); 202086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("[\\cz]", "[\\x1a]"); 203086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("[\\cA]", "[\\x01]"); 204086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("[\\cZ]", "[\\x1a]"); 205086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("[\\c1]", "[\\x11]"); 206086aeeaae12517475c22695a200be45495516549Ben Murdoch 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[a\\]c]", "[a ] c]"); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\[\\]\\{\\}\\(\\)\\%\\^\\#\\ ", "'[]{}()%^# '"); 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\[\\]\\{\\}\\(\\)\\%\\^\\#\\ ]", "[[ ] { } ( ) % ^ # ]"); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\0", "'\\x00'"); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\8", "'8'"); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\9", "'9'"); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\11", "'\\x09'"); 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\11a", "'\\x09a'"); 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\011", "'\\x09'"); 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\00011", "'\\x0011'"); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\118", "'\\x098'"); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\111", "'I'"); 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\1111", "'I1'"); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)\\1", "(: (^ 'x') (^ 'x') (^ 'x') (<- 1))"); 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)\\2", "(: (^ 'x') (^ 'x') (^ 'x') (<- 2))"); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)\\3", "(: (^ 'x') (^ 'x') (^ 'x') (<- 3))"); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)\\4", "(: (^ 'x') (^ 'x') (^ 'x') '\\x04')"); 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)\\1*", "(: (^ 'x') (^ 'x') (^ 'x')" 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " (# 0 - g (<- 1)))"); 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)\\2*", "(: (^ 'x') (^ 'x') (^ 'x')" 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " (# 0 - g (<- 2)))"); 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)\\3*", "(: (^ 'x') (^ 'x') (^ 'x')" 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " (# 0 - g (<- 3)))"); 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)\\4*", "(: (^ 'x') (^ 'x') (^ 'x')" 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " (# 0 - g '\\x04'))"); 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)(x)(x)(x)(x)(x)(x)(x)\\10", 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "(: (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x')" 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " (^ 'x') (^ 'x') (^ 'x') (^ 'x') (<- 10))"); 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(x)(x)(x)(x)(x)(x)(x)(x)(x)(x)\\11", 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "(: (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x') (^ 'x')" 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " (^ 'x') (^ 'x') (^ 'x') (^ 'x') '\\x09')"); 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(a)\\1", "(: (^ 'a') (<- 1))"); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(a\\1)", "(^ 'a')"); 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(\\1a)", "(^ 'a')"); 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?=a)?a", "'a'"); 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?=a){0,10}a", "'a'"); 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?=a){1,10}a", "(: (-> + 'a') 'a')"); 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?=a){9,10}a", "(: (-> + 'a') 'a')"); 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?!a)?a", "'a'"); 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\1(a)", "(^ 'a')"); 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?!(a))\\1", "(: (-> - (^ 'a')) (<- 1))"); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("(?!\\1(a\\1)\\1)\\1", "(: (-> - (: (^ 'a') (<- 1))) (<- 1))"); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\0]", "[\\x00]"); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\11]", "[\\x09]"); 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\11a]", "[\\x09 a]"); 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\011]", "[\\x09]"); 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\00011]", "[\\x00 1 1]"); 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\118]", "[\\x09 8]"); 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\111]", "[I]"); 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[\\1111]", "[I 1]"); 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\x34", "'\x34'"); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\x60", "'\x60'"); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\x3z", "'x3z'"); 260086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_PARSE_EQ("\\c", "'\\c'"); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\u0034", "'\x34'"); 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("\\u003z", "'u003z'"); 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("foo[z]*", "(: 'foo' (# 0 - g [z]))"); 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a", true); 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a|b", false); 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\n", false); 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("^a", false); 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a$", false); 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\b!", false); 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\Bb", false); 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a*", false); 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a*?", false); 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a?", false); 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a??", false); 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a{0,1}?", false); 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a{1,1}?", false); 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a{1,2}?", false); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a+?", false); 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("(a)", false); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("(a)\\1", false); 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("(\\1a)", false); 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("\\1(a)", false); 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\s", false); 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\S", false); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\d", false); 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\D", false); 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\w", false); 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\W", false); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a.", false); 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a\\q", false); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a[a]", false); 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a[^a]", false); 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a[a-z]", false); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a[\\q]", false); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a(?:b)", false); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a(?=b)", false); 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("a(?!b)", false); 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("\\x60", false); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("\\u0060", false); 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("\\cA", false); 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("\\q", false); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("\\1112", false); 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("\\0", false); 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("(a)\\1", false); 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("(?=a)?a", false); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("(?!a)?a\\1", false); 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_SIMPLE("(?:(?=a))a\\1", false); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{}", "'a{}'"); 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{,}", "'a{,}'"); 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{", "'a{'"); 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{z}", "'a{z}'"); 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{1z}", "'a{1z}'"); 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{12z}", "'a{12z}'"); 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{12,", "'a{12,'"); 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{12,3b", "'a{12,3b'"); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{}", "'{}'"); 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{,}", "'{,}'"); 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{", "'{'"); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{z}", "'{z}'"); 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{1z}", "'{1z}'"); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{12z}", "'{12z}'"); 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{12,", "'{12,'"); 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{12,3b", "'{12,3b'"); 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a", 1, 1); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("abc", 3, 3); 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a[bc]d", 3, 3); 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a|bc", 1, 2); 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("ab|c", 1, 2); 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a||bc", 0, 2); 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("|", 0, 0); 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:ab)", 2, 2); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:ab|cde)", 2, 3); 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:ab)|cde", 2, 3); 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(ab)", 2, 2); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(ab|cde)", 2, 3); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(ab)\\1", 2, 4); 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(ab|cde)\\1", 2, 6); 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:ab)?", 0, 2); 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:ab)*", 0, RegExpTree::kInfinity); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:ab)+", 2, RegExpTree::kInfinity); 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a?", 0, 1); 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a*", 0, RegExpTree::kInfinity); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a+", 1, RegExpTree::kInfinity); 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a??", 0, 1); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a*?", 0, RegExpTree::kInfinity); 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a+?", 1, RegExpTree::kInfinity); 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a?)?", 0, 1); 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a*)?", 0, RegExpTree::kInfinity); 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a+)?", 0, RegExpTree::kInfinity); 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a?)+", 0, RegExpTree::kInfinity); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a*)+", 0, RegExpTree::kInfinity); 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a+)+", 1, RegExpTree::kInfinity); 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a?)*", 0, RegExpTree::kInfinity); 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a*)*", 0, RegExpTree::kInfinity); 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a+)*", 0, RegExpTree::kInfinity); 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a{0}", 0, 0); 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a+){0}", 0, 0); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a+){0,0}", 0, 0); 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a*b", 1, RegExpTree::kInfinity); 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a+b", 2, RegExpTree::kInfinity); 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a*b|c", 1, RegExpTree::kInfinity); 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a+b|c", 1, RegExpTree::kInfinity); 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:a{5,1000000}){3,1000000}", 15, RegExpTree::kInfinity); 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("(?:ab){4,7}", 8, 14); 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a\\bc", 2, 2); 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a\\Bc", 2, 2); 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a\\sc", 3, 3); 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a\\Sc", 3, 3); 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a(?=b)c", 2, 2); 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a(?=bbb|bb)c", 2, 2); 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MIN_MAX("a(?!bbb|bb)c", 2, 2); 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ParserRegression) { 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("[A-Z$-][x]", "(! [A-Z $ -] [x])"); 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a{3,4*}", "(: 'a{3,' (# 0 - g '4') '}')"); 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("{", "'{'"); 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_PARSE_EQ("a|", "(| 'a' %)"); 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ExpectError(const char* input, 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* expected) { 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 38944f0eee88ff00398ff7f715fab053374d808c90dSteve Block FlatStringReader reader(Isolate::Current(), CStrVector(input)); 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpCompileData result; 3913e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu CHECK(!v8::internal::RegExpParser::ParseRegExp(&reader, false, &result)); 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result.tree == NULL); 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!result.error.is_null()); 394589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS); 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(expected, *str); 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(Errors) { 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* kEndBackslash = "\\ at end of pattern"; 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("\\", kEndBackslash); 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* kUnterminatedGroup = "Unterminated group"; 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("(foo", kUnterminatedGroup); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* kInvalidGroup = "Invalid group"; 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("(?", kInvalidGroup); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* kUnterminatedCharacterClass = "Unterminated character class"; 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("[", kUnterminatedCharacterClass); 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("[a-", kUnterminatedCharacterClass); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* kNothingToRepeat = "Nothing to repeat"; 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("*", kNothingToRepeat); 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("?", kNothingToRepeat); 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("+", kNothingToRepeat); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("{1}", kNothingToRepeat); 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("{1,2}", kNothingToRepeat); 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError("{1,}", kNothingToRepeat); 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that we don't allow more than kMaxCapture captures 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kMaxCaptures = 1 << 16; // Must match RegExpParser::kMaxCaptures. 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* kTooManyCaptures = "Too many captures"; 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapStringAllocator allocator; 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StringStream accumulator(&allocator); 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i <= kMaxCaptures; i++) { 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator.Add("()"); 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 426589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<const char> many_captures(accumulator.ToCString()); 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExpectError(*many_captures, kTooManyCaptures); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool IsDigit(uc16 c) { 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ('0' <= c && c <= '9'); 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool NotDigit(uc16 c) { 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !IsDigit(c); 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool IsWhiteSpace(uc16 c) { 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (c) { 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0x09: 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0x0A: 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0x0B: 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0x0C: 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0x0d: 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0x20: 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0xA0: 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0x2028: 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 0x2029: 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case 0xFEFF: 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return unibrow::Space::Is(c); 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool NotWhiteSpace(uc16 c) { 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !IsWhiteSpace(c); 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool NotWord(uc16 c) { 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !IsRegExpWord(c); 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) { 471257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT); 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange::AddClassEscape(c, ranges); 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned i = 0; i < (1 << 16); i++) { 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool in_class = false; 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; !in_class && j < ranges->length(); j++) { 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange& range = ranges->at(j); 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block in_class = (range.from() <= i && i <= range.to()); 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(pred(i), in_class); 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(CharacterClassEscapes) { 48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestCharacterClassEscapes('.', IsRegExpNewline); 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestCharacterClassEscapes('d', IsDigit); 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestCharacterClassEscapes('D', NotDigit); 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestCharacterClassEscapes('s', IsWhiteSpace); 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestCharacterClassEscapes('S', NotWhiteSpace); 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestCharacterClassEscapes('w', IsRegExpWord); 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestCharacterClassEscapes('W', NotWord); 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic RegExpNode* Compile(const char* input, bool multiline, bool is_ascii) { 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 4998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); 5008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch FlatStringReader reader(isolate, CStrVector(input)); 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpCompileData compile_data; 5023e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (!v8::internal::RegExpParser::ParseRegExp(&reader, multiline, 5033e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu &compile_data)) 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 5058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> pattern = isolate->factory()-> 5068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch NewStringFromUtf8(CStrVector(input)); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpEngine::Compile(&compile_data, false, multiline, pattern, is_ascii); 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return compile_data.node; 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Execute(const char* input, 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool multiline, 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_ascii, 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool dot_output = false) { 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpNode* node = Compile(input, multiline, is_ascii); 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block USE(node); 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dot_output) { 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpEngine::DotPrint(input, node, false); 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exit(0); 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // DEBUG 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestConfig { 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef int Key; 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef int Value; 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kNoKey; 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static int NoValue() { return 0; } 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline int Compare(int a, int b) { 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (a < b) 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return -1; 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else if (a > b) 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1; 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0; 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int TestConfig::kNoKey = 0; 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic unsigned PseudoRandom(int i, int j) { 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ~(~((i * 781) ^ (j * 329))); 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SplayTreeSimple) { 55544f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const unsigned kLimit = 1000; 557257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneSplayTree<TestConfig> tree; 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool seen[kLimit]; 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned i = 0; i < kLimit; i++) seen[i] = false; 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CHECK_MAPS_EQUAL() do { \ 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned k = 0; k < kLimit; k++) \ 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(seen[k], tree.Find(k, &loc)); \ 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (false) 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 50; i++) { 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; j < 50; j++) { 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned next = PseudoRandom(i, j) % kLimit; 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (seen[next]) { 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We've already seen this one. Check the value and remove 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // it. 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneSplayTree<TestConfig>::Locator loc; 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(tree.Find(next, &loc)); 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(next, loc.key()); 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3 * next, loc.value()); 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tree.Remove(next); 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block seen[next] = false; 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MAPS_EQUAL(); 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that it wasn't there already and then add it. 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneSplayTree<TestConfig>::Locator loc; 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!tree.Find(next, &loc)); 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(tree.Insert(next, &loc)); 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(next, loc.key()); 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block loc.set_value(3 * next); 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block seen[next] = true; 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_MAPS_EQUAL(); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int val = PseudoRandom(j, i) % kLimit; 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (seen[val]) { 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneSplayTree<TestConfig>::Locator loc; 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(tree.FindGreatestLessThan(val, &loc)); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(loc.key(), val); 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block val = PseudoRandom(i + j, i - j) % kLimit; 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (seen[val]) { 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneSplayTree<TestConfig>::Locator loc; 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(tree.FindLeastGreaterThan(val, &loc)); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(loc.key(), val); 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DispatchTableConstruction) { 60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialize test data. 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kLimit = 1000; 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kRangeCount = 8; 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kRangeSize = 16; 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc16 ranges[kRangeCount][2 * kRangeSize]; 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kRangeCount; i++) { 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<uc16> range(ranges[i], 2 * kRangeSize); 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; j < 2 * kRangeSize; j++) { 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block range[j] = PseudoRandom(i + 25, j + 87) % kLimit; 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block range.Sort(); 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 1; j < 2 * kRangeSize; j++) { 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(range[j-1] <= range[j]); 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter test data into dispatch table. 625257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DispatchTable table; 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kRangeCount; i++) { 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc16* range = ranges[i]; 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; j < 2 * kRangeSize; j += 2) 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block table.AddRange(CharacterRange(range[j], range[j + 1]), i); 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the table looks as we would expect 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int p = 0; p < kLimit; p++) { 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OutSet* outs = table.Get(p); 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; j < kRangeCount; j++) { 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc16* range = ranges[j]; 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_on = false; 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int k = 0; !is_on && (k < 2 * kRangeSize); k += 2) 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_on = (range[k] <= p && p <= range[k + 1]); 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(is_on, outs->Get(j)); 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 645e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Test of debug-only syntax. 646e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG 647e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 648e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(ParsePossessiveRepetition) { 649e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool old_flag_value = FLAG_regexp_possessive_quantifier; 650e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 651e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Enable possessive quantifier syntax. 652e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke FLAG_regexp_possessive_quantifier = true; 653e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 654e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_EQ("a*+", "(# 0 - p 'a')"); 655e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_EQ("a++", "(# 1 - p 'a')"); 656e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_EQ("a?+", "(# 0 1 p 'a')"); 657e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_EQ("a{10,20}+", "(# 10 20 p 'a')"); 658e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_EQ("za{10,20}+b", "(: 'z' (# 10 20 p 'a') 'b')"); 659e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 660e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Disable possessive quantifier syntax. 661e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke FLAG_regexp_possessive_quantifier = false; 662e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 663e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_ERROR("a*+"); 664e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_ERROR("a++"); 665e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_ERROR("a?+"); 666e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_ERROR("a{10,20}+"); 667e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_PARSE_ERROR("a{10,20}+b"); 668e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 669e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke FLAG_regexp_possessive_quantifier = old_flag_value; 670e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 671e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 672e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests of interpreter. 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_INTERPRETED_REGEXP 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if V8_TARGET_ARCH_IA32 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef RegExpMacroAssemblerIA32 ArchRegExpMacroAssembler; 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#elif V8_TARGET_ARCH_X64 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef RegExpMacroAssemblerX64 ArchRegExpMacroAssembler; 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#elif V8_TARGET_ARCH_ARM 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef RegExpMacroAssemblerARM ArchRegExpMacroAssembler; 6853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#elif V8_TARGET_ARCH_MIPS 68644f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktypedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler; 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ContextInitializer { 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer() 692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch : env_(), scope_(), zone_(Isolate::Current(), DELETE_ON_EXIT) { 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env_ = v8::Context::New(); 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env_->Enter(); 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~ContextInitializer() { 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env_->Exit(); 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env_.Dispose(); 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Persistent<v8::Context> env_; 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope_; 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::ZoneScope zone_; 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic ArchRegExpMacroAssembler::Result Execute(Code* code, 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* input, 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int start_offset, 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const byte* input_start, 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const byte* input_end, 712d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int* captures) { 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NativeRegExpMacroAssembler::Execute( 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code, 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block input, 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_offset, 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block input_start, 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block input_end, 71944f0eee88ff00398ff7f715fab053374d808c90dSteve Block captures, 72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()); 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeSuccess) { 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 7278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4); 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> source = factory->NewStringFromAscii(CStrVector("")); 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int captures[4] = {42, 37, 87, 117}; 7388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> input = factory->NewStringFromAscii(CStrVector("foofoo")); 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const byte* start_adr = 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<const byte*>(seq_input->GetCharsAddress()); 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + seq_input->length(), 749d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke captures); 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, captures[0]); 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, captures[1]); 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, captures[2]); 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, captures[3]); 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeSimple) { 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 7628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4); 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc16 foo_chars[3] = {'f', 'o', 'o'}; 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const uc16> foo(foo_chars, 3); 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label fail; 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckCharacters(foo, 0, &fail, true); 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(0, 0); 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(3); 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(1, 0); 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&fail); 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> source = factory->NewStringFromAscii(CStrVector("^foo")); 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int captures[4] = {42, 37, 87, 117}; 7838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> input = factory->NewStringFromAscii(CStrVector("foofoo")); 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 793d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke captures); 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, captures[0]); 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, captures[1]); 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, captures[2]); 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, captures[3]); 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch input = factory->NewStringFromAscii(CStrVector("barbarbar")); 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block seq_input = Handle<SeqAsciiString>::cast(input); 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr = seq_input->GetCharsAddress(); 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Execute(*code, 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 810d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke captures); 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result); 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeSimpleUC16) { 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 8198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4); 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc16 foo_chars[3] = {'f', 'o', 'o'}; 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const uc16> foo(foo_chars, 3); 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label fail; 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckCharacters(foo, 0, &fail, true); 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(0, 0); 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(3); 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(1, 0); 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&fail); 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> source = factory->NewStringFromAscii(CStrVector("^foo")); 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int captures[4] = {42, 37, 87, 117}; 8403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const uc16 input_data[6] = {'f', 'o', 'o', 'f', 'o', 8413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<uc16>('\xa0')}; 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> input = 8438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromTwoByte(Vector<const uc16>(input_data, 6)); 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqTwoByteString> seq_input = Handle<SeqTwoByteString>::cast(input); 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 853d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke captures); 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, captures[0]); 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, captures[1]); 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, captures[2]); 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, captures[3]); 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const uc16 input_data2[9] = {'b', 'a', 'r', 'b', 'a', 'r', 'b', 'a', 8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<uc16>('\xa0')}; 8638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch input = factory->NewStringFromTwoByte(Vector<const uc16>(input_data2, 9)); 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block seq_input = Handle<SeqTwoByteString>::cast(input); 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr = seq_input->GetCharsAddress(); 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Execute(*code, 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length() * 2, 872d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke captures); 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result); 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeBacktrack) { 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 8818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0); 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label fail; 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label backtrack; 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.LoadCurrentCharacter(10, &fail); 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&fail); 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushBacktrack(&backtrack); 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.LoadCurrentCharacter(10, NULL); 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&backtrack); 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> source = factory->NewStringFromAscii(CStrVector("..........")); 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> input = factory->NewStringFromAscii(CStrVector("foofoo")); 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 910d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NULL); 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result); 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeBackReferenceASCII) { 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 9198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4); 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(0, 0); 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(2); 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(1, 0); 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label nomatch; 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReference(0, &nomatch); 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&nomatch); 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(2); 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label missing_match; 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReference(0, &missing_match); 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(2, 0); 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&missing_match); 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> source = factory->NewStringFromAscii(CStrVector("^(..)..\1")); 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> input = factory->NewStringFromAscii(CStrVector("fooofo")); 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int output[4]; 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 953d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke output); 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, output[0]); 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, output[1]); 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, output[2]); 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, output[3]); 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeBackReferenceUC16) { 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 9668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4); 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(0, 0); 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(2); 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(1, 0); 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label nomatch; 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReference(0, &nomatch); 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&nomatch); 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(2); 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label missing_match; 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReference(0, &missing_match); 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(2, 0); 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&missing_match); 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> source = factory->NewStringFromAscii(CStrVector("^(..)..\1")); 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const uc16 input_data[6] = {'f', 0x2028, 'o', 'o', 'f', 0x2028}; 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> input = 9918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromTwoByte(Vector<const uc16>(input_data, 6)); 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqTwoByteString> seq_input = Handle<SeqTwoByteString>::cast(input); 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int output[4]; 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length() * 2, 1002d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke output); 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, output[0]); 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, output[1]); 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, output[2]); 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, output[3]); 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblernativeAtStart) { 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 10168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0); 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label not_at_start, newline, fail; 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotAtStart(¬_at_start); 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that prevchar = '\n' and current = 'f'. 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckCharacter('\n', &newline); 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&fail); 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&newline); 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.LoadCurrentCharacter(0, &fail); 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotCharacter('f', &fail); 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(¬_at_start); 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that prevchar = 'o' and current = 'b'. 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label prevo; 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckCharacter('o', &prevo); 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&prevo); 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.LoadCurrentCharacter(0, &fail); 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotCharacter('b', &fail); 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> source = factory->NewStringFromAscii(CStrVector("(^f|ob)")); 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> input = factory->NewStringFromAscii(CStrVector("foobar")); 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 1055d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NULL); 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Execute(*code, 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3, 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + 3, 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 1064d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NULL); 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeBackRefNoCase) { 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 10738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4); 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label fail, succ; 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(0, 0); 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(2, 0); 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(3); 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(3, 0); 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReferenceIgnoreCase(2, &fail); // Match "AbC". 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReferenceIgnoreCase(2, &fail); // Match "ABC". 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label expected_fail; 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReferenceIgnoreCase(2, &expected_fail); 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&fail); 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&expected_fail); 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(3); // Skip "xYz" 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReferenceIgnoreCase(2, &succ); 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&succ); 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(1, 0); 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> source = 11008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromAscii(CStrVector("^(abc)\1\1(?!\1)...(?!\1)")); 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> input = 11058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromAscii(CStrVector("aBcAbCABCxYzab")); 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int output[4]; 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 1116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke output); 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, output[0]); 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(12, output[1]); 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, output[2]); 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, output[3]); 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeRegisters) { 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 11308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = Isolate::Current()->factory(); 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 6); 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc16 foo_chars[3] = {'f', 'o', 'o'}; 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const uc16> foo(foo_chars, 3); 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum registers { out1, out2, out3, out4, out5, out6, sp, loop_cnt }; 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label fail; 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label backtrack; 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(out1, 0); // Output: [0] 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushRegister(out1, RegExpMacroAssembler::kNoStackLimitCheck); 1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushBacktrack(&backtrack); 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteStackPointerToRegister(sp); 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fill stack and registers 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(2); 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(out1, 0); 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushRegister(out1, RegExpMacroAssembler::kNoStackLimitCheck); 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushBacktrack(&fail); 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Drop backtrack stack frames. 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.ReadStackPointerFromRegister(sp); 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // And take the first backtrack (to &backtrack) 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Backtrack(); 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushCurrentPosition(); 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(2); 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PopCurrentPosition(); 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&backtrack); 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PopRegister(out1); 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.ReadCurrentPositionFromRegister(out1); 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(3); 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(out2, 0); // [0,3] 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label loop; 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.SetRegister(loop_cnt, 0); // loop counter 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&loop); 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceRegister(loop_cnt, 1); 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(1); 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.IfRegisterLT(loop_cnt, 3, &loop); 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(out3, 0); // [0,3,6] 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label loop2; 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.SetRegister(loop_cnt, 2); // loop counter 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&loop2); 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceRegister(loop_cnt, -1); 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(1); 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.IfRegisterGE(loop_cnt, 0, &loop2); 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(out4, 0); // [0,3,6,9] 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label loop3; 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label exit_loop3; 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushRegister(out4, RegExpMacroAssembler::kNoStackLimitCheck); 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushRegister(out4, RegExpMacroAssembler::kNoStackLimitCheck); 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.ReadCurrentPositionFromRegister(out3); 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&loop3); 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(1); 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckGreedyLoop(&exit_loop3); 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.GoTo(&loop3); 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&exit_loop3); 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PopCurrentPosition(); 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(out5, 0); // [0,3,6,9,9,-1] 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&fail); 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> source = 11998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromAscii(CStrVector("<loop test>")); 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // String long enough for test (content doesn't matter). 1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> input = 12058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromAscii(CStrVector("foofoofoofoofoo")); 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int output[6]; 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 1216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke output); 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, output[0]); 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, output[1]); 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, output[2]); 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(9, output[3]); 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(9, output[4]); 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, output[5]); 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerStackOverflow) { 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 12318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); 12328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = isolate->factory(); 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0); 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label loop; 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&loop); 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushBacktrack(&loop); 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.GoTo(&loop); 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> source = 12428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromAscii(CStrVector("<stack overflow test>")); 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // String long enough for test (content doesn't matter). 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> input = 12488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromAscii(CStrVector("dummy")); 1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 1253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 1255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 1258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NULL); 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::EXCEPTION, result); 12618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK(isolate->has_pending_exception()); 12628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->clear_pending_exception(); 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssemblerNativeLotsOfRegisters) { 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::Initialize(); 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextInitializer initializer; 12698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); 12708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = isolate->factory(); 1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 2); 1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // At least 2048, to ensure the allocated space for registers 1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // span one full page. 1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int large_number = 8000; 1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(large_number, 42); 1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(0, 0); 1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(1, 1); 1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label done; 1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckNotBackReference(0, &done); // Performs a system-stack push. 1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&done); 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushRegister(large_number, RegExpMacroAssembler::kNoStackLimitCheck); 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PopRegister(1); 1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> source = 12888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromAscii(CStrVector("<huge register space test>")); 1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> code_object = m.GetCode(source); 1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code = Handle<Code>::cast(code_object); 1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // String long enough for test (content doesn't matter). 1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> input = 12948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromAscii(CStrVector("sample text")); 1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input); 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address start_adr = seq_input->GetCharsAddress(); 1297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int captures[2]; 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NativeRegExpMacroAssembler::Result result = 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execute(*code, 1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *input, 1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr, 1304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start_adr + input->length(), 1305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke captures); 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result); 1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, captures[0]); 1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(42, captures[1]); 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->clear_pending_exception(); 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#else // V8_INTERPRETED_REGEXP 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MacroAssembler) { 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte codes[1024]; 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024)); 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ^f(o)o. 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label fail, fail2, start; 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc16 foo_chars[3]; 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo_chars[0] = 'f'; 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo_chars[1] = 'o'; 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo_chars[2] = 'o'; 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const uc16> foo(foo_chars, 3); 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.SetRegister(4, 42); 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushRegister(4, RegExpMacroAssembler::kNoStackLimitCheck); 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceRegister(4, 42); 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.GoTo(&start); 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&start); 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushBacktrack(&fail2); 1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.CheckCharacters(foo, 0, &fail, true); 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(0, 0); 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PushCurrentPosition(); 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(3); 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(1, 0); 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PopCurrentPosition(); 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(1); 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(2, 0); 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.AdvanceCurrentPosition(1); 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.WriteCurrentPositionToRegister(3, 0); 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&fail); 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Backtrack(); 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Succeed(); 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Bind(&fail2); 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.PopRegister(0); 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block m.Fail(); 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); 13558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = isolate->factory(); 13568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HandleScope scope(isolate); 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<String> source = factory->NewStringFromAscii(CStrVector("^f(o)o")); 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<ByteArray> array = Handle<ByteArray>::cast(m.GetCode(source)); 1360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int captures[5]; 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const uc16 str1[] = {'f', 'o', 'o', 'b', 'a', 'r'}; 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> f1_16 = 13648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromTwoByte(Vector<const uc16>(str1, 6)); 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK(IrregexpInterpreter::Match(isolate, array, f1_16, captures, 0)); 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, captures[0]); 1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, captures[1]); 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, captures[2]); 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, captures[3]); 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(84, captures[4]); 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const uc16 str2[] = {'b', 'a', 'r', 'f', 'o', 'o'}; 1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> f2_16 = 13758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->NewStringFromTwoByte(Vector<const uc16>(str2, 6)); 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch CHECK(!IrregexpInterpreter::Match(isolate, array, f2_16, captures, 0)); 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(42, captures[0]); 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif // V8_INTERPRETED_REGEXP 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AddInverseToTable) { 138544f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kLimit = 1000; 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kRangeCount = 16; 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int t = 0; t < 10; t++) { 1389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<CharacterRange>* ranges = 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new ZoneList<CharacterRange>(kRangeCount); 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kRangeCount; i++) { 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int from = PseudoRandom(t + 87, i + 25) % kLimit; 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int to = from + (PseudoRandom(i + 87, t + 25) % (kLimit / 20)); 1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (to > kLimit) to = kLimit; 1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ranges->Add(CharacterRange(from, to)); 1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DispatchTable table; 1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DispatchTableConstructor cons(&table, false); 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cons.set_choice_index(0); 1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cons.AddInverse(ranges); 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kLimit; i++) { 1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool is_on = false; 1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; !is_on && j < kRangeCount; j++) 1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_on = ranges->at(j).Contains(i); 1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OutSet* set = table.Get(i); 1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(is_on, set->Get(0) == false); 1408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1410257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<CharacterRange>* ranges = 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new ZoneList<CharacterRange>(1); 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ranges->Add(CharacterRange(0xFFF0, 0xFFFE)); 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DispatchTable table; 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DispatchTableConstructor cons(&table, false); 1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cons.set_choice_index(0); 1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cons.AddInverse(ranges); 1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!table.Get(0xFFFE)->Get(0)); 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(table.Get(0xFFFF)->Get(0)); 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic uc32 canonicalize(uc32 c) { 1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::uchar canon[unibrow::Ecma262Canonicalize::kMaxWidth]; 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = unibrow::Ecma262Canonicalize::Convert(c, '\0', canon, NULL); 1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (count == 0) { 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return c; 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, count); 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return canon[0]; 1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(LatinCanonicalize) { 1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::Mapping<unibrow::Ecma262UnCanonicalize> un_canonicalize; 1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (char lower = 'a'; lower <= 'z'; lower++) { 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char upper = lower + ('A' - 'a'); 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(canonicalize(lower), canonicalize(upper)); 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::uchar uncanon[unibrow::Ecma262UnCanonicalize::kMaxWidth]; 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int length = un_canonicalize.get(lower, '\0', uncanon); 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, length); 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(upper, uncanon[0]); 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(lower, uncanon[1]); 1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (uc32 c = 128; c < (1 << 21); c++) 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GE(canonicalize(c), 128); 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::Mapping<unibrow::ToUppercase> to_upper; 1449bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Canonicalization is only defined for the Basic Multilingual Plane. 1450bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch for (uc32 c = 0; c < (1 << 16); c++) { 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::uchar upper[unibrow::ToUppercase::kMaxWidth]; 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int length = to_upper.get(c, '\0', upper); 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length == 0) { 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block length = 1; 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block upper[0] = c; 1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 u = upper[0]; 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length > 1 || (c >= 128 && u < 128)) 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block u = c; 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(u, canonicalize(c)); 1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1465bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochstatic uc32 CanonRangeEnd(uc32 c) { 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::uchar canon[unibrow::CanonicalizationRange::kMaxWidth]; 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = unibrow::CanonicalizationRange::Convert(c, '\0', canon, NULL); 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (count == 0) { 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return c; 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, count); 1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return canon[0]; 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(RangeCanonicalization) { 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that we arrive at the same result when using the basic 1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // range canonicalization primitives as when using immediate 1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // canonicalization. 1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::Mapping<unibrow::Ecma262UnCanonicalize> un_canonicalize; 1482bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int block_start = 0; 1483bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch while (block_start <= 0xFFFF) { 1484bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch uc32 block_end = CanonRangeEnd(block_start); 1485bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch unsigned block_length = block_end - block_start + 1; 1486bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (block_length > 1) { 1487bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch unibrow::uchar first[unibrow::Ecma262UnCanonicalize::kMaxWidth]; 1488bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int first_length = un_canonicalize.get(block_start, '\0', first); 1489bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch for (unsigned i = 1; i < block_length; i++) { 1490bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch unibrow::uchar succ[unibrow::Ecma262UnCanonicalize::kMaxWidth]; 1491bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int succ_length = un_canonicalize.get(block_start + i, '\0', succ); 1492bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch CHECK_EQ(first_length, succ_length); 1493bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch for (int j = 0; j < succ_length; j++) { 1494bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int calc = first[j] + i; 1495bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int found = succ[j]; 1496bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch CHECK_EQ(calc, found); 1497bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1500bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch block_start = block_start + block_length; 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(UncanonicalizeEquivalence) { 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::Mapping<unibrow::Ecma262UnCanonicalize> un_canonicalize; 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < (1 << 16); i++) { 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int length = un_canonicalize.get(i, '\0', chars); 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; j < length; j++) { 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unibrow::uchar chars2[unibrow::Ecma262UnCanonicalize::kMaxWidth]; 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int length2 = un_canonicalize.get(chars[j], '\0', chars2); 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(length, length2); 1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int k = 0; k < length; k++) 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(static_cast<int>(chars[k]), static_cast<int>(chars2[k])); 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void TestRangeCaseIndependence(CharacterRange input, 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<CharacterRange> expected) { 1523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = expected.length(); 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<CharacterRange>* list = new ZoneList<CharacterRange>(count); 1526d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block input.AddCaseEquivalents(list, false); 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(count, list->length()); 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < list->length(); i++) { 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(expected[i].from(), list->at(i).from()); 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(expected[i].to(), list->at(i).to()); 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void TestSimpleRangeCaseIndependence(CharacterRange input, 1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange expected) { 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<CharacterRange, 1> vector; 1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block vector[0] = expected; 1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestRangeCaseIndependence(input, vector); 1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(CharacterRangeCaseIndependence) { 154444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange::Singleton('a'), 1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange::Singleton('A')); 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange::Singleton('z'), 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange::Singleton('Z')); 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('a', 'z'), 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('A', 'Z')); 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('c', 'f'), 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('C', 'F')); 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('a', 'b'), 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('A', 'B')); 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('y', 'z'), 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('Y', 'Z')); 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('a' - 1, 'z' + 1), 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('A', 'Z')); 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('A', 'Z'), 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('a', 'z')); 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('C', 'F'), 1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('c', 'f')); 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('A' - 1, 'Z' + 1), 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('a', 'z')); 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Here we need to add [l-z] to complete the case independence of 1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [A-Za-z] but we expect [a-z] to be added since we always add a 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // whole block at a time. 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestSimpleRangeCaseIndependence(CharacterRange('A', 'k'), 1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange('a', 'z')); 1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool InClass(uc16 c, ZoneList<CharacterRange>* ranges) { 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ranges == NULL) 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < ranges->length(); i++) { 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange range = ranges->at(i); 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (range.from() <= c && c <= range.to()) 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(CharClassDifference) { 158644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 1587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<CharacterRange>* base = new ZoneList<CharacterRange>(1); 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block base->Add(CharacterRange::Everything()); 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const uc16> overlay = CharacterRange::GetWordBounds(); 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<CharacterRange>* included = NULL; 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ZoneList<CharacterRange>* excluded = NULL; 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CharacterRange::Split(base, overlay, &included, &excluded); 1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < (1 << 16); i++) { 1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool in_base = InClass(i, base); 1596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (in_base) { 1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool in_overlay = false; 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; !in_overlay && j < overlay.length(); j += 2) { 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (overlay[j] <= i && i <= overlay[j+1]) 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block in_overlay = true; 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(in_overlay, InClass(i, included)); 1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(!in_overlay, InClass(i, excluded)); 1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!InClass(i, included)); 1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!InClass(i, excluded)); 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1612e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(CanonicalizeCharacterSets) { 161344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 1614257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope scope(Isolate::Current(), DELETE_ON_EXIT); 1615e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ZoneList<CharacterRange>* list = new ZoneList<CharacterRange>(4); 1616e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CharacterSet set(list); 1617e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1618e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(10, 20)); 1619e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(30, 40)); 1620e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(50, 60)); 1621e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke set.Canonicalize(); 1622e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(3, list->length()); 1623e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(10, list->at(0).from()); 1624e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(20, list->at(0).to()); 1625e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(30, list->at(1).from()); 1626e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(40, list->at(1).to()); 1627e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(50, list->at(2).from()); 1628e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(60, list->at(2).to()); 1629e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1630e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Rewind(0); 1631e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(10, 20)); 1632e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(50, 60)); 1633e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(30, 40)); 1634e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke set.Canonicalize(); 1635e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(3, list->length()); 1636e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(10, list->at(0).from()); 1637e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(20, list->at(0).to()); 1638e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(30, list->at(1).from()); 1639e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(40, list->at(1).to()); 1640e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(50, list->at(2).from()); 1641e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(60, list->at(2).to()); 1642e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1643e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Rewind(0); 1644e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(30, 40)); 1645e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(10, 20)); 1646e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(25, 25)); 1647e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(100, 100)); 1648e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(1, 1)); 1649e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke set.Canonicalize(); 1650e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(5, list->length()); 1651e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(1, list->at(0).from()); 1652e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(1, list->at(0).to()); 1653e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(10, list->at(1).from()); 1654e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(20, list->at(1).to()); 1655e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(25, list->at(2).from()); 1656e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(25, list->at(2).to()); 1657e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(30, list->at(3).from()); 1658e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(40, list->at(3).to()); 1659e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(100, list->at(4).from()); 1660e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(100, list->at(4).to()); 1661e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1662e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Rewind(0); 1663e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(10, 19)); 1664e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(21, 30)); 1665e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke list->Add(CharacterRange(20, 20)); 1666e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke set.Canonicalize(); 1667e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(1, list->length()); 1668e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(10, list->at(0).from()); 1669e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT_EQ(30, list->at(0).to()); 1670e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1671e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1672d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Checks whether a character is in the set represented by a list of ranges. 1673d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkestatic bool CharacterInSet(ZoneList<CharacterRange>* set, uc16 value) { 1674d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < set->length(); i++) { 1675d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CharacterRange range = set->at(i); 1676d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (range.from() <= value && value <= range.to()) { 1677d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return true; 1678d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1679d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1680d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return false; 1681d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1682d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1683d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(CharacterRangeMerge) { 168444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::V8::Initialize(NULL); 1685257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 1686d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<CharacterRange> l1(4); 1687d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<CharacterRange> l2(4); 1688d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Create all combinations of intersections of ranges, both singletons and 1689d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // longer. 1690d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1691d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int offset = 0; 1692d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1693d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The five kinds of singleton intersections: 1694d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // X 1695d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - outside before 1696d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - outside touching start 1697d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - overlap 1698d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - outside touching end 1699d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - outside after 1700d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1701d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < 5; i++) { 1702d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l1.Add(CharacterRange::Singleton(offset + 2)); 1703d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l2.Add(CharacterRange::Singleton(offset + i)); 1704d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += 6; 1705d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1706d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1707d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The seven kinds of singleton/non-singleton intersections: 1708d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // XXX 1709d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - outside before 1710d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - outside touching start 1711d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - inside touching start 1712d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - entirely inside 1713d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - inside touching end 1714d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - outside touching end 1715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Y - disjoint after 1716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < 7; i++) { 1718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l1.Add(CharacterRange::Range(offset + 2, offset + 4)); 1719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l2.Add(CharacterRange::Singleton(offset + i)); 1720d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += 8; 1721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1723d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The eleven kinds of non-singleton intersections: 1724d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1725d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // XXXXXXXX 1726d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - outside before. 1727d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - outside touching start. 1728d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - overlapping start 1729d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - inside touching start 1730d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - entirely inside 1731d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - inside touching end 1732d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - overlapping end 1733d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - outside touching end 1734d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY - outside after 1735d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYYYYYY - identical 1736d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYYYYYYYYYY - containing entirely. 1737d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1738d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < 9; i++) { 1739d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l1.Add(CharacterRange::Range(offset + 6, offset + 15)); // Length 8. 1740d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l2.Add(CharacterRange::Range(offset + 2 * i, offset + 2 * i + 3)); 1741d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += 22; 1742d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1743d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l1.Add(CharacterRange::Range(offset + 6, offset + 15)); 1744d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l2.Add(CharacterRange::Range(offset + 6, offset + 15)); 1745d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += 22; 1746d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l1.Add(CharacterRange::Range(offset + 6, offset + 15)); 1747d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l2.Add(CharacterRange::Range(offset + 4, offset + 17)); 1748d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += 22; 1749d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1750d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Different kinds of multi-range overlap: 1751d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX 1752d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // YYYY Y YYYY Y YYYY Y YYYY Y YYYY Y YYYY Y 1753d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1754d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l1.Add(CharacterRange::Range(offset, offset + 21)); 1755d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l1.Add(CharacterRange::Range(offset + 31, offset + 52)); 1756d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < 6; i++) { 1757d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l2.Add(CharacterRange::Range(offset + 2, offset + 5)); 1758d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke l2.Add(CharacterRange::Singleton(offset + 8)); 1759d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += 9; 1760d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1761d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1762d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(CharacterRange::IsCanonical(&l1)); 1763d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(CharacterRange::IsCanonical(&l2)); 1764d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1765d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<CharacterRange> first_only(4); 1766d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<CharacterRange> second_only(4); 1767d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<CharacterRange> both(4); 1768d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1769d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Merge one direction. 1770d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CharacterRange::Merge(&l1, &l2, &first_only, &second_only, &both); 1771d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1772d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK(CharacterRange::IsCanonical(&first_only)); 1773d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK(CharacterRange::IsCanonical(&second_only)); 1774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK(CharacterRange::IsCanonical(&both)); 1775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (uc16 i = 0; i < offset; i++) { 1777d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool in_first = CharacterInSet(&l1, i); 1778d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool in_second = CharacterInSet(&l2, i); 1779d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK((in_first && !in_second) == CharacterInSet(&first_only, i)); 1780d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK((!in_first && in_second) == CharacterInSet(&second_only, i)); 1781d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK((in_first && in_second) == CharacterInSet(&both, i)); 1782d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1783d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1784d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke first_only.Clear(); 1785d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke second_only.Clear(); 1786d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke both.Clear(); 1787d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1788d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Merge other direction. 1789d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CharacterRange::Merge(&l2, &l1, &second_only, &first_only, &both); 1790d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1791d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK(CharacterRange::IsCanonical(&first_only)); 1792d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK(CharacterRange::IsCanonical(&second_only)); 1793d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK(CharacterRange::IsCanonical(&both)); 1794d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1795d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (uc16 i = 0; i < offset; i++) { 1796d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool in_first = CharacterInSet(&l1, i); 1797d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool in_second = CharacterInSet(&l2, i); 1798d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK((in_first && !in_second) == CharacterInSet(&first_only, i)); 1799d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK((!in_first && in_second) == CharacterInSet(&second_only, i)); 1800d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK((in_first && in_second) == CharacterInSet(&both, i)); 1801d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1802d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1803d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke first_only.Clear(); 1804d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke second_only.Clear(); 1805d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke both.Clear(); 1806d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1807d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Merge but don't record all combinations. 1808d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CharacterRange::Merge(&l1, &l2, NULL, NULL, &both); 1809d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1810d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK(CharacterRange::IsCanonical(&both)); 1811d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1812d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (uc16 i = 0; i < offset; i++) { 1813d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool in_first = CharacterInSet(&l1, i); 1814d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool in_second = CharacterInSet(&l2, i); 1815d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK((in_first && in_second) == CharacterInSet(&both, i)); 1816d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1817d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1818d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Merge into same set. 1819d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<CharacterRange> all(4); 1820d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CharacterRange::Merge(&l1, &l2, &all, &all, &all); 1821d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1822d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK(CharacterRange::IsCanonical(&all)); 1823d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1824d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (uc16 i = 0; i < offset; i++) { 1825d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool in_first = CharacterInSet(&l1, i); 1826d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool in_second = CharacterInSet(&l2, i); 1827d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK((in_first || in_second) == CharacterInSet(&all, i)); 1828d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1829d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1830e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1831e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(Graph) { 1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8::Initialize(NULL); 1834e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Execute("\\b\\w+\\b", false, true, true); 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1836