diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2011-12-05 16:29:01 -0800 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2011-12-05 16:29:01 -0800 |
commit | 21d081fd7f83aa168ea0bef0870c7f1fed410a63 (patch) | |
tree | 23a04eef49364b1cbee204a87fd0904be2430c2e /deps/v8/test/cctest/test-parsing.cc | |
parent | e90623edc2befb06602ff8c3e01809ba0a21d593 (diff) | |
download | node-new-21d081fd7f83aa168ea0bef0870c7f1fed410a63.tar.gz |
Upgrade V8 to 3.7.12
Diffstat (limited to 'deps/v8/test/cctest/test-parsing.cc')
-rwxr-xr-x | deps/v8/test/cctest/test-parsing.cc | 208 |
1 files changed, 193 insertions, 15 deletions
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc index f5aed96d7d..bd1e24e115 100755 --- a/deps/v8/test/cctest/test-parsing.cc +++ b/deps/v8/test/cctest/test-parsing.cc @@ -32,6 +32,7 @@ #include "v8.h" #include "cctest.h" +#include "compiler.h" #include "execution.h" #include "isolate.h" #include "parser.h" @@ -63,9 +64,9 @@ TEST(ScanKeywords) { CHECK(static_cast<int>(sizeof(buffer)) >= length); { i::Utf8ToUC16CharacterStream stream(keyword, length); - i::JavaScriptScanner scanner(&unicode_cache); + i::Scanner scanner(&unicode_cache); // The scanner should parse 'let' as Token::LET for this test. - scanner.SetHarmonyBlockScoping(true); + scanner.SetHarmonyScoping(true); scanner.Initialize(&stream); CHECK_EQ(key_token.token, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next()); @@ -73,7 +74,7 @@ TEST(ScanKeywords) { // Removing characters will make keyword matching fail. { i::Utf8ToUC16CharacterStream stream(keyword, length - 1); - i::JavaScriptScanner scanner(&unicode_cache); + i::Scanner scanner(&unicode_cache); scanner.Initialize(&stream); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next()); @@ -84,7 +85,7 @@ TEST(ScanKeywords) { memmove(buffer, keyword, length); buffer[length] = chars_to_append[j]; i::Utf8ToUC16CharacterStream stream(buffer, length + 1); - i::JavaScriptScanner scanner(&unicode_cache); + i::Scanner scanner(&unicode_cache); scanner.Initialize(&stream); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next()); @@ -94,7 +95,7 @@ TEST(ScanKeywords) { memmove(buffer, keyword, length); buffer[length - 1] = '_'; i::Utf8ToUC16CharacterStream stream(buffer, length); - i::JavaScriptScanner scanner(&unicode_cache); + i::Scanner scanner(&unicode_cache); scanner.Initialize(&stream); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next()); @@ -229,7 +230,7 @@ TEST(Preparsing) { CHECK_EQ(11, error_location.end_pos); // Should not crash. const char* message = pre_impl->BuildMessage(); - i::Vector<const char*> args = pre_impl->BuildArgs(); + i::Vector<const char*> args(pre_impl->BuildArgs()); CHECK_GT(strlen(message), 0); } @@ -257,13 +258,14 @@ TEST(StandAlonePreParser) { reinterpret_cast<const i::byte*>(program), static_cast<unsigned>(strlen(program))); i::CompleteParserRecorder log; - i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(i::Isolate::Current()->unicode_cache()); scanner.Initialize(&stream); + int flags = i::kAllowLazy | i::kAllowNativesSyntax; v8::preparser::PreParser::PreParseResult result = v8::preparser::PreParser::PreParseProgram(&scanner, &log, - true, + flags, stack_limit); CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result); i::ScriptDataImpl data(log.ExtractData()); @@ -272,6 +274,43 @@ TEST(StandAlonePreParser) { } +TEST(StandAlonePreParserNoNatives) { + v8::V8::Initialize(); + + int marker; + i::Isolate::Current()->stack_guard()->SetStackLimit( + reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); + + const char* programs[] = { + "%ArgleBargle(glop);", + "var x = %_IsSmi(42);", + NULL + }; + + uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit(); + for (int i = 0; programs[i]; i++) { + const char* program = programs[i]; + i::Utf8ToUC16CharacterStream stream( + reinterpret_cast<const i::byte*>(program), + static_cast<unsigned>(strlen(program))); + i::CompleteParserRecorder log; + i::Scanner scanner(i::Isolate::Current()->unicode_cache()); + scanner.Initialize(&stream); + + // Flags don't allow natives syntax. + v8::preparser::PreParser::PreParseResult result = + v8::preparser::PreParser::PreParseProgram(&scanner, + &log, + i::kAllowLazy, + stack_limit); + CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result); + i::ScriptDataImpl data(log.ExtractData()); + // Data contains syntax error. + CHECK(data.has_error()); + } +} + + TEST(RegressChromium62639) { v8::V8::Initialize(); @@ -310,10 +349,10 @@ TEST(Regress928) { "try { } catch (e) { var foo = function () { /* first */ } }" "var bar = function () { /* second */ }"; - i::Utf8ToUC16CharacterStream stream(reinterpret_cast<const i::byte*>(program), - static_cast<unsigned>(strlen(program))); - i::ScriptDataImpl* data = - i::ParserApi::PartialPreParse(&stream, NULL, false); + v8::HandleScope handles; + i::Handle<i::String> source( + FACTORY->NewStringFromAscii(i::CStrVector(program))); + i::ScriptDataImpl* data = i::ParserApi::PartialPreParse(source, NULL, false); CHECK(!data->HasError()); data->Initialize(); @@ -356,7 +395,7 @@ TEST(PreParseOverflow) { reinterpret_cast<const i::byte*>(*program), static_cast<unsigned>(kProgramSize)); i::CompleteParserRecorder log; - i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(i::Isolate::Current()->unicode_cache()); scanner.Initialize(&stream); @@ -574,7 +613,7 @@ void TestStreamScanner(i::UC16CharacterStream* stream, i::Token::Value* expected_tokens, int skip_pos = 0, // Zero means not skipping. int skip_to = 0) { - i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(i::Isolate::Current()->unicode_cache()); scanner.Initialize(stream); int i = 0; @@ -655,7 +694,7 @@ void TestScanRegExp(const char* re_source, const char* expected) { i::Utf8ToUC16CharacterStream stream( reinterpret_cast<const i::byte*>(re_source), static_cast<unsigned>(strlen(re_source))); - i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache()); + i::Scanner scanner(i::Isolate::Current()->unicode_cache()); scanner.Initialize(&stream); i::Token::Value start = scanner.peek(); @@ -706,3 +745,142 @@ TEST(RegExpScanning) { TestScanRegExp("/=/", "="); TestScanRegExp("/=?/", "=?"); } + + +TEST(ScopePositions) { + // Test the parser for correctly setting the start and end positions + // of a scope. We check the scope positions of exactly one scope + // nested in the global scope of a program. 'inner source' is the + // source code that determines the part of the source belonging + // to the nested scope. 'outer_prefix' and 'outer_suffix' are + // parts of the source that belong to the global scope. + struct SourceData { + const char* outer_prefix; + const char* inner_source; + const char* outer_suffix; + i::ScopeType scope_type; + i::LanguageMode language_mode; + }; + + const SourceData source_data[] = { + { " with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, + { " with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::CLASSIC_MODE }, + { " with ({}) ", "{\n" + " block;\n" + " }", "\n" + " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, + { " with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, + { " with ({}) ", "statement", "\n" + " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, + { " with ({})\n" + " ", "statement;", "\n" + " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, + { " try {} catch ", "(e) { block; }", " more;", + i::CATCH_SCOPE, i::CLASSIC_MODE }, + { " try {} catch ", "(e) { block; }", "; more;", + i::CATCH_SCOPE, i::CLASSIC_MODE }, + { " try {} catch ", "(e) {\n" + " block;\n" + " }", "\n" + " more;", i::CATCH_SCOPE, i::CLASSIC_MODE }, + { " try {} catch ", "(e) { block; }", " finally { block; } more;", + i::CATCH_SCOPE, i::CLASSIC_MODE }, + { " start;\n" + " ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " start;\n" + " ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " start;\n" + " ", "{\n" + " let block;\n" + " }", "\n" + " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " start;\n" + " function fun", "(a,b) { infunction; }", " more;", + i::FUNCTION_SCOPE, i::CLASSIC_MODE }, + { " start;\n" + " function fun", "(a,b) {\n" + " infunction;\n" + " }", "\n" + " more;", i::FUNCTION_SCOPE, i::CLASSIC_MODE }, + { " (function fun", "(a,b) { infunction; }", ")();", + i::FUNCTION_SCOPE, i::CLASSIC_MODE }, + { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;", + i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;", + i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x = 1 ; x < 10; ++ x) {\n" + " block;\n" + " }", "\n" + " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;", + i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x = 1 ; x < 10; ++ x) statement", "\n" + " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x = 1 ; x < 10; ++ x)\n" + " statement;", "\n" + " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x in {}) { block; }", " more;", + i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x in {}) { block; }", "; more;", + i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x in {}) {\n" + " block;\n" + " }", "\n" + " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x in {}) statement;", " more;", + i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x in {}) statement", "\n" + " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { " for ", "(let x in {})\n" + " statement;", "\n" + " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, + { NULL, NULL, NULL, i::EVAL_SCOPE, i::CLASSIC_MODE } + }; + + v8::HandleScope handles; + v8::Persistent<v8::Context> context = v8::Context::New(); + v8::Context::Scope context_scope(context); + + int marker; + i::Isolate::Current()->stack_guard()->SetStackLimit( + reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); + i::FLAG_harmony_scoping = true; + + for (int i = 0; source_data[i].outer_prefix; i++) { + int kPrefixLen = i::StrLength(source_data[i].outer_prefix); + int kInnerLen = i::StrLength(source_data[i].inner_source); + int kSuffixLen = i::StrLength(source_data[i].outer_suffix); + int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen; + i::Vector<char> program = i::Vector<char>::New(kProgramSize + 1); + int length = i::OS::SNPrintF(program, "%s%s%s", + source_data[i].outer_prefix, + source_data[i].inner_source, + source_data[i].outer_suffix); + CHECK(length == kProgramSize); + + // Parse program source. + i::Handle<i::String> source( + FACTORY->NewStringFromAscii(i::CStrVector(program.start()))); + i::Handle<i::Script> script = FACTORY->NewScript(source); + i::Parser parser(script, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL); + i::CompilationInfo info(script); + info.MarkAsGlobal(); + info.SetLanguageMode(source_data[i].language_mode); + i::FunctionLiteral* function = parser.ParseProgram(&info); + CHECK(function != NULL); + + // Check scope types and positions. + i::Scope* scope = function->scope(); + CHECK(scope->is_global_scope()); + CHECK_EQ(scope->start_position(), 0); + CHECK_EQ(scope->end_position(), kProgramSize); + CHECK_EQ(scope->inner_scopes()->length(), 1); + + i::Scope* inner_scope = scope->inner_scopes()->at(0); + CHECK_EQ(inner_scope->type(), source_data[i].scope_type); + CHECK_EQ(inner_scope->start_position(), kPrefixLen); + // The end position of a token is one position after the last + // character belonging to that token. + CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen); + } +} |