Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 4a572c8..a91058c 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -28,55 +28,61 @@
#include <cstdlib>
#include <sstream>
+#include "include/v8.h"
#include "src/v8.h"
-#include "src/ast.h"
+#include "src/ast/ast.h"
#include "src/char-predicates-inl.h"
-#include "src/jsregexp.h"
#include "src/ostreams.h"
-#include "src/parser.h"
-#include "src/regexp-macro-assembler.h"
-#include "src/regexp-macro-assembler-irregexp.h"
+#include "src/regexp/jsregexp.h"
+#include "src/regexp/regexp-macro-assembler.h"
+#include "src/regexp/regexp-macro-assembler-irregexp.h"
+#include "src/regexp/regexp-parser.h"
+#include "src/splay-tree-inl.h"
#include "src/string-stream.h"
-#include "src/zone-inl.h"
#ifdef V8_INTERPRETED_REGEXP
-#include "src/interpreter-irregexp.h"
+#include "src/regexp/interpreter-irregexp.h"
#else // V8_INTERPRETED_REGEXP
#include "src/macro-assembler.h"
#if V8_TARGET_ARCH_ARM
#include "src/arm/assembler-arm.h" // NOLINT
#include "src/arm/macro-assembler-arm.h"
-#include "src/arm/regexp-macro-assembler-arm.h"
+#include "src/regexp/arm/regexp-macro-assembler-arm.h"
#endif
#if V8_TARGET_ARCH_ARM64
#include "src/arm64/assembler-arm64.h"
#include "src/arm64/macro-assembler-arm64.h"
-#include "src/arm64/regexp-macro-assembler-arm64.h"
+#include "src/regexp/arm64/regexp-macro-assembler-arm64.h"
+#endif
+#if V8_TARGET_ARCH_PPC
+#include "src/ppc/assembler-ppc.h"
+#include "src/ppc/macro-assembler-ppc.h"
+#include "src/regexp/ppc/regexp-macro-assembler-ppc.h"
#endif
#if V8_TARGET_ARCH_MIPS
#include "src/mips/assembler-mips.h"
#include "src/mips/macro-assembler-mips.h"
-#include "src/mips/regexp-macro-assembler-mips.h"
+#include "src/regexp/mips/regexp-macro-assembler-mips.h"
#endif
#if V8_TARGET_ARCH_MIPS64
#include "src/mips64/assembler-mips64.h"
#include "src/mips64/macro-assembler-mips64.h"
-#include "src/mips64/regexp-macro-assembler-mips64.h"
+#include "src/regexp/mips64/regexp-macro-assembler-mips64.h"
#endif
#if V8_TARGET_ARCH_X64
+#include "src/regexp/x64/regexp-macro-assembler-x64.h"
#include "src/x64/assembler-x64.h"
#include "src/x64/macro-assembler-x64.h"
-#include "src/x64/regexp-macro-assembler-x64.h"
#endif
#if V8_TARGET_ARCH_IA32
#include "src/ia32/assembler-ia32.h"
#include "src/ia32/macro-assembler-ia32.h"
-#include "src/ia32/regexp-macro-assembler-ia32.h"
+#include "src/regexp/ia32/regexp-macro-assembler-ia32.h"
#endif
#if V8_TARGET_ARCH_X87
+#include "src/regexp/x87/regexp-macro-assembler-x87.h"
#include "src/x87/assembler-x87.h"
#include "src/x87/macro-assembler-x87.h"
-#include "src/x87/regexp-macro-assembler-x87.h"
#endif
#endif // V8_INTERPRETED_REGEXP
#include "test/cctest/cctest.h"
@@ -86,36 +92,40 @@
static bool CheckParse(const char* input) {
v8::HandleScope scope(CcTest::isolate());
- Zone zone(CcTest::i_isolate());
+ Zone zone;
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
RegExpCompileData result;
return v8::internal::RegExpParser::ParseRegExp(
- &reader, false, &result, &zone);
+ CcTest::i_isolate(), &zone, &reader, false, false, &result);
}
-static void CheckParseEq(const char* input, const char* expected) {
+static void CheckParseEq(const char* input, const char* expected,
+ bool unicode = false) {
v8::HandleScope scope(CcTest::isolate());
- Zone zone(CcTest::i_isolate());
+ Zone zone;
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
RegExpCompileData result;
CHECK(v8::internal::RegExpParser::ParseRegExp(
- &reader, false, &result, &zone));
+ CcTest::i_isolate(), &zone, &reader, false, unicode, &result));
CHECK(result.tree != NULL);
CHECK(result.error.is_null());
std::ostringstream os;
result.tree->Print(os, &zone);
- CHECK_EQ(expected, os.str().c_str());
+ if (strcmp(expected, os.str().c_str()) != 0) {
+ printf("%s | %s\n", expected, os.str().c_str());
+ }
+ CHECK_EQ(0, strcmp(expected, os.str().c_str()));
}
static bool CheckSimple(const char* input) {
v8::HandleScope scope(CcTest::isolate());
- Zone zone(CcTest::i_isolate());
+ Zone zone;
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
RegExpCompileData result;
CHECK(v8::internal::RegExpParser::ParseRegExp(
- &reader, false, &result, &zone));
+ CcTest::i_isolate(), &zone, &reader, false, false, &result));
CHECK(result.tree != NULL);
CHECK(result.error.is_null());
return result.simple;
@@ -129,11 +139,11 @@
static MinMaxPair CheckMinMaxMatch(const char* input) {
v8::HandleScope scope(CcTest::isolate());
- Zone zone(CcTest::i_isolate());
+ Zone zone;
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
RegExpCompileData result;
CHECK(v8::internal::RegExpParser::ParseRegExp(
- &reader, false, &result, &zone));
+ CcTest::i_isolate(), &zone, &reader, false, false, &result));
CHECK(result.tree != NULL);
CHECK(result.error.is_null());
int min_match = result.tree->min_match();
@@ -151,7 +161,11 @@
CHECK_EQ(max, min_max.max_match); \
}
-TEST(Parser) {
+
+void TestRegExpParser(bool lookbehind) {
+ FLAG_harmony_regexp_lookbehind = lookbehind;
+ FLAG_harmony_unicode_regexps = true;
+
CHECK_PARSE_ERROR("?");
CheckParseEq("abc", "'abc'");
@@ -183,6 +197,13 @@
CheckParseEq("foo|(bar|baz)|quux", "(| 'foo' (^ (| 'bar' 'baz')) 'quux')");
CheckParseEq("foo(?=bar)baz", "(: 'foo' (-> + 'bar') 'baz')");
CheckParseEq("foo(?!bar)baz", "(: 'foo' (-> - 'bar') 'baz')");
+ if (lookbehind) {
+ CheckParseEq("foo(?<=bar)baz", "(: 'foo' (<- + 'bar') 'baz')");
+ CheckParseEq("foo(?<!bar)baz", "(: 'foo' (<- - 'bar') 'baz')");
+ } else {
+ CHECK_PARSE_ERROR("foo(?<=bar)baz");
+ CHECK_PARSE_ERROR("foo(?<!bar)baz");
+ }
CheckParseEq("()", "(^ %)");
CheckParseEq("(?=)", "(-> + %)");
CheckParseEq("[]", "^[\\x00-\\uffff]"); // Doesn't compile on windows
@@ -254,14 +275,22 @@
CheckParseEq("(a)\\1", "(: (^ 'a') (<- 1))");
CheckParseEq("(a\\1)", "(^ 'a')");
CheckParseEq("(\\1a)", "(^ 'a')");
+ CheckParseEq("(\\2)(\\1)", "(: (^ (<- 2)) (^ (<- 1)))");
CheckParseEq("(?=a)?a", "'a'");
CheckParseEq("(?=a){0,10}a", "'a'");
CheckParseEq("(?=a){1,10}a", "(: (-> + 'a') 'a')");
CheckParseEq("(?=a){9,10}a", "(: (-> + 'a') 'a')");
CheckParseEq("(?!a)?a", "'a'");
- CheckParseEq("\\1(a)", "(^ 'a')");
+ CheckParseEq("\\1(a)", "(: (<- 1) (^ 'a'))");
CheckParseEq("(?!(a))\\1", "(: (-> - (^ 'a')) (<- 1))");
- CheckParseEq("(?!\\1(a\\1)\\1)\\1", "(: (-> - (: (^ 'a') (<- 1))) (<- 1))");
+ CheckParseEq("(?!\\1(a\\1)\\1)\\1",
+ "(: (-> - (: (<- 1) (^ 'a') (<- 1))) (<- 1))");
+ CheckParseEq("\\1\\2(a(?:\\1(b\\1\\2))\\2)\\1",
+ "(: (<- 1) (<- 2) (^ (: 'a' (^ 'b') (<- 2))) (<- 1))");
+ if (lookbehind) {
+ CheckParseEq("\\1\\2(a(?<=\\1(b\\1\\2))\\2)\\1",
+ "(: (<- 1) (<- 2) (^ (: 'a' (<- + (^ 'b')) (<- 2))) (<- 1))");
+ }
CheckParseEq("[\\0]", "[\\x00]");
CheckParseEq("[\\11]", "[\\x09]");
CheckParseEq("[\\11a]", "[\\x09 a]");
@@ -278,6 +307,15 @@
CheckParseEq("\\u003z", "'u003z'");
CheckParseEq("foo[z]*", "(: 'foo' (# 0 - g [z]))");
+ // Unicode regexps
+ CheckParseEq("\\u{12345}", "'\\ud808\\udf45'", true);
+ CheckParseEq("\\u{12345}\\u{23456}", "(! '\\ud808\\udf45' '\\ud84d\\udc56')",
+ true);
+ CheckParseEq("\\u{12345}|\\u{23456}", "(| '\\ud808\\udf45' '\\ud84d\\udc56')",
+ true);
+ CheckParseEq("\\u{12345}{3}", "(# 3 3 g '\\ud808\\udf45')", true);
+ CheckParseEq("\\u{12345}*", "(# 0 - g '\\ud808\\udf45')", true);
+
CHECK_SIMPLE("", false);
CHECK_SIMPLE("a", true);
CHECK_SIMPLE("a|b", false);
@@ -353,8 +391,8 @@
CHECK_MIN_MAX("(?:ab)|cde", 2, 3);
CHECK_MIN_MAX("(ab)", 2, 2);
CHECK_MIN_MAX("(ab|cde)", 2, 3);
- CHECK_MIN_MAX("(ab)\\1", 2, 4);
- CHECK_MIN_MAX("(ab|cde)\\1", 2, 6);
+ CHECK_MIN_MAX("(ab)\\1", 2, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(ab|cde)\\1", 2, RegExpTree::kInfinity);
CHECK_MIN_MAX("(?:ab)?", 0, 2);
CHECK_MIN_MAX("(?:ab)*", 0, RegExpTree::kInfinity);
CHECK_MIN_MAX("(?:ab)+", 2, RegExpTree::kInfinity);
@@ -392,6 +430,16 @@
}
+TEST(ParserWithLookbehind) {
+ TestRegExpParser(true); // Lookbehind enabled.
+}
+
+
+TEST(ParserWithoutLookbehind) {
+ TestRegExpParser(true); // Lookbehind enabled.
+}
+
+
TEST(ParserRegression) {
CheckParseEq("[A-Z$-][x]", "(! [A-Z $ -] [x])");
CheckParseEq("a{3,4*}", "(: 'a{3,' (# 0 - g '4') '}')");
@@ -402,15 +450,15 @@
static void ExpectError(const char* input,
const char* expected) {
v8::HandleScope scope(CcTest::isolate());
- Zone zone(CcTest::i_isolate());
+ Zone zone;
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
RegExpCompileData result;
CHECK(!v8::internal::RegExpParser::ParseRegExp(
- &reader, false, &result, &zone));
+ CcTest::i_isolate(), &zone, &reader, false, false, &result));
CHECK(result.tree == NULL);
CHECK(!result.error.is_null());
- SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS);
- CHECK_EQ(expected, str.get());
+ v8::base::SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS);
+ CHECK_EQ(0, strcmp(expected, str.get()));
}
@@ -471,7 +519,7 @@
static void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) {
- Zone zone(CcTest::i_isolate());
+ Zone zone;
ZoneList<CharacterRange>* ranges =
new(&zone) ZoneList<CharacterRange>(2, &zone);
CharacterRange::AddClassEscape(c, ranges, &zone);
@@ -497,29 +545,31 @@
}
-static RegExpNode* Compile(const char* input, bool multiline, bool is_one_byte,
- Zone* zone) {
+static RegExpNode* Compile(const char* input, bool multiline, bool unicode,
+ bool is_one_byte, Zone* zone) {
Isolate* isolate = CcTest::i_isolate();
FlatStringReader reader(isolate, CStrVector(input));
RegExpCompileData compile_data;
- if (!v8::internal::RegExpParser::ParseRegExp(&reader, multiline,
- &compile_data, zone))
+ if (!v8::internal::RegExpParser::ParseRegExp(CcTest::i_isolate(), zone,
+ &reader, multiline, unicode,
+ &compile_data))
return NULL;
- Handle<String> pattern = isolate->factory()->
- NewStringFromUtf8(CStrVector(input)).ToHandleChecked();
+ Handle<String> pattern = isolate->factory()
+ ->NewStringFromUtf8(CStrVector(input))
+ .ToHandleChecked();
Handle<String> sample_subject =
isolate->factory()->NewStringFromUtf8(CStrVector("")).ToHandleChecked();
- RegExpEngine::Compile(&compile_data, false, false, multiline, false, pattern,
- sample_subject, is_one_byte, zone);
+ RegExpEngine::Compile(isolate, zone, &compile_data, false, false, multiline,
+ false, pattern, sample_subject, is_one_byte);
return compile_data.node;
}
-static void Execute(const char* input, bool multiline, bool is_one_byte,
- bool dot_output = false) {
+static void Execute(const char* input, bool multiline, bool unicode,
+ bool is_one_byte, bool dot_output = false) {
v8::HandleScope scope(CcTest::isolate());
- Zone zone(CcTest::i_isolate());
- RegExpNode* node = Compile(input, multiline, is_one_byte, &zone);
+ Zone zone;
+ RegExpNode* node = Compile(input, multiline, unicode, is_one_byte, &zone);
USE(node);
#ifdef DEBUG
if (dot_output) {
@@ -556,7 +606,7 @@
TEST(SplayTreeSimple) {
static const unsigned kLimit = 1000;
- Zone zone(CcTest::i_isolate());
+ Zone zone;
ZoneSplayTree<TestConfig> tree(&zone);
bool seen[kLimit];
for (unsigned i = 0; i < kLimit; i++) seen[i] = false;
@@ -566,7 +616,7 @@
} while (false)
for (int i = 0; i < 50; i++) {
for (int j = 0; j < 50; j++) {
- unsigned next = PseudoRandom(i, j) % kLimit;
+ int next = PseudoRandom(i, j) % kLimit;
if (seen[next]) {
// We've already seen this one. Check the value and remove
// it.
@@ -623,7 +673,7 @@
}
}
// Enter test data into dispatch table.
- Zone zone(CcTest::i_isolate());
+ Zone zone;
DispatchTable table(&zone);
for (int i = 0; i < kRangeCount; i++) {
uc16* range = ranges[i];
@@ -686,6 +736,8 @@
typedef RegExpMacroAssemblerARM ArchRegExpMacroAssembler;
#elif V8_TARGET_ARCH_ARM64
typedef RegExpMacroAssemblerARM64 ArchRegExpMacroAssembler;
+#elif V8_TARGET_ARCH_PPC
+typedef RegExpMacroAssemblerPPC ArchRegExpMacroAssembler;
#elif V8_TARGET_ARCH_MIPS
typedef RegExpMacroAssemblerMIPS ArchRegExpMacroAssembler;
#elif V8_TARGET_ARCH_MIPS64
@@ -706,7 +758,7 @@
}
private:
v8::HandleScope scope_;
- v8::Handle<v8::Context> env_;
+ v8::Local<v8::Context> env_;
};
@@ -733,9 +785,10 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 4, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 4);
m.Succeed();
@@ -770,13 +823,14 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 4, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 4);
Label fail, backtrack;
m.PushBacktrack(&fail);
- m.CheckNotAtStart(NULL);
+ m.CheckNotAtStart(0, NULL);
m.LoadCurrentCharacter(2, NULL);
m.CheckNotCharacter('o', NULL);
m.LoadCurrentCharacter(1, NULL, false);
@@ -836,13 +890,14 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::UC16,
+ 4);
Label fail, backtrack;
m.PushBacktrack(&fail);
- m.CheckNotAtStart(NULL);
+ m.CheckNotAtStart(0, NULL);
m.LoadCurrentCharacter(2, NULL);
m.CheckNotCharacter('o', NULL);
m.LoadCurrentCharacter(1, NULL, false);
@@ -908,9 +963,10 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 0, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 0);
Label fail;
Label backtrack;
@@ -948,20 +1004,21 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 4, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 4);
m.WriteCurrentPositionToRegister(0, 0);
m.AdvanceCurrentPosition(2);
m.WriteCurrentPositionToRegister(1, 0);
Label nomatch;
- m.CheckNotBackReference(0, &nomatch);
+ m.CheckNotBackReference(0, false, &nomatch);
m.Fail();
m.Bind(&nomatch);
m.AdvanceCurrentPosition(2);
Label missing_match;
- m.CheckNotBackReference(0, &missing_match);
+ m.CheckNotBackReference(0, false, &missing_match);
m.WriteCurrentPositionToRegister(2, 0);
m.Succeed();
m.Bind(&missing_match);
@@ -997,20 +1054,21 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::UC16,
+ 4);
m.WriteCurrentPositionToRegister(0, 0);
m.AdvanceCurrentPosition(2);
m.WriteCurrentPositionToRegister(1, 0);
Label nomatch;
- m.CheckNotBackReference(0, &nomatch);
+ m.CheckNotBackReference(0, false, &nomatch);
m.Fail();
m.Bind(&nomatch);
m.AdvanceCurrentPosition(2);
Label missing_match;
- m.CheckNotBackReference(0, &missing_match);
+ m.CheckNotBackReference(0, false, &missing_match);
m.WriteCurrentPositionToRegister(2, 0);
m.Succeed();
m.Bind(&missing_match);
@@ -1049,12 +1107,13 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 0, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 0);
Label not_at_start, newline, fail;
- m.CheckNotAtStart(¬_at_start);
+ m.CheckNotAtStart(0, ¬_at_start);
// Check that prevchar = '\n' and current = 'f'.
m.CheckCharacter('\n', &newline);
m.Bind(&fail);
@@ -1108,9 +1167,10 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 4, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 4);
Label fail, succ;
@@ -1118,16 +1178,16 @@
m.WriteCurrentPositionToRegister(2, 0);
m.AdvanceCurrentPosition(3);
m.WriteCurrentPositionToRegister(3, 0);
- m.CheckNotBackReferenceIgnoreCase(2, &fail); // Match "AbC".
- m.CheckNotBackReferenceIgnoreCase(2, &fail); // Match "ABC".
+ m.CheckNotBackReferenceIgnoreCase(2, false, &fail); // Match "AbC".
+ m.CheckNotBackReferenceIgnoreCase(2, false, &fail); // Match "ABC".
Label expected_fail;
- m.CheckNotBackReferenceIgnoreCase(2, &expected_fail);
+ m.CheckNotBackReferenceIgnoreCase(2, false, &expected_fail);
m.Bind(&fail);
m.Fail();
m.Bind(&expected_fail);
m.AdvanceCurrentPosition(3); // Skip "xYz"
- m.CheckNotBackReferenceIgnoreCase(2, &succ);
+ m.CheckNotBackReferenceIgnoreCase(2, false, &succ);
m.Fail();
m.Bind(&succ);
@@ -1166,9 +1226,10 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 6, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 6);
uc16 foo_chars[3] = {'f', 'o', 'o'};
Vector<const uc16> foo(foo_chars, 3);
@@ -1267,9 +1328,10 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 0, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 0);
Label loop;
m.Bind(&loop);
@@ -1305,9 +1367,10 @@
ContextInitializer initializer;
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Zone zone(isolate);
+ Zone zone;
- ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::LATIN1, 2, &zone);
+ ArchRegExpMacroAssembler m(isolate, &zone, NativeRegExpMacroAssembler::LATIN1,
+ 2);
// At least 2048, to ensure the allocated space for registers
// span one full page.
@@ -1316,7 +1379,7 @@
m.WriteCurrentPositionToRegister(0, 0);
m.WriteCurrentPositionToRegister(1, 1);
Label done;
- m.CheckNotBackReference(0, &done); // Performs a system-stack push.
+ m.CheckNotBackReference(0, false, &done); // Performs a system-stack push.
m.Bind(&done);
m.PushRegister(large_number, RegExpMacroAssembler::kNoStackLimitCheck);
m.PopRegister(1);
@@ -1352,8 +1415,9 @@
TEST(MacroAssembler) {
byte codes[1024];
- Zone zone(CcTest::i_isolate());
- RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024), &zone);
+ Zone zone;
+ RegExpMacroAssemblerIrregexp m(CcTest::i_isolate(), Vector<byte>(codes, 1024),
+ &zone);
// ^f(o)o.
Label start, fail, backtrack;
@@ -1364,7 +1428,7 @@
m.Fail();
m.Bind(&start);
m.PushBacktrack(&fail);
- m.CheckNotAtStart(NULL);
+ m.CheckNotAtStart(0, NULL);
m.LoadCurrentCharacter(0, NULL);
m.CheckNotCharacter('f', NULL);
m.LoadCurrentCharacter(1, NULL);
@@ -1419,7 +1483,7 @@
static const int kLimit = 1000;
static const int kRangeCount = 16;
for (int t = 0; t < 10; t++) {
- Zone zone(CcTest::i_isolate());
+ Zone zone;
ZoneList<CharacterRange>* ranges =
new(&zone) ZoneList<CharacterRange>(kRangeCount, &zone);
for (int i = 0; i < kRangeCount; i++) {
@@ -1440,7 +1504,7 @@
CHECK_EQ(is_on, set->Get(0) == false);
}
}
- Zone zone(CcTest::i_isolate());
+ Zone zone;
ZoneList<CharacterRange>* ranges =
new(&zone) ZoneList<CharacterRange>(1, &zone);
ranges->Add(CharacterRange(0xFFF0, 0xFFFE), &zone);
@@ -1467,8 +1531,8 @@
TEST(LatinCanonicalize) {
unibrow::Mapping<unibrow::Ecma262UnCanonicalize> un_canonicalize;
- for (char lower = 'a'; lower <= 'z'; lower++) {
- char upper = lower + ('A' - 'a');
+ for (unibrow::uchar lower = 'a'; lower <= 'z'; lower++) {
+ unibrow::uchar upper = lower + ('A' - 'a');
CHECK_EQ(canonicalize(lower), canonicalize(upper));
unibrow::uchar uncanon[unibrow::Ecma262UnCanonicalize::kMaxWidth];
int length = un_canonicalize.get(lower, '\0', uncanon);
@@ -1551,13 +1615,13 @@
}
-static void TestRangeCaseIndependence(CharacterRange input,
+static void TestRangeCaseIndependence(Isolate* isolate, CharacterRange input,
Vector<CharacterRange> expected) {
- Zone zone(CcTest::i_isolate());
+ Zone zone;
int count = expected.length();
ZoneList<CharacterRange>* list =
new(&zone) ZoneList<CharacterRange>(count, &zone);
- input.AddCaseEquivalents(list, false, &zone);
+ input.AddCaseEquivalents(isolate, &zone, list, false);
CHECK_EQ(count, list->length());
for (int i = 0; i < list->length(); i++) {
CHECK_EQ(expected[i].from(), list->at(i).from());
@@ -1566,39 +1630,41 @@
}
-static void TestSimpleRangeCaseIndependence(CharacterRange input,
+static void TestSimpleRangeCaseIndependence(Isolate* isolate,
+ CharacterRange input,
CharacterRange expected) {
EmbeddedVector<CharacterRange, 1> vector;
vector[0] = expected;
- TestRangeCaseIndependence(input, vector);
+ TestRangeCaseIndependence(isolate, input, vector);
}
TEST(CharacterRangeCaseIndependence) {
- TestSimpleRangeCaseIndependence(CharacterRange::Singleton('a'),
+ Isolate* isolate = CcTest::i_isolate();
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange::Singleton('a'),
CharacterRange::Singleton('A'));
- TestSimpleRangeCaseIndependence(CharacterRange::Singleton('z'),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange::Singleton('z'),
CharacterRange::Singleton('Z'));
- TestSimpleRangeCaseIndependence(CharacterRange('a', 'z'),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('a', 'z'),
CharacterRange('A', 'Z'));
- TestSimpleRangeCaseIndependence(CharacterRange('c', 'f'),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('c', 'f'),
CharacterRange('C', 'F'));
- TestSimpleRangeCaseIndependence(CharacterRange('a', 'b'),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('a', 'b'),
CharacterRange('A', 'B'));
- TestSimpleRangeCaseIndependence(CharacterRange('y', 'z'),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('y', 'z'),
CharacterRange('Y', 'Z'));
- TestSimpleRangeCaseIndependence(CharacterRange('a' - 1, 'z' + 1),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('a' - 1, 'z' + 1),
CharacterRange('A', 'Z'));
- TestSimpleRangeCaseIndependence(CharacterRange('A', 'Z'),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('A', 'Z'),
CharacterRange('a', 'z'));
- TestSimpleRangeCaseIndependence(CharacterRange('C', 'F'),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('C', 'F'),
CharacterRange('c', 'f'));
- TestSimpleRangeCaseIndependence(CharacterRange('A' - 1, 'Z' + 1),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('A' - 1, 'Z' + 1),
CharacterRange('a', 'z'));
// Here we need to add [l-z] to complete the case independence of
// [A-Za-z] but we expect [a-z] to be added since we always add a
// whole block at a time.
- TestSimpleRangeCaseIndependence(CharacterRange('A', 'k'),
+ TestSimpleRangeCaseIndependence(isolate, CharacterRange('A', 'k'),
CharacterRange('a', 'z'));
}
@@ -1616,7 +1682,7 @@
TEST(CharClassDifference) {
- Zone zone(CcTest::i_isolate());
+ Zone zone;
ZoneList<CharacterRange>* base =
new(&zone) ZoneList<CharacterRange>(1, &zone);
base->Add(CharacterRange::Everything(), &zone);
@@ -1643,7 +1709,7 @@
TEST(CanonicalizeCharacterSets) {
- Zone zone(CcTest::i_isolate());
+ Zone zone;
ZoneList<CharacterRange>* list =
new(&zone) ZoneList<CharacterRange>(4, &zone);
CharacterSet set(list);
@@ -1652,26 +1718,26 @@
list->Add(CharacterRange(30, 40), &zone);
list->Add(CharacterRange(50, 60), &zone);
set.Canonicalize();
- DCHECK_EQ(3, list->length());
- DCHECK_EQ(10, list->at(0).from());
- DCHECK_EQ(20, list->at(0).to());
- DCHECK_EQ(30, list->at(1).from());
- DCHECK_EQ(40, list->at(1).to());
- DCHECK_EQ(50, list->at(2).from());
- DCHECK_EQ(60, list->at(2).to());
+ CHECK_EQ(3, list->length());
+ CHECK_EQ(10, list->at(0).from());
+ CHECK_EQ(20, list->at(0).to());
+ CHECK_EQ(30, list->at(1).from());
+ CHECK_EQ(40, list->at(1).to());
+ CHECK_EQ(50, list->at(2).from());
+ CHECK_EQ(60, list->at(2).to());
list->Rewind(0);
list->Add(CharacterRange(10, 20), &zone);
list->Add(CharacterRange(50, 60), &zone);
list->Add(CharacterRange(30, 40), &zone);
set.Canonicalize();
- DCHECK_EQ(3, list->length());
- DCHECK_EQ(10, list->at(0).from());
- DCHECK_EQ(20, list->at(0).to());
- DCHECK_EQ(30, list->at(1).from());
- DCHECK_EQ(40, list->at(1).to());
- DCHECK_EQ(50, list->at(2).from());
- DCHECK_EQ(60, list->at(2).to());
+ CHECK_EQ(3, list->length());
+ CHECK_EQ(10, list->at(0).from());
+ CHECK_EQ(20, list->at(0).to());
+ CHECK_EQ(30, list->at(1).from());
+ CHECK_EQ(40, list->at(1).to());
+ CHECK_EQ(50, list->at(2).from());
+ CHECK_EQ(60, list->at(2).to());
list->Rewind(0);
list->Add(CharacterRange(30, 40), &zone);
@@ -1680,31 +1746,31 @@
list->Add(CharacterRange(100, 100), &zone);
list->Add(CharacterRange(1, 1), &zone);
set.Canonicalize();
- DCHECK_EQ(5, list->length());
- DCHECK_EQ(1, list->at(0).from());
- DCHECK_EQ(1, list->at(0).to());
- DCHECK_EQ(10, list->at(1).from());
- DCHECK_EQ(20, list->at(1).to());
- DCHECK_EQ(25, list->at(2).from());
- DCHECK_EQ(25, list->at(2).to());
- DCHECK_EQ(30, list->at(3).from());
- DCHECK_EQ(40, list->at(3).to());
- DCHECK_EQ(100, list->at(4).from());
- DCHECK_EQ(100, list->at(4).to());
+ CHECK_EQ(5, list->length());
+ CHECK_EQ(1, list->at(0).from());
+ CHECK_EQ(1, list->at(0).to());
+ CHECK_EQ(10, list->at(1).from());
+ CHECK_EQ(20, list->at(1).to());
+ CHECK_EQ(25, list->at(2).from());
+ CHECK_EQ(25, list->at(2).to());
+ CHECK_EQ(30, list->at(3).from());
+ CHECK_EQ(40, list->at(3).to());
+ CHECK_EQ(100, list->at(4).from());
+ CHECK_EQ(100, list->at(4).to());
list->Rewind(0);
list->Add(CharacterRange(10, 19), &zone);
list->Add(CharacterRange(21, 30), &zone);
list->Add(CharacterRange(20, 20), &zone);
set.Canonicalize();
- DCHECK_EQ(1, list->length());
- DCHECK_EQ(10, list->at(0).from());
- DCHECK_EQ(30, list->at(0).to());
+ CHECK_EQ(1, list->length());
+ CHECK_EQ(10, list->at(0).from());
+ CHECK_EQ(30, list->at(0).to());
}
TEST(CharacterRangeMerge) {
- Zone zone(CcTest::i_isolate());
+ Zone zone;
ZoneList<CharacterRange> l1(4, &zone);
ZoneList<CharacterRange> l2(4, &zone);
// Create all combinations of intersections of ranges, both singletons and
@@ -1781,8 +1847,8 @@
offset += 9;
}
- DCHECK(CharacterRange::IsCanonical(&l1));
- DCHECK(CharacterRange::IsCanonical(&l2));
+ CHECK(CharacterRange::IsCanonical(&l1));
+ CHECK(CharacterRange::IsCanonical(&l2));
ZoneList<CharacterRange> first_only(4, &zone);
ZoneList<CharacterRange> second_only(4, &zone);
@@ -1793,3 +1859,82 @@
TEST(Graph) {
Execute("\\b\\w+\\b", false, true, true);
}
+
+
+namespace {
+
+int* global_use_counts = NULL;
+
+void MockUseCounterCallback(v8::Isolate* isolate,
+ v8::Isolate::UseCounterFeature feature) {
+ ++global_use_counts[feature];
+}
+}
+
+
+// Test that ES2015 RegExp compatibility fixes are in place, that they
+// are not overly broad, and the appropriate UseCounters are incremented
+TEST(UseCountRegExp) {
+ i::FLAG_harmony_regexps = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
+ global_use_counts = use_counts;
+ CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
+
+ // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it
+ v8::Local<v8::Value> resultSticky = CompileRun("RegExp.prototype.sticky");
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+ CHECK(resultSticky->IsUndefined());
+
+ // re.sticky has approriate value and doesn't touch UseCounter
+ v8::Local<v8::Value> resultReSticky = CompileRun("/a/.sticky");
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+ CHECK(resultReSticky->IsFalse());
+
+ // When the getter is caleld on another object, throw an exception
+ // and don't increment the UseCounter
+ v8::Local<v8::Value> resultStickyError = CompileRun(
+ "var exception;"
+ "try { "
+ " Object.getOwnPropertyDescriptor(RegExp.prototype, 'sticky')"
+ " .get.call(null);"
+ "} catch (e) {"
+ " exception = e;"
+ "}"
+ "exception");
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+ CHECK(resultStickyError->IsObject());
+
+ // RegExp.prototype.toString() returns '/(?:)/' as a compatibility fix;
+ // a UseCounter is incremented to track it.
+ v8::Local<v8::Value> resultToString =
+ CompileRun("RegExp.prototype.toString().length");
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+ CHECK(resultToString->IsInt32());
+ CHECK_EQ(6,
+ resultToString->Int32Value(isolate->GetCurrentContext()).FromJust());
+
+ // .toString() works on normal RegExps
+ v8::Local<v8::Value> resultReToString = CompileRun("/a/.toString().length");
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+ CHECK(resultReToString->IsInt32());
+ CHECK_EQ(
+ 3, resultReToString->Int32Value(isolate->GetCurrentContext()).FromJust());
+
+ // .toString() throws on non-RegExps that aren't RegExp.prototype
+ v8::Local<v8::Value> resultToStringError = CompileRun(
+ "var exception;"
+ "try { RegExp.prototype.toString.call(null) }"
+ "catch (e) { exception = e; }"
+ "exception");
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
+ CHECK(resultToStringError->IsObject());
+}