7 #include "src/allocation.h" 8 #include "src/base/logging.h" 9 #include "src/conversions-inl.h" 10 #include "src/conversions.h" 11 #include "src/globals.h" 12 #include "src/parsing/parser-base.h" 13 #include "src/parsing/preparsed-scope-data.h" 14 #include "src/parsing/preparser.h" 16 #include "src/utils.h" 23 PreParserIdentifier GetSymbolHelper(Scanner* scanner,
24 const AstRawString*
string,
25 AstValueFactory* avf) {
30 switch (scanner->current_token()) {
32 return PreParserIdentifier::Await();
34 return PreParserIdentifier::Async();
35 case Token::PRIVATE_NAME:
36 return PreParserIdentifier::PrivateName();
40 if (
string == avf->constructor_string()) {
41 return PreParserIdentifier::Constructor();
43 if (
string == avf->name_string()) {
44 return PreParserIdentifier::Name();
46 if (scanner->literal_contains_escapes()) {
47 return PreParserIdentifier::Default();
49 if (
string == avf->eval_string()) {
50 return PreParserIdentifier::Eval();
52 if (
string == avf->arguments_string()) {
53 return PreParserIdentifier::Arguments();
55 return PreParserIdentifier::Default();
60 PreParserIdentifier PreParser::GetSymbol()
const {
61 const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
62 PreParserIdentifier symbol =
63 GetSymbolHelper(scanner(), result, ast_value_factory());
64 DCHECK_NOT_NULL(result);
65 symbol.string_ = result;
69 PreParser::PreParseResult PreParser::PreParseProgram() {
71 DeclarationScope* scope = NewScriptScope();
73 scope->set_is_being_lazily_parsed(
true);
79 if (parsing_module_) scope = NewModuleScope(scope);
81 FunctionState top_scope(&function_state_, &scope_, scope);
82 original_scope_ = scope_;
83 int start_position = peek_position();
84 PreParserScopedStatementList body(pointer_buffer());
85 ParseStatementList(&body, Token::EOS);
86 original_scope_ =
nullptr;
87 if (stack_overflow())
return kPreParseStackOverflow;
88 if (is_strict(language_mode())) {
89 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos);
91 return kPreParseSuccess;
94 PreParser::PreParseResult PreParser::PreParseFunction(
95 const AstRawString* function_name, FunctionKind kind,
96 FunctionLiteral::FunctionType function_type,
97 DeclarationScope* function_scope,
bool may_abort,
int* use_counts,
98 ProducedPreParsedScopeData** produced_preparsed_scope_data,
int script_id) {
99 DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
100 use_counts_ = use_counts;
101 set_script_id(script_id);
103 function_scope->set_is_being_lazily_parsed(
true);
108 std::unique_ptr<PreParsedScopeDataBuilder::DataGatheringScope>
109 preparsed_scope_data_builder_scope;
110 if (!IsArrowFunction(kind)) {
111 preparsed_scope_data_builder_scope.reset(
112 new PreParsedScopeDataBuilder::DataGatheringScope(function_scope,
119 ResetFunctionLiteralId();
124 DCHECK_NULL(function_state_);
126 FunctionState function_state(&function_state_, &scope_, function_scope);
128 PreParserFormalParameters formals(function_scope);
129 std::unique_ptr<ExpressionClassifier> formals_classifier;
133 if (!IsArrowFunction(kind)) {
134 formals_classifier.reset(
new ExpressionClassifier(
this));
137 ParseFormalParameterList(&formals);
138 Expect(Token::RPAREN);
139 int formals_end_position = scanner()->location().end_pos;
141 CheckArityRestrictions(formals.arity, kind, formals.has_rest,
142 function_scope->start_position(),
143 formals_end_position);
146 Expect(Token::LBRACE);
147 DeclarationScope* inner_scope = function_scope;
148 LazyParsingResult result;
150 if (!formals.is_simple) {
151 inner_scope = NewVarblockScope();
152 inner_scope->set_start_position(position());
156 BlockState block_state(&scope_, inner_scope);
157 result = ParseStatementListAndLogFunction(&formals, may_abort);
160 bool allow_duplicate_parameters =
false;
162 if (formals.is_simple) {
163 if (is_sloppy(function_scope->language_mode())) {
164 function_scope->HoistSloppyBlockFunctions(
nullptr);
167 allow_duplicate_parameters = is_sloppy(function_scope->language_mode()) &&
168 !IsConciseMethod(kind) &&
169 !IsArrowFunction(kind);
171 BuildParameterInitializationBlock(formals);
173 if (is_sloppy(inner_scope->language_mode())) {
174 inner_scope->HoistSloppyBlockFunctions(
nullptr);
177 SetLanguageMode(function_scope, inner_scope->language_mode());
178 inner_scope->set_end_position(scanner()->peek_location().end_pos);
179 inner_scope->FinalizeBlockScope();
182 use_counts_ =
nullptr;
184 if (stack_overflow()) {
185 return kPreParseStackOverflow;
186 }
else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
187 return kPreParseNotIdentifiableError;
188 }
else if (has_error()) {
189 DCHECK(pending_error_handler()->has_pending_error());
190 }
else if (result == kLazyParsingAborted) {
191 DCHECK(!pending_error_handler()->has_error_unidentifiable_by_preparser());
192 return kPreParseAbort;
194 DCHECK_EQ(Token::RBRACE, scanner()->peek());
195 DCHECK(result == kLazyParsingComplete);
197 if (!IsArrowFunction(kind)) {
200 ValidateFormalParameters(language_mode(), formals,
201 allow_duplicate_parameters);
203 if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
204 return kPreParseNotIdentifiableError;
206 return kPreParseSuccess;
214 function_scope->DeclareArguments(ast_value_factory());
216 DeclareFunctionNameVar(function_name, function_type, function_scope);
218 *produced_preparsed_scope_data = ProducedPreParsedScopeData::For(
219 preparsed_scope_data_builder_, main_zone());
222 if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
223 return kPreParseNotIdentifiableError;
226 if (is_strict(function_scope->language_mode())) {
227 int end_pos = scanner()->location().end_pos;
228 CheckStrictOctalLiteral(function_scope->start_position(), end_pos);
232 DCHECK(!pending_error_handler()->has_error_unidentifiable_by_preparser());
233 return kPreParseSuccess;
250 PreParser::Expression PreParser::ParseFunctionLiteral(
251 Identifier function_name, Scanner::Location function_name_location,
252 FunctionNameValidity function_name_validity, FunctionKind kind,
253 int function_token_pos, FunctionLiteral::FunctionType function_type,
254 LanguageMode language_mode,
255 ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
257 DCHECK_NULL(arguments_for_wrapped_function);
258 DCHECK_NE(FunctionLiteral::kWrapped, function_type);
261 const RuntimeCallCounterId counters[2] = {
262 RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
263 RuntimeCallCounterId::kPreParseWithVariableResolution};
264 RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
265 counters[parsing_on_main_thread_]);
267 base::ElapsedTimer timer;
268 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
270 DeclarationScope* function_scope = NewFunctionScope(kind);
271 function_scope->SetLanguageMode(language_mode);
272 int func_id = GetNextFunctionLiteralId();
273 bool skippable_function =
false;
278 std::unique_ptr<PreParsedScopeDataBuilder::DataGatheringScope>
279 preparsed_scope_data_builder_scope;
280 if (!function_state_->next_function_is_likely_called() &&
281 preparsed_scope_data_builder_ !=
nullptr) {
282 skippable_function =
true;
283 preparsed_scope_data_builder_scope.reset(
284 new PreParsedScopeDataBuilder::DataGatheringScope(function_scope,
288 FunctionState function_state(&function_state_, &scope_, function_scope);
289 ExpressionClassifier formals_classifier(
this);
291 Expect(Token::LPAREN);
292 int start_position = position();
293 function_scope->set_start_position(start_position);
294 PreParserFormalParameters formals(function_scope);
295 ParseFormalParameterList(&formals);
296 Expect(Token::RPAREN);
297 int formals_end_position = scanner()->location().end_pos;
299 CheckArityRestrictions(formals.arity, kind, formals.has_rest,
300 start_position, formals_end_position);
302 Expect(Token::LBRACE);
305 PreParserScopedStatementList body(pointer_buffer());
306 int pos = function_token_pos == kNoSourcePosition ? peek_position()
307 : function_token_pos;
308 AcceptINScope scope(
this,
true);
309 ParseFunctionBody(&body, function_name, pos, formals, kind, function_type,
310 FunctionBodyType::kBlock);
313 language_mode = function_scope->language_mode();
315 if (is_sloppy(language_mode)) {
316 function_scope->HoistSloppyBlockFunctions(
nullptr);
321 CheckFunctionName(language_mode, function_name, function_name_validity,
322 function_name_location);
324 if (is_strict(language_mode)) {
325 CheckStrictOctalLiteral(start_position, end_position());
329 if (skippable_function) {
330 preparsed_scope_data_builder_->AddSkippableFunction(
331 function_scope->start_position(), end_position(),
332 function_scope->num_parameters(), GetLastFunctionLiteralId() - func_id,
333 function_scope->language_mode(), function_scope->NeedsHomeObject());
336 if (V8_UNLIKELY(FLAG_log_function_events)) {
337 double ms = timer.Elapsed().InMillisecondsF();
338 const char* event_name =
"preparse-resolution";
341 const char* name =
"";
342 size_t name_byte_length = 0;
343 const AstRawString*
string = function_name.string_;
344 if (
string !=
nullptr) {
345 name =
reinterpret_cast<const char*
>(
string->raw_data());
346 name_byte_length =
string->byte_length();
348 logger_->FunctionEvent(
349 event_name, script_id(), ms, function_scope->start_position(),
350 function_scope->end_position(), name, name_byte_length);
353 return Expression::Default();
356 PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
357 PreParserFormalParameters* formals,
bool may_abort) {
358 PreParserScopedStatementList body(pointer_buffer());
359 LazyParsingResult result =
360 ParseStatementList(&body, Token::RBRACE, may_abort);
361 if (result == kLazyParsingAborted)
return result;
364 DCHECK_IMPLIES(!has_error(), scanner()->peek() == Token::RBRACE);
365 int body_end = scanner()->peek_location().end_pos;
366 DCHECK_EQ(this->scope()->is_function_scope(), formals->is_simple);
367 log_.LogFunction(body_end, formals->num_parameters(),
368 GetLastFunctionLiteralId());
369 return kLazyParsingComplete;
372 PreParserStatement PreParser::BuildParameterInitializationBlock(
373 const PreParserFormalParameters& parameters) {
374 DCHECK(!parameters.is_simple);
375 DCHECK(scope()->is_function_scope());
376 if (scope()->AsDeclarationScope()->calls_sloppy_eval() &&
377 preparsed_scope_data_builder_ !=
nullptr) {
381 if (preparsed_scope_data_builder_->parent() !=
nullptr) {
385 preparsed_scope_data_builder_->parent()->Bailout();
389 preparsed_scope_data_builder_->Bailout();
393 return PreParserStatement::Default();
396 bool PreParser::IdentifierEquals(
const PreParserIdentifier& identifier,
397 const AstRawString* other) {
398 return identifier.string_ == other;
401 PreParserExpression PreParser::ExpressionFromIdentifier(
402 const PreParserIdentifier& name,
int start_position, InferName infer) {
403 VariableProxy* proxy =
nullptr;
404 DCHECK_EQ(name.string_ ==
nullptr, has_error());
405 if (name.string_ ==
nullptr)
return PreParserExpression::Default();
406 proxy = scope()->NewUnresolved(factory()->ast_node_factory(), name.string_,
407 start_position, NORMAL_VARIABLE);
408 return PreParserExpression::FromIdentifier(name, proxy, zone());
411 void PreParser::DeclareAndInitializeVariables(
412 PreParserStatement block,
413 const DeclarationDescriptor* declaration_descriptor,
414 const DeclarationParsingResult::Declaration* declaration,
415 ZonePtrList<const AstRawString>* names) {
416 if (declaration->pattern.variables_ !=
nullptr) {
417 for (
auto variable : *(declaration->pattern.variables_)) {
418 declaration_descriptor->scope->DeleteUnresolved(variable);
419 Variable* var = scope()->DeclareVariableName(
420 variable->raw_name(), declaration_descriptor->mode);
421 MarkLoopVariableAsAssigned(declaration_descriptor->scope, var,
422 declaration_descriptor->declaration_kind);
427 names->Add(variable->raw_name(), zone());