ScriptData* ScriptData::PreCompile(const char* input, int length) {
i::Utf8ToUtf16CharacterStream stream(
reinterpret_cast<const unsigned char*>(input), length);
- return i::ParserApi::PreParse(&stream);
+ return i::PreParserApi::PreParse(&stream);
}
if (str->IsExternalTwoByteString()) {
i::ExternalTwoByteStringUtf16CharacterStream stream(
i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
- return i::ParserApi::PreParse(&stream);
+ return i::PreParserApi::PreParse(&stream);
} else {
i::GenericStringUtf16CharacterStream stream(str, 0, str->length());
- return i::ParserApi::PreParse(&stream);
+ return i::PreParserApi::PreParse(&stream);
}
}
// Only allow non-global compiles for eval.
ASSERT(info->is_eval() || info->is_global());
- ParsingFlags flags = kNoParsingFlags;
- if ((info->pre_parse_data() != NULL ||
- String::cast(script->source())->length() > FLAG_min_preparse_length) &&
- !DebuggerWantsEagerCompilation(info)) {
- flags = kAllowLazy;
- }
- if (!ParserApi::Parse(info, flags)) {
- return Handle<SharedFunctionInfo>::null();
+ {
+ Parser parser(info);
+ if ((info->pre_parse_data() != NULL ||
+ String::cast(script->source())->length() > FLAG_min_preparse_length) &&
+ !DebuggerWantsEagerCompilation(info))
+ parser.set_allow_lazy(true);
+ if (!parser.Parse()) {
+ return Handle<SharedFunctionInfo>::null();
+ }
}
// Measure how long it takes to do the compilation; only take the
if (InstallCodeFromOptimizedCodeMap(info)) return true;
// Generate the AST for the lazily compiled function.
- if (ParserApi::Parse(info, kNoParsingFlags)) {
+ if (Parser::Parse(info)) {
// Measure how long it takes to do the lazy compilation; only take the
// rest of the function into account to avoid overlap with the lazy
// parsing statistics.
return;
}
- if (ParserApi::Parse(*info, kNoParsingFlags)) {
+ if (Parser::Parse(*info)) {
LanguageMode language_mode = info->function()->language_mode();
info->SetLanguageMode(language_mode);
shared->set_language_mode(language_mode);
// Parse and allocate variables.
CompilationInfo target_info(target, zone());
Handle<SharedFunctionInfo> target_shared(target->shared());
- if (!ParserApi::Parse(&target_info, kNoParsingFlags) ||
- !Scope::Analyze(&target_info)) {
+ if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) {
if (target_info.isolate()->has_pending_exception()) {
// Parse or scope error, never optimize this function.
SetStackOverflow();
CompilationInfoWithZone info(script);
info.MarkAsGlobal();
// Parse and don't allow skipping lazy functions.
- if (ParserApi::Parse(&info, kNoParsingFlags)) {
+ if (Parser::Parse(&info)) {
// Compile the code.
LiveEditFunctionTracker tracker(info.isolate(), info.function());
if (Compiler::MakeCodeForLiveEdit(&info)) {
// ----------------------------------------------------------------------------
// Implementation of Parser
-Parser::Parser(CompilationInfo* info,
- int parser_flags,
- v8::Extension* extension,
- ScriptDataImpl* pre_data)
+Parser::Parser(CompilationInfo* info)
: isolate_(info->isolate()),
- symbol_cache_(pre_data ? pre_data->symbol_count() : 0, info->zone()),
+ symbol_cache_(0, info->zone()),
script_(info->script()),
scanner_(isolate_->unicode_cache()),
reusable_preparser_(NULL),
top_scope_(NULL),
current_function_state_(NULL),
target_stack_(NULL),
- extension_(extension),
- pre_data_(pre_data),
+ extension_(info->extension()),
+ pre_parse_data_(NULL),
fni_(NULL),
- allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0),
- allow_lazy_((parser_flags & kAllowLazy) != 0),
- allow_modules_((parser_flags & kAllowModules) != 0),
+ allow_natives_syntax_(false),
+ allow_lazy_(false),
+ allow_generators_(false),
stack_overflow_(false),
parenthesized_function_(false),
zone_(info->zone()),
info_(info) {
ASSERT(!script_.is_null());
isolate_->set_ast_node_id(0);
- if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) {
- scanner().SetHarmonyScoping(true);
- }
- if ((parser_flags & kAllowModules) != 0) {
- scanner().SetHarmonyModules(true);
- }
+ set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
+ set_allow_modules(!info->is_native() && FLAG_harmony_modules);
+ set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
+ set_allow_lazy(false); // Must be explicitly enabled.
+ set_allow_generators(FLAG_harmony_generators);
}
ZoneScope* zone_scope) {
ASSERT(top_scope_ == NULL);
ASSERT(target_stack_ == NULL);
- if (pre_data_ != NULL) pre_data_->Initialize();
+ if (pre_parse_data_ != NULL) pre_parse_data_->Initialize();
Handle<String> no_name = isolate()->factory()->empty_string();
scope->set_end_position(source->length());
// Compute the parsing mode.
- Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
- if (allow_natives_syntax_ || extension_ != NULL || scope->is_eval_scope()) {
+ Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
+ if (allow_natives_syntax() ||
+ extension_ != NULL ||
+ scope->is_eval_scope()) {
mode = PARSE_EAGERLY;
}
ParsingModeScope parsing_mode(this, mode);
Handle<String> Parser::GetSymbol(bool* ok) {
int symbol_id = -1;
- if (pre_data() != NULL) {
- symbol_id = pre_data()->GetSymbolIdentifier();
+ if (pre_parse_data() != NULL) {
+ symbol_id = pre_parse_data()->GetSymbolIdentifier();
}
return LookupSymbol(symbol_id);
}
mode_ = PARSE_EAGERLY;
}
// TODO(ES6): Fix entering extended mode, once it is specified.
- top_scope_->SetLanguageMode(FLAG_harmony_scoping
+ top_scope_->SetLanguageMode(allow_harmony_scoping()
? EXTENDED_MODE : STRICT_MODE);
// "use strict" is the only directive for now.
directive_prologue = false;
// '{' FunctionBody '}'
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
- bool is_generator = FLAG_harmony_generators && Check(Token::MUL);
+ bool is_generator = allow_generators() && Check(Token::MUL);
bool is_strict_reserved = false;
Handle<String> name = ParseIdentifierOrStrictReservedWord(
&is_strict_reserved, CHECK_OK);
if (peek() == Token::FUNCTION) {
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
- bool is_generator = FLAG_harmony_generators && Check(Token::MUL);
+ bool is_generator = allow_generators() && Check(Token::MUL);
Handle<String> name;
bool is_strict_reserved_name = false;
if (peek_any_identifier()) {
break;
case Token::MOD:
- if (allow_natives_syntax_ || extension_ != NULL) {
+ if (allow_natives_syntax() || extension_ != NULL) {
result = ParseV8Intrinsic(CHECK_OK);
break;
}
if (is_lazily_compiled) {
int function_block_pos = scanner().location().beg_pos;
FunctionEntry entry;
- if (pre_data_ != NULL) {
- // If we have pre_data_, we use it to skip parsing the function body.
- // the preparser data contains the information we need to construct the
- // lazy function.
- entry = pre_data()->GetFunctionEntry(function_block_pos);
+ if (pre_parse_data_ != NULL) {
+ // If we have pre_parse_data_, we use it to skip parsing the function
+ // body. The preparser data contains the information we need to
+ // construct the lazy function.
+ entry = pre_parse_data()->GetFunctionEntry(function_block_pos);
if (entry.is_valid()) {
if (entry.end_pos() <= function_block_pos) {
// End position greater than end of stream is safe, and hard
if (reusable_preparser_ == NULL) {
intptr_t stack_limit = isolate()->stack_guard()->real_climit();
- bool do_allow_lazy = true;
reusable_preparser_ = new preparser::PreParser(&scanner_,
NULL,
- stack_limit,
- do_allow_lazy,
- allow_natives_syntax_,
- allow_modules_,
- FLAG_harmony_generators);
+ stack_limit);
+ reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
+ reusable_preparser_->set_allow_modules(allow_modules());
+ reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
+ reusable_preparser_->set_allow_lazy(true);
+ reusable_preparser_->set_allow_generators(allow_generators());
}
preparser::PreParser::PreParseResult result =
reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
// Create a Scanner for the preparser to use as input, and preparse the source.
-static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source,
- int flags,
- ParserRecorder* recorder) {
+ScriptDataImpl* PreParserApi::PreParse(Utf16CharacterStream* source) {
+ CompleteParserRecorder recorder;
Isolate* isolate = Isolate::Current();
HistogramTimerScope timer(isolate->counters()->pre_parse());
Scanner scanner(isolate->unicode_cache());
- scanner.SetHarmonyScoping(FLAG_harmony_scoping);
- scanner.Initialize(source);
intptr_t stack_limit = isolate->stack_guard()->real_climit();
- preparser::PreParser::PreParseResult result =
- preparser::PreParser::PreParseProgram(&scanner,
- recorder,
- flags,
- stack_limit);
+ preparser::PreParser preparser(&scanner, &recorder, stack_limit);
+ preparser.set_allow_lazy(true);
+ preparser.set_allow_generators(FLAG_harmony_generators);
+ preparser.set_allow_harmony_scoping(FLAG_harmony_scoping);
+ scanner.Initialize(source);
+ preparser::PreParser::PreParseResult result = preparser.PreParseProgram();
if (result == preparser::PreParser::kPreParseStackOverflow) {
isolate->StackOverflow();
return NULL;
// Extract the accumulated data from the recorder as a single
// contiguous vector that we are responsible for disposing.
- Vector<unsigned> store = recorder->ExtractData();
+ Vector<unsigned> store = recorder.ExtractData();
return new ScriptDataImpl(store);
}
-ScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source) {
- int flags = kNoParsingFlags;
- if (FLAG_lazy) {
- flags |= kAllowLazy;
- }
- if (FLAG_harmony_generators) {
- flags |= kAllowGenerators;
- }
- CompleteParserRecorder recorder;
- return DoPreParse(source, flags, &recorder);
-}
-
-
bool RegExpParser::ParseRegExp(FlatStringReader* input,
bool multiline,
RegExpCompileData* result,
}
-bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
- ASSERT(info->function() == NULL);
+bool Parser::Parse() {
+ ASSERT(info()->function() == NULL);
FunctionLiteral* result = NULL;
- ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE);
- if (!info->is_native() && FLAG_harmony_scoping) {
- // Harmony scoping is requested.
- parsing_flags |= EXTENDED_MODE;
- }
- if (!info->is_native() && FLAG_harmony_modules) {
- parsing_flags |= kAllowModules;
- }
- if (FLAG_allow_natives_syntax || info->is_native()) {
- // We require %identifier(..) syntax.
- parsing_flags |= kAllowNativesSyntax;
- }
- if (info->is_lazy()) {
- ASSERT(!info->is_eval());
- Parser parser(info, parsing_flags, NULL, NULL);
- if (info->shared_info()->is_function()) {
- result = parser.ParseLazy();
+ if (info()->is_lazy()) {
+ ASSERT(!info()->is_eval());
+ if (info()->shared_info()->is_function()) {
+ result = ParseLazy();
} else {
- result = parser.ParseProgram();
+ result = ParseProgram();
}
} else {
- ScriptDataImpl* pre_data = info->pre_parse_data();
- Parser parser(info, parsing_flags, info->extension(), pre_data);
- if (pre_data != NULL && pre_data->has_error()) {
- Scanner::Location loc = pre_data->MessageLocation();
- const char* message = pre_data->BuildMessage();
- Vector<const char*> args = pre_data->BuildArgs();
- parser.ReportMessageAt(loc, message, args);
+ ScriptDataImpl* pre_parse_data = info()->pre_parse_data();
+ set_pre_parse_data(pre_parse_data);
+ if (pre_parse_data != NULL && pre_parse_data->has_error()) {
+ Scanner::Location loc = pre_parse_data->MessageLocation();
+ const char* message = pre_parse_data->BuildMessage();
+ Vector<const char*> args = pre_parse_data->BuildArgs();
+ ReportMessageAt(loc, message, args);
DeleteArray(message);
for (int i = 0; i < args.length(); i++) {
DeleteArray(args[i]);
}
DeleteArray(args.start());
- ASSERT(info->isolate()->has_pending_exception());
+ ASSERT(info()->isolate()->has_pending_exception());
} else {
- result = parser.ParseProgram();
+ result = ParseProgram();
}
}
- info->SetFunction(result);
+ info()->SetFunction(result);
return (result != NULL);
}
};
-class ParserApi {
+class PreParserApi {
public:
- // Parses the source code represented by the compilation info and sets its
- // function literal. Returns false (and deallocates any allocated AST
- // nodes) if parsing failed.
- static bool Parse(CompilationInfo* info, int flags);
-
- // Generic preparser generating full preparse data.
+ // Pre-parse a character stream and return full preparse data.
+ //
+ // This interface is here instead of in preparser.h because it instantiates a
+ // preparser recorder object that is suited to the parser's purposes. Also,
+ // the preparser doesn't know about ScriptDataImpl.
static ScriptDataImpl* PreParse(Utf16CharacterStream* source);
};
+
// ----------------------------------------------------------------------------
// REGEXP PARSING
class Parser {
public:
- Parser(CompilationInfo* info,
- int parsing_flags, // Combination of ParsingFlags
- v8::Extension* extension,
- ScriptDataImpl* pre_data);
+ explicit Parser(CompilationInfo* info);
virtual ~Parser() {
delete reusable_preparser_;
reusable_preparser_ = NULL;
}
+ bool allow_natives_syntax() const { return allow_natives_syntax_; }
+ bool allow_lazy() const { return allow_lazy_; }
+ bool allow_modules() { return scanner().HarmonyModules(); }
+ bool allow_harmony_scoping() { return scanner().HarmonyScoping(); }
+ bool allow_generators() const { return allow_generators_; }
+
+ void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
+ void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
+ void set_allow_modules(bool allow) { scanner().SetHarmonyModules(allow); }
+ void set_allow_harmony_scoping(bool allow) {
+ scanner().SetHarmonyScoping(allow);
+ }
+ void set_allow_generators(bool allow) { allow_generators_ = allow; }
+
+ // Parses the source code represented by the compilation info and sets its
+ // function literal. Returns false (and deallocates any allocated AST
+ // nodes) if parsing failed.
+ static bool Parse(CompilationInfo* info) { return Parser(info).Parse(); }
+ bool Parse();
+
// Returns NULL if parsing failed.
FunctionLiteral* ParseProgram();
- FunctionLiteral* ParseLazy();
void ReportMessageAt(Scanner::Location loc,
const char* message,
Mode old_mode_;
};
+ FunctionLiteral* ParseLazy();
FunctionLiteral* ParseLazy(Utf16CharacterStream* source,
ZoneScope* zone_scope);
void ReportMessage(const char* message, Vector<const char*> args);
void ReportMessage(const char* message, Vector<Handle<String> > args);
+ void set_pre_parse_data(ScriptDataImpl *data) {
+ pre_parse_data_ = data;
+ symbol_cache_.Initialize(data ? data->symbol_count() : 0, zone());
+ }
+
bool inside_with() const { return top_scope_->inside_with(); }
Scanner& scanner() { return scanner_; }
Mode mode() const { return mode_; }
- ScriptDataImpl* pre_data() const { return pre_data_; }
+ ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
bool is_extended_mode() {
ASSERT(top_scope_ != NULL);
return top_scope_->is_extended_mode();
FunctionState* current_function_state_;
Target* target_stack_; // for break, continue statements
v8::Extension* extension_;
- ScriptDataImpl* pre_data_;
+ ScriptDataImpl* pre_parse_data_;
FuncNameInferrer* fni_;
Mode mode_;
bool allow_natives_syntax_;
bool allow_lazy_;
- bool allow_modules_;
+ bool allow_generators_;
bool stack_overflow_;
// If true, the next (and immediately following) function literal is
// preceded by a parenthesis.
internal::Scanner scanner(&unicode_cache);
scanner.Initialize(&buffer);
internal::CompleteParserRecorder recorder;
- preparser::PreParser::PreParseResult result =
- preparser::PreParser::PreParseProgram(&scanner,
- &recorder,
- internal::kAllowLazy,
- stack_limit);
+ preparser::PreParser preparser(&scanner, &recorder, stack_limit);
+ preparser.set_allow_lazy(true);
+ preparser::PreParser::PreParseResult result = preparser.PreParseProgram();
if (result == preparser::PreParser::kPreParseStackOverflow) {
return PreParserData::StackOverflow();
}
Statement statement = ParseSourceElement(CHECK_OK);
if (allow_directive_prologue) {
if (statement.IsUseStrictLiteral()) {
- set_language_mode(harmony_scoping_ ?
+ set_language_mode(allow_harmony_scoping() ?
i::EXTENDED_MODE : i::STRICT_MODE);
} else if (!statement.IsStringLiteral()) {
allow_directive_prologue = false;
PreParser(i::Scanner* scanner,
i::ParserRecorder* log,
- uintptr_t stack_limit,
- bool allow_lazy,
- bool allow_natives_syntax,
- bool allow_modules,
- bool allow_generators)
+ uintptr_t stack_limit)
: scanner_(scanner),
log_(log),
scope_(NULL),
strict_mode_violation_location_(i::Scanner::Location::invalid()),
strict_mode_violation_type_(NULL),
stack_overflow_(false),
- allow_lazy_(allow_lazy),
- allow_modules_(allow_modules),
- allow_natives_syntax_(allow_natives_syntax),
- allow_generators_(allow_generators),
- parenthesized_function_(false),
- harmony_scoping_(scanner->HarmonyScoping()) { }
+ allow_lazy_(false),
+ allow_natives_syntax_(false),
+ allow_generators_(false),
+ parenthesized_function_(false) { }
~PreParser() {}
+ bool allow_natives_syntax() const { return allow_natives_syntax_; }
+ bool allow_lazy() const { return allow_lazy_; }
+ bool allow_modules() const { return scanner_->HarmonyModules(); }
+ bool allow_harmony_scoping() const { return scanner_->HarmonyScoping(); }
+ bool allow_generators() const { return allow_generators_; }
+
+ void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
+ void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
+ void set_allow_modules(bool allow) { scanner_->SetHarmonyModules(allow); }
+ void set_allow_harmony_scoping(bool allow) {
+ scanner_->SetHarmonyScoping(allow);
+ }
+ void set_allow_generators(bool allow) { allow_generators_ = allow; }
+
// Pre-parse the program from the character stream; returns true on
// success (even if parsing failed, the pre-parse data successfully
// captured the syntax error), and false if a stack-overflow happened
// during parsing.
- static PreParseResult PreParseProgram(i::Scanner* scanner,
- i::ParserRecorder* log,
- int flags,
- uintptr_t stack_limit) {
- bool allow_lazy = (flags & i::kAllowLazy) != 0;
- bool allow_natives_syntax = (flags & i::kAllowNativesSyntax) != 0;
- bool allow_modules = (flags & i::kAllowModules) != 0;
- bool allow_generators = (flags & i::kAllowGenerators) != 0;
- return PreParser(scanner, log, stack_limit, allow_lazy,
- allow_natives_syntax, allow_modules,
- allow_generators).PreParse();
+ PreParseResult PreParseProgram() {
+ Scope top_scope(&scope_, kTopLevelScope);
+ bool ok = true;
+ int start_position = scanner_->peek_location().beg_pos;
+ ParseSourceElements(i::Token::EOS, &ok);
+ if (stack_overflow_) return kPreParseStackOverflow;
+ if (!ok) {
+ ReportUnexpectedToken(scanner_->current_token());
+ } else if (!scope_->is_classic_mode()) {
+ CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok);
+ }
+ return kPreParseSuccess;
}
// Parses a single function literal, from the opening parentheses before
bool is_generator_;
};
- // Preparse the program. Only called in PreParseProgram after creating
- // the instance.
- PreParseResult PreParse() {
- Scope top_scope(&scope_, kTopLevelScope);
- bool ok = true;
- int start_position = scanner_->peek_location().beg_pos;
- ParseSourceElements(i::Token::EOS, &ok);
- if (stack_overflow_) return kPreParseStackOverflow;
- if (!ok) {
- ReportUnexpectedToken(scanner_->current_token());
- } else if (!scope_->is_classic_mode()) {
- CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok);
- }
- return kPreParseSuccess;
- }
-
// Report syntax error
void ReportUnexpectedToken(i::Token::Value token);
void ReportMessageAt(i::Scanner::Location location,
const char* strict_mode_violation_type_;
bool stack_overflow_;
bool allow_lazy_;
- bool allow_modules_;
bool allow_natives_syntax_;
bool allow_generators_;
bool parenthesized_function_;
- bool harmony_scoping_;
};
} } // v8::preparser
info.MarkAsEval();
info.SetContext(Handle<Context>(function_->context()));
}
- if (ParserApi::Parse(&info, kNoParsingFlags) && Scope::Analyze(&info)) {
+ if (Parser::Parse(&info) && Scope::Analyze(&info)) {
scope = info.function()->scope();
}
RetrieveScopeChain(scope, shared_info);
} else {
// Function code
CompilationInfoWithZone info(shared_info);
- if (ParserApi::Parse(&info, kNoParsingFlags) && Scope::Analyze(&info)) {
+ if (Parser::Parse(&info) && Scope::Analyze(&info)) {
scope = info.function()->scope();
}
RetrieveScopeChain(scope, shared_info);
namespace internal {
-// General collection of (multi-)bit-flags that can be passed to scanners and
-// parsers to signify their (initial) mode of operation.
-enum ParsingFlags {
- kNoParsingFlags = 0,
- // Embed LanguageMode values in parsing flags, i.e., equivalent to:
- // CLASSIC_MODE = 0,
- // STRICT_MODE,
- // EXTENDED_MODE,
- kLanguageModeMask = 0x03,
- kAllowLazy = 0x04,
- kAllowNativesSyntax = 0x08,
- kAllowModules = 0x10,
- kAllowGenerators = 0x20
-};
-
-STATIC_ASSERT((kLanguageModeMask & CLASSIC_MODE) == CLASSIC_MODE);
-STATIC_ASSERT((kLanguageModeMask & STRICT_MODE) == STRICT_MODE);
-STATIC_ASSERT((kLanguageModeMask & EXTENDED_MODE) == EXTENDED_MODE);
-
-
// Returns the value (0 .. 15) of a hexadecimal character c.
// If c is not a legal hexadecimal character, returns a value < 0.
inline int HexValue(uc32 c) {
i::Scanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
- int flags = i::kAllowLazy | i::kAllowNativesSyntax;
+ v8::preparser::PreParser preparser(&scanner, &log, stack_limit);
+ preparser.set_allow_lazy(true);
+ preparser.set_allow_natives_syntax(true);
v8::preparser::PreParser::PreParseResult result =
- v8::preparser::PreParser::PreParseProgram(&scanner,
- &log,
- flags,
- stack_limit);
+ preparser.PreParseProgram();
CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
i::ScriptDataImpl data(log.ExtractData());
CHECK(!data.has_error());
i::Scanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
- // Flags don't allow natives syntax.
+ // Preparser defaults to disallowing natives syntax.
+ v8::preparser::PreParser preparser(&scanner, &log, stack_limit);
+ preparser.set_allow_lazy(true);
v8::preparser::PreParser::PreParseResult result =
- v8::preparser::PreParser::PreParseProgram(&scanner,
- &log,
- i::kAllowLazy,
- stack_limit);
+ preparser.PreParseProgram();
CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
i::ScriptDataImpl data(log.ExtractData());
// Data contains syntax error.
i::Utf8ToUtf16CharacterStream stream(
reinterpret_cast<const i::byte*>(program),
static_cast<unsigned>(strlen(program)));
- i::ScriptDataImpl* data = i::ParserApi::PreParse(&stream);
+ i::ScriptDataImpl* data = i::PreParserApi::PreParse(&stream);
CHECK(data->HasError());
delete data;
}
i::Handle<i::String> source(
FACTORY->NewStringFromAscii(i::CStrVector(program)));
i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
- i::ScriptDataImpl* data = i::ParserApi::PreParse(&stream);
+ i::ScriptDataImpl* data = i::PreParserApi::PreParse(&stream);
CHECK(!data->HasError());
data->Initialize();
i::Scanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
-
+ v8::preparser::PreParser preparser(&scanner, &log, stack_limit);
+ preparser.set_allow_lazy(true);
v8::preparser::PreParser::PreParseResult result =
- v8::preparser::PreParser::PreParseProgram(&scanner,
- &log,
- true,
- stack_limit);
+ preparser.PreParseProgram();
CHECK_EQ(v8::preparser::PreParser::kPreParseStackOverflow, result);
}
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 = Utf8LengthHelper(source_data[i].outer_prefix);
CHECK_EQ(source->length(), kProgramSize);
i::Handle<i::Script> script = FACTORY->NewScript(source);
i::CompilationInfoWithZone info(script);
- i::Parser parser(&info, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL);
+ i::Parser parser(&info);
+ parser.set_allow_lazy(true);
+ parser.set_allow_harmony_scoping(true);
info.MarkAsGlobal();
info.SetLanguageMode(source_data[i].language_mode);
i::FunctionLiteral* function = parser.ParseProgram();
}
-void TestParserSync(i::Handle<i::String> source, int flags) {
+enum ParserFlag {
+ kAllowLazy,
+ kAllowNativesSyntax,
+ kAllowHarmonyScoping,
+ kAllowModules,
+ kAllowGenerators,
+ kParserFlagCount
+};
+
+
+static bool checkParserFlag(unsigned flags, ParserFlag flag) {
+ return flags & (1 << flag);
+}
+
+
+#define SET_PARSER_FLAGS(parser, flags) \
+ parser.set_allow_lazy(checkParserFlag(flags, kAllowLazy)); \
+ parser.set_allow_natives_syntax(checkParserFlag(flags, \
+ kAllowNativesSyntax)); \
+ parser.set_allow_harmony_scoping(checkParserFlag(flags, \
+ kAllowHarmonyScoping)); \
+ parser.set_allow_modules(checkParserFlag(flags, kAllowModules)); \
+ parser.set_allow_generators(checkParserFlag(flags, kAllowGenerators));
+
+void TestParserSyncWithFlags(i::Handle<i::String> source, unsigned flags) {
uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
- bool harmony_scoping = ((i::kLanguageModeMask & flags) == i::EXTENDED_MODE);
// Preparse the data.
i::CompleteParserRecorder log;
- i::Scanner scanner(i::Isolate::Current()->unicode_cache());
- i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
- scanner.SetHarmonyScoping(harmony_scoping);
- scanner.Initialize(&stream);
- v8::preparser::PreParser::PreParseResult result =
- v8::preparser::PreParser::PreParseProgram(
- &scanner, &log, flags, stack_limit);
- CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
+ {
+ i::Scanner scanner(i::Isolate::Current()->unicode_cache());
+ i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
+ v8::preparser::PreParser preparser(&scanner, &log, stack_limit);
+ SET_PARSER_FLAGS(preparser, flags);
+ scanner.Initialize(&stream);
+ v8::preparser::PreParser::PreParseResult result =
+ preparser.PreParseProgram();
+ CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
+ }
i::ScriptDataImpl data(log.ExtractData());
// Parse the data
- i::Handle<i::Script> script = FACTORY->NewScript(source);
- bool save_harmony_scoping = i::FLAG_harmony_scoping;
- i::FLAG_harmony_scoping = harmony_scoping;
- i::CompilationInfoWithZone info(script);
- i::Parser parser(&info, flags, NULL, NULL);
- info.MarkAsGlobal();
- i::FunctionLiteral* function = parser.ParseProgram();
- i::FLAG_harmony_scoping = save_harmony_scoping;
+ i::FunctionLiteral* function;
+ {
+ i::Handle<i::Script> script = FACTORY->NewScript(source);
+ i::CompilationInfoWithZone info(script);
+ i::Parser parser(&info);
+ SET_PARSER_FLAGS(parser, flags);
+ info.MarkAsGlobal();
+ function = parser.ParseProgram();
+ }
// Check that preparsing fails iff parsing fails.
if (function == NULL) {
}
-void TestParserSyncWithFlags(i::Handle<i::String> source) {
- static const int kFlagsCount = 6;
- const int flags[kFlagsCount] = {
- i::kNoParsingFlags | i::CLASSIC_MODE,
- i::kNoParsingFlags | i::STRICT_MODE,
- i::kNoParsingFlags | i::EXTENDED_MODE,
- i::kAllowLazy | i::CLASSIC_MODE,
- i::kAllowLazy | i::STRICT_MODE,
- i::kAllowLazy | i::EXTENDED_MODE
- };
-
- for (int k = 0; k < kFlagsCount; ++k) {
- TestParserSync(source, flags[k]);
+void TestParserSync(i::Handle<i::String> source) {
+ for (unsigned flags = 0; flags < (1 << kParserFlagCount); ++flags) {
+ TestParserSyncWithFlags(source, flags);
}
}
CHECK(length == kProgramSize);
i::Handle<i::String> source =
FACTORY->NewStringFromAscii(i::CStrVector(program.start()));
- TestParserSyncWithFlags(source);
+ TestParserSync(source);
}
}
}