Minor bugfixes and optimizations.
Added command line debugger to D8 shell.
Fixed subtle bug that caused the wrong 'this' to be used when calling a caught function in a catch clause.
Inline array loads within loops directly in the code instead of
git-svn-id: http://v8.googlecode.com/svn/trunk@1031 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/test/cctest/SConscript b/test/cctest/SConscript
index c2a96f2..c70b07d 100644
--- a/test/cctest/SConscript
+++ b/test/cctest/SConscript
@@ -38,7 +38,7 @@
'test-ast.cc', 'test-heap.cc', 'test-utils.cc', 'test-compiler.cc',
'test-spaces.cc', 'test-mark-compact.cc', 'test-lock.cc',
'test-conversions.cc', 'test-strings.cc', 'test-serialize.cc',
- 'test-decls.cc', 'test-alloc.cc', 'test-regexp.cc'
+ 'test-decls.cc', 'test-alloc.cc', 'test-regexp.cc', 'test-threads.cc'
],
'arch:arm': ['test-assembler-arm.cc', 'test-disasm-arm.cc'],
'arch:ia32': ['test-assembler-ia32.cc', 'test-disasm-ia32.cc'],
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 0f6ceab..926272e 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -5094,6 +5094,12 @@
static int GetSurvivingGlobalObjectsCount() {
int count = 0;
+ // We need to collect all garbage twice to be sure that everything
+ // has been collected. This is because inline caches are cleared in
+ // the first garbage collection but some of the maps have already
+ // been marked at that point. Therefore some of the maps are not
+ // collected until the second garbage collection.
+ v8::internal::Heap::CollectAllGarbage();
v8::internal::Heap::CollectAllGarbage();
v8::internal::HeapIterator it;
while (it.has_next()) {
@@ -5114,10 +5120,6 @@
v8::V8::Initialize();
- // TODO(121): when running "cctest test-api", the initial count is 2,
- // after second GC, the counter drops to 1. Needs to figure out why
- // one GC is not enough to collect all garbage.
- GetSurvivingGlobalObjectsCount();
int count = GetSurvivingGlobalObjectsCount();
for (int i = 0; i < 5; i++) {
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 782bb11..19ced16 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -63,7 +63,7 @@
return output;
}
-static bool ParseEscapes(const char* input) {
+static bool CheckSimple(const char* input) {
V8::Initialize(NULL);
v8::HandleScope scope;
unibrow::Utf8InputBuffer<> buffer(input, strlen(input));
@@ -73,13 +73,39 @@
CHECK(v8::internal::ParseRegExp(&reader, false, &result));
CHECK(result.tree != NULL);
CHECK(result.error.is_null());
- return result.has_character_escapes;
+ return result.simple;
+}
+
+struct MinMaxPair {
+ int min_match;
+ int max_match;
+};
+
+static MinMaxPair CheckMinMaxMatch(const char* input) {
+ V8::Initialize(NULL);
+ v8::HandleScope scope;
+ unibrow::Utf8InputBuffer<> buffer(input, strlen(input));
+ ZoneScope zone_scope(DELETE_ON_EXIT);
+ FlatStringReader reader(CStrVector(input));
+ RegExpCompileData result;
+ CHECK(v8::internal::ParseRegExp(&reader, false, &result));
+ CHECK(result.tree != NULL);
+ CHECK(result.error.is_null());
+ int min_match = result.tree->min_match();
+ int max_match = result.tree->max_match();
+ MinMaxPair pair = { min_match, max_match };
+ return pair;
}
+
#define CHECK_PARSE_EQ(input, expected) CHECK_EQ(expected, *Parse(input))
-#define CHECK_ESCAPES(input, has_escapes) CHECK_EQ(has_escapes, \
- ParseEscapes(input));
+#define CHECK_SIMPLE(input, simple) CHECK_EQ(simple, CheckSimple(input));
+#define CHECK_MIN_MAX(input, min, max) \
+ { MinMaxPair min_max = CheckMinMaxMatch(input); \
+ CHECK_EQ(min, min_max.min_match); \
+ CHECK_EQ(max, min_max.max_match); \
+ }
TEST(Parser) {
V8::Initialize(NULL);
@@ -168,6 +194,11 @@
CHECK_PARSE_EQ("(a)\\1", "(: (^ 'a') (<- 1))");
CHECK_PARSE_EQ("(a\\1)", "(^ 'a')");
CHECK_PARSE_EQ("(\\1a)", "(^ 'a')");
+ CHECK_PARSE_EQ("(?=a)?a", "'a'");
+ CHECK_PARSE_EQ("(?=a){0,10}a", "'a'");
+ CHECK_PARSE_EQ("(?=a){1,10}a", "(: (-> + 'a') 'a')");
+ CHECK_PARSE_EQ("(?=a){9,10}a", "(: (-> + 'a') 'a')");
+ CHECK_PARSE_EQ("(?!a)?a", "'a'");
CHECK_PARSE_EQ("\\1(a)", "(^ 'a')");
CHECK_PARSE_EQ("(?!(a))\\1", "(-> - (^ 'a'))");
CHECK_PARSE_EQ("(?!\\1(a\\1)\\1)\\1", "(-> - (: (^ 'a') (<- 1)))");
@@ -186,47 +217,50 @@
CHECK_PARSE_EQ("\\u003z", "'u003z'");
CHECK_PARSE_EQ("foo[z]*", "(: 'foo' (# 0 - g [z]))");
- CHECK_ESCAPES("a", false);
- CHECK_ESCAPES("a|b", false);
- CHECK_ESCAPES("a\\n", true);
- CHECK_ESCAPES("^a", false);
- CHECK_ESCAPES("a$", false);
- CHECK_ESCAPES("a\\b!", false);
- CHECK_ESCAPES("a\\Bb", false);
- CHECK_ESCAPES("a*", false);
- CHECK_ESCAPES("a*?", false);
- CHECK_ESCAPES("a?", false);
- CHECK_ESCAPES("a??", false);
- CHECK_ESCAPES("a{0,1}?", false);
- CHECK_ESCAPES("a{1,1}?", false);
- CHECK_ESCAPES("a{1,2}?", false);
- CHECK_ESCAPES("a+?", false);
- CHECK_ESCAPES("(a)", false);
- CHECK_ESCAPES("(a)\\1", false);
- CHECK_ESCAPES("(\\1a)", false);
- CHECK_ESCAPES("\\1(a)", false);
- CHECK_ESCAPES("a\\s", false);
- CHECK_ESCAPES("a\\S", false);
- CHECK_ESCAPES("a\\d", false);
- CHECK_ESCAPES("a\\D", false);
- CHECK_ESCAPES("a\\w", false);
- CHECK_ESCAPES("a\\W", false);
- CHECK_ESCAPES("a.", false);
- CHECK_ESCAPES("a\\q", true);
- CHECK_ESCAPES("a[a]", false);
- CHECK_ESCAPES("a[^a]", false);
- CHECK_ESCAPES("a[a-z]", false);
- CHECK_ESCAPES("a[\\q]", false);
- CHECK_ESCAPES("a(?:b)", false);
- CHECK_ESCAPES("a(?=b)", false);
- CHECK_ESCAPES("a(?!b)", false);
- CHECK_ESCAPES("\\x60", true);
- CHECK_ESCAPES("\\u0060", true);
- CHECK_ESCAPES("\\cA", true);
- CHECK_ESCAPES("\\q", true);
- CHECK_ESCAPES("\\1112", true);
- CHECK_ESCAPES("\\0", true);
- CHECK_ESCAPES("(a)\\1", false);
+ CHECK_SIMPLE("a", true);
+ CHECK_SIMPLE("a|b", false);
+ CHECK_SIMPLE("a\\n", false);
+ CHECK_SIMPLE("^a", false);
+ CHECK_SIMPLE("a$", false);
+ CHECK_SIMPLE("a\\b!", false);
+ CHECK_SIMPLE("a\\Bb", false);
+ CHECK_SIMPLE("a*", false);
+ CHECK_SIMPLE("a*?", false);
+ CHECK_SIMPLE("a?", false);
+ CHECK_SIMPLE("a??", false);
+ CHECK_SIMPLE("a{0,1}?", false);
+ CHECK_SIMPLE("a{1,1}?", false);
+ CHECK_SIMPLE("a{1,2}?", false);
+ CHECK_SIMPLE("a+?", false);
+ CHECK_SIMPLE("(a)", false);
+ CHECK_SIMPLE("(a)\\1", false);
+ CHECK_SIMPLE("(\\1a)", false);
+ CHECK_SIMPLE("\\1(a)", false);
+ CHECK_SIMPLE("a\\s", false);
+ CHECK_SIMPLE("a\\S", false);
+ CHECK_SIMPLE("a\\d", false);
+ CHECK_SIMPLE("a\\D", false);
+ CHECK_SIMPLE("a\\w", false);
+ CHECK_SIMPLE("a\\W", false);
+ CHECK_SIMPLE("a.", false);
+ CHECK_SIMPLE("a\\q", false);
+ CHECK_SIMPLE("a[a]", false);
+ CHECK_SIMPLE("a[^a]", false);
+ CHECK_SIMPLE("a[a-z]", false);
+ CHECK_SIMPLE("a[\\q]", false);
+ CHECK_SIMPLE("a(?:b)", false);
+ CHECK_SIMPLE("a(?=b)", false);
+ CHECK_SIMPLE("a(?!b)", false);
+ CHECK_SIMPLE("\\x60", false);
+ CHECK_SIMPLE("\\u0060", false);
+ CHECK_SIMPLE("\\cA", false);
+ CHECK_SIMPLE("\\q", false);
+ CHECK_SIMPLE("\\1112", false);
+ CHECK_SIMPLE("\\0", false);
+ CHECK_SIMPLE("(a)\\1", false);
+ CHECK_SIMPLE("(?=a)?a", false);
+ CHECK_SIMPLE("(?!a)?a\\1", false);
+ CHECK_SIMPLE("(?:(?=a))a\\1", false);
CHECK_PARSE_EQ("a{}", "'a{}'");
CHECK_PARSE_EQ("a{,}", "'a{,}'");
@@ -244,6 +278,55 @@
CHECK_PARSE_EQ("{12z}", "'{12z}'");
CHECK_PARSE_EQ("{12,", "'{12,'");
CHECK_PARSE_EQ("{12,3b", "'{12,3b'");
+
+ CHECK_MIN_MAX("a", 1, 1);
+ CHECK_MIN_MAX("abc", 3, 3);
+ CHECK_MIN_MAX("a[bc]d", 3, 3);
+ CHECK_MIN_MAX("a|bc", 1, 2);
+ CHECK_MIN_MAX("ab|c", 1, 2);
+ CHECK_MIN_MAX("a||bc", 0, 2);
+ CHECK_MIN_MAX("|", 0, 0);
+ CHECK_MIN_MAX("(?:ab)", 2, 2);
+ CHECK_MIN_MAX("(?:ab|cde)", 2, 3);
+ 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", 4, 4);
+ CHECK_MIN_MAX("(ab|cde)\\1", 4, 6);
+ CHECK_MIN_MAX("(?:ab)?", 0, 2);
+ CHECK_MIN_MAX("(?:ab)*", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:ab)+", 2, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("a?", 0, 1);
+ CHECK_MIN_MAX("a*", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("a+", 1, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("a??", 0, 1);
+ CHECK_MIN_MAX("a*?", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("a+?", 1, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a?)?", 0, 1);
+ CHECK_MIN_MAX("(?:a*)?", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a+)?", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a?)+", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a*)+", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a+)+", 1, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a?)*", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a*)*", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a+)*", 0, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("a{0}", 0, 0);
+ CHECK_MIN_MAX("(?:a+){0}", 0, 0);
+ CHECK_MIN_MAX("(?:a+){0,0}", 0, 0);
+ CHECK_MIN_MAX("a*b", 1, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("a+b", 2, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("a*b|c", 1, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("a+b|c", 1, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:a{5,1000000}){3,1000000}", 15, RegExpTree::kInfinity);
+ CHECK_MIN_MAX("(?:ab){4,7}", 8, 14);
+ CHECK_MIN_MAX("a\\bc", 2, 2);
+ CHECK_MIN_MAX("a\\Bc", 2, 2);
+ CHECK_MIN_MAX("a\\sc", 3, 3);
+ CHECK_MIN_MAX("a\\Sc", 3, 3);
+ CHECK_MIN_MAX("a(?=b)c", 2, 2);
+ CHECK_MIN_MAX("a(?=bbb|bb)c", 2, 2);
+ CHECK_MIN_MAX("a(?!bbb|bb)c", 2, 2);
}
TEST(ParserRegression) {
@@ -567,12 +650,26 @@
#ifndef ARM // IA32 only tests.
-TEST(MacroAssemblerIA32Success) {
- V8::Initialize(NULL);
+class ContextInitializer {
+ public:
+ ContextInitializer() : env_(), scope_(), stack_guard_() {
+ env_ = v8::Context::New();
+ env_->Enter();
+ }
+ ~ContextInitializer() {
+ env_->Exit();
+ env_.Dispose();
+ }
+ private:
+ v8::Persistent<v8::Context> env_;
+ v8::HandleScope scope_;
+ v8::internal::StackGuard stack_guard_;
+};
- // regexp-macro-assembler-ia32 needs a handle scope to allocate
- // byte-arrays for constants.
- v8::HandleScope scope;
+
+TEST(MacroAssemblerIA32Success) {
+ v8::V8::Initialize();
+ ContextInitializer initializer;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4);
@@ -589,14 +686,15 @@
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length();
- bool success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- captures,
- true);
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ captures,
+ true);
- CHECK(success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
CHECK_EQ(-1, captures[0]);
CHECK_EQ(-1, captures[1]);
CHECK_EQ(-1, captures[2]);
@@ -605,11 +703,8 @@
TEST(MacroAssemblerIA32Simple) {
- V8::Initialize(NULL);
-
- // regexp-macro-assembler-ia32 needs a handle scope to allocate
- // byte-arrays for constants.
- v8::HandleScope scope;
+ v8::V8::Initialize();
+ ContextInitializer initializer;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4);
@@ -636,14 +731,15 @@
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length();
- bool success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- captures,
- true);
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ captures,
+ true);
- CHECK(success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
CHECK_EQ(0, captures[0]);
CHECK_EQ(3, captures[1]);
CHECK_EQ(-1, captures[2]);
@@ -655,23 +751,20 @@
start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
end_offset = start_offset + seq_input->length();
- success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- captures,
- true);
+ result = RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ captures,
+ true);
- CHECK(!success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::FAILURE, result);
}
TEST(MacroAssemblerIA32SimpleUC16) {
- V8::Initialize(NULL);
-
- // regexp-macro-assembler-ia32 needs a handle scope to allocate
- // byte-arrays for constants.
- v8::HandleScope scope;
+ v8::V8::Initialize();
+ ContextInitializer initializer;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::UC16, 4);
@@ -700,14 +793,15 @@
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length() * sizeof(uc16);
- bool success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- captures,
- true);
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ captures,
+ true);
- CHECK(success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
CHECK_EQ(0, captures[0]);
CHECK_EQ(3, captures[1]);
CHECK_EQ(-1, captures[2]);
@@ -720,23 +814,20 @@
start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
end_offset = start_offset + seq_input->length() * sizeof(uc16);
- success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- captures,
- true);
+ result = RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ captures,
+ true);
- CHECK(!success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::FAILURE, result);
}
TEST(MacroAssemblerIA32Backtrack) {
- V8::Initialize(NULL);
-
- // regexp-macro-assembler-ia32 needs a handle scope to allocate
- // byte-arrays for constants.
- v8::HandleScope scope;
+ v8::V8::Initialize();
+ ContextInitializer initializer;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0);
@@ -761,23 +852,21 @@
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length();
- bool success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- NULL,
- true);
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ NULL,
+ true);
- CHECK(!success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::FAILURE, result);
}
-TEST(MacroAssemblerIA32BackReference) {
- V8::Initialize(NULL);
-
- // regexp-macro-assembler-ia32 needs a handle scope to allocate
- // byte-arrays for constants.
- v8::HandleScope scope;
+TEST(MacroAssemblerIA32BackReferenceASCII) {
+ v8::V8::Initialize();
+ ContextInitializer initializer;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 3);
@@ -807,26 +896,75 @@
int end_offset = start_offset + seq_input->length();
int output[3];
- bool success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- output,
- true);
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ output,
+ true);
- CHECK(success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
CHECK_EQ(0, output[0]);
CHECK_EQ(2, output[1]);
CHECK_EQ(6, output[2]);
}
-TEST(MacroAssemblerIA32AtStart) {
- V8::Initialize(NULL);
+TEST(MacroAssemblerIA32BackReferenceUC16) {
+ v8::V8::Initialize();
+ ContextInitializer initializer;
- // regexp-macro-assembler-ia32 needs a handle scope to allocate
- // byte-arrays for constants.
- v8::HandleScope scope;
+ RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::UC16, 3);
+
+ m.WriteCurrentPositionToRegister(0, 0);
+ m.AdvanceCurrentPosition(2);
+ m.WriteCurrentPositionToRegister(1, 0);
+ Label nomatch;
+ m.CheckNotBackReference(0, &nomatch);
+ m.Fail();
+ m.Bind(&nomatch);
+ m.AdvanceCurrentPosition(2);
+ Label missing_match;
+ m.CheckNotBackReference(0, &missing_match);
+ m.WriteCurrentPositionToRegister(2, 0);
+ m.Succeed();
+ m.Bind(&missing_match);
+ m.Fail();
+
+ Handle<String> source = Factory::NewStringFromAscii(CStrVector("^(..)..\1"));
+ Handle<Object> code_object = m.GetCode(source);
+ Handle<Code> code = Handle<Code>::cast(code_object);
+
+ const uc16 input_data[6] = {'f', 0x2028, 'o', 'o', 'f', 0x2028};
+ Handle<String> input =
+ Factory::NewStringFromTwoByte(Vector<const uc16>(input_data, 6));
+ Handle<SeqTwoByteString> seq_input = Handle<SeqTwoByteString>::cast(input);
+ Address start_adr = seq_input->GetCharsAddress();
+
+ int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
+ int end_offset = start_offset + seq_input->length() * sizeof(input_data[0]);
+
+ int output[3];
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ output,
+ true);
+
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+ CHECK_EQ(0, output[0]);
+ CHECK_EQ(2, output[1]);
+ CHECK_EQ(6, output[2]);
+}
+
+
+
+TEST(MacroAssemblerIA32AtStart) {
+ v8::V8::Initialize();
+ ContextInitializer initializer;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0);
@@ -861,35 +999,33 @@
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length();
- bool success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- NULL,
- true);
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ NULL,
+ true);
- CHECK(success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
start_offset += 3;
- success = RegExpMacroAssemblerIA32::Execute(*code,
+ result = RegExpMacroAssemblerIA32::Execute(*code,
seq_input.location(),
start_offset,
end_offset,
NULL,
false);
- CHECK(success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
}
TEST(MacroAssemblerIA32BackRefNoCase) {
- V8::Initialize(NULL);
-
- // regexp-macro-assembler-ia32 needs a handle scope to allocate
- // byte-arrays for constants.
- v8::HandleScope scope;
+ v8::V8::Initialize();
+ ContextInitializer initializer;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4);
@@ -928,14 +1064,15 @@
int end_offset = start_offset + seq_input->length();
int output[4];
- bool success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- output,
- true);
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ output,
+ true);
- CHECK(success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
CHECK_EQ(0, output[0]);
CHECK_EQ(12, output[1]);
CHECK_EQ(0, output[2]);
@@ -945,11 +1082,8 @@
TEST(MacroAssemblerIA32Registers) {
- V8::Initialize(NULL);
-
- // regexp-macro-assembler-ia32 needs a handle scope to allocate
- // byte-arrays for constants.
- v8::HandleScope scope;
+ v8::V8::Initialize();
+ ContextInitializer initializer;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 5);
@@ -1031,14 +1165,15 @@
int end_offset = start_offset + seq_input->length();
int output[5];
- bool success = RegExpMacroAssemblerIA32::Execute(*code,
- seq_input.location(),
- start_offset,
- end_offset,
- output,
- true);
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ output,
+ true);
- CHECK(success);
+ CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
CHECK_EQ(0, output[0]);
CHECK_EQ(3, output[1]);
CHECK_EQ(6, output[2]);
@@ -1046,6 +1181,45 @@
CHECK_EQ(9, output[4]);
}
+
+TEST(MacroAssemblerIA32StackOverflow) {
+ v8::V8::Initialize();
+ ContextInitializer initializer;
+
+ RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0);
+
+ Label loop;
+ m.Bind(&loop);
+ m.PushBacktrack(&loop);
+ m.GoTo(&loop);
+
+ Handle<String> source =
+ Factory::NewStringFromAscii(CStrVector("<stack overflow test>"));
+ Handle<Object> code_object = m.GetCode(source);
+ Handle<Code> code = Handle<Code>::cast(code_object);
+
+ // String long enough for test (content doesn't matter).
+ Handle<String> input =
+ Factory::NewStringFromAscii(CStrVector("dummy"));
+ Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
+ Address start_adr = seq_input->GetCharsAddress();
+ int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
+ int end_offset = start_offset + seq_input->length();
+
+ RegExpMacroAssemblerIA32::Result result =
+ RegExpMacroAssemblerIA32::Execute(*code,
+ seq_input.location(),
+ start_offset,
+ end_offset,
+ NULL,
+ true);
+
+ CHECK_EQ(RegExpMacroAssemblerIA32::EXCEPTION, result);
+ CHECK(Top::has_pending_exception());
+ Top::clear_pending_exception();
+}
+
+
#endif // !defined ARM
TEST(AddInverseToTable) {
@@ -1292,5 +1466,5 @@
TEST(Graph) {
V8::Initialize(NULL);
- Execute("\\bboy\\b", false, true, true);
+ Execute("\\b\\w+\\b", false, true, true);
}