V8 Project
v8::internal::Parser Class Reference

#include <parser.h>

+ Inheritance diagram for v8::internal::Parser:
+ Collaboration diagram for v8::internal::Parser:

Classes

struct  ParseInfo
 

Public Member Functions

 Parser (CompilationInfo *info, ParseInfo *parse_info)
 
 ~Parser ()
 
bool Parse ()
 
void ParseOnBackground ()
 
void Internalize ()
 
- Public Member Functions inherited from v8::internal::ParserBase< ParserTraits >
 ParserBase (Scanner *scanner, uintptr_t stack_limit, v8::Extension *extension, ParserRecorder *log, typename Traits::Type::Zone *zone, AstNode::IdGen *ast_node_id_gen, typename Traits::Type::Parser this_object)
 
bool allow_lazy () const
 
bool allow_natives_syntax () const
 
bool allow_arrow_functions () const
 
bool allow_modules () const
 
bool allow_harmony_scoping () const
 
bool allow_harmony_numeric_literals () const
 
bool allow_classes () const
 
bool allow_harmony_object_literals () const
 
void set_allow_lazy (bool allow)
 
void set_allow_natives_syntax (bool allow)
 
void set_allow_arrow_functions (bool allow)
 
void set_allow_modules (bool allow)
 
void set_allow_harmony_scoping (bool allow)
 
void set_allow_harmony_numeric_literals (bool allow)
 
void set_allow_classes (bool allow)
 
void set_allow_harmony_object_literals (bool allow)
 
- Public Member Functions inherited from v8::internal::ParserTraits
 ParserTraits (Parser *parser)
 
bool IsEvalOrArguments (const AstRawString *identifier) const
 
bool IsFutureStrictReserved (const AstRawString *identifier) const
 
bool IsPrototype (const AstRawString *identifier) const
 
bool IsConstructor (const AstRawString *identifier) const
 
void PushPropertyName (FuncNameInferrer *fni, Expression *expression)
 
void CheckPossibleEvalCall (Expression *expression, Scope *scope)
 
bool ShortcutNumericLiteralBinaryExpression (Expression **x, Expression *y, Token::Value op, int pos, AstNodeFactory< AstConstructionVisitor > *factory)
 
ExpressionBuildUnaryExpression (Expression *expression, Token::Value op, int pos, AstNodeFactory< AstConstructionVisitor > *factory)
 
ExpressionNewThrowReferenceError (const char *type, int pos)
 
ExpressionNewThrowSyntaxError (const char *type, const AstRawString *arg, int pos)
 
ExpressionNewThrowTypeError (const char *type, const AstRawString *arg, int pos)
 
ExpressionNewThrowError (const AstRawString *constructor, const char *type, const AstRawString *arg, int pos)
 
void ReportMessageAt (Scanner::Location source_location, const char *message, const char *arg=NULL, bool is_reference_error=false)
 
void ReportMessage (const char *message, const char *arg=NULL, bool is_reference_error=false)
 
void ReportMessage (const char *message, const AstRawString *arg, bool is_reference_error=false)
 
void ReportMessageAt (Scanner::Location source_location, const char *message, const AstRawString *arg, bool is_reference_error=false)
 
const AstRawStringEmptyIdentifierString ()
 
Literal * GetLiteralTheHole (int position, AstNodeFactory< AstConstructionVisitor > *factory)
 
const AstRawStringGetSymbol (Scanner *scanner)
 
const AstRawStringGetNextSymbol (Scanner *scanner)
 
const AstRawStringGetNumberAsSymbol (Scanner *scanner)
 
ExpressionThisExpression (Scope *scope, AstNodeFactory< AstConstructionVisitor > *factory, int pos=RelocInfo::kNoPosition)
 
ExpressionSuperReference (Scope *scope, AstNodeFactory< AstConstructionVisitor > *factory, int pos=RelocInfo::kNoPosition)
 
ExpressionClassLiteral (const AstRawString *name, Expression *extends, Expression *constructor, ZoneList< ObjectLiteral::Property * > *properties, int pos, AstNodeFactory< AstConstructionVisitor > *factory)
 
Literal * ExpressionFromLiteral (Token::Value token, int pos, Scanner *scanner, AstNodeFactory< AstConstructionVisitor > *factory)
 
ExpressionExpressionFromIdentifier (const AstRawString *name, int pos, Scope *scope, AstNodeFactory< AstConstructionVisitor > *factory)
 
ExpressionExpressionFromString (int pos, Scanner *scanner, AstNodeFactory< AstConstructionVisitor > *factory)
 
ExpressionGetIterator (Expression *iterable, AstNodeFactory< AstConstructionVisitor > *factory)
 
ZoneList< v8::internal::Expression * > * NewExpressionList (int size, Zone *zone)
 
ZoneList< ObjectLiteral::Property * > * NewPropertyList (int size, Zone *zone)
 
ZoneList< v8::internal::Statement * > * NewStatementList (int size, Zone *zone)
 
ScopeNewScope (Scope *parent_scope, ScopeType scope_type)
 
int DeclareArrowParametersFromExpression (Expression *expression, Scope *scope, Scanner::Location *dupe_loc, bool *ok)
 
AstValueFactoryast_value_factory ()
 
ExpressionParseV8Intrinsic (bool *ok)
 
FunctionLiteral * ParseFunctionLiteral (const AstRawString *name, Scanner::Location function_name_location, bool name_is_strict_reserved, FunctionKind kind, int function_token_position, FunctionLiteral::FunctionType type, FunctionLiteral::ArityRestriction arity_restriction, bool *ok)
 
void SkipLazyFunctionBody (const AstRawString *name, int *materialized_literal_count, int *expected_property_count, bool *ok)
 
ZoneList< Statement * > * ParseEagerFunctionBody (const AstRawString *name, int pos, Variable *fvar, Token::Value fvar_init_op, bool is_generator, bool *ok)
 
void CheckConflictingVarDeclarations (v8::internal::Scope *scope, bool *ok)
 

Static Public Member Functions

static bool Parse (CompilationInfo *info, bool allow_lazy=false)
 
- Static Public Member Functions inherited from v8::internal::ParserTraits
template<typename FunctionState >
static void SetUpFunctionState (FunctionState *function_state)
 
template<typename FunctionState >
static void TearDownFunctionState (FunctionState *function_state)
 
static bool IsThisProperty (Expression *expression)
 
static bool IsIdentifier (Expression *expression)
 
static const AstRawStringAsIdentifier (Expression *expression)
 
static bool IsBoilerplateProperty (ObjectLiteral::Property *property)
 
static bool IsArrayIndex (const AstRawString *string, uint32_t *index)
 
static void PushLiteralName (FuncNameInferrer *fni, const AstRawString *id)
 
static void InferFunctionName (FuncNameInferrer *fni, FunctionLiteral *func_to_infer)
 
static void CheckFunctionLiteralInsideTopLevelObjectLiteral (Scope *scope, ObjectLiteralProperty *property, bool *has_function)
 
static void CheckAssigningFunctionLiteralToProperty (Expression *left, Expression *right)
 
static ExpressionMarkExpressionAsAssigned (Expression *expression)
 
static const AstRawStringEmptyIdentifier ()
 
static ExpressionEmptyExpression ()
 
static ExpressionEmptyArrowParamList ()
 
static Literal * EmptyLiteral ()
 
static ObjectLiteralProperty * EmptyObjectLiteralProperty ()
 
static FunctionLiteral * EmptyFunctionLiteral ()
 
static ZoneList< Expression * > * NullExpressionList ()
 

Private Types

enum  VariableDeclarationContext { kModuleElement , kBlockElement , kStatement , kForStatement }
 
enum  VariableDeclarationProperties { kHasInitializers , kHasNoInitializers }
 

Private Member Functions

FunctionLiteral * ParseProgram ()
 
FunctionLiteral * ParseLazy ()
 
FunctionLiteral * ParseLazy (Utf16CharacterStream *source)
 
Isolateisolate ()
 
CompilationInfoinfo () const
 
Handle< Scriptscript () const
 
AstValueFactoryast_value_factory () const
 
FunctionLiteral * DoParseProgram (CompilationInfo *info, Scope **scope, Scope **ad_hoc_eval_scope)
 
void SetCachedData ()
 
bool inside_with () const
 
ScriptCompiler::CompileOptions compile_options () const
 
ScopeDeclarationScope (VariableMode mode)
 
void * ParseSourceElements (ZoneList< Statement * > *processor, int end_token, bool is_eval, bool is_global, Scope **ad_hoc_eval_scope, bool *ok)
 
StatementParseModuleElement (ZoneList< const AstRawString * > *labels, bool *ok)
 
StatementParseModuleDeclaration (ZoneList< const AstRawString * > *names, bool *ok)
 
ModuleParseModule (bool *ok)
 
ModuleParseModuleLiteral (bool *ok)
 
ModuleParseModulePath (bool *ok)
 
ModuleParseModuleVariable (bool *ok)
 
ModuleParseModuleUrl (bool *ok)
 
ModuleParseModuleSpecifier (bool *ok)
 
Block * ParseImportDeclaration (bool *ok)
 
StatementParseExportDeclaration (bool *ok)
 
StatementParseBlockElement (ZoneList< const AstRawString * > *labels, bool *ok)
 
StatementParseStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
StatementParseFunctionDeclaration (ZoneList< const AstRawString * > *names, bool *ok)
 
StatementParseClassDeclaration (ZoneList< const AstRawString * > *names, bool *ok)
 
StatementParseNativeDeclaration (bool *ok)
 
Block * ParseBlock (ZoneList< const AstRawString * > *labels, bool *ok)
 
Block * ParseVariableStatement (VariableDeclarationContext var_context, ZoneList< const AstRawString * > *names, bool *ok)
 
Block * ParseVariableDeclarations (VariableDeclarationContext var_context, VariableDeclarationProperties *decl_props, ZoneList< const AstRawString * > *names, const AstRawString **out, bool *ok)
 
StatementParseExpressionOrLabelledStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
IfStatement * ParseIfStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
StatementParseContinueStatement (bool *ok)
 
StatementParseBreakStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
StatementParseReturnStatement (bool *ok)
 
StatementParseWithStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
CaseClause * ParseCaseClause (bool *default_seen_ptr, bool *ok)
 
SwitchStatement * ParseSwitchStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
DoWhileStatement * ParseDoWhileStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
WhileStatement * ParseWhileStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
StatementParseForStatement (ZoneList< const AstRawString * > *labels, bool *ok)
 
StatementParseThrowStatement (bool *ok)
 
ExpressionMakeCatchContext (Handle< String > id, VariableProxy *value)
 
TryStatementParseTryStatement (bool *ok)
 
DebuggerStatement * ParseDebuggerStatement (bool *ok)
 
Block * ParseScopedBlock (ZoneList< const AstRawString * > *labels, bool *ok)
 
void InitializeForEachStatement (ForEachStatement *stmt, Expression *each, Expression *subject, Statement *body)
 
StatementDesugarLetBindingsInForStatement (Scope *inner_scope, ZoneList< const AstRawString * > *names, ForStatement *loop, Statement *init, Expression *cond, Statement *next, Statement *body, bool *ok)
 
FunctionLiteral * ParseFunctionLiteral (const AstRawString *name, Scanner::Location function_name_location, bool name_is_strict_reserved, FunctionKind kind, int function_token_position, FunctionLiteral::FunctionType type, FunctionLiteral::ArityRestriction arity_restriction, bool *ok)
 
ExpressionParseV8Intrinsic (bool *ok)
 
bool CheckInOrOf (bool accept_OF, ForEachStatement::VisitMode *visit_mode)
 
Literal * GetLiteralUndefined (int position)
 
void CheckConflictingVarDeclarations (Scope *scope, bool *ok)
 
VariableProxy * NewUnresolved (const AstRawString *name, VariableMode mode, Interface *interface)
 
void Declare (Declaration *declaration, bool resolve, bool *ok)
 
bool TargetStackContainsLabel (const AstRawString *label)
 
BreakableStatementLookupBreakTarget (const AstRawString *label, bool *ok)
 
IterationStatementLookupContinueTarget (const AstRawString *label, bool *ok)
 
void RegisterTargetUse (Label *target, Target *stop)
 
ScopeNewScope (Scope *parent, ScopeType type)
 
void SkipLazyFunctionBody (const AstRawString *function_name, int *materialized_literal_count, int *expected_property_count, bool *ok)
 
PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser (SingletonLogger *logger)
 
ZoneList< Statement * > * ParseEagerFunctionBody (const AstRawString *function_name, int pos, Variable *fvar, Token::Value fvar_init_op, bool is_generator, bool *ok)
 
void HandleSourceURLComments ()
 
void ThrowPendingError ()
 

Private Attributes

Scanner scanner_
 
PreParserreusable_preparser_
 
Scopeoriginal_scope_
 
Target * target_stack_
 
ParseDatacached_parse_data_
 
CompilationInfoinfo_
 
bool has_pending_error_
 
Scanner::Location pending_error_location_
 
const char * pending_error_message_
 
const AstRawStringpending_error_arg_
 
const char * pending_error_char_arg_
 
bool pending_error_is_reference_error_
 
int use_counts_ [v8::Isolate::kUseCounterFeatureCount]
 
int total_preparse_skipped_
 
HistogramTimerpre_parse_timer_
 

Static Private Attributes

static const int kMaxNumFunctionLocals = 4194303
 

Friends

class ParserTraits
 

Additional Inherited Members

- Public Types inherited from v8::internal::ParserBase< ParserTraits >
typedef Traits::Type::Expression ExpressionT
 
typedef Traits::Type::Identifier IdentifierT
 
typedef Traits::Type::FunctionLiteral FunctionLiteralT
 
typedef Traits::Type::Literal LiteralT
 
typedef Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT
 
- Protected Types inherited from v8::internal::ParserBase< ParserTraits >
enum  AllowEvalOrArgumentsAsIdentifier
 
enum  Mode
 
enum  PropertyKind
 
- Protected Member Functions inherited from v8::internal::ParserBase< ParserTraits >
Scannerscanner () const
 
int position ()
 
int peek_position ()
 
bool stack_overflow () const
 
void set_stack_overflow ()
 
Mode mode () const
 
Traits::Type::Zone * zone () const
 
AstNode::IdGenast_node_id_gen () const
 
 INLINE (Token::Value peek())
 
 INLINE (Token::Value Next())
 
void Consume (Token::Value token)
 
bool Check (Token::Value token)
 
void Expect (Token::Value token, bool *ok)
 
void ExpectSemicolon (bool *ok)
 
bool peek_any_identifier ()
 
bool CheckContextualKeyword (Vector< const char > keyword)
 
void ExpectContextualKeyword (Vector< const char > keyword, bool *ok)
 
void CheckOctalLiteral (int beg_pos, int end_pos, bool *ok)
 
void CheckStrictFunctionNameAndParameters (IdentifierT function_name, bool function_name_is_strict_reserved, const Scanner::Location &function_name_loc, const Scanner::Location &eval_args_error_loc, const Scanner::Location &dupe_error_loc, const Scanner::Location &reserved_loc, bool *ok)
 
Traits::Type::Factory * factory ()
 
StrictMode strict_mode ()
 
bool is_generator () const
 
void ReportMessage (const char *message, const char *arg=NULL, bool is_reference_error=false)
 
void ReportMessageAt (Scanner::Location location, const char *message, bool is_reference_error=false)
 
void ReportUnexpectedToken (Token::Value token)
 
IdentifierT ParseIdentifier (AllowEvalOrArgumentsAsIdentifier, bool *ok)
 
IdentifierT ParseIdentifierOrStrictReservedWord (bool *is_strict_reserved, bool *ok)
 
IdentifierT ParseIdentifierName (bool *ok)
 
IdentifierT ParseIdentifierNameOrGetOrSet (bool *is_get, bool *is_set, bool *ok)
 
ExpressionT ParseRegExpLiteral (bool seen_equal, bool *ok)
 
ExpressionT ParsePrimaryExpression (bool *ok)
 
ExpressionT ParseExpression (bool accept_IN, bool *ok)
 
ExpressionT ParseArrayLiteral (bool *ok)
 
IdentifierT ParsePropertyName (bool *is_get, bool *is_set, bool *is_static, bool *ok)
 
ExpressionT ParseObjectLiteral (bool *ok)
 
ObjectLiteralPropertyT ParsePropertyDefinition (ObjectLiteralChecker *checker, bool in_class, bool is_static, bool *ok)
 
Traits::Type::ExpressionList ParseArguments (bool *ok)
 
ExpressionT ParseAssignmentExpression (bool accept_IN, bool *ok)
 
ExpressionT ParseYieldExpression (bool *ok)
 
ExpressionT ParseConditionalExpression (bool accept_IN, bool *ok)
 
ExpressionT ParseBinaryExpression (int prec, bool accept_IN, bool *ok)
 
ExpressionT ParseUnaryExpression (bool *ok)
 
ExpressionT ParsePostfixExpression (bool *ok)
 
ExpressionT ParseLeftHandSideExpression (bool *ok)
 
ExpressionT ParseMemberWithNewPrefixesExpression (bool *ok)
 
ExpressionT ParseMemberExpression (bool *ok)
 
ExpressionT ParseMemberExpressionContinuation (ExpressionT expression, bool *ok)
 
ExpressionT ParseArrowFunctionLiteral (int start_pos, ExpressionT params_ast, bool *ok)
 
ExpressionT ParseClassLiteral (IdentifierT name, Scanner::Location function_name_location, bool name_is_strict_reserved, int pos, bool *ok)
 
ExpressionT CheckAndRewriteReferenceExpression (ExpressionT expression, Scanner::Location location, const char *message, bool *ok)
 
- Static Protected Member Functions inherited from v8::internal::ParserBase< ParserTraits >
static int Precedence (Token::Value token, bool accept_IN)
 
- Protected Attributes inherited from v8::internal::ParserBase< ParserTraits >
bool parenthesized_function_
 
Traits::Type::Scope * scope_
 
FunctionState * function_state_
 
v8::Extensionextension_
 
FuncNameInferrerfni_
 
ParserRecorderlog_
 
Mode mode_
 
uintptr_t stack_limit_
 

Detailed Description

Definition at line 606 of file parser.h.

Member Enumeration Documentation

◆ VariableDeclarationContext

Enumerator
kModuleElement 
kBlockElement 
kStatement 
kForStatement 

Definition at line 660 of file parser.h.

660  {
663  kStatement,
665  };

◆ VariableDeclarationProperties

Enumerator
kHasInitializers 
kHasNoInitializers 

Definition at line 668 of file parser.h.

668  {
671  };

Constructor & Destructor Documentation

◆ Parser()

v8::internal::Parser::Parser ( CompilationInfo info,
ParseInfo parse_info 
)

Definition at line 755 of file parser.cc.

756  : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit,
757  info->extension(), NULL, info->zone(),
758  info->ast_node_id_gen(), this),
759  scanner_(parse_info->unicode_cache),
764  info_(info),
765  has_pending_error_(false),
771  DCHECK(!script().is_null() || info->source_stream() != NULL);
772  set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
773  set_allow_modules(!info->is_native() && FLAG_harmony_modules);
774  set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
775  set_allow_lazy(false); // Must be explicitly enabled.
776  set_allow_arrow_functions(FLAG_harmony_arrow_functions);
777  set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
778  set_allow_classes(FLAG_harmony_classes);
779  set_allow_harmony_object_literals(FLAG_harmony_object_literals);
780  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
781  ++feature) {
782  use_counts_[feature] = 0;
783  }
784  if (info->ast_value_factory() == NULL) {
785  // info takes ownership of AstValueFactory.
787  new AstValueFactory(zone(), parse_info->hash_seed));
788  }
789 }
@ kUseCounterFeatureCount
Definition: v8.h:4488
AstNode::IdGen * ast_node_id_gen()
Definition: compiler.h:395
ScriptCompiler::ExternalSourceStream * source_stream() const
Definition: compiler.h:121
v8::Extension * extension() const
Definition: compiler.h:116
AstValueFactory * ast_value_factory() const
Definition: compiler.h:388
void SetAstValueFactory(AstValueFactory *ast_value_factory, bool owned=true)
Definition: compiler.h:389
Traits::Type::Zone * zone() const
Definition: preparser.h:291
void set_allow_harmony_numeric_literals(bool allow)
Definition: preparser.h:117
void set_allow_harmony_object_literals(bool allow)
Definition: preparser.h:121
CompilationInfo * info_
Definition: parser.h:838
int use_counts_[v8::Isolate::kUseCounterFeatureCount]
Definition: parser.h:850
Handle< Script > script() const
Definition: parser.h:681
Target * target_stack_
Definition: parser.h:835
const AstRawString * pending_error_arg_
Definition: parser.h:844
bool has_pending_error_
Definition: parser.h:841
ParseData * cached_parse_data_
Definition: parser.h:836
HistogramTimer * pre_parse_timer_
Definition: parser.h:852
const char * pending_error_char_arg_
Definition: parser.h:845
CompilationInfo * info() const
Definition: parser.h:680
Scanner scanner_
Definition: parser.h:832
Scope * original_scope_
Definition: parser.h:834
const char * pending_error_message_
Definition: parser.h:843
int total_preparse_skipped_
Definition: parser.h:851
PreParser * reusable_preparser_
Definition: parser.h:833
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205

References v8::internal::CompilationInfo::ast_value_factory(), DCHECK, v8::internal::Parser::ParseInfo::hash_seed, info(), v8::internal::CompilationInfo::is_native(), v8::Isolate::kUseCounterFeatureCount, NULL, script(), v8::internal::ParserBase< ParserTraits >::set_allow_arrow_functions(), v8::internal::ParserBase< ParserTraits >::set_allow_classes(), v8::internal::ParserBase< ParserTraits >::set_allow_harmony_numeric_literals(), v8::internal::ParserBase< ParserTraits >::set_allow_harmony_object_literals(), v8::internal::ParserBase< ParserTraits >::set_allow_harmony_scoping(), v8::internal::ParserBase< ParserTraits >::set_allow_lazy(), v8::internal::ParserBase< ParserTraits >::set_allow_modules(), v8::internal::ParserBase< ParserTraits >::set_allow_natives_syntax(), v8::internal::CompilationInfo::SetAstValueFactory(), v8::internal::CompilationInfo::source_stream(), use_counts_, and v8::internal::ParserBase< ParserTraits >::zone().

+ Here is the call graph for this function:

◆ ~Parser()

v8::internal::Parser::~Parser ( )
inline

Definition at line 618 of file parser.h.

618  {
619  delete reusable_preparser_;
621  delete cached_parse_data_;
623  }

References cached_parse_data_, NULL, and reusable_preparser_.

Member Function Documentation

◆ ast_value_factory()

AstValueFactory* v8::internal::Parser::ast_value_factory ( ) const
inlineprivate

◆ CheckConflictingVarDeclarations()

void v8::internal::Parser::CheckConflictingVarDeclarations ( Scope scope,
bool ok 
)
private

Definition at line 3919 of file parser.cc.

3919  {
3920  Declaration* decl = scope->CheckConflictingVarDeclarations();
3921  if (decl != NULL) {
3922  // In harmony mode we treat conflicting variable bindinds as early
3923  // errors. See ES5 16 for a definition of early errors.
3924  const AstRawString* name = decl->proxy()->raw_name();
3925  int position = decl->proxy()->position();
3926  Scanner::Location location = position == RelocInfo::kNoPosition
3928  : Scanner::Location(position, position + 1);
3929  ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
3930  *ok = false;
3931  }
3932 }
void ReportMessageAt(Scanner::Location source_location, const char *message, const char *arg=NULL, bool is_reference_error=false)
Definition: parser.cc:580
static const int kNoPosition
Definition: assembler.h:317
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
static Location invalid()
Definition: scanner.h:337

References v8::internal::Scope::CheckConflictingVarDeclarations(), v8::internal::Scanner::Location::invalid(), v8::internal::RelocInfo::kNoPosition, name, NULL, v8::internal::ParserBase< ParserTraits >::position(), v8::internal::Declaration::proxy(), and v8::internal::ParserTraits::ReportMessageAt().

Referenced by v8::internal::ParserTraits::CheckConflictingVarDeclarations(), DoParseProgram(), and ParseFunctionLiteral().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CheckInOrOf()

bool v8::internal::Parser::CheckInOrOf ( bool  accept_OF,
ForEachStatement::VisitMode visit_mode 
)
private

Definition at line 2856 of file parser.cc.

2857  {
2858  if (Check(Token::IN)) {
2859  *visit_mode = ForEachStatement::ENUMERATE;
2860  return true;
2861  } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) {
2862  *visit_mode = ForEachStatement::ITERATE;
2863  return true;
2864  }
2865  return false;
2866 }
bool Check(Token::Value token)
Definition: preparser.h:319
bool CheckContextualKeyword(Vector< const char > keyword)
Definition: preparser.h:361
Vector< const char > CStrVector(const char *data)
Definition: vector.h:158
#define IN

References v8::internal::ParserBase< ParserTraits >::Check(), v8::internal::ParserBase< ParserTraits >::CheckContextualKeyword(), v8::internal::CStrVector(), v8::internal::ForEachStatement::ENUMERATE, IN, and v8::internal::ForEachStatement::ITERATE.

Referenced by ParseForStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compile_options()

ScriptCompiler::CompileOptions v8::internal::Parser::compile_options ( ) const
inlineprivate

Definition at line 693 of file parser.h.

693  {
694  return info_->compile_options();
695  }
ScriptCompiler::CompileOptions compile_options() const
Definition: compiler.h:118

References v8::internal::CompilationInfo::compile_options(), and info_.

Referenced by ParseOnBackground(), ParseProgram(), SetCachedData(), and SkipLazyFunctionBody().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ DeclarationScope()

Scope* v8::internal::Parser::DeclarationScope ( VariableMode  mode)
inlineprivate

Definition at line 696 of file parser.h.

696  {
698  ? scope_ : scope_->DeclarationScope();
699  }
bool IsLexicalVariableMode(VariableMode mode)
Definition: globals.h:710

References v8::internal::IsLexicalVariableMode(), v8::internal::ParserBase< ParserTraits >::mode(), and v8::internal::ParserBase< ParserTraits >::scope_.

Referenced by Declare(), NewUnresolved(), ParseNativeDeclaration(), and ParseVariableDeclarations().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Declare()

void v8::internal::Parser::Declare ( Declaration declaration,
bool  resolve,
bool ok 
)
private

Definition at line 1717 of file parser.cc.

1717  {
1718  VariableProxy* proxy = declaration->proxy();
1719  DCHECK(proxy->raw_name() != NULL);
1720  const AstRawString* name = proxy->raw_name();
1721  VariableMode mode = declaration->mode();
1722  Scope* declaration_scope = DeclarationScope(mode);
1723  Variable* var = NULL;
1724 
1725  // If a suitable scope exists, then we can statically declare this
1726  // variable and also set its mode. In any case, a Declaration node
1727  // will be added to the scope so that the declaration can be added
1728  // to the corresponding activation frame at runtime if necessary.
1729  // For instance declarations inside an eval scope need to be added
1730  // to the calling function context.
1731  // Similarly, strict mode eval scope does not leak variable declarations to
1732  // the caller's scope so we declare all locals, too.
1733  if (declaration_scope->is_function_scope() ||
1734  declaration_scope->is_strict_eval_scope() ||
1735  declaration_scope->is_block_scope() ||
1736  declaration_scope->is_module_scope() ||
1737  declaration_scope->is_global_scope()) {
1738  // Declare the variable in the declaration scope.
1739  // For the global scope, we have to check for collisions with earlier
1740  // (i.e., enclosing) global scopes, to maintain the illusion of a single
1741  // global scope.
1742  var = declaration_scope->is_global_scope()
1743  ? declaration_scope->Lookup(name)
1744  : declaration_scope->LookupLocal(name);
1745  if (var == NULL) {
1746  // Declare the name.
1747  var = declaration_scope->DeclareLocal(name, mode,
1748  declaration->initialization(),
1749  kNotAssigned, proxy->interface());
1750  } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
1751  || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1752  !declaration_scope->is_global_scope())) {
1753  // The name was declared in this scope before; check for conflicting
1754  // re-declarations. We have a conflict if either of the declarations is
1755  // not a var (in the global scope, we also have to ignore legacy const for
1756  // compatibility). There is similar code in runtime.cc in the Declare
1757  // functions. The function CheckConflictingVarDeclarations checks for
1758  // var and let bindings from different scopes whereas this is a check for
1759  // conflicting declarations within the same scope. This check also covers
1760  // the special case
1761  //
1762  // function () { let x; { var x; } }
1763  //
1764  // because the var declaration is hoisted to the function scope where 'x'
1765  // is already bound.
1766  DCHECK(IsDeclaredVariableMode(var->mode()));
1767  if (allow_harmony_scoping() && strict_mode() == STRICT) {
1768  // In harmony we treat re-declarations as early errors. See
1769  // ES5 16 for a definition of early errors.
1770  ParserTraits::ReportMessage("var_redeclaration", name);
1771  *ok = false;
1772  return;
1773  }
1774  Expression* expression = NewThrowTypeError(
1775  "var_redeclaration", name, declaration->position());
1776  declaration_scope->SetIllegalRedeclaration(expression);
1777  } else if (mode == VAR) {
1778  var->set_maybe_assigned();
1779  }
1780  }
1781 
1782  // We add a declaration node for every declaration. The compiler
1783  // will only generate code if necessary. In particular, declarations
1784  // for inner local variables that do not represent functions won't
1785  // result in any generated code.
1786  //
1787  // Note that we always add an unresolved proxy even if it's not
1788  // used, simply because we don't know in this method (w/o extra
1789  // parameters) if the proxy is needed or not. The proxy will be
1790  // bound during variable resolution time unless it was pre-bound
1791  // below.
1792  //
1793  // WARNING: This will lead to multiple declaration nodes for the
1794  // same variable if it is declared several times. This is not a
1795  // semantic issue as long as we keep the source order, but it may be
1796  // a performance issue since it may lead to repeated
1797  // RuntimeHidden_DeclareLookupSlot calls.
1798  declaration_scope->AddDeclaration(declaration);
1799 
1800  if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
1801  // For global const variables we bind the proxy to a variable.
1802  DCHECK(resolve); // should be set by all callers
1804  var = new (zone())
1805  Variable(declaration_scope, name, mode, true, kind,
1806  kNeedsInitialization, kNotAssigned, proxy->interface());
1807  } else if (declaration_scope->is_eval_scope() &&
1808  declaration_scope->strict_mode() == SLOPPY) {
1809  // For variable declarations in a sloppy eval scope the proxy is bound
1810  // to a lookup variable to force a dynamic declaration using the
1811  // DeclareLookupSlot runtime function.
1813  // TODO(sigurds) figure out if kNotAssigned is OK here
1814  var = new (zone()) Variable(declaration_scope, name, mode, true, kind,
1815  declaration->initialization(), kNotAssigned,
1816  proxy->interface());
1817  var->AllocateTo(Variable::LOOKUP, -1);
1818  resolve = true;
1819  }
1820 
1821  // If requested and we have a local variable, bind the proxy to the variable
1822  // at parse-time. This is used for functions (and consts) declared inside
1823  // statements: the corresponding function (or const) variable must be in the
1824  // function scope and not a statement-local scope, e.g. as provided with a
1825  // 'with' statement:
1826  //
1827  // with (obj) {
1828  // function f() {}
1829  // }
1830  //
1831  // which is translated into:
1832  //
1833  // with (obj) {
1834  // // in this case this is not: 'var f; f = function () {};'
1835  // var f = function () {};
1836  // }
1837  //
1838  // Note that if 'f' is accessed from inside the 'with' statement, it
1839  // will be allocated in the context (because we must be able to look
1840  // it up dynamically) but it will also be accessed statically, i.e.,
1841  // with a context slot index and a context chain length for this
1842  // initialization code. Thus, inside the 'with' statement, we need
1843  // both access to the static and the dynamic context chain; the
1844  // runtime needs to provide both.
1845  if (resolve && var != NULL) {
1846  proxy->BindTo(var);
1847 
1848  if (FLAG_harmony_modules) {
1849  bool ok;
1850 #ifdef DEBUG
1851  if (FLAG_print_interface_details) {
1852  PrintF("# Declare %.*s ", var->raw_name()->length(),
1853  var->raw_name()->raw_data());
1854  }
1855 #endif
1856  proxy->interface()->Unify(var->interface(), zone(), &ok);
1857  if (!ok) {
1858 #ifdef DEBUG
1859  if (FLAG_print_interfaces) {
1860  PrintF("DECLARE TYPE ERROR\n");
1861  PrintF("proxy: ");
1862  proxy->interface()->Print();
1863  PrintF("var: ");
1864  var->interface()->Print();
1865  }
1866 #endif
1867  ParserTraits::ReportMessage("module_type_error", name);
1868  }
1869  }
1870  }
1871 }
void ReportMessage(const char *message, const char *arg=NULL, bool is_reference_error=false)
Definition: parser.cc:599
Expression * NewThrowTypeError(const char *type, const AstRawString *arg, int pos)
Definition: parser.cc:552
Scope * DeclarationScope(VariableMode mode)
Definition: parser.h:696
@ kNeedsInitialization
Definition: globals.h:752
bool IsDeclaredVariableMode(VariableMode mode)
Definition: globals.h:705
@ kNotAssigned
Definition: globals.h:757
@ CONST_LEGACY
Definition: globals.h:671
void PrintF(const char *format,...)
Definition: utils.cc:80

References v8::internal::Scope::AddDeclaration(), v8::internal::Variable::AllocateTo(), v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), v8::internal::CONST_LEGACY, DCHECK, DeclarationScope(), v8::internal::Scope::DeclareLocal(), v8::internal::Declaration::initialization(), v8::internal::Variable::interface(), v8::internal::Scope::is_block_scope(), v8::internal::Scope::is_eval_scope(), v8::internal::Scope::is_function_scope(), v8::internal::Scope::is_global_scope(), v8::internal::Scope::is_module_scope(), v8::internal::Scope::is_strict_eval_scope(), v8::internal::IsDeclaredVariableMode(), v8::internal::IsLexicalVariableMode(), v8::internal::kNeedsInitialization, v8::internal::kNotAssigned, v8::internal::AstRawString::length(), v8::internal::Scope::Lookup(), v8::internal::Variable::LOOKUP, v8::internal::Scope::LookupLocal(), v8::internal::Declaration::mode(), v8::internal::ParserBase< ParserTraits >::mode(), v8::internal::Variable::mode(), name, v8::internal::ParserTraits::NewThrowTypeError(), v8::internal::Variable::NORMAL, NULL, v8::internal::AstNode::position(), v8::internal::PrintF(), v8::internal::Declaration::proxy(), v8::internal::AstRawString::raw_data(), v8::internal::Variable::raw_name(), v8::internal::ParserTraits::ReportMessage(), v8::internal::Variable::set_maybe_assigned(), v8::internal::Scope::SetIllegalRedeclaration(), v8::internal::SLOPPY, v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), v8::internal::Scope::strict_mode(), v8::internal::VAR, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by DesugarLetBindingsInForStatement(), ParseClassDeclaration(), ParseFunctionDeclaration(), ParseImportDeclaration(), ParseModuleDeclaration(), ParseNativeDeclaration(), and ParseVariableDeclarations().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ DesugarLetBindingsInForStatement()

Statement * v8::internal::Parser::DesugarLetBindingsInForStatement ( Scope inner_scope,
ZoneList< const AstRawString * > *  names,
ForStatement *  loop,
Statement init,
Expression cond,
Statement next,
Statement body,
bool ok 
)
private

Definition at line 2938 of file parser.cc.

2941  {
2942  // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
2943  // copied into a new environment. After copying, the "next" statement of the
2944  // loop is executed to update the loop variables. The loop condition is
2945  // checked and the loop body is executed.
2946  //
2947  // We rewrite a for statement of the form
2948  //
2949  // for (let x = i; cond; next) body
2950  //
2951  // into
2952  //
2953  // {
2954  // let x = i;
2955  // temp_x = x;
2956  // flag = 1;
2957  // for (;;) {
2958  // let x = temp_x;
2959  // if (flag == 1) {
2960  // flag = 0;
2961  // } else {
2962  // next;
2963  // }
2964  // if (cond) {
2965  // <empty>
2966  // } else {
2967  // break;
2968  // }
2969  // b
2970  // temp_x = x;
2971  // }
2972  // }
2973 
2974  DCHECK(names->length() > 0);
2975  Scope* for_scope = scope_;
2976  ZoneList<Variable*> temps(names->length(), zone());
2977 
2978  Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
2980  outer_block->AddStatement(init, zone());
2981 
2982  const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2983 
2984  // For each let variable x:
2985  // make statement: temp_x = x.
2986  for (int i = 0; i < names->length(); i++) {
2987  VariableProxy* proxy =
2988  NewUnresolved(names->at(i), LET, Interface::NewValue());
2989  Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
2990  VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2991  Assignment* assignment = factory()->NewAssignment(
2992  Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
2993  Statement* assignment_statement = factory()->NewExpressionStatement(
2994  assignment, RelocInfo::kNoPosition);
2995  outer_block->AddStatement(assignment_statement, zone());
2996  temps.Add(temp, zone());
2997  }
2998 
2999  Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
3000  // Make statement: flag = 1.
3001  {
3002  VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3003  Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3004  Assignment* assignment = factory()->NewAssignment(
3005  Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3006  Statement* assignment_statement = factory()->NewExpressionStatement(
3007  assignment, RelocInfo::kNoPosition);
3008  outer_block->AddStatement(assignment_statement, zone());
3009  }
3010 
3011  outer_block->AddStatement(loop, zone());
3012  outer_block->set_scope(for_scope);
3013  scope_ = inner_scope;
3014 
3015  Block* inner_block = factory()->NewBlock(NULL, 2 * names->length() + 3,
3016  false, RelocInfo::kNoPosition);
3017  int pos = scanner()->location().beg_pos;
3018  ZoneList<Variable*> inner_vars(names->length(), zone());
3019 
3020  // For each let variable x:
3021  // make statement: let x = temp_x.
3022  for (int i = 0; i < names->length(); i++) {
3023  VariableProxy* proxy =
3024  NewUnresolved(names->at(i), LET, Interface::NewValue());
3025  Declaration* declaration =
3026  factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
3027  Declare(declaration, true, CHECK_OK);
3028  inner_vars.Add(declaration->proxy()->var(), zone());
3029  VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3030  Assignment* assignment = factory()->NewAssignment(
3031  Token::INIT_LET, proxy, temp_proxy, pos);
3032  Statement* assignment_statement = factory()->NewExpressionStatement(
3033  assignment, pos);
3034  proxy->var()->set_initializer_position(pos);
3035  inner_block->AddStatement(assignment_statement, zone());
3036  }
3037 
3038  // Make statement: if (flag == 1) { flag = 0; } else { next; }.
3039  if (next) {
3040  Expression* compare = NULL;
3041  // Make compare expresion: flag == 1.
3042  {
3043  Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3044  VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3045  compare = factory()->NewCompareOperation(
3046  Token::EQ, flag_proxy, const1, pos);
3047  }
3048  Statement* clear_flag = NULL;
3049  // Make statement: flag = 0.
3050  {
3051  VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3052  Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3053  Assignment* assignment = factory()->NewAssignment(
3054  Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
3055  clear_flag = factory()->NewExpressionStatement(assignment, pos);
3056  }
3057  Statement* clear_flag_or_next = factory()->NewIfStatement(
3058  compare, clear_flag, next, RelocInfo::kNoPosition);
3059  inner_block->AddStatement(clear_flag_or_next, zone());
3060  }
3061 
3062 
3063  // Make statement: if (cond) { } else { break; }.
3064  if (cond) {
3065  Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3066  BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK);
3067  Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition);
3068  Statement* if_not_cond_break = factory()->NewIfStatement(
3069  cond, empty, stop, cond->position());
3070  inner_block->AddStatement(if_not_cond_break, zone());
3071  }
3072 
3073  inner_block->AddStatement(body, zone());
3074 
3075  // For each let variable x:
3076  // make statement: temp_x = x;
3077  for (int i = 0; i < names->length(); i++) {
3078  VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3079  int pos = scanner()->location().end_pos;
3080  VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
3081  Assignment* assignment = factory()->NewAssignment(
3082  Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3083  Statement* assignment_statement = factory()->NewExpressionStatement(
3084  assignment, RelocInfo::kNoPosition);
3085  inner_block->AddStatement(assignment_statement, zone());
3086  }
3087 
3088  inner_scope->set_end_position(scanner()->location().end_pos);
3089  inner_block->set_scope(inner_scope);
3090  scope_ = for_scope;
3091 
3092  loop->Initialize(NULL, NULL, NULL, inner_block);
3093  return outer_block;
3094 }
static Interface * NewValue()
Definition: interface.h:44
Traits::Type::Factory * factory()
Definition: preparser.h:436
BreakableStatement * LookupBreakTarget(const AstRawString *label, bool *ok)
Definition: parser.cc:3949
VariableProxy * NewUnresolved(const AstRawString *name, VariableMode mode, Interface *interface)
Definition: parser.cc:1705
void Declare(Declaration *declaration, bool resolve, bool *ok)
Definition: parser.cc:1717
AstValueFactory * ast_value_factory() const
Definition: parser.h:682
Location location() const
Definition: scanner.h:356
kFeedbackVectorOffset flag
Definition: objects-inl.h:5418
#define CHECK_OK
Definition: parser.cc:330

References v8::internal::List< T, AllocationPolicy >::Add(), ast_value_factory(), v8::internal::List< T, AllocationPolicy >::at(), v8::internal::Scanner::Location::beg_pos, CHECK_OK, DCHECK, Declare(), v8::internal::Scanner::Location::end_pos, v8::internal::EQ, v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::flag, v8::internal::Scope::Initialize(), v8::internal::RelocInfo::kNoPosition, v8::internal::LET, v8::internal::Scanner::location(), LookupBreakTarget(), NewUnresolved(), v8::internal::Interface::NewValue(), NULL, v8::internal::AstNode::position(), v8::internal::Declaration::proxy(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Scope::set_end_position(), and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseForStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ DoParseProgram()

FunctionLiteral * v8::internal::Parser::DoParseProgram ( CompilationInfo info,
Scope **  scope,
Scope **  ad_hoc_eval_scope 
)
private

Definition at line 861 of file parser.cc.

862  {
863  DCHECK(scope_ == NULL);
865 
866  FunctionLiteral* result = NULL;
867  {
868  *scope = NewScope(scope_, GLOBAL_SCOPE);
869  info->SetGlobalScope(*scope);
870  if (!info->context().is_null() && !info->context()->IsNativeContext()) {
871  *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone());
872  // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
873  // means the Parser cannot operate independent of the V8 heap. Tell the
874  // string table to internalize strings and values right after they're
875  // created.
877  }
878  original_scope_ = *scope;
879  if (info->is_eval()) {
880  if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) {
881  *scope = NewScope(*scope, EVAL_SCOPE);
882  }
883  } else if (info->is_global()) {
884  *scope = NewScope(*scope, GLOBAL_SCOPE);
885  }
886  (*scope)->set_start_position(0);
887  // End position will be set by the caller.
888 
889  // Compute the parsing mode.
890  Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
891  if (allow_natives_syntax() || extension_ != NULL ||
892  (*scope)->is_eval_scope()) {
894  }
895  ParsingModeScope parsing_mode(this, mode);
896 
897  // Enters 'scope'.
898  FunctionState function_state(&function_state_, &scope_, *scope, zone(),
900 
901  scope_->SetStrictMode(info->strict_mode());
902  ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
903  bool ok = true;
904  int beg_pos = scanner()->location().beg_pos;
905  ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope,
906  &ok);
907 
908  if (ok && strict_mode() == STRICT) {
909  CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
910  }
911 
912  if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
914  }
915 
917  if (body->length() != 1 ||
918  !body->at(0)->IsExpressionStatement() ||
919  !body->at(0)->AsExpressionStatement()->
920  expression()->IsFunctionLiteral()) {
921  ReportMessage("single_function_literal");
922  ok = false;
923  }
924  }
925 
926  if (ok) {
927  result = factory()->NewFunctionLiteral(
928  ast_value_factory()->empty_string(), ast_value_factory(), scope_,
929  body, function_state.materialized_literal_count(),
930  function_state.expected_property_count(),
931  function_state.handler_count(), 0,
932  FunctionLiteral::kNoDuplicateParameters,
933  FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
934  FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
935  result->set_ast_properties(factory()->visitor()->ast_properties());
936  result->set_dont_optimize_reason(
937  factory()->visitor()->dont_optimize_reason());
938  }
939  }
940 
941  // Make sure the target stack is empty.
943 
944  return result;
945 }
void Internalize(Isolate *isolate)
void SetGlobalScope(Scope *global_scope)
Definition: compiler.h:235
Handle< Context > context() const
Definition: compiler.h:127
StrictMode strict_mode() const
Definition: compiler.h:104
ParseRestriction parse_restriction() const
Definition: compiler.h:225
void CheckOctalLiteral(int beg_pos, int end_pos, bool *ok)
Definition: preparser.h:381
void ReportMessage(const char *message, const char *arg=NULL, bool is_reference_error=false)
Definition: preparser.h:444
Scope * NewScope(Scope *parent, ScopeType type)
Definition: parser.cc:269
void CheckConflictingVarDeclarations(Scope *scope, bool *ok)
Definition: parser.cc:3919
void * ParseSourceElements(ZoneList< Statement * > *processor, int end_token, bool is_eval, bool is_global, Scope **ad_hoc_eval_scope, bool *ok)
Definition: parser.cc:1050
Isolate * isolate()
Definition: parser.h:679
static Scope * DeserializeScopeChain(Context *context, Scope *global_scope, Zone *zone)
Definition: scopes.cc:187
@ ONLY_SINGLE_FUNCTION_LITERAL
Definition: compiler.h:23
@ GLOBAL_SCOPE
Definition: globals.h:649
@ kNormalFunction
Definition: globals.h:776

References v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), v8::internal::ParserBase< ParserTraits >::allow_lazy(), v8::internal::ParserBase< ParserTraits >::allow_natives_syntax(), v8::internal::CompilationInfo::ast_node_id_gen(), ast_value_factory(), v8::internal::List< T, AllocationPolicy >::at(), v8::internal::Scanner::Location::beg_pos, CheckConflictingVarDeclarations(), v8::internal::ParserBase< ParserTraits >::CheckOctalLiteral(), v8::internal::CompilationInfo::context(), DCHECK, v8::internal::Scope::DeserializeScopeChain(), v8::internal::EVAL_SCOPE, v8::internal::ParserBase< ParserTraits >::extension_, v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::function_state_, v8::internal::GLOBAL_SCOPE, info(), v8::internal::AstValueFactory::Internalize(), v8::internal::CompilationInfo::is_eval(), v8::internal::CompilationInfo::is_global(), isolate(), v8::internal::kNormalFunction, v8::internal::Scanner::location(), v8::internal::ParserBase< ParserTraits >::mode(), NewScope(), NULL, v8::internal::ONLY_SINGLE_FUNCTION_LITERAL, original_scope_, v8::internal::ParserBase< ParserTraits >::PARSE_EAGERLY, v8::internal::ParserBase< ParserTraits >::PARSE_LAZILY, v8::internal::CompilationInfo::parse_restriction(), ParseSourceElements(), v8::internal::ParserBase< ParserTraits >::ReportMessage(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::CompilationInfo::SetGlobalScope(), v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), v8::internal::CompilationInfo::strict_mode(), target_stack_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseOnBackground(), and ParseProgram().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetLiteralUndefined()

Literal * v8::internal::Parser::GetLiteralUndefined ( int  position)
private

Definition at line 3914 of file parser.cc.

3914  {
3915  return factory()->NewUndefinedLiteral(position);
3916 }

References v8::internal::ParserBase< ParserTraits >::factory(), and v8::internal::ParserBase< ParserTraits >::position().

Referenced by ParseReturnStatement(), and ParseVariableDeclarations().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HandleSourceURLComments()

void v8::internal::Parser::HandleSourceURLComments ( )
private

Definition at line 3993 of file parser.cc.

3993  {
3994  if (scanner_.source_url()->length() > 0) {
3995  Handle<String> source_url = scanner_.source_url()->Internalize(isolate());
3996  info_->script()->set_source_url(*source_url);
3997  }
3998  if (scanner_.source_mapping_url()->length() > 0) {
3999  Handle<String> source_mapping_url =
4001  info_->script()->set_source_mapping_url(*source_mapping_url);
4002  }
4003 }
Handle< Script > script() const
Definition: compiler.h:113
Handle< String > Internalize(Isolate *isolate) const
Definition: scanner.cc:23
const LiteralBuffer * source_url() const
Definition: scanner.h:462
const LiteralBuffer * source_mapping_url() const
Definition: scanner.h:463

References info_, v8::internal::LiteralBuffer::Internalize(), isolate(), v8::internal::LiteralBuffer::length(), scanner_, v8::internal::CompilationInfo::script(), v8::internal::Scanner::source_mapping_url(), and v8::internal::Scanner::source_url().

Referenced by ParseProgram().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ info()

CompilationInfo* v8::internal::Parser::info ( ) const
inlineprivate

Definition at line 680 of file parser.h.

680 { return info_; }

References info_.

Referenced by DoParseProgram(), Internalize(), Parse(), ParseFunctionLiteral(), ParseLazy(), ParseOnBackground(), ParseProgram(), and Parser().

+ Here is the caller graph for this function:

◆ InitializeForEachStatement()

void v8::internal::Parser::InitializeForEachStatement ( ForEachStatement stmt,
Expression each,
Expression subject,
Statement body 
)
private

Definition at line 2869 of file parser.cc.

2872  {
2873  ForOfStatement* for_of = stmt->AsForOfStatement();
2874 
2875  if (for_of != NULL) {
2876  Variable* iterator = scope_->DeclarationScope()->NewTemporary(
2877  ast_value_factory()->dot_iterator_string());
2878  Variable* result = scope_->DeclarationScope()->NewTemporary(
2879  ast_value_factory()->dot_result_string());
2880 
2881  Expression* assign_iterator;
2882  Expression* next_result;
2883  Expression* result_done;
2884  Expression* assign_each;
2885 
2886  // var iterator = subject[Symbol.iterator]();
2887  assign_iterator = factory()->NewAssignment(
2888  Token::ASSIGN, factory()->NewVariableProxy(iterator),
2890 
2891  // var result = iterator.next();
2892  {
2893  Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2894  Expression* next_literal = factory()->NewStringLiteral(
2895  ast_value_factory()->next_string(), RelocInfo::kNoPosition);
2896  Expression* next_property = factory()->NewProperty(
2897  iterator_proxy, next_literal, RelocInfo::kNoPosition);
2898  ZoneList<Expression*>* next_arguments =
2899  new(zone()) ZoneList<Expression*>(0, zone());
2900  Expression* next_call = factory()->NewCall(
2901  next_property, next_arguments, RelocInfo::kNoPosition);
2902  Expression* result_proxy = factory()->NewVariableProxy(result);
2903  next_result = factory()->NewAssignment(
2904  Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
2905  }
2906 
2907  // result.done
2908  {
2909  Expression* done_literal = factory()->NewStringLiteral(
2910  ast_value_factory()->done_string(), RelocInfo::kNoPosition);
2911  Expression* result_proxy = factory()->NewVariableProxy(result);
2912  result_done = factory()->NewProperty(
2913  result_proxy, done_literal, RelocInfo::kNoPosition);
2914  }
2915 
2916  // each = result.value
2917  {
2918  Expression* value_literal = factory()->NewStringLiteral(
2919  ast_value_factory()->value_string(), RelocInfo::kNoPosition);
2920  Expression* result_proxy = factory()->NewVariableProxy(result);
2921  Expression* result_value = factory()->NewProperty(
2922  result_proxy, value_literal, RelocInfo::kNoPosition);
2923  assign_each = factory()->NewAssignment(
2924  Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
2925  }
2926 
2927  for_of->Initialize(each, subject, body,
2928  assign_iterator,
2929  next_result,
2930  result_done,
2931  assign_each);
2932  } else {
2933  stmt->Initialize(each, subject, body);
2934  }
2935 }
Expression * GetIterator(Expression *iterable, AstNodeFactory< AstConstructionVisitor > *factory)
Definition: parser.cc:720

References ast_value_factory(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserTraits::GetIterator(), v8::internal::ForEachStatement::Initialize(), v8::internal::RelocInfo::kNoPosition, NULL, v8::internal::ParserBase< ParserTraits >::scope_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseForStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ inside_with()

bool v8::internal::Parser::inside_with ( ) const
inlineprivate

Definition at line 692 of file parser.h.

692 { return scope_->inside_with(); }

References v8::internal::ParserBase< ParserTraits >::scope_.

Referenced by ParseVariableDeclarations().

+ Here is the caller graph for this function:

◆ Internalize()

void v8::internal::Parser::Internalize ( )

Definition at line 4037 of file parser.cc.

4037  {
4038  // Internalize strings.
4040 
4041  // Error processing.
4042  if (info()->function() == NULL) {
4043  if (stack_overflow()) {
4044  isolate()->StackOverflow();
4045  } else {
4047  }
4048  }
4049 
4050  // Move statistics to Isolate.
4051  for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
4052  ++feature) {
4053  for (int i = 0; i < use_counts_[feature]; ++i) {
4055  }
4056  }
4057  isolate()->counters()->total_preparse_skipped()->Increment(
4059 }
UseCounterFeature
Features reported via the SetUseCounterCallback callback.
Definition: v8.h:4486
void CountUsage(v8::Isolate::UseCounterFeature feature)
Definition: isolate.cc:2358
Counters * counters()
Definition: isolate.h:857
Object * StackOverflow()
Definition: isolate.cc:773
void ThrowPendingError()
Definition: parser.cc:4006

References ast_value_factory(), v8::internal::Isolate::counters(), v8::internal::Isolate::CountUsage(), info(), v8::internal::AstValueFactory::Internalize(), isolate(), v8::Isolate::kUseCounterFeatureCount, NULL, v8::internal::ParserBase< ParserTraits >::stack_overflow(), v8::internal::Isolate::StackOverflow(), ThrowPendingError(), total_preparse_skipped_, and use_counts_.

Referenced by Parse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isolate()

Isolate* v8::internal::Parser::isolate ( )
inlineprivate

Definition at line 679 of file parser.h.

679 { return info_->isolate(); }
Isolate * isolate() const
Definition: compiler.h:96

References info_, and v8::internal::CompilationInfo::isolate().

Referenced by DoParseProgram(), v8::internal::CompileTimeValue::GetValue(), HandleSourceURLComments(), Internalize(), Parse(), ParseLazy(), ParseProgram(), and ThrowPendingError().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ LookupBreakTarget()

BreakableStatement * v8::internal::Parser::LookupBreakTarget ( const AstRawString label,
bool ok 
)
private

Definition at line 3949 of file parser.cc.

3950  {
3951  bool anonymous = label == NULL;
3952  for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3953  BreakableStatement* stat = t->node()->AsBreakableStatement();
3954  if (stat == NULL) continue;
3955  if ((anonymous && stat->is_target_for_anonymous()) ||
3956  (!anonymous && ContainsLabel(stat->labels(), label))) {
3957  RegisterTargetUse(stat->break_target(), t->previous());
3958  return stat;
3959  }
3960  }
3961  return NULL;
3962 }
void RegisterTargetUse(Label *target, Target *stop)
Definition: parser.cc:3982
static bool ContainsLabel(ZoneList< const AstRawString * > *labels, const AstRawString *label)
Definition: parser.cc:2386

References v8::internal::BreakableStatement::AsBreakableStatement(), v8::internal::BreakableStatement::break_target(), v8::internal::ContainsLabel(), v8::internal::BreakableStatement::is_target_for_anonymous(), v8::internal::BreakableStatement::labels(), NULL, RegisterTargetUse(), and target_stack_.

Referenced by DesugarLetBindingsInForStatement(), and ParseBreakStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ LookupContinueTarget()

IterationStatement * v8::internal::Parser::LookupContinueTarget ( const AstRawString label,
bool ok 
)
private

Definition at line 3965 of file parser.cc.

3966  {
3967  bool anonymous = label == NULL;
3968  for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3969  IterationStatement* stat = t->node()->AsIterationStatement();
3970  if (stat == NULL) continue;
3971 
3972  DCHECK(stat->is_target_for_anonymous());
3973  if (anonymous || ContainsLabel(stat->labels(), label)) {
3974  RegisterTargetUse(stat->continue_target(), t->previous());
3975  return stat;
3976  }
3977  }
3978  return NULL;
3979 }

References v8::internal::IterationStatement::AsIterationStatement(), v8::internal::ContainsLabel(), v8::internal::IterationStatement::continue_target(), DCHECK, v8::internal::BreakableStatement::is_target_for_anonymous(), v8::internal::BreakableStatement::labels(), NULL, RegisterTargetUse(), and target_stack_.

Referenced by ParseContinueStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ MakeCatchContext()

Expression* v8::internal::Parser::MakeCatchContext ( Handle< String id,
VariableProxy *  value 
)
private

◆ NewScope()

Scope * v8::internal::Parser::NewScope ( Scope parent,
ScopeType  type 
)
private

Definition at line 269 of file parser.cc.

269  {
271  Scope* result =
272  new (zone()) Scope(parent, scope_type, ast_value_factory(), zone());
273  result->Initialize();
274  return result;
275 }

References ast_value_factory(), DCHECK, v8::internal::Scope::Initialize(), and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by DoParseProgram(), v8::internal::ParserTraits::NewScope(), ParseForStatement(), ParseFunctionLiteral(), ParseLazy(), ParseModuleLiteral(), ParseModuleUrl(), ParseScopedBlock(), ParseSourceElements(), ParseTryStatement(), and ParseWithStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ NewUnresolved()

VariableProxy * v8::internal::Parser::NewUnresolved ( const AstRawString name,
VariableMode  mode,
Interface interface 
)
private

Definition at line 1705 of file parser.cc.

1706  {
1707  // If we are inside a function, a declaration of a var/const variable is a
1708  // truly local variable, and the scope of the variable is always the function
1709  // scope.
1710  // Let/const variables in harmony mode are always added to the immediately
1711  // enclosing scope.
1713  factory(), name, interface, position());
1714 }
VariableProxy * NewUnresolved(AstNodeFactory< Visitor > *factory, const AstRawString *name, Interface *interface=Interface::NewValue(), int position=RelocInfo::kNoPosition)
Definition: scopes.h:145

References DeclarationScope(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::mode(), name, v8::internal::Scope::NewUnresolved(), and v8::internal::ParserBase< ParserTraits >::position().

Referenced by DesugarLetBindingsInForStatement(), ParseClassDeclaration(), ParseExportDeclaration(), ParseForStatement(), ParseFunctionDeclaration(), ParseImportDeclaration(), ParseModuleDeclaration(), ParseNativeDeclaration(), and ParseVariableDeclarations().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Parse() [1/2]

bool v8::internal::Parser::Parse ( )

Definition at line 4893 of file parser.cc.

4893  {
4894  DCHECK(info()->function() == NULL);
4895  FunctionLiteral* result = NULL;
4896  pre_parse_timer_ = isolate()->counters()->pre_parse();
4897  if (FLAG_trace_parse || allow_natives_syntax() || extension_ != NULL) {
4898  // If intrinsics are allowed, the Parser cannot operate independent of the
4899  // V8 heap because of Runtime. Tell the string table to internalize strings
4900  // and values right after they're created.
4902  }
4903 
4904  if (info()->is_lazy()) {
4905  DCHECK(!info()->is_eval());
4906  if (info()->shared_info()->is_function()) {
4907  result = ParseLazy();
4908  } else {
4909  result = ParseProgram();
4910  }
4911  } else {
4912  SetCachedData();
4913  result = ParseProgram();
4914  }
4915  info()->SetFunction(result);
4916 
4917  Internalize();
4918  DCHECK(ast_value_factory()->IsInternalized());
4919  return (result != NULL);
4920 }
void SetFunction(FunctionLiteral *literal)
Definition: compiler.h:230
void SetCachedData()
Definition: parser.cc:257
FunctionLiteral * ParseLazy()
Definition: parser.cc:948
FunctionLiteral * ParseProgram()
Definition: parser.cc:792

References v8::internal::ParserBase< ParserTraits >::allow_natives_syntax(), ast_value_factory(), v8::internal::Isolate::counters(), DCHECK, v8::internal::ParserBase< ParserTraits >::extension_, info(), Internalize(), v8::internal::AstValueFactory::Internalize(), isolate(), NULL, ParseLazy(), ParseProgram(), pre_parse_timer_, SetCachedData(), and v8::internal::CompilationInfo::SetFunction().

Referenced by v8::internal::Compiler::CompileForLiveEdit(), v8::internal::CompileOptimizedPrologue(), v8::internal::CompileToplevel(), v8::internal::GetUnoptimizedCodeCommon(), v8::internal::compiler::Parse(), v8::internal::ScopeIterator::ScopeIterator(), and v8::internal::HOptimizedGraphBuilder::TryInline().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Parse() [2/2]

static bool v8::internal::Parser::Parse ( CompilationInfo info,
bool  allow_lazy = false 
)
inlinestatic

Definition at line 628 of file parser.h.

629  {
630  ParseInfo parse_info = {info->isolate()->stack_guard()->real_climit(),
631  info->isolate()->heap()->HashSeed(),
632  info->isolate()->unicode_cache()};
633  Parser parser(info, &parse_info);
634  parser.set_allow_lazy(allow_lazy);
635  if (parser.Parse()) {
636  info->SetStrictMode(info->function()->strict_mode());
637  return true;
638  }
639  return false;
640  }
void SetStrictMode(StrictMode strict_mode)
Definition: compiler.h:156
FunctionLiteral * function() const
Definition: compiler.h:107
uint32_t HashSeed()
Definition: heap.h:1237
StackGuard * stack_guard()
Definition: isolate.h:872
UnicodeCache * unicode_cache()
Definition: isolate.h:907
Parser(CompilationInfo *info, ParseInfo *parse_info)
Definition: parser.cc:755

References v8::internal::ParserBase< ParserTraits >::allow_lazy(), v8::internal::CompilationInfo::function(), v8::internal::Heap::HashSeed(), v8::internal::Isolate::heap(), info(), v8::internal::CompilationInfo::isolate(), Parse(), v8::internal::ParserBase< Traits >::set_allow_lazy(), v8::internal::CompilationInfo::SetStrictMode(), v8::internal::Isolate::stack_guard(), and v8::internal::Isolate::unicode_cache().

Referenced by Parse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseBlock()

Block * v8::internal::Parser::ParseBlock ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 1995 of file parser.cc.

1995  {
1996  if (allow_harmony_scoping() && strict_mode() == STRICT) {
1997  return ParseScopedBlock(labels, ok);
1998  }
1999 
2000  // Block ::
2001  // '{' Statement* '}'
2002 
2003  // Note that a Block does not introduce a new execution scope!
2004  // (ECMA-262, 3rd, 12.2)
2005  //
2006  // Construct block expecting 16 statements.
2007  Block* result =
2008  factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2009  Target target(&this->target_stack_, result);
2010  Expect(Token::LBRACE, CHECK_OK);
2011  while (peek() != Token::RBRACE) {
2012  Statement* stat = ParseStatement(NULL, CHECK_OK);
2013  if (stat && !stat->IsEmpty()) {
2014  result->AddStatement(stat, zone());
2015  }
2016  }
2017  Expect(Token::RBRACE, CHECK_OK);
2018  return result;
2019 }
void Expect(Token::Value token, bool *ok)
Definition: preparser.h:328
Block * ParseScopedBlock(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:2022
Statement * ParseStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:1586

References v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Statement::IsEmpty(), v8::internal::RelocInfo::kNoPosition, NULL, ParseScopedBlock(), ParseStatement(), v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), target_stack_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseStatement(), and ParseTryStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseBlockElement()

Statement * v8::internal::Parser::ParseBlockElement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 1553 of file parser.cc.

1554  {
1555  // (Ecma 262 5th Edition, clause 14):
1556  // SourceElement:
1557  // Statement
1558  // FunctionDeclaration
1559  //
1560  // In harmony mode we allow additionally the following productions
1561  // BlockElement (aka SourceElement):
1562  // LetDeclaration
1563  // ConstDeclaration
1564  // GeneratorDeclaration
1565  // ClassDeclaration
1566 
1567  switch (peek()) {
1568  case Token::FUNCTION:
1569  return ParseFunctionDeclaration(NULL, ok);
1570  case Token::CLASS:
1571  return ParseClassDeclaration(NULL, ok);
1572  case Token::CONST:
1574  case Token::LET:
1576  if (strict_mode() == STRICT) {
1578  }
1579  // Fall through.
1580  default:
1581  return ParseStatement(labels, ok);
1582  }
1583 }
Block * ParseVariableStatement(VariableDeclarationContext var_context, ZoneList< const AstRawString * > *names, bool *ok)
Definition: parser.cc:2057
Statement * ParseClassDeclaration(ZoneList< const AstRawString * > *names, bool *ok)
Definition: parser.cc:1954
Statement * ParseFunctionDeclaration(ZoneList< const AstRawString * > *names, bool *ok)
Definition: parser.cc:1917

References v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), v8::internal::CONST, DCHECK, kModuleElement, v8::internal::LET, NULL, ParseClassDeclaration(), ParseFunctionDeclaration(), ParseStatement(), ParseVariableStatement(), v8::internal::STRICT, and v8::internal::ParserBase< ParserTraits >::strict_mode().

Referenced by ParseScopedBlock(), and ParseSourceElements().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseBreakStatement()

Statement * v8::internal::Parser::ParseBreakStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 2515 of file parser.cc.

2516  {
2517  // BreakStatement ::
2518  // 'break' Identifier? ';'
2519 
2520  int pos = peek_position();
2522  const AstRawString* label = NULL;
2523  Token::Value tok = peek();
2524  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2525  tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2526  // ECMA allows "eval" or "arguments" as labels even in strict mode.
2528  }
2529  // Parse labeled break statements that target themselves into
2530  // empty statements, e.g. 'l1: l2: l3: break l2;'
2531  if (label != NULL && ContainsLabel(labels, label)) {
2533  return factory()->NewEmptyStatement(pos);
2534  }
2535  BreakableStatement* target = NULL;
2536  target = LookupBreakTarget(label, CHECK_OK);
2537  if (target == NULL) {
2538  // Illegal break statement.
2539  const char* message = "illegal_break";
2540  if (label != NULL) {
2541  message = "unknown_label";
2542  }
2543  ParserTraits::ReportMessage(message, label);
2544  *ok = false;
2545  return NULL;
2546  }
2548  return factory()->NewBreakStatement(target, pos);
2549 }
IdentifierT ParseIdentifier(AllowEvalOrArgumentsAsIdentifier, bool *ok)
Definition: preparser.h:1637

References v8::internal::BREAK, CHECK_OK, v8::internal::ContainsLabel(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::kAllowEvalOrArguments, LookupBreakTarget(), NULL, v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::ParserTraits::ReportMessage(), and v8::internal::ParserBase< ParserTraits >::scanner().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseCaseClause()

CaseClause * v8::internal::Parser::ParseCaseClause ( bool default_seen_ptr,
bool ok 
)
private

Definition at line 2624 of file parser.cc.

2624  {
2625  // CaseClause ::
2626  // 'case' Expression ':' Statement*
2627  // 'default' ':' Statement*
2628 
2629  Expression* label = NULL; // NULL expression indicates default case
2630  if (peek() == Token::CASE) {
2632  label = ParseExpression(true, CHECK_OK);
2633  } else {
2635  if (*default_seen_ptr) {
2636  ReportMessage("multiple_defaults_in_switch");
2637  *ok = false;
2638  return NULL;
2639  }
2640  *default_seen_ptr = true;
2641  }
2642  Expect(Token::COLON, CHECK_OK);
2643  int pos = position();
2644  ZoneList<Statement*>* statements =
2645  new(zone()) ZoneList<Statement*>(5, zone());
2646  while (peek() != Token::CASE &&
2647  peek() != Token::DEFAULT &&
2648  peek() != Token::RBRACE) {
2649  Statement* stat = ParseStatement(NULL, CHECK_OK);
2650  statements->Add(stat, zone());
2651  }
2652 
2653  return factory()->NewCaseClause(label, statements, pos);
2654 }
ExpressionT ParseExpression(bool accept_IN, bool *ok)
Definition: preparser.h:1870
#define CASE(Name)

References v8::internal::List< T, AllocationPolicy >::Add(), CASE, CHECK_OK, v8::internal::DEFAULT, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), ParseStatement(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::ParserBase< ParserTraits >::ReportMessage(), and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseSwitchStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseClassDeclaration()

Statement * v8::internal::Parser::ParseClassDeclaration ( ZoneList< const AstRawString * > *  names,
bool ok 
)
private

Definition at line 1954 of file parser.cc.

1955  {
1956  // ClassDeclaration ::
1957  // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1958  //
1959  // A ClassDeclaration
1960  //
1961  // class C { ... }
1962  //
1963  // has the same semantics as:
1964  //
1965  // let C = class C { ... };
1966  //
1967  // so rewrite it as such.
1968 
1969  Expect(Token::CLASS, CHECK_OK);
1970  int pos = position();
1971  bool is_strict_reserved = false;
1972  const AstRawString* name =
1973  ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1974  Expression* value = ParseClassLiteral(name, scanner()->location(),
1975  is_strict_reserved, pos, CHECK_OK);
1976 
1977  Block* block = factory()->NewBlock(NULL, 1, true, pos);
1978  VariableMode mode = LET;
1979  VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1980  Declaration* declaration =
1981  factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
1982  Declare(declaration, true, CHECK_OK);
1983 
1984  Token::Value init_op = Token::INIT_LET;
1985  Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
1986  block->AddStatement(
1987  factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
1988  zone());
1989 
1990  if (names) names->Add(name, zone());
1991  return block;
1992 }
ExpressionT ParseClassLiteral(IdentifierT name, Scanner::Location function_name_location, bool name_is_strict_reserved, int pos, bool *ok)
Definition: preparser.h:2721
IdentifierT ParseIdentifierOrStrictReservedWord(bool *is_strict_reserved, bool *ok)
Definition: preparser.h:1664

References v8::internal::List< T, AllocationPolicy >::Add(), CHECK_OK, Declare(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::RelocInfo::kNoPosition, v8::internal::LET, v8::internal::ParserBase< ParserTraits >::mode(), name, NewUnresolved(), v8::internal::Interface::NewValue(), NULL, v8::internal::ParserBase< ParserTraits >::ParseClassLiteral(), v8::internal::ParserBase< ParserTraits >::ParseIdentifierOrStrictReservedWord(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseBlockElement(), ParseExportDeclaration(), ParseModuleElement(), and ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseContinueStatement()

Statement * v8::internal::Parser::ParseContinueStatement ( bool ok)
private

Definition at line 2486 of file parser.cc.

2486  {
2487  // ContinueStatement ::
2488  // 'continue' Identifier? ';'
2489 
2490  int pos = peek_position();
2491  Expect(Token::CONTINUE, CHECK_OK);
2492  const AstRawString* label = NULL;
2493  Token::Value tok = peek();
2494  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2495  tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2496  // ECMA allows "eval" or "arguments" as labels even in strict mode.
2498  }
2499  IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2500  if (target == NULL) {
2501  // Illegal continue statement.
2502  const char* message = "illegal_continue";
2503  if (label != NULL) {
2504  message = "unknown_label";
2505  }
2506  ParserTraits::ReportMessage(message, label);
2507  *ok = false;
2508  return NULL;
2509  }
2511  return factory()->NewContinueStatement(target, pos);
2512 }
IterationStatement * LookupContinueTarget(const AstRawString *label, bool *ok)
Definition: parser.cc:3965

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::kAllowEvalOrArguments, LookupContinueTarget(), NULL, v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::ParserTraits::ReportMessage(), and v8::internal::ParserBase< ParserTraits >::scanner().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseDebuggerStatement()

DebuggerStatement * v8::internal::Parser::ParseDebuggerStatement ( bool ok)
private

Definition at line 3317 of file parser.cc.

3317  {
3318  // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3319  // contexts this is used as a statement which invokes the debugger as i a
3320  // break point is present.
3321  // DebuggerStatement ::
3322  // 'debugger' ';'
3323 
3324  int pos = peek_position();
3325  Expect(Token::DEBUGGER, CHECK_OK);
3327  return factory()->NewDebuggerStatement(pos);
3328 }

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), v8::internal::ParserBase< ParserTraits >::factory(), and v8::internal::ParserBase< ParserTraits >::peek_position().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseDoWhileStatement()

DoWhileStatement * v8::internal::Parser::ParseDoWhileStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 2809 of file parser.cc.

2810  {
2811  // DoStatement ::
2812  // 'do' Statement 'while' '(' Expression ')' ';'
2813 
2814  DoWhileStatement* loop =
2815  factory()->NewDoWhileStatement(labels, peek_position());
2816  Target target(&this->target_stack_, loop);
2817 
2818  Expect(Token::DO, CHECK_OK);
2819  Statement* body = ParseStatement(NULL, CHECK_OK);
2820  Expect(Token::WHILE, CHECK_OK);
2821  Expect(Token::LPAREN, CHECK_OK);
2822 
2823  Expression* cond = ParseExpression(true, CHECK_OK);
2824  Expect(Token::RPAREN, CHECK_OK);
2825 
2826  // Allow do-statements to be terminated with and without
2827  // semi-colons. This allows code such as 'do;while(0)return' to
2828  // parse, which would not be the case if we had used the
2829  // ExpectSemicolon() functionality here.
2830  if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2831 
2832  if (loop != NULL) loop->Initialize(cond, body);
2833  return loop;
2834 }
void Consume(Token::Value token)
Definition: preparser.h:312

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::Consume(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), ParseStatement(), v8::internal::ParserBase< ParserTraits >::peek_position(), and target_stack_.

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseEagerFunctionBody()

ZoneList< Statement * > * v8::internal::Parser::ParseEagerFunctionBody ( const AstRawString function_name,
int  pos,
Variable fvar,
Token::Value  fvar_init_op,
bool  is_generator,
bool ok 
)
private

Definition at line 3767 of file parser.cc.

3769  {
3770  // Everything inside an eagerly parsed function will be parsed eagerly
3771  // (see comment above).
3772  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3773  ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
3774  if (fvar != NULL) {
3775  VariableProxy* fproxy = scope_->NewUnresolved(
3776  factory(), function_name, Interface::NewConst());
3777  fproxy->BindTo(fvar);
3778  body->Add(factory()->NewExpressionStatement(
3779  factory()->NewAssignment(fvar_init_op,
3780  fproxy,
3781  factory()->NewThisFunction(pos),
3784  }
3785 
3786  // For generators, allocate and yield an iterator on function entry.
3787  if (is_generator) {
3788  ZoneList<Expression*>* arguments =
3789  new(zone()) ZoneList<Expression*>(0, zone());
3790  CallRuntime* allocation = factory()->NewCallRuntime(
3791  ast_value_factory()->empty_string(),
3792  Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments,
3793  pos);
3794  VariableProxy* init_proxy = factory()->NewVariableProxy(
3795  function_state_->generator_object_variable());
3796  Assignment* assignment = factory()->NewAssignment(
3797  Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3798  VariableProxy* get_proxy = factory()->NewVariableProxy(
3799  function_state_->generator_object_variable());
3800  Yield* yield = factory()->NewYield(
3801  get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
3802  body->Add(factory()->NewExpressionStatement(
3803  yield, RelocInfo::kNoPosition), zone());
3804  }
3805 
3806  ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK);
3807 
3808  if (is_generator) {
3809  VariableProxy* get_proxy = factory()->NewVariableProxy(
3810  function_state_->generator_object_variable());
3811  Expression* undefined =
3812  factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
3813  Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
3815  body->Add(factory()->NewExpressionStatement(
3816  yield, RelocInfo::kNoPosition), zone());
3817  }
3818 
3819  Expect(Token::RBRACE, CHECK_OK);
3820  scope_->set_end_position(scanner()->location().end_pos);
3821 
3822  return body;
3823 }
static Interface * NewConst()
Definition: interface.h:49
static const Function * FunctionForId(FunctionId id)
Definition: runtime.cc:9312

References v8::internal::List< T, AllocationPolicy >::Add(), ast_value_factory(), CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::function_state_, v8::internal::Runtime::FunctionForId(), v8::internal::ParserBase< ParserTraits >::is_generator(), v8::internal::RelocInfo::kNoPosition, v8::internal::Interface::NewConst(), NULL, v8::internal::ParserBase< ParserTraits >::PARSE_EAGERLY, ParseSourceElements(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by v8::internal::ParserTraits::ParseEagerFunctionBody(), and ParseFunctionLiteral().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseExportDeclaration()

Statement * v8::internal::Parser::ParseExportDeclaration ( bool ok)
private

Definition at line 1460 of file parser.cc.

1460  {
1461  // ExportDeclaration:
1462  // 'export' Identifier (',' Identifier)* ';'
1463  // 'export' VariableDeclaration
1464  // 'export' FunctionDeclaration
1465  // 'export' GeneratorDeclaration
1466  // 'export' ModuleDeclaration
1467  //
1468  // TODO(ES6): implement structuring ExportSpecifiers
1469 
1470  Expect(Token::EXPORT, CHECK_OK);
1471 
1472  Statement* result = NULL;
1473  ZoneList<const AstRawString*> names(1, zone());
1474  switch (peek()) {
1475  case Token::IDENTIFIER: {
1476  int pos = position();
1477  const AstRawString* name =
1479  // Handle 'module' as a context-sensitive keyword.
1480  if (name != ast_value_factory()->module_string()) {
1481  names.Add(name, zone());
1482  while (peek() == Token::COMMA) {
1485  names.Add(name, zone());
1486  }
1488  result = factory()->NewEmptyStatement(pos);
1489  } else {
1490  result = ParseModuleDeclaration(&names, CHECK_OK);
1491  }
1492  break;
1493  }
1494 
1495  case Token::FUNCTION:
1496  result = ParseFunctionDeclaration(&names, CHECK_OK);
1497  break;
1498 
1499  case Token::CLASS:
1500  result = ParseClassDeclaration(&names, CHECK_OK);
1501  break;
1502 
1503  case Token::VAR:
1504  case Token::LET:
1505  case Token::CONST:
1506  result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1507  break;
1508 
1509  default:
1510  *ok = false;
1511  ReportUnexpectedToken(scanner()->current_token());
1512  return NULL;
1513  }
1514 
1515  // Every export of a module may be assigned.
1516  for (int i = 0; i < names.length(); ++i) {
1517  Variable* var = scope_->Lookup(names[i]);
1518  if (var == NULL) {
1519  // TODO(sigurds) This is an export that has no definition yet,
1520  // not clear what to do in this case.
1521  continue;
1522  }
1523  if (!IsImmutableVariableMode(var->mode())) {
1524  var->set_maybe_assigned();
1525  }
1526  }
1527 
1528  // Extract declared names into export declarations and interface.
1529  Interface* interface = scope_->interface();
1530  for (int i = 0; i < names.length(); ++i) {
1531 #ifdef DEBUG
1532  if (FLAG_print_interface_details)
1533  PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data());
1534 #endif
1535  Interface* inner = Interface::NewUnknown(zone());
1536  interface->Add(names[i], inner, zone(), CHECK_OK);
1537  if (!*ok)
1538  return NULL;
1539  VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1540  USE(proxy);
1541  // TODO(rossberg): Rethink whether we actually need to store export
1542  // declarations (for compilation?).
1543  // ExportDeclaration* declaration =
1544  // factory()->NewExportDeclaration(proxy, scope_, position);
1545  // scope_->AddDeclaration(declaration);
1546  }
1547 
1548  DCHECK(result != NULL);
1549  return result;
1550 }
static Interface * NewUnknown(Zone *zone)
Definition: interface.h:40
void ReportUnexpectedToken(Token::Value token)
Definition: preparser.h:1608
Statement * ParseModuleDeclaration(ZoneList< const AstRawString * > *names, bool *ok)
Definition: parser.cc:1193
#define COMMA
void USE(T)
Definition: macros.h:322
bool IsImmutableVariableMode(VariableMode mode)
Definition: globals.h:715

References v8::internal::List< T, AllocationPolicy >::Add(), ast_value_factory(), CHECK_OK, COMMA, v8::internal::CONST, v8::internal::ParserBase< ParserTraits >::Consume(), DCHECK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::IsImmutableVariableMode(), v8::internal::ParserBase< ParserTraits >::kDontAllowEvalOrArguments, kModuleElement, v8::internal::LET, v8::internal::Variable::mode(), name, v8::internal::Interface::NewUnknown(), NewUnresolved(), NULL, ParseClassDeclaration(), ParseFunctionDeclaration(), v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), ParseModuleDeclaration(), ParseVariableStatement(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::PrintF(), v8::internal::ParserBase< ParserTraits >::ReportUnexpectedToken(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Variable::set_maybe_assigned(), USE(), v8::internal::VAR, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseModuleElement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseExpressionOrLabelledStatement()

Statement * v8::internal::Parser::ParseExpressionOrLabelledStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 2400 of file parser.cc.

2401  {
2402  // ExpressionStatement | LabelledStatement ::
2403  // Expression ';'
2404  // Identifier ':' Statement
2405  int pos = peek_position();
2406  bool starts_with_idenfifier = peek_any_identifier();
2407  Expression* expr = ParseExpression(true, CHECK_OK);
2408  if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2409  expr->AsVariableProxy() != NULL &&
2410  !expr->AsVariableProxy()->is_this()) {
2411  // Expression is a single identifier, and not, e.g., a parenthesized
2412  // identifier.
2413  VariableProxy* var = expr->AsVariableProxy();
2414  const AstRawString* label = var->raw_name();
2415  // TODO(1240780): We don't check for redeclaration of labels
2416  // during preparsing since keeping track of the set of active
2417  // labels requires nontrivial changes to the way scopes are
2418  // structured. However, these are probably changes we want to
2419  // make later anyway so we should go back and fix this then.
2420  if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2421  ParserTraits::ReportMessage("label_redeclaration", label);
2422  *ok = false;
2423  return NULL;
2424  }
2425  if (labels == NULL) {
2426  labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2427  }
2428  labels->Add(label, zone());
2429  // Remove the "ghost" variable that turned out to be a label
2430  // from the top scope. This way, we don't try to resolve it
2431  // during the scope processing.
2432  scope_->RemoveUnresolved(var);
2433  Expect(Token::COLON, CHECK_OK);
2434  return ParseStatement(labels, ok);
2435  }
2436 
2437  // If we have an extension, we allow a native function declaration.
2438  // A native function declaration starts with "native function" with
2439  // no line-terminator between the two words.
2440  if (extension_ != NULL && peek() == Token::FUNCTION &&
2441  !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2442  expr->AsVariableProxy() != NULL &&
2443  expr->AsVariableProxy()->raw_name() ==
2444  ast_value_factory()->native_string() &&
2445  !scanner()->literal_contains_escapes()) {
2446  return ParseNativeDeclaration(ok);
2447  }
2448 
2449  // Parsed expression statement, or the context-sensitive 'module' keyword.
2450  // Only expect semicolon in the former case.
2451  if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER ||
2452  scanner()->HasAnyLineTerminatorBeforeNext() ||
2453  expr->AsVariableProxy() == NULL ||
2454  expr->AsVariableProxy()->raw_name() !=
2455  ast_value_factory()->module_string() ||
2456  scanner()->literal_contains_escapes()) {
2458  }
2459  return factory()->NewExpressionStatement(expr, pos);
2460 }
bool TargetStackContainsLabel(const AstRawString *label)
Definition: parser.cc:3939
Statement * ParseNativeDeclaration(bool *ok)
Definition: parser.cc:1878

References v8::internal::List< T, AllocationPolicy >::Add(), ast_value_factory(), CHECK_OK, v8::internal::ContainsLabel(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), v8::internal::ParserBase< ParserTraits >::extension_, v8::internal::ParserBase< ParserTraits >::factory(), NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), ParseNativeDeclaration(), ParseStatement(), v8::internal::ParserBase< ParserTraits >::peek_any_identifier(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::ParserTraits::ReportMessage(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, TargetStackContainsLabel(), and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseForStatement()

Statement * v8::internal::Parser::ParseForStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 3097 of file parser.cc.

3098  {
3099  // ForStatement ::
3100  // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3101 
3102  int pos = peek_position();
3103  Statement* init = NULL;
3104  ZoneList<const AstRawString*> let_bindings(1, zone());
3105 
3106  // Create an in-between scope for let-bound iteration variables.
3107  Scope* saved_scope = scope_;
3108  Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3109  scope_ = for_scope;
3110 
3111  Expect(Token::FOR, CHECK_OK);
3112  Expect(Token::LPAREN, CHECK_OK);
3113  for_scope->set_start_position(scanner()->location().beg_pos);
3114  if (peek() != Token::SEMICOLON) {
3115  if (peek() == Token::VAR || peek() == Token::CONST) {
3116  bool is_const = peek() == Token::CONST;
3117  const AstRawString* name = NULL;
3119  Block* variable_statement =
3121  CHECK_OK);
3122  bool accept_OF = decl_props == kHasNoInitializers;
3124 
3125  if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
3126  Interface* interface =
3127  is_const ? Interface::NewConst() : Interface::NewValue();
3128  ForEachStatement* loop =
3129  factory()->NewForEachStatement(mode, labels, pos);
3130  Target target(&this->target_stack_, loop);
3131 
3132  Expression* enumerable = ParseExpression(true, CHECK_OK);
3133  Expect(Token::RPAREN, CHECK_OK);
3134 
3135  VariableProxy* each =
3136  scope_->NewUnresolved(factory(), name, interface);
3137  Statement* body = ParseStatement(NULL, CHECK_OK);
3138  InitializeForEachStatement(loop, each, enumerable, body);
3139  Block* result =
3140  factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3141  result->AddStatement(variable_statement, zone());
3142  result->AddStatement(loop, zone());
3143  scope_ = saved_scope;
3144  for_scope->set_end_position(scanner()->location().end_pos);
3145  for_scope = for_scope->FinalizeBlockScope();
3146  DCHECK(for_scope == NULL);
3147  // Parsed for-in loop w/ variable/const declaration.
3148  return result;
3149  } else {
3150  init = variable_statement;
3151  }
3152  } else if (peek() == Token::LET && strict_mode() == STRICT) {
3154  const AstRawString* name = NULL;
3156  Block* variable_statement =
3157  ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3158  &name, CHECK_OK);
3159  bool accept_IN = name != NULL && decl_props != kHasInitializers;
3160  bool accept_OF = decl_props == kHasNoInitializers;
3162 
3163  if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
3164  // Rewrite a for-in statement of the form
3165  //
3166  // for (let x in e) b
3167  //
3168  // into
3169  //
3170  // <let x' be a temporary variable>
3171  // for (x' in e) {
3172  // let x;
3173  // x = x';
3174  // b;
3175  // }
3176 
3177  // TODO(keuchel): Move the temporary variable to the block scope, after
3178  // implementing stack allocated block scoped variables.
3179  Variable* temp = scope_->DeclarationScope()->NewTemporary(
3180  ast_value_factory()->dot_for_string());
3181  VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3182  ForEachStatement* loop =
3183  factory()->NewForEachStatement(mode, labels, pos);
3184  Target target(&this->target_stack_, loop);
3185 
3186  // The expression does not see the loop variable.
3187  scope_ = saved_scope;
3188  Expression* enumerable = ParseExpression(true, CHECK_OK);
3189  scope_ = for_scope;
3190  Expect(Token::RPAREN, CHECK_OK);
3191 
3192  VariableProxy* each =
3193  scope_->NewUnresolved(factory(), name, Interface::NewValue());
3194  Statement* body = ParseStatement(NULL, CHECK_OK);
3195  Block* body_block =
3196  factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3197  Assignment* assignment = factory()->NewAssignment(
3198  Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
3199  Statement* assignment_statement = factory()->NewExpressionStatement(
3200  assignment, RelocInfo::kNoPosition);
3201  body_block->AddStatement(variable_statement, zone());
3202  body_block->AddStatement(assignment_statement, zone());
3203  body_block->AddStatement(body, zone());
3204  InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3205  scope_ = saved_scope;
3206  for_scope->set_end_position(scanner()->location().end_pos);
3207  for_scope = for_scope->FinalizeBlockScope();
3208  body_block->set_scope(for_scope);
3209  // Parsed for-in loop w/ let declaration.
3210  return loop;
3211 
3212  } else {
3213  init = variable_statement;
3214  }
3215  } else {
3216  Scanner::Location lhs_location = scanner()->peek_location();
3217  Expression* expression = ParseExpression(false, CHECK_OK);
3219  bool accept_OF = expression->AsVariableProxy();
3220 
3221  if (CheckInOrOf(accept_OF, &mode)) {
3222  expression = this->CheckAndRewriteReferenceExpression(
3223  expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3224 
3225  ForEachStatement* loop =
3226  factory()->NewForEachStatement(mode, labels, pos);
3227  Target target(&this->target_stack_, loop);
3228 
3229  Expression* enumerable = ParseExpression(true, CHECK_OK);
3230  Expect(Token::RPAREN, CHECK_OK);
3231 
3232  Statement* body = ParseStatement(NULL, CHECK_OK);
3233  InitializeForEachStatement(loop, expression, enumerable, body);
3234  scope_ = saved_scope;
3235  for_scope->set_end_position(scanner()->location().end_pos);
3236  for_scope = for_scope->FinalizeBlockScope();
3237  DCHECK(for_scope == NULL);
3238  // Parsed for-in loop.
3239  return loop;
3240 
3241  } else {
3242  init = factory()->NewExpressionStatement(
3243  expression, RelocInfo::kNoPosition);
3244  }
3245  }
3246  }
3247 
3248  // Standard 'for' loop
3249  ForStatement* loop = factory()->NewForStatement(labels, pos);
3250  Target target(&this->target_stack_, loop);
3251 
3252  // Parsed initializer at this point.
3253  Expect(Token::SEMICOLON, CHECK_OK);
3254 
3255  // If there are let bindings, then condition and the next statement of the
3256  // for loop must be parsed in a new scope.
3257  Scope* inner_scope = NULL;
3258  if (let_bindings.length() > 0) {
3259  inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3260  inner_scope->set_start_position(scanner()->location().beg_pos);
3261  scope_ = inner_scope;
3262  }
3263 
3264  Expression* cond = NULL;
3265  if (peek() != Token::SEMICOLON) {
3266  cond = ParseExpression(true, CHECK_OK);
3267  }
3268  Expect(Token::SEMICOLON, CHECK_OK);
3269 
3270  Statement* next = NULL;
3271  if (peek() != Token::RPAREN) {
3272  Expression* exp = ParseExpression(true, CHECK_OK);
3273  next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
3274  }
3275  Expect(Token::RPAREN, CHECK_OK);
3276 
3277  Statement* body = ParseStatement(NULL, CHECK_OK);
3278 
3279  Statement* result = NULL;
3280  if (let_bindings.length() > 0) {
3281  scope_ = for_scope;
3282  result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop,
3283  init, cond, next, body, CHECK_OK);
3284  scope_ = saved_scope;
3285  for_scope->set_end_position(scanner()->location().end_pos);
3286  } else {
3287  scope_ = saved_scope;
3288  for_scope->set_end_position(scanner()->location().end_pos);
3289  for_scope = for_scope->FinalizeBlockScope();
3290  if (for_scope) {
3291  // Rewrite a for statement of the form
3292  // for (const x = i; c; n) b
3293  //
3294  // into
3295  //
3296  // {
3297  // const x = i;
3298  // for (; c; n) b
3299  // }
3300  DCHECK(init != NULL);
3301  Block* block =
3302  factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3303  block->AddStatement(init, zone());
3304  block->AddStatement(loop, zone());
3305  block->set_scope(for_scope);
3306  loop->Initialize(NULL, cond, next, body);
3307  result = block;
3308  } else {
3309  loop->Initialize(init, cond, next, body);
3310  result = loop;
3311  }
3312  }
3313  return result;
3314 }
ExpressionT CheckAndRewriteReferenceExpression(ExpressionT expression, Scanner::Location location, const char *message, bool *ok)
Definition: preparser.h:2782
Block * ParseVariableDeclarations(VariableDeclarationContext var_context, VariableDeclarationProperties *decl_props, ZoneList< const AstRawString * > *names, const AstRawString **out, bool *ok)
Definition: parser.cc:2076
Statement * DesugarLetBindingsInForStatement(Scope *inner_scope, ZoneList< const AstRawString * > *names, ForStatement *loop, Statement *init, Expression *cond, Statement *next, Statement *body, bool *ok)
Definition: parser.cc:2938
bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode *visit_mode)
Definition: parser.cc:2856
void InitializeForEachStatement(ForEachStatement *stmt, Expression *each, Expression *subject, Statement *body)
Definition: parser.cc:2869
Location peek_location() const
Definition: scanner.h:363

References v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), ast_value_factory(), v8::internal::BLOCK_SCOPE, CHECK_OK, v8::internal::ParserBase< ParserTraits >::CheckAndRewriteReferenceExpression(), CheckInOrOf(), v8::internal::CONST, DCHECK, DesugarLetBindingsInForStatement(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Scope::FinalizeBlockScope(), InitializeForEachStatement(), kForStatement, kHasInitializers, kHasNoInitializers, v8::internal::RelocInfo::kNoPosition, v8::internal::LET, v8::internal::ParserBase< ParserTraits >::mode(), name, NewScope(), NewUnresolved(), v8::internal::Interface::NewValue(), NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), ParseStatement(), ParseVariableDeclarations(), v8::internal::Scanner::peek_location(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Scope::set_end_position(), v8::internal::Scope::set_start_position(), v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), target_stack_, v8::internal::VAR, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseFunctionDeclaration()

Statement * v8::internal::Parser::ParseFunctionDeclaration ( ZoneList< const AstRawString * > *  names,
bool ok 
)
private

Definition at line 1917 of file parser.cc.

1918  {
1919  // FunctionDeclaration ::
1920  // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1921  // GeneratorDeclaration ::
1922  // 'function' '*' Identifier '(' FormalParameterListopt ')'
1923  // '{' FunctionBody '}'
1924  Expect(Token::FUNCTION, CHECK_OK);
1925  int pos = position();
1926  bool is_generator = Check(Token::MUL);
1927  bool is_strict_reserved = false;
1928  const AstRawString* name = ParseIdentifierOrStrictReservedWord(
1929  &is_strict_reserved, CHECK_OK);
1930  FunctionLiteral* fun =
1931  ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
1934  pos, FunctionLiteral::DECLARATION,
1935  FunctionLiteral::NORMAL_ARITY, CHECK_OK);
1936  // Even if we're not at the top-level of the global or a function
1937  // scope, we treat it as such and introduce the function with its
1938  // initial value upon entering the corresponding scope.
1939  // In ES6, a function behaves as a lexical binding, except in the
1940  // global scope, or the initial scope of eval or another function.
1941  VariableMode mode =
1943  !(scope_->is_global_scope() || scope_->is_eval_scope() ||
1944  scope_->is_function_scope()) ? LET : VAR;
1945  VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1946  Declaration* declaration =
1947  factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
1948  Declare(declaration, true, CHECK_OK);
1949  if (names) names->Add(name, zone());
1950  return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1951 }
FunctionLiteral * ParseFunctionLiteral(const AstRawString *name, Scanner::Location function_name_location, bool name_is_strict_reserved, FunctionKind kind, int function_token_position, FunctionLiteral::FunctionType type, FunctionLiteral::ArityRestriction arity_restriction, bool *ok)
Definition: parser.cc:3436
@ kGeneratorFunction
Definition: globals.h:778

References v8::internal::List< T, AllocationPolicy >::Add(), v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), v8::internal::ParserBase< ParserTraits >::Check(), CHECK_OK, Declare(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::is_generator(), v8::internal::kGeneratorFunction, v8::internal::RelocInfo::kNoPosition, v8::internal::kNormalFunction, v8::internal::LET, v8::internal::ParserBase< ParserTraits >::mode(), v8::internal::MUL, name, NewUnresolved(), v8::internal::Interface::NewValue(), ParseFunctionLiteral(), v8::internal::ParserBase< ParserTraits >::ParseIdentifierOrStrictReservedWord(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), v8::internal::VAR, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseBlockElement(), ParseExportDeclaration(), ParseModuleElement(), and ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseFunctionLiteral()

FunctionLiteral * v8::internal::Parser::ParseFunctionLiteral ( const AstRawString name,
Scanner::Location  function_name_location,
bool  name_is_strict_reserved,
FunctionKind  kind,
int  function_token_position,
FunctionLiteral::FunctionType  type,
FunctionLiteral::ArityRestriction  arity_restriction,
bool ok 
)
private

Definition at line 3436 of file parser.cc.

3440  {
3441  // Function ::
3442  // '(' FormalParameterList? ')' '{' FunctionBody '}'
3443  //
3444  // Getter ::
3445  // '(' ')' '{' FunctionBody '}'
3446  //
3447  // Setter ::
3448  // '(' PropertySetParameterList ')' '{' FunctionBody '}'
3449 
3450  int pos = function_token_pos == RelocInfo::kNoPosition
3451  ? peek_position() : function_token_pos;
3452 
3453  bool is_generator = IsGeneratorFunction(kind);
3454 
3455  // Anonymous functions were passed either the empty symbol or a null
3456  // handle as the function name. Remember if we were passed a non-empty
3457  // handle to decide whether to invoke function name inference.
3458  bool should_infer_name = function_name == NULL;
3459 
3460  // We want a non-null handle as the function name.
3461  if (should_infer_name) {
3462  function_name = ast_value_factory()->empty_string();
3463  }
3464 
3465  int num_parameters = 0;
3466  // Function declarations are function scoped in normal mode, so they are
3467  // hoisted. In harmony block scoping mode they are block scoped, so they
3468  // are not hoisted.
3469  //
3470  // One tricky case are function declarations in a local sloppy-mode eval:
3471  // their declaration is hoisted, but they still see the local scope. E.g.,
3472  //
3473  // function() {
3474  // var x = 0
3475  // try { throw 1 } catch (x) { eval("function g() { return x }") }
3476  // return g()
3477  // }
3478  //
3479  // needs to return 1. To distinguish such cases, we need to detect
3480  // (1) whether a function stems from a sloppy eval, and
3481  // (2) whether it actually hoists across the eval.
3482  // Unfortunately, we do not represent sloppy eval scopes, so we do not have
3483  // either information available directly, especially not when lazily compiling
3484  // a function like 'g'. We hence rely on the following invariants:
3485  // - (1) is the case iff the innermost scope of the deserialized scope chain
3486  // under which we compile is _not_ a declaration scope. This holds because
3487  // in all normal cases, function declarations are fully hoisted to a
3488  // declaration scope and compiled relative to that.
3489  // - (2) is the case iff the current declaration scope is still the original
3490  // one relative to the deserialized scope chain. Otherwise we must be
3491  // compiling a function in an inner declaration scope in the eval, e.g. a
3492  // nested function, and hoisting works normally relative to that.
3493  Scope* declaration_scope = scope_->DeclarationScope();
3494  Scope* original_declaration_scope = original_scope_->DeclarationScope();
3495  Scope* scope =
3496  function_type == FunctionLiteral::DECLARATION &&
3497  (!allow_harmony_scoping() || strict_mode() == SLOPPY) &&
3498  (original_scope_ == original_declaration_scope ||
3499  declaration_scope != original_declaration_scope)
3500  ? NewScope(declaration_scope, FUNCTION_SCOPE)
3502  ZoneList<Statement*>* body = NULL;
3503  int materialized_literal_count = -1;
3504  int expected_property_count = -1;
3505  int handler_count = 0;
3506  FunctionLiteral::ParameterFlag duplicate_parameters =
3507  FunctionLiteral::kNoDuplicateParameters;
3508  FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3509  ? FunctionLiteral::kIsParenthesized
3510  : FunctionLiteral::kNotParenthesized;
3511  AstProperties ast_properties;
3512  BailoutReason dont_optimize_reason = kNoReason;
3513  // Parse function body.
3514  {
3515  FunctionState function_state(&function_state_, &scope_, scope, zone(),
3517  info()->ast_node_id_gen());
3518  scope_->SetScopeName(function_name);
3519 
3520  if (is_generator) {
3521  // For generators, allocating variables in contexts is currently a win
3522  // because it minimizes the work needed to suspend and resume an
3523  // activation.
3524  scope_->ForceContextAllocation();
3525 
3526  // Calling a generator returns a generator object. That object is stored
3527  // in a temporary variable, a definition that is used by "yield"
3528  // expressions. This also marks the FunctionState as a generator.
3529  Variable* temp = scope_->DeclarationScope()->NewTemporary(
3530  ast_value_factory()->dot_generator_object_string());
3531  function_state.set_generator_object_variable(temp);
3532  }
3533 
3534  // FormalParameterList ::
3535  // '(' (Identifier)*[','] ')'
3536  Expect(Token::LPAREN, CHECK_OK);
3537  scope->set_start_position(scanner()->location().beg_pos);
3538 
3539  // We don't yet know if the function will be strict, so we cannot yet
3540  // produce errors for parameter names or duplicates. However, we remember
3541  // the locations of these errors if they occur and produce the errors later.
3542  Scanner::Location eval_args_error_log = Scanner::Location::invalid();
3543  Scanner::Location dupe_error_loc = Scanner::Location::invalid();
3544  Scanner::Location reserved_loc = Scanner::Location::invalid();
3545 
3546  bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3547  (peek() == Token::RPAREN &&
3548  arity_restriction != FunctionLiteral::SETTER_ARITY);
3549  while (!done) {
3550  bool is_strict_reserved = false;
3551  const AstRawString* param_name =
3552  ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3553 
3554  // Store locations for possible future error reports.
3555  if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
3556  eval_args_error_log = scanner()->location();
3557  }
3558  if (!reserved_loc.IsValid() && is_strict_reserved) {
3559  reserved_loc = scanner()->location();
3560  }
3561  if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
3562  duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3563  dupe_error_loc = scanner()->location();
3564  }
3565 
3566  Variable* var = scope_->DeclareParameter(param_name, VAR);
3567  if (scope->strict_mode() == SLOPPY) {
3568  // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3569  // conservative approximation necessary to account for parameters
3570  // that are assigned via the arguments array.
3571  var->set_maybe_assigned();
3572  }
3573 
3574  num_parameters++;
3575  if (num_parameters > Code::kMaxArguments) {
3576  ReportMessage("too_many_parameters");
3577  *ok = false;
3578  return NULL;
3579  }
3580  if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
3581  done = (peek() == Token::RPAREN);
3582  if (!done) Expect(Token::COMMA, CHECK_OK);
3583  }
3584  Expect(Token::RPAREN, CHECK_OK);
3585 
3586  Expect(Token::LBRACE, CHECK_OK);
3587 
3588  // If we have a named function expression, we add a local variable
3589  // declaration to the body of the function with the name of the
3590  // function and let it refer to the function itself (closure).
3591  // NOTE: We create a proxy and resolve it here so that in the
3592  // future we can change the AST to only refer to VariableProxies
3593  // instead of Variables and Proxis as is the case now.
3594  Variable* fvar = NULL;
3595  Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3596  if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3597  if (allow_harmony_scoping() && strict_mode() == STRICT) {
3598  fvar_init_op = Token::INIT_CONST;
3599  }
3600  VariableMode fvar_mode =
3602  ? CONST : CONST_LEGACY;
3603  DCHECK(function_name != NULL);
3604  fvar = new (zone())
3605  Variable(scope_, function_name, fvar_mode, true /* is valid LHS */,
3608  VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3609  VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3610  proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3611  scope_->DeclareFunctionVar(fvar_declaration);
3612  }
3613 
3614  // Determine if the function can be parsed lazily. Lazy parsing is different
3615  // from lazy compilation; we need to parse more eagerly than we compile.
3616 
3617  // We can only parse lazily if we also compile lazily. The heuristics for
3618  // lazy compilation are:
3619  // - It must not have been prohibited by the caller to Parse (some callers
3620  // need a full AST).
3621  // - The outer scope must allow lazy compilation of inner functions.
3622  // - The function mustn't be a function expression with an open parenthesis
3623  // before; we consider that a hint that the function will be called
3624  // immediately, and it would be a waste of time to make it lazily
3625  // compiled.
3626  // These are all things we can know at this point, without looking at the
3627  // function itself.
3628 
3629  // In addition, we need to distinguish between these cases:
3630  // (function foo() {
3631  // bar = function() { return 1; }
3632  // })();
3633  // and
3634  // (function foo() {
3635  // var a = 1;
3636  // bar = function() { return a; }
3637  // })();
3638 
3639  // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3640  // parenthesis before the function means that it will be called
3641  // immediately). The inner function *must* be parsed eagerly to resolve the
3642  // possible reference to the variable in foo's scope. However, it's possible
3643  // that it will be compiled lazily.
3644 
3645  // To make this additional case work, both Parser and PreParser implement a
3646  // logic where only top-level functions will be parsed lazily.
3647  bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3648  scope_->AllowsLazyCompilation() &&
3650  parenthesized_function_ = false; // The bit was set for this function only.
3651 
3652  if (is_lazily_parsed) {
3653  SkipLazyFunctionBody(function_name, &materialized_literal_count,
3654  &expected_property_count, CHECK_OK);
3655  } else {
3656  body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
3658  materialized_literal_count = function_state.materialized_literal_count();
3659  expected_property_count = function_state.expected_property_count();
3660  handler_count = function_state.handler_count();
3661  }
3662 
3663  // Validate strict mode.
3664  // Concise methods use StrictFormalParameters.
3665  if (strict_mode() == STRICT || IsConciseMethod(kind)) {
3667  name_is_strict_reserved,
3668  function_name_location,
3669  eval_args_error_log,
3670  dupe_error_loc,
3671  reserved_loc,
3672  CHECK_OK);
3673  }
3674  if (strict_mode() == STRICT) {
3675  CheckOctalLiteral(scope->start_position(),
3676  scope->end_position(),
3677  CHECK_OK);
3678  }
3679  ast_properties = *factory()->visitor()->ast_properties();
3680  dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
3681 
3682  if (allow_harmony_scoping() && strict_mode() == STRICT) {
3684  }
3685  }
3686 
3687  FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3688  function_name, ast_value_factory(), scope, body,
3689  materialized_literal_count, expected_property_count, handler_count,
3690  num_parameters, duplicate_parameters, function_type,
3691  FunctionLiteral::kIsFunction, parenthesized, kind, pos);
3692  function_literal->set_function_token_position(function_token_pos);
3693  function_literal->set_ast_properties(&ast_properties);
3694  function_literal->set_dont_optimize_reason(dont_optimize_reason);
3695 
3696  if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3697  return function_literal;
3698 }
static const int kMaxArguments
Definition: objects.h:5445
void AddFunction(FunctionLiteral *func_to_infer)
AstNode::IdGen * ast_node_id_gen() const
Definition: preparser.h:292
void CheckStrictFunctionNameAndParameters(IdentifierT function_name, bool function_name_is_strict_reserved, const Scanner::Location &function_name_loc, const Scanner::Location &eval_args_error_loc, const Scanner::Location &dupe_error_loc, const Scanner::Location &reserved_loc, bool *ok)
Definition: preparser.h:394
bool IsEvalOrArguments(const AstRawString *identifier) const
Definition: parser.cc:364
void SkipLazyFunctionBody(const AstRawString *function_name, int *materialized_literal_count, int *expected_property_count, bool *ok)
Definition: parser.cc:3701
ZoneList< Statement * > * ParseEagerFunctionBody(const AstRawString *function_name, int pos, Variable *fvar, Token::Value fvar_init_op, bool is_generator, bool *ok)
Definition: parser.cc:3767
Scope * DeclarationScope()
Definition: scopes.cc:737
@ kCreatedInitialized
Definition: globals.h:753
bool IsGeneratorFunction(FunctionKind kind)
Definition: globals.h:799
bool IsConciseMethod(FunctionKind kind)
Definition: globals.h:805
@ FUNCTION_SCOPE
Definition: globals.h:647

References v8::internal::FuncNameInferrer::AddFunction(), v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), v8::internal::ParserBase< ParserTraits >::ast_node_id_gen(), ast_value_factory(), CHECK_OK, CheckConflictingVarDeclarations(), v8::internal::ParserBase< ParserTraits >::CheckOctalLiteral(), v8::internal::ParserBase< ParserTraits >::CheckStrictFunctionNameAndParameters(), COMMA, v8::internal::CONST, v8::internal::CONST_LEGACY, DCHECK, v8::internal::Scope::DeclarationScope(), v8::internal::Scope::end_position(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::fni_, v8::internal::FUNCTION_SCOPE, v8::internal::ParserBase< ParserTraits >::function_state_, info(), v8::internal::Scanner::Location::invalid(), v8::internal::ParserBase< ParserTraits >::is_generator(), v8::internal::IsConciseMethod(), v8::internal::ParserTraits::IsEvalOrArguments(), v8::internal::IsGeneratorFunction(), v8::internal::Scanner::Location::IsValid(), v8::internal::kCreatedInitialized, v8::internal::Code::kMaxArguments, v8::internal::RelocInfo::kNoPosition, v8::internal::kNotAssigned, v8::internal::Scanner::location(), v8::internal::ParserBase< ParserTraits >::mode(), v8::internal::Interface::NewConst(), NewScope(), v8::internal::Variable::NORMAL, NULL, original_scope_, v8::internal::ParserBase< ParserTraits >::parenthesized_function_, v8::internal::ParserBase< ParserTraits >::PARSE_LAZILY, ParseEagerFunctionBody(), v8::internal::ParserBase< ParserTraits >::ParseIdentifierOrStrictReservedWord(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::ParserBase< ParserTraits >::ReportMessage(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Variable::set_maybe_assigned(), v8::internal::Scope::set_start_position(), SkipLazyFunctionBody(), v8::internal::SLOPPY, v8::internal::Scope::start_position(), v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), v8::internal::Scope::strict_mode(), v8::internal::VAR, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseFunctionDeclaration(), v8::internal::ParserTraits::ParseFunctionLiteral(), and ParseLazy().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseIfStatement()

IfStatement * v8::internal::Parser::ParseIfStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 2463 of file parser.cc.

2464  {
2465  // IfStatement ::
2466  // 'if' '(' Expression ')' Statement ('else' Statement)?
2467 
2468  int pos = peek_position();
2469  Expect(Token::IF, CHECK_OK);
2470  Expect(Token::LPAREN, CHECK_OK);
2471  Expression* condition = ParseExpression(true, CHECK_OK);
2472  Expect(Token::RPAREN, CHECK_OK);
2473  Statement* then_statement = ParseStatement(labels, CHECK_OK);
2474  Statement* else_statement = NULL;
2475  if (peek() == Token::ELSE) {
2476  Next();
2477  else_statement = ParseStatement(labels, CHECK_OK);
2478  } else {
2479  else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2480  }
2481  return factory()->NewIfStatement(
2482  condition, then_statement, else_statement, pos);
2483 }

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::RelocInfo::kNoPosition, NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), ParseStatement(), and v8::internal::ParserBase< ParserTraits >::peek_position().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseImportDeclaration()

Block * v8::internal::Parser::ParseImportDeclaration ( bool ok)
private

Definition at line 1406 of file parser.cc.

1406  {
1407  // ImportDeclaration:
1408  // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1409  //
1410  // TODO(ES6): implement destructuring ImportSpecifiers
1411 
1412  int pos = peek_position();
1413  Expect(Token::IMPORT, CHECK_OK);
1414  ZoneList<const AstRawString*> names(1, zone());
1415 
1416  const AstRawString* name = ParseIdentifierName(CHECK_OK);
1417  names.Add(name, zone());
1418  while (peek() == Token::COMMA) {
1421  names.Add(name, zone());
1422  }
1423 
1425  Module* module = ParseModuleSpecifier(CHECK_OK);
1427 
1428  // Generate a separate declaration for each identifier.
1429  // TODO(ES6): once we implement destructuring, make that one declaration.
1430  Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
1431  for (int i = 0; i < names.length(); ++i) {
1432 #ifdef DEBUG
1433  if (FLAG_print_interface_details)
1434  PrintF("# Import %.*s ", name->length(), name->raw_data());
1435 #endif
1436  Interface* interface = Interface::NewUnknown(zone());
1437  module->interface()->Add(names[i], interface, zone(), ok);
1438  if (!*ok) {
1439 #ifdef DEBUG
1440  if (FLAG_print_interfaces) {
1441  PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(),
1442  name->raw_data());
1443  PrintF("module: ");
1444  module->interface()->Print();
1445  }
1446 #endif
1447  ParserTraits::ReportMessage("invalid_module_path", name);
1448  return NULL;
1449  }
1450  VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1451  Declaration* declaration =
1452  factory()->NewImportDeclaration(proxy, module, scope_, pos);
1453  Declare(declaration, true, CHECK_OK);
1454  }
1455 
1456  return block;
1457 }
void Add(const AstRawString *name, Interface *interface, Zone *zone, bool *ok)
Definition: interface.h:63
IdentifierT ParseIdentifierName(bool *ok)
Definition: preparser.h:1684
void ExpectContextualKeyword(Vector< const char > keyword, bool *ok)
Definition: preparser.h:370
Module * ParseModuleSpecifier(bool *ok)
Definition: parser.cc:1393

References v8::internal::Interface::Add(), v8::internal::List< T, AllocationPolicy >::Add(), CHECK_OK, COMMA, v8::internal::ParserBase< ParserTraits >::Consume(), v8::internal::CStrVector(), Declare(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectContextualKeyword(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Module::interface(), v8::internal::RelocInfo::kNoPosition, v8::internal::LET, name, v8::internal::Interface::NewUnknown(), NewUnresolved(), NULL, v8::internal::ParserBase< ParserTraits >::ParseIdentifierName(), ParseModuleSpecifier(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::PrintF(), v8::internal::ParserTraits::ReportMessage(), v8::internal::ParserBase< ParserTraits >::scope_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseModuleElement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseLazy() [1/2]

FunctionLiteral * v8::internal::Parser::ParseLazy ( )
private

Definition at line 948 of file parser.cc.

948  {
949  // It's OK to use the counters here, since this function is only called in
950  // the main thread.
951  HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy());
952  Handle<String> source(String::cast(script()->source()));
953  isolate()->counters()->total_parse_size()->Increment(source->length());
954  base::ElapsedTimer timer;
955  if (FLAG_trace_parse) {
956  timer.Start();
957  }
958  Handle<SharedFunctionInfo> shared_info = info()->shared_info();
959 
960  // Initialize parser state.
961  source = String::Flatten(source);
962  FunctionLiteral* result;
963  if (source->IsExternalTwoByteString()) {
964  ExternalTwoByteStringUtf16CharacterStream stream(
966  shared_info->start_position(),
967  shared_info->end_position());
968  result = ParseLazy(&stream);
969  } else {
970  GenericStringUtf16CharacterStream stream(source,
971  shared_info->start_position(),
972  shared_info->end_position());
973  result = ParseLazy(&stream);
974  }
975 
976  if (FLAG_trace_parse && result != NULL) {
977  double ms = timer.Elapsed().InMillisecondsF();
978  SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
979  PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
980  }
981  return result;
982 }
Handle< SharedFunctionInfo > shared_info() const
Definition: compiler.h:112
static Handle< T > cast(Handle< S > that)
Definition: handles.h:116
static Handle< String > Flatten(Handle< String > string, PretenureFlag pretenure=NOT_TENURED)
Definition: objects-inl.h:3354

References v8::internal::Isolate::counters(), v8::internal::String::Flatten(), v8::internal::SmartPointerBase< Deallocator, T >::get(), info(), isolate(), NULL, v8::internal::PrintF(), script(), and v8::internal::CompilationInfo::shared_info().

Referenced by Parse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseLazy() [2/2]

FunctionLiteral * v8::internal::Parser::ParseLazy ( Utf16CharacterStream source)
private

Definition at line 985 of file parser.cc.

985  {
986  Handle<SharedFunctionInfo> shared_info = info()->shared_info();
987  scanner_.Initialize(source);
988  DCHECK(scope_ == NULL);
990 
991  Handle<String> name(String::cast(shared_info->name()));
993  fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
994  const AstRawString* raw_name = ast_value_factory()->GetString(name);
995  fni_->PushEnclosingName(raw_name);
996 
997  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
998 
999  // Place holder for the result.
1000  FunctionLiteral* result = NULL;
1001 
1002  {
1003  // Parse the function literal.
1004  Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
1005  info()->SetGlobalScope(scope);
1006  if (!info()->closure().is_null()) {
1007  scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
1008  zone());
1009  }
1010  original_scope_ = scope;
1011  FunctionState function_state(&function_state_, &scope_, scope, zone(),
1013  info()->ast_node_id_gen());
1014  DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
1015  DCHECK(info()->strict_mode() == shared_info->strict_mode());
1016  scope->SetStrictMode(shared_info->strict_mode());
1017  FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1018  ? (shared_info->is_anonymous()
1019  ? FunctionLiteral::ANONYMOUS_EXPRESSION
1020  : FunctionLiteral::NAMED_EXPRESSION)
1021  : FunctionLiteral::DECLARATION;
1022  bool ok = true;
1023 
1024  if (shared_info->is_arrow()) {
1025  Expression* expression = ParseExpression(false, &ok);
1026  DCHECK(expression->IsFunctionLiteral());
1027  result = expression->AsFunctionLiteral();
1028  } else {
1029  result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
1030  false, // Strict mode name already checked.
1031  shared_info->kind(), RelocInfo::kNoPosition,
1032  function_type,
1033  FunctionLiteral::NORMAL_ARITY, &ok);
1034  }
1035  // Make sure the results agree.
1036  DCHECK(ok == (result != NULL));
1037  }
1038 
1039  // Make sure the target stack is empty.
1041 
1042  if (result != NULL) {
1043  Handle<String> inferred_name(shared_info->inferred_name());
1044  result->set_inferred_name(inferred_name);
1045  }
1046  return result;
1047 }
const AstRawString * GetString(Handle< String > literal)
void PushEnclosingName(const AstRawString *name)
void Initialize(Utf16CharacterStream *source)
Definition: scanner.cc:43

References v8::internal::ParserBase< ParserTraits >::ast_node_id_gen(), ast_value_factory(), DCHECK, v8::internal::Scope::DeserializeScopeChain(), v8::internal::ParserBase< ParserTraits >::fni_, v8::internal::ParserBase< ParserTraits >::function_state_, v8::internal::AstValueFactory::GetString(), v8::internal::GLOBAL_SCOPE, info(), v8::internal::Scanner::Initialize(), v8::internal::Scanner::Location::invalid(), v8::internal::RelocInfo::kNoPosition, name, NewScope(), NULL, original_scope_, v8::internal::ParserBase< ParserTraits >::PARSE_EAGERLY, v8::internal::ParserBase< ParserTraits >::ParseExpression(), ParseFunctionLiteral(), v8::internal::FuncNameInferrer::PushEnclosingName(), scanner_, v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::CompilationInfo::SetGlobalScope(), v8::internal::Scope::SetStrictMode(), v8::internal::CompilationInfo::shared_info(), v8::internal::SLOPPY, v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), v8::internal::Scope::strict_mode(), target_stack_, and v8::internal::ParserBase< ParserTraits >::zone().

+ Here is the call graph for this function:

◆ ParseLazyFunctionBodyWithPreParser()

PreParser::PreParseResult v8::internal::Parser::ParseLazyFunctionBodyWithPreParser ( SingletonLogger logger)
private

Definition at line 3826 of file parser.cc.

3827  {
3828  // This function may be called on a background thread too; record only the
3829  // main thread preparse times.
3830  if (pre_parse_timer_ != NULL) {
3832  }
3833  DCHECK_EQ(Token::LBRACE, scanner()->current_token());
3834 
3835  if (reusable_preparser_ == NULL) {
3836  reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_);
3847  }
3848  PreParser::PreParseResult result =
3850  is_generator(),
3851  logger);
3852  if (pre_parse_timer_ != NULL) {
3854  }
3855  return result;
3856 }
PreParseResult PreParseLazyFunction(StrictMode strict_mode, bool is_generator, ParserRecorder *log)
Definition: preparser.cc:121
#define DCHECK_EQ(v1, v2)
Definition: logging.h:206

References v8::internal::ParserBase< ParserTraits >::allow_arrow_functions(), v8::internal::ParserBase< ParserTraits >::allow_classes(), v8::internal::ParserBase< ParserTraits >::allow_harmony_numeric_literals(), v8::internal::ParserBase< ParserTraits >::allow_harmony_object_literals(), v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), v8::internal::ParserBase< ParserTraits >::allow_modules(), v8::internal::ParserBase< ParserTraits >::allow_natives_syntax(), DCHECK_EQ, v8::internal::ParserBase< ParserTraits >::is_generator(), NULL, pre_parse_timer_, v8::internal::PreParser::PreParseLazyFunction(), reusable_preparser_, v8::internal::ParserBase< ParserTraits >::scanner(), scanner_, v8::internal::ParserBase< Traits >::set_allow_arrow_functions(), v8::internal::ParserBase< Traits >::set_allow_classes(), v8::internal::ParserBase< Traits >::set_allow_harmony_numeric_literals(), v8::internal::ParserBase< Traits >::set_allow_harmony_object_literals(), v8::internal::ParserBase< Traits >::set_allow_harmony_scoping(), v8::internal::ParserBase< Traits >::set_allow_lazy(), v8::internal::ParserBase< Traits >::set_allow_modules(), v8::internal::ParserBase< Traits >::set_allow_natives_syntax(), v8::internal::ParserBase< ParserTraits >::stack_limit_, v8::internal::HistogramTimer::Start(), v8::internal::HistogramTimer::Stop(), and v8::internal::ParserBase< ParserTraits >::strict_mode().

Referenced by SkipLazyFunctionBody().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseModule()

Module * v8::internal::Parser::ParseModule ( bool ok)
private

Definition at line 1230 of file parser.cc.

1230  {
1231  // Module:
1232  // '{' ModuleElement '}'
1233  // '=' ModulePath ';'
1234  // 'at' String ';'
1235 
1236  switch (peek()) {
1237  case Token::LBRACE:
1238  return ParseModuleLiteral(ok);
1239 
1240  case Token::ASSIGN: {
1241  Expect(Token::ASSIGN, CHECK_OK);
1242  Module* result = ParseModulePath(CHECK_OK);
1244  return result;
1245  }
1246 
1247  default: {
1249  Module* result = ParseModuleUrl(CHECK_OK);
1251  return result;
1252  }
1253  }
1254 }
Module * ParseModulePath(bool *ok)
Definition: parser.cc:1310
Module * ParseModuleUrl(bool *ok)
Definition: parser.cc:1364
Module * ParseModuleLiteral(bool *ok)
Definition: parser.cc:1257

References CHECK_OK, v8::internal::CStrVector(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectContextualKeyword(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), ParseModuleLiteral(), ParseModulePath(), and ParseModuleUrl().

Referenced by ParseModuleDeclaration().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseModuleDeclaration()

Statement * v8::internal::Parser::ParseModuleDeclaration ( ZoneList< const AstRawString * > *  names,
bool ok 
)
private

Definition at line 1193 of file parser.cc.

1194  {
1195  // ModuleDeclaration:
1196  // 'module' Identifier Module
1197 
1198  int pos = peek_position();
1199  const AstRawString* name =
1201 
1202 #ifdef DEBUG
1203  if (FLAG_print_interface_details)
1204  PrintF("# Module %.*s ", name->length(), name->raw_data());
1205 #endif
1206 
1207  Module* module = ParseModule(CHECK_OK);
1208  VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
1209  Declaration* declaration =
1210  factory()->NewModuleDeclaration(proxy, module, scope_, pos);
1211  Declare(declaration, true, CHECK_OK);
1212 
1213 #ifdef DEBUG
1214  if (FLAG_print_interface_details)
1215  PrintF("# Module %.*s ", name->length(), name->raw_data());
1216  if (FLAG_print_interfaces) {
1217  PrintF("module %.*s: ", name->length(), name->raw_data());
1218  module->interface()->Print();
1219  }
1220 #endif
1221 
1222  if (names) names->Add(name, zone());
1223  if (module->body() == NULL)
1224  return factory()->NewEmptyStatement(pos);
1225  else
1226  return factory()->NewModuleStatement(proxy, module->body(), pos);
1227 }
Module * ParseModule(bool *ok)
Definition: parser.cc:1230

References v8::internal::List< T, AllocationPolicy >::Add(), v8::internal::Module::body(), CHECK_OK, Declare(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Module::interface(), v8::internal::ParserBase< ParserTraits >::kDontAllowEvalOrArguments, v8::internal::MODULE, name, NewUnresolved(), NULL, v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), ParseModule(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::PrintF(), v8::internal::ParserBase< ParserTraits >::scope_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseExportDeclaration(), and ParseModuleElement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseModuleElement()

Statement * v8::internal::Parser::ParseModuleElement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 1139 of file parser.cc.

1140  {
1141  // (Ecma 262 5th Edition, clause 14):
1142  // SourceElement:
1143  // Statement
1144  // FunctionDeclaration
1145  //
1146  // In harmony mode we allow additionally the following productions
1147  // ModuleElement:
1148  // LetDeclaration
1149  // ConstDeclaration
1150  // ModuleDeclaration
1151  // ImportDeclaration
1152  // ExportDeclaration
1153  // GeneratorDeclaration
1154 
1155  switch (peek()) {
1156  case Token::FUNCTION:
1157  return ParseFunctionDeclaration(NULL, ok);
1158  case Token::CLASS:
1159  return ParseClassDeclaration(NULL, ok);
1160  case Token::IMPORT:
1161  return ParseImportDeclaration(ok);
1162  case Token::EXPORT:
1163  return ParseExportDeclaration(ok);
1164  case Token::CONST:
1166  case Token::LET:
1168  if (strict_mode() == STRICT) {
1170  }
1171  // Fall through.
1172  default: {
1173  Statement* stmt = ParseStatement(labels, CHECK_OK);
1174  // Handle 'module' as a context-sensitive keyword.
1175  if (FLAG_harmony_modules &&
1176  peek() == Token::IDENTIFIER &&
1177  !scanner()->HasAnyLineTerminatorBeforeNext() &&
1178  stmt != NULL) {
1179  ExpressionStatement* estmt = stmt->AsExpressionStatement();
1180  if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL &&
1181  estmt->expression()->AsVariableProxy()->raw_name() ==
1182  ast_value_factory()->module_string() &&
1183  !scanner()->literal_contains_escapes()) {
1184  return ParseModuleDeclaration(NULL, ok);
1185  }
1186  }
1187  return stmt;
1188  }
1189  }
1190 }
Block * ParseImportDeclaration(bool *ok)
Definition: parser.cc:1406
Statement * ParseExportDeclaration(bool *ok)
Definition: parser.cc:1460

References v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), ast_value_factory(), CHECK_OK, v8::internal::CONST, DCHECK, kModuleElement, v8::internal::LET, NULL, ParseClassDeclaration(), ParseExportDeclaration(), ParseFunctionDeclaration(), ParseImportDeclaration(), ParseModuleDeclaration(), ParseStatement(), ParseVariableStatement(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::STRICT, and v8::internal::ParserBase< ParserTraits >::strict_mode().

Referenced by ParseModuleLiteral(), and ParseSourceElements().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseModuleLiteral()

Module * v8::internal::Parser::ParseModuleLiteral ( bool ok)
private

Definition at line 1257 of file parser.cc.

1257  {
1258  // Module:
1259  // '{' ModuleElement '}'
1260 
1261  int pos = peek_position();
1262  // Construct block expecting 16 statements.
1263  Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
1264 #ifdef DEBUG
1265  if (FLAG_print_interface_details) PrintF("# Literal ");
1266 #endif
1267  Scope* scope = NewScope(scope_, MODULE_SCOPE);
1268 
1269  Expect(Token::LBRACE, CHECK_OK);
1270  scope->set_start_position(scanner()->location().beg_pos);
1271  scope->SetStrictMode(STRICT);
1272 
1273  {
1274  BlockState block_state(&scope_, scope);
1275  TargetCollector collector(zone());
1276  Target target(&this->target_stack_, &collector);
1277  Target target_body(&this->target_stack_, body);
1278 
1279  while (peek() != Token::RBRACE) {
1280  Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1281  if (stat && !stat->IsEmpty()) {
1282  body->AddStatement(stat, zone());
1283  }
1284  }
1285  }
1286 
1287  Expect(Token::RBRACE, CHECK_OK);
1288  scope->set_end_position(scanner()->location().end_pos);
1289  body->set_scope(scope);
1290 
1291  // Check that all exports are bound.
1292  Interface* interface = scope->interface();
1293  for (Interface::Iterator it = interface->iterator();
1294  !it.done(); it.Advance()) {
1295  if (scope->LookupLocal(it.name()) == NULL) {
1296  ParserTraits::ReportMessage("module_export_undefined", it.name());
1297  *ok = false;
1298  return NULL;
1299  }
1300  }
1301 
1302  interface->MakeModule(ok);
1303  DCHECK(*ok);
1304  interface->Freeze(ok);
1305  DCHECK(*ok);
1306  return factory()->NewModuleLiteral(body, interface, pos);
1307 }
Statement * ParseModuleElement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:1139
@ MODULE_SCOPE
Definition: globals.h:648

References CHECK_OK, DCHECK, v8::internal::Interface::Iterator::done(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Statement::IsEmpty(), v8::internal::RelocInfo::kNoPosition, v8::internal::Scope::LookupLocal(), v8::internal::MODULE_SCOPE, NewScope(), NULL, ParseModuleElement(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::PrintF(), v8::internal::ParserTraits::ReportMessage(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Scope::set_end_position(), v8::internal::Scope::set_start_position(), v8::internal::Scope::SetStrictMode(), v8::internal::STRICT, target_stack_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseModule().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseModulePath()

Module * v8::internal::Parser::ParseModulePath ( bool ok)
private

Definition at line 1310 of file parser.cc.

1310  {
1311  // ModulePath:
1312  // Identifier
1313  // ModulePath '.' Identifier
1314 
1315  int pos = peek_position();
1316  Module* result = ParseModuleVariable(CHECK_OK);
1317  while (Check(Token::PERIOD)) {
1318  const AstRawString* name = ParseIdentifierName(CHECK_OK);
1319 #ifdef DEBUG
1320  if (FLAG_print_interface_details)
1321  PrintF("# Path .%.*s ", name->length(), name->raw_data());
1322 #endif
1323  Module* member = factory()->NewModulePath(result, name, pos);
1324  result->interface()->Add(name, member->interface(), zone(), ok);
1325  if (!*ok) {
1326 #ifdef DEBUG
1327  if (FLAG_print_interfaces) {
1328  PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data());
1329  PrintF("result: ");
1330  result->interface()->Print();
1331  PrintF("member: ");
1332  member->interface()->Print();
1333  }
1334 #endif
1335  ParserTraits::ReportMessage("invalid_module_path", name);
1336  return NULL;
1337  }
1338  result = member;
1339  }
1340 
1341  return result;
1342 }
Module * ParseModuleVariable(bool *ok)
Definition: parser.cc:1345

References v8::internal::Interface::Add(), v8::internal::ParserBase< ParserTraits >::Check(), CHECK_OK, v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Module::interface(), name, NULL, v8::internal::ParserBase< ParserTraits >::ParseIdentifierName(), ParseModuleVariable(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::PrintF(), v8::internal::ParserTraits::ReportMessage(), and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseModule(), and ParseModuleSpecifier().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseModuleSpecifier()

Module * v8::internal::Parser::ParseModuleSpecifier ( bool ok)
private

Definition at line 1393 of file parser.cc.

1393  {
1394  // ModuleSpecifier:
1395  // String
1396  // ModulePath
1397 
1398  if (peek() == Token::STRING) {
1399  return ParseModuleUrl(ok);
1400  } else {
1401  return ParseModulePath(ok);
1402  }
1403 }
@ STRING

References ParseModulePath(), ParseModuleUrl(), and STRING.

Referenced by ParseImportDeclaration().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseModuleUrl()

Module * v8::internal::Parser::ParseModuleUrl ( bool ok)
private

Definition at line 1364 of file parser.cc.

1364  {
1365  // Module:
1366  // String
1367 
1368  int pos = peek_position();
1370  const AstRawString* symbol = GetSymbol(scanner());
1371 
1372  // TODO(ES6): Request JS resource from environment...
1373 
1374 #ifdef DEBUG
1375  if (FLAG_print_interface_details) PrintF("# Url ");
1376 #endif
1377 
1378  // Create an empty literal as long as the feature isn't finished.
1379  USE(symbol);
1380  Scope* scope = NewScope(scope_, MODULE_SCOPE);
1381  Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
1382  body->set_scope(scope);
1383  Interface* interface = scope->interface();
1384  Module* result = factory()->NewModuleLiteral(body, interface, pos);
1385  interface->Freeze(ok);
1386  DCHECK(*ok);
1387  interface->Unify(scope->interface(), zone(), ok);
1388  DCHECK(*ok);
1389  return result;
1390 }
const AstRawString * GetSymbol(Scanner *scanner)
Definition: parser.cc:634

References CHECK_OK, DCHECK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserTraits::GetSymbol(), v8::internal::Scope::interface(), v8::internal::RelocInfo::kNoPosition, v8::internal::MODULE_SCOPE, NewScope(), NULL, v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::PrintF(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, STRING, USE(), and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseModule(), and ParseModuleSpecifier().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseModuleVariable()

Module * v8::internal::Parser::ParseModuleVariable ( bool ok)
private

Definition at line 1345 of file parser.cc.

1345  {
1346  // ModulePath:
1347  // Identifier
1348 
1349  int pos = peek_position();
1350  const AstRawString* name =
1352 #ifdef DEBUG
1353  if (FLAG_print_interface_details)
1354  PrintF("# Module variable %.*s ", name->length(), name->raw_data());
1355 #endif
1356  VariableProxy* proxy = scope_->NewUnresolved(
1358  scanner()->location().beg_pos);
1359 
1360  return factory()->NewModuleVariable(proxy, pos);
1361 }
static Interface * NewModule(Zone *zone)
Definition: interface.h:54

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::kDontAllowEvalOrArguments, name, v8::internal::Interface::NewModule(), v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::PrintF(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseModulePath().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseNativeDeclaration()

Statement * v8::internal::Parser::ParseNativeDeclaration ( bool ok)
private

Definition at line 1878 of file parser.cc.

1878  {
1879  int pos = peek_position();
1880  Expect(Token::FUNCTION, CHECK_OK);
1881  // Allow "eval" or "arguments" for backward compatibility.
1882  const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1883  Expect(Token::LPAREN, CHECK_OK);
1884  bool done = (peek() == Token::RPAREN);
1885  while (!done) {
1887  done = (peek() == Token::RPAREN);
1888  if (!done) {
1890  }
1891  }
1892  Expect(Token::RPAREN, CHECK_OK);
1893  Expect(Token::SEMICOLON, CHECK_OK);
1894 
1895  // Make sure that the function containing the native declaration
1896  // isn't lazily compiled. The extension structures are only
1897  // accessible while parsing the first time not when reparsing
1898  // because of lazy compilation.
1900 
1901  // TODO(1240846): It's weird that native function declarations are
1902  // introduced dynamically when we meet their declarations, whereas
1903  // other functions are set up when entering the surrounding scope.
1904  VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
1905  Declaration* declaration =
1906  factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
1907  Declare(declaration, true, CHECK_OK);
1908  NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
1910  return factory()->NewExpressionStatement(
1911  factory()->NewAssignment(
1912  Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
1913  pos);
1914 }
void ForceEagerCompilation()
Definition: scopes.h:364

References CHECK_OK, COMMA, DeclarationScope(), Declare(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::extension_, v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Scope::ForceEagerCompilation(), v8::internal::ParserBase< ParserTraits >::kAllowEvalOrArguments, v8::internal::RelocInfo::kNoPosition, name, NewUnresolved(), v8::internal::Interface::NewValue(), v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::ParserBase< ParserTraits >::scope_, and v8::internal::VAR.

Referenced by ParseExpressionOrLabelledStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseOnBackground()

void v8::internal::Parser::ParseOnBackground ( )

Definition at line 4923 of file parser.cc.

4923  {
4924  DCHECK(info()->function() == NULL);
4925  FunctionLiteral* result = NULL;
4926  fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
4927 
4928  CompleteParserRecorder recorder;
4930  log_ = &recorder;
4931  }
4932 
4933  DCHECK(info()->source_stream() != NULL);
4934  ExternalStreamingStream stream(info()->source_stream(),
4935  info()->source_stream_encoding());
4936  scanner_.Initialize(&stream);
4937  DCHECK(info()->context().is_null() || info()->context()->IsNativeContext());
4938 
4939  // When streaming, we don't know the length of the source until we have parsed
4940  // it. The raw data can be UTF-8, so we wouldn't know the source length until
4941  // we have decoded it anyway even if we knew the raw data length (which we
4942  // don't). We work around this by storing all the scopes which need their end
4943  // position set at the end of the script (the top scope and possible eval
4944  // scopes) and set their end position after we know the script length.
4945  Scope* top_scope = NULL;
4946  Scope* eval_scope = NULL;
4947  result = DoParseProgram(info(), &top_scope, &eval_scope);
4948 
4949  top_scope->set_end_position(scanner()->location().end_pos);
4950  if (eval_scope != NULL) {
4951  eval_scope->set_end_position(scanner()->location().end_pos);
4952  }
4953 
4954  info()->SetFunction(result);
4955 
4956  // We cannot internalize on a background thread; a foreground task will take
4957  // care of calling Parser::Internalize just before compilation.
4958 
4960  if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
4961  log_ = NULL;
4962  }
4963 }
@ kProduceParserCache
Definition: v8.h:1161
ScriptData ** cached_data() const
Definition: compiler.h:117
ScriptCompiler::CompileOptions compile_options() const
Definition: parser.h:693
FunctionLiteral * DoParseProgram(CompilationInfo *info, Scope **scope, Scope **ad_hoc_eval_scope)
Definition: parser.cc:861

References ast_value_factory(), v8::internal::CompilationInfo::cached_data(), compile_options(), DCHECK, DoParseProgram(), v8::internal::ParserBase< ParserTraits >::fni_, v8::internal::CompleteParserRecorder::GetScriptData(), info(), info_, v8::internal::Scanner::Initialize(), v8::ScriptCompiler::kProduceParserCache, v8::internal::ParserBase< ParserTraits >::log_, NULL, v8::internal::ParserBase< ParserTraits >::scanner(), scanner_, v8::internal::Scope::set_end_position(), v8::internal::CompilationInfo::SetFunction(), and v8::internal::ParserBase< ParserTraits >::zone().

+ Here is the call graph for this function:

◆ ParseProgram()

FunctionLiteral * v8::internal::Parser::ParseProgram ( )
private

Definition at line 792 of file parser.cc.

792  {
793  // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
794  // see comment for HistogramTimerScope class.
795 
796  // It's OK to use the counters here, since this function is only called in
797  // the main thread.
798  HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
799  Handle<String> source(String::cast(script()->source()));
800  isolate()->counters()->total_parse_size()->Increment(source->length());
801  base::ElapsedTimer timer;
802  if (FLAG_trace_parse) {
803  timer.Start();
804  }
805  fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
806 
807  // Initialize parser state.
808  CompleteParserRecorder recorder;
809 
811  log_ = &recorder;
814  }
815 
816  source = String::Flatten(source);
817  FunctionLiteral* result;
818 
819  Scope* top_scope = NULL;
820  Scope* eval_scope = NULL;
821  if (source->IsExternalTwoByteString()) {
822  // Notice that the stream is destroyed at the end of the branch block.
823  // The last line of the blocks can't be moved outside, even though they're
824  // identical calls.
825  ExternalTwoByteStringUtf16CharacterStream stream(
826  Handle<ExternalTwoByteString>::cast(source), 0, source->length());
827  scanner_.Initialize(&stream);
828  result = DoParseProgram(info(), &top_scope, &eval_scope);
829  } else {
830  GenericStringUtf16CharacterStream stream(source, 0, source->length());
831  scanner_.Initialize(&stream);
832  result = DoParseProgram(info(), &top_scope, &eval_scope);
833  }
834  top_scope->set_end_position(source->length());
835  if (eval_scope != NULL) {
836  eval_scope->set_end_position(source->length());
837  }
839 
840  if (FLAG_trace_parse && result != NULL) {
841  double ms = timer.Elapsed().InMillisecondsF();
842  if (info()->is_eval()) {
843  PrintF("[parsing eval");
844  } else if (info()->script()->name()->IsString()) {
845  String* name = String::cast(info()->script()->name());
846  SmartArrayPointer<char> name_chars = name->ToCString();
847  PrintF("[parsing script: %s", name_chars.get());
848  } else {
849  PrintF("[parsing script");
850  }
851  PrintF(" - took %0.3f ms]\n", ms);
852  }
854  if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
855  log_ = NULL;
856  }
857  return result;
858 }
@ kConsumeParserCache
Definition: v8.h:1162
void HandleSourceURLComments()
Definition: parser.cc:3993

References ast_value_factory(), v8::internal::CompilationInfo::cached_data(), cached_parse_data_, compile_options(), v8::internal::Isolate::counters(), DoParseProgram(), v8::internal::String::Flatten(), v8::internal::ParserBase< ParserTraits >::fni_, v8::internal::SmartPointerBase< Deallocator, T >::get(), v8::internal::CompleteParserRecorder::GetScriptData(), HandleSourceURLComments(), info(), info_, v8::internal::ParseData::Initialize(), v8::internal::Scanner::Initialize(), isolate(), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProduceParserCache, v8::internal::ParserBase< ParserTraits >::log_, name, NULL, v8::internal::PrintF(), scanner_, script(), v8::internal::Scope::set_end_position(), and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by Parse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseReturnStatement()

Statement * v8::internal::Parser::ParseReturnStatement ( bool ok)
private

Definition at line 2552 of file parser.cc.

2552  {
2553  // ReturnStatement ::
2554  // 'return' Expression? ';'
2555 
2556  // Consume the return token. It is necessary to do that before
2557  // reporting any errors on it, because of the way errors are
2558  // reported (underlining).
2559  Expect(Token::RETURN, CHECK_OK);
2560  Scanner::Location loc = scanner()->location();
2561 
2562  Token::Value tok = peek();
2563  Statement* result;
2564  Expression* return_value;
2565  if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2566  tok == Token::SEMICOLON ||
2567  tok == Token::RBRACE ||
2568  tok == Token::EOS) {
2569  return_value = GetLiteralUndefined(position());
2570  } else {
2571  return_value = ParseExpression(true, CHECK_OK);
2572  }
2574  if (is_generator()) {
2575  Expression* generator = factory()->NewVariableProxy(
2576  function_state_->generator_object_variable());
2577  Expression* yield = factory()->NewYield(
2578  generator, return_value, Yield::kFinal, loc.beg_pos);
2579  result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2580  } else {
2581  result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2582  }
2583 
2584  Scope* decl_scope = scope_->DeclarationScope();
2585  if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) {
2586  ReportMessageAt(loc, "illegal_return");
2587  *ok = false;
2588  return NULL;
2589  }
2590  return result;
2591 }
void ReportMessageAt(Scanner::Location location, const char *message, bool is_reference_error=false)
Definition: preparser.h:450
Literal * GetLiteralUndefined(int position)
Definition: parser.cc:3914

References v8::internal::Scanner::Location::beg_pos, CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::function_state_, GetLiteralUndefined(), v8::internal::Scope::is_eval_scope(), v8::internal::ParserBase< ParserTraits >::is_generator(), v8::internal::Scope::is_global_scope(), v8::internal::Scanner::location(), NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::ParserBase< ParserTraits >::ReportMessageAt(), v8::internal::ParserBase< ParserTraits >::scanner(), and v8::internal::ParserBase< ParserTraits >::scope_.

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseScopedBlock()

Block * v8::internal::Parser::ParseScopedBlock ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 2022 of file parser.cc.

2023  {
2024  // The harmony mode uses block elements instead of statements.
2025  //
2026  // Block ::
2027  // '{' BlockElement* '}'
2028 
2029  // Construct block expecting 16 statements.
2030  Block* body =
2031  factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2032  Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2033 
2034  // Parse the statements and collect escaping labels.
2035  Expect(Token::LBRACE, CHECK_OK);
2036  block_scope->set_start_position(scanner()->location().beg_pos);
2037  { BlockState block_state(&scope_, block_scope);
2038  TargetCollector collector(zone());
2039  Target target(&this->target_stack_, &collector);
2040  Target target_body(&this->target_stack_, body);
2041 
2042  while (peek() != Token::RBRACE) {
2043  Statement* stat = ParseBlockElement(NULL, CHECK_OK);
2044  if (stat && !stat->IsEmpty()) {
2045  body->AddStatement(stat, zone());
2046  }
2047  }
2048  }
2049  Expect(Token::RBRACE, CHECK_OK);
2050  block_scope->set_end_position(scanner()->location().end_pos);
2051  block_scope = block_scope->FinalizeBlockScope();
2052  body->set_scope(block_scope);
2053  return body;
2054 }
Statement * ParseBlockElement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:1553

References v8::internal::BLOCK_SCOPE, CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Scope::FinalizeBlockScope(), v8::internal::Statement::IsEmpty(), v8::internal::RelocInfo::kNoPosition, NewScope(), NULL, ParseBlockElement(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Scope::set_end_position(), v8::internal::Scope::set_start_position(), target_stack_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseBlock().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseSourceElements()

void * v8::internal::Parser::ParseSourceElements ( ZoneList< Statement * > *  processor,
int  end_token,
bool  is_eval,
bool  is_global,
Scope **  ad_hoc_eval_scope,
bool ok 
)
private

Definition at line 1050 of file parser.cc.

1052  {
1053  // SourceElements ::
1054  // (ModuleElement)* <end_token>
1055 
1056  // Allocate a target stack to use for this set of source
1057  // elements. This way, all scripts and functions get their own
1058  // target stack thus avoiding illegal breaks and continues across
1059  // functions.
1060  TargetScope scope(&this->target_stack_);
1061 
1062  DCHECK(processor != NULL);
1063  bool directive_prologue = true; // Parsing directive prologue.
1064 
1065  while (peek() != end_token) {
1066  if (directive_prologue && peek() != Token::STRING) {
1067  directive_prologue = false;
1068  }
1069 
1070  Scanner::Location token_loc = scanner()->peek_location();
1071  Statement* stat;
1072  if (is_global && !is_eval) {
1073  stat = ParseModuleElement(NULL, CHECK_OK);
1074  } else {
1075  stat = ParseBlockElement(NULL, CHECK_OK);
1076  }
1077  if (stat == NULL || stat->IsEmpty()) {
1078  directive_prologue = false; // End of directive prologue.
1079  continue;
1080  }
1081 
1082  if (directive_prologue) {
1083  // A shot at a directive.
1084  ExpressionStatement* e_stat;
1085  Literal* literal;
1086  // Still processing directive prologue?
1087  if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1088  (literal = e_stat->expression()->AsLiteral()) != NULL &&
1089  literal->raw_value()->IsString()) {
1090  // Check "use strict" directive (ES5 14.1) and "use asm" directive. Only
1091  // one can be present.
1092  if (strict_mode() == SLOPPY &&
1093  literal->raw_value()->AsString() ==
1094  ast_value_factory()->use_strict_string() &&
1095  token_loc.end_pos - token_loc.beg_pos ==
1096  ast_value_factory()->use_strict_string()->length() + 2) {
1097  // TODO(mstarzinger): Global strict eval calls, need their own scope
1098  // as specified in ES5 10.4.2(3). The correct fix would be to always
1099  // add this scope in DoParseProgram(), but that requires adaptations
1100  // all over the code base, so we go with a quick-fix for now.
1101  // In the same manner, we have to patch the parsing mode.
1102  if (is_eval && !scope_->is_eval_scope()) {
1103  DCHECK(scope_->is_global_scope());
1104  Scope* scope = NewScope(scope_, EVAL_SCOPE);
1105  scope->set_start_position(scope_->start_position());
1106  scope->set_end_position(scope_->end_position());
1107  scope_ = scope;
1108  if (eval_scope != NULL) {
1109  // Caller will correct the positions of the ad hoc eval scope.
1110  *eval_scope = scope;
1111  }
1112  mode_ = PARSE_EAGERLY;
1113  }
1114  scope_->SetStrictMode(STRICT);
1115  // "use strict" is the only directive for now.
1116  directive_prologue = false;
1117  } else if (literal->raw_value()->AsString() ==
1118  ast_value_factory()->use_asm_string() &&
1119  token_loc.end_pos - token_loc.beg_pos ==
1120  ast_value_factory()->use_asm_string()->length() + 2) {
1121  // Store the usage count; The actual use counter on the isolate is
1122  // incremented after parsing is done.
1124  scope_->SetAsmModule();
1125  }
1126  } else {
1127  // End of the directive prologue.
1128  directive_prologue = false;
1129  }
1130  }
1131 
1132  processor->Add(stat, zone());
1133  }
1134 
1135  return 0;
1136 }
@ kUseAsm
Definition: v8.h:4487

References v8::internal::List< T, AllocationPolicy >::Add(), ast_value_factory(), v8::internal::Scanner::Location::beg_pos, CHECK_OK, DCHECK, v8::internal::Scanner::Location::end_pos, v8::internal::EVAL_SCOPE, v8::internal::Statement::IsEmpty(), v8::Isolate::kUseAsm, v8::internal::ParserBase< ParserTraits >::mode_, NewScope(), NULL, v8::internal::ParserBase< ParserTraits >::PARSE_EAGERLY, ParseBlockElement(), ParseModuleElement(), v8::internal::Scanner::peek_location(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Scope::set_end_position(), v8::internal::Scope::set_start_position(), v8::internal::SLOPPY, v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), STRING, target_stack_, use_counts_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by DoParseProgram(), and ParseEagerFunctionBody().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseStatement()

Statement * v8::internal::Parser::ParseStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 1586 of file parser.cc.

1587  {
1588  // Statement ::
1589  // Block
1590  // VariableStatement
1591  // EmptyStatement
1592  // ExpressionStatement
1593  // IfStatement
1594  // IterationStatement
1595  // ContinueStatement
1596  // BreakStatement
1597  // ReturnStatement
1598  // WithStatement
1599  // LabelledStatement
1600  // SwitchStatement
1601  // ThrowStatement
1602  // TryStatement
1603  // DebuggerStatement
1604 
1605  // Note: Since labels can only be used by 'break' and 'continue'
1606  // statements, which themselves are only valid within blocks,
1607  // iterations or 'switch' statements (i.e., BreakableStatements),
1608  // labels can be simply ignored in all other cases; except for
1609  // trivial labeled break statements 'label: break label' which is
1610  // parsed into an empty statement.
1611  switch (peek()) {
1612  case Token::LBRACE:
1613  return ParseBlock(labels, ok);
1614 
1615  case Token::SEMICOLON:
1616  Next();
1617  return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1618 
1619  case Token::IF:
1620  return ParseIfStatement(labels, ok);
1621 
1622  case Token::DO:
1623  return ParseDoWhileStatement(labels, ok);
1624 
1625  case Token::WHILE:
1626  return ParseWhileStatement(labels, ok);
1627 
1628  case Token::FOR:
1629  return ParseForStatement(labels, ok);
1630 
1631  case Token::CONTINUE:
1632  return ParseContinueStatement(ok);
1633 
1634  case Token::BREAK:
1635  return ParseBreakStatement(labels, ok);
1636 
1637  case Token::RETURN:
1638  return ParseReturnStatement(ok);
1639 
1640  case Token::WITH:
1641  return ParseWithStatement(labels, ok);
1642 
1643  case Token::SWITCH:
1644  return ParseSwitchStatement(labels, ok);
1645 
1646  case Token::THROW:
1647  return ParseThrowStatement(ok);
1648 
1649  case Token::TRY: {
1650  // NOTE: It is somewhat complicated to have labels on
1651  // try-statements. When breaking out of a try-finally statement,
1652  // one must take great care not to treat it as a
1653  // fall-through. It is much easier just to wrap the entire
1654  // try-statement in a statement block and put the labels there
1655  Block* result =
1656  factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1657  Target target(&this->target_stack_, result);
1658  TryStatement* statement = ParseTryStatement(CHECK_OK);
1659  if (result) result->AddStatement(statement, zone());
1660  return result;
1661  }
1662 
1663  case Token::FUNCTION: {
1664  // FunctionDeclaration is only allowed in the context of SourceElements
1665  // (Ecma 262 5th Edition, clause 14):
1666  // SourceElement:
1667  // Statement
1668  // FunctionDeclaration
1669  // Common language extension is to allow function declaration in place
1670  // of any statement. This language extension is disabled in strict mode.
1671  //
1672  // In Harmony mode, this case also handles the extension:
1673  // Statement:
1674  // GeneratorDeclaration
1675  if (strict_mode() == STRICT) {
1676  ReportMessageAt(scanner()->peek_location(), "strict_function");
1677  *ok = false;
1678  return NULL;
1679  }
1680  return ParseFunctionDeclaration(NULL, ok);
1681  }
1682 
1683  case Token::CLASS:
1684  return ParseClassDeclaration(NULL, ok);
1685 
1686  case Token::DEBUGGER:
1687  return ParseDebuggerStatement(ok);
1688 
1689  case Token::VAR:
1690  case Token::CONST:
1691  return ParseVariableStatement(kStatement, NULL, ok);
1692 
1693  case Token::LET:
1695  if (strict_mode() == STRICT) {
1696  return ParseVariableStatement(kStatement, NULL, ok);
1697  }
1698  // Fall through.
1699  default:
1700  return ParseExpressionOrLabelledStatement(labels, ok);
1701  }
1702 }
Statement * ParseExpressionOrLabelledStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:2400
Statement * ParseReturnStatement(bool *ok)
Definition: parser.cc:2552
Block * ParseBlock(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:1995
IfStatement * ParseIfStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:2463
Statement * ParseContinueStatement(bool *ok)
Definition: parser.cc:2486
SwitchStatement * ParseSwitchStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:2657
WhileStatement * ParseWhileStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:2837
Statement * ParseForStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:3097
Statement * ParseWithStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:2594
DebuggerStatement * ParseDebuggerStatement(bool *ok)
Definition: parser.cc:3317
Statement * ParseBreakStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:2515
DoWhileStatement * ParseDoWhileStatement(ZoneList< const AstRawString * > *labels, bool *ok)
Definition: parser.cc:2809
Statement * ParseThrowStatement(bool *ok)
Definition: parser.cc:2685
TryStatement * ParseTryStatement(bool *ok)
Definition: parser.cc:2704

References v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), v8::internal::BREAK, CHECK_OK, v8::internal::CONST, DCHECK, v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::RelocInfo::kNoPosition, kStatement, v8::internal::LET, NULL, ParseBlock(), ParseBreakStatement(), ParseClassDeclaration(), ParseContinueStatement(), ParseDebuggerStatement(), ParseDoWhileStatement(), ParseExpressionOrLabelledStatement(), ParseForStatement(), ParseFunctionDeclaration(), ParseIfStatement(), ParseReturnStatement(), ParseSwitchStatement(), ParseThrowStatement(), ParseTryStatement(), ParseVariableStatement(), ParseWhileStatement(), ParseWithStatement(), v8::internal::ParserBase< ParserTraits >::ReportMessageAt(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), target_stack_, v8::internal::VAR, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseBlock(), ParseBlockElement(), ParseCaseClause(), ParseDoWhileStatement(), ParseExpressionOrLabelledStatement(), ParseForStatement(), ParseIfStatement(), ParseModuleElement(), ParseWhileStatement(), and ParseWithStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseSwitchStatement()

SwitchStatement * v8::internal::Parser::ParseSwitchStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 2657 of file parser.cc.

2658  {
2659  // SwitchStatement ::
2660  // 'switch' '(' Expression ')' '{' CaseClause* '}'
2661 
2662  SwitchStatement* statement =
2663  factory()->NewSwitchStatement(labels, peek_position());
2664  Target target(&this->target_stack_, statement);
2665 
2666  Expect(Token::SWITCH, CHECK_OK);
2667  Expect(Token::LPAREN, CHECK_OK);
2668  Expression* tag = ParseExpression(true, CHECK_OK);
2669  Expect(Token::RPAREN, CHECK_OK);
2670 
2671  bool default_seen = false;
2672  ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
2673  Expect(Token::LBRACE, CHECK_OK);
2674  while (peek() != Token::RBRACE) {
2675  CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2676  cases->Add(clause, zone());
2677  }
2678  Expect(Token::RBRACE, CHECK_OK);
2679 
2680  if (statement) statement->Initialize(tag, cases);
2681  return statement;
2682 }
CaseClause * ParseCaseClause(bool *default_seen_ptr, bool *ok)
Definition: parser.cc:2624

References v8::internal::List< T, AllocationPolicy >::Add(), CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), ParseCaseClause(), v8::internal::ParserBase< ParserTraits >::ParseExpression(), v8::internal::ParserBase< ParserTraits >::peek_position(), target_stack_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseThrowStatement()

Statement * v8::internal::Parser::ParseThrowStatement ( bool ok)
private

Definition at line 2685 of file parser.cc.

2685  {
2686  // ThrowStatement ::
2687  // 'throw' Expression ';'
2688 
2689  Expect(Token::THROW, CHECK_OK);
2690  int pos = position();
2691  if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2692  ReportMessage("newline_after_throw");
2693  *ok = false;
2694  return NULL;
2695  }
2696  Expression* exception = ParseExpression(true, CHECK_OK);
2698 
2699  return factory()->NewExpressionStatement(
2700  factory()->NewThrow(exception, pos), pos);
2701 }

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), v8::internal::ParserBase< ParserTraits >::factory(), NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::ParserBase< ParserTraits >::ReportMessage(), and v8::internal::ParserBase< ParserTraits >::scanner().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseTryStatement()

TryStatement * v8::internal::Parser::ParseTryStatement ( bool ok)
private

Definition at line 2704 of file parser.cc.

2704  {
2705  // TryStatement ::
2706  // 'try' Block Catch
2707  // 'try' Block Finally
2708  // 'try' Block Catch Finally
2709  //
2710  // Catch ::
2711  // 'catch' '(' Identifier ')' Block
2712  //
2713  // Finally ::
2714  // 'finally' Block
2715 
2716  Expect(Token::TRY, CHECK_OK);
2717  int pos = position();
2718 
2719  TargetCollector try_collector(zone());
2720  Block* try_block;
2721 
2722  { Target target(&this->target_stack_, &try_collector);
2723  try_block = ParseBlock(NULL, CHECK_OK);
2724  }
2725 
2726  Token::Value tok = peek();
2727  if (tok != Token::CATCH && tok != Token::FINALLY) {
2728  ReportMessage("no_catch_or_finally");
2729  *ok = false;
2730  return NULL;
2731  }
2732 
2733  // If we can break out from the catch block and there is a finally block,
2734  // then we will need to collect escaping targets from the catch
2735  // block. Since we don't know yet if there will be a finally block, we
2736  // always collect the targets.
2737  TargetCollector catch_collector(zone());
2738  Scope* catch_scope = NULL;
2739  Variable* catch_variable = NULL;
2740  Block* catch_block = NULL;
2741  const AstRawString* name = NULL;
2742  if (tok == Token::CATCH) {
2743  Consume(Token::CATCH);
2744 
2745  Expect(Token::LPAREN, CHECK_OK);
2746  catch_scope = NewScope(scope_, CATCH_SCOPE);
2747  catch_scope->set_start_position(scanner()->location().beg_pos);
2749 
2750  Expect(Token::RPAREN, CHECK_OK);
2751 
2752  Target target(&this->target_stack_, &catch_collector);
2753  VariableMode mode =
2755  catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
2756  BlockState block_state(&scope_, catch_scope);
2757  catch_block = ParseBlock(NULL, CHECK_OK);
2758 
2759  catch_scope->set_end_position(scanner()->location().end_pos);
2760  tok = peek();
2761  }
2762 
2763  Block* finally_block = NULL;
2764  DCHECK(tok == Token::FINALLY || catch_block != NULL);
2765  if (tok == Token::FINALLY) {
2766  Consume(Token::FINALLY);
2767  finally_block = ParseBlock(NULL, CHECK_OK);
2768  }
2769 
2770  // Simplify the AST nodes by converting:
2771  // 'try B0 catch B1 finally B2'
2772  // to:
2773  // 'try { try B0 catch B1 } finally B2'
2774 
2775  if (catch_block != NULL && finally_block != NULL) {
2776  // If we have both, create an inner try/catch.
2777  DCHECK(catch_scope != NULL && catch_variable != NULL);
2778  int index = function_state_->NextHandlerIndex();
2779  TryCatchStatement* statement = factory()->NewTryCatchStatement(
2780  index, try_block, catch_scope, catch_variable, catch_block,
2782  statement->set_escaping_targets(try_collector.targets());
2783  try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2784  try_block->AddStatement(statement, zone());
2785  catch_block = NULL; // Clear to indicate it's been handled.
2786  }
2787 
2788  TryStatement* result = NULL;
2789  if (catch_block != NULL) {
2790  DCHECK(finally_block == NULL);
2791  DCHECK(catch_scope != NULL && catch_variable != NULL);
2792  int index = function_state_->NextHandlerIndex();
2793  result = factory()->NewTryCatchStatement(
2794  index, try_block, catch_scope, catch_variable, catch_block, pos);
2795  } else {
2796  DCHECK(finally_block != NULL);
2797  int index = function_state_->NextHandlerIndex();
2798  result = factory()->NewTryFinallyStatement(
2799  index, try_block, finally_block, pos);
2800  // Combine the jump targets of the try block and the possible catch block.
2801  try_collector.targets()->AddAll(*catch_collector.targets(), zone());
2802  }
2803 
2804  result->set_escaping_targets(try_collector.targets());
2805  return result;
2806 }

References v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), v8::internal::CATCH_SCOPE, CHECK_OK, v8::internal::ParserBase< ParserTraits >::Consume(), DCHECK, v8::internal::Scope::DeclareLocal(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::function_state_, v8::internal::kCreatedInitialized, v8::internal::ParserBase< ParserTraits >::kDontAllowEvalOrArguments, v8::internal::RelocInfo::kNoPosition, v8::internal::LET, v8::internal::ParserBase< ParserTraits >::mode(), name, NewScope(), NULL, ParseBlock(), v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::ParserBase< ParserTraits >::ReportMessage(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Scope::set_end_position(), v8::internal::TryStatement::set_escaping_targets(), v8::internal::Scope::set_start_position(), v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), target_stack_, v8::internal::VAR, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseV8Intrinsic()

Expression * v8::internal::Parser::ParseV8Intrinsic ( bool ok)
private

Definition at line 3859 of file parser.cc.

3859  {
3860  // CallRuntime ::
3861  // '%' Identifier Arguments
3862 
3863  int pos = peek_position();
3864  Expect(Token::MOD, CHECK_OK);
3865  // Allow "eval" or "arguments" for backward compatibility.
3866  const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
3867  ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3868 
3869  if (extension_ != NULL) {
3870  // The extension structures are only accessible while parsing the
3871  // very first time not when reparsing because of lazy compilation.
3872  scope_->DeclarationScope()->ForceEagerCompilation();
3873  }
3874 
3875  const Runtime::Function* function = Runtime::FunctionForName(name->string());
3876 
3877  // Check for built-in IS_VAR macro.
3878  if (function != NULL &&
3879  function->intrinsic_type == Runtime::RUNTIME &&
3880  function->function_id == Runtime::kIS_VAR) {
3881  // %IS_VAR(x) evaluates to x if x is a variable,
3882  // leads to a parse error otherwise. Could be implemented as an
3883  // inline function %_IS_VAR(x) to eliminate this special case.
3884  if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
3885  return args->at(0);
3886  } else {
3887  ReportMessage("not_isvar");
3888  *ok = false;
3889  return NULL;
3890  }
3891  }
3892 
3893  // Check that the expected number of arguments are being passed.
3894  if (function != NULL &&
3895  function->nargs != -1 &&
3896  function->nargs != args->length()) {
3897  ReportMessage("illegal_access");
3898  *ok = false;
3899  return NULL;
3900  }
3901 
3902  // Check that the function is defined if it's an inline runtime call.
3903  if (function == NULL && name->FirstCharacter() == '_') {
3904  ParserTraits::ReportMessage("not_defined", name);
3905  *ok = false;
3906  return NULL;
3907  }
3908 
3909  // We have a valid intrinsics call or a call to a builtin.
3910  return factory()->NewCallRuntime(name, function, args, pos);
3911 }
Traits::Type::ExpressionList ParseArguments(bool *ok)
Definition: preparser.h:2106
static const Function * FunctionForName(Handle< String > name)
Definition: runtime.cc:9290

References v8::internal::List< T, AllocationPolicy >::at(), CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::extension_, v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::Runtime::FunctionForName(), v8::internal::ParserBase< ParserTraits >::kAllowEvalOrArguments, name, NULL, v8::internal::ParserBase< ParserTraits >::ParseArguments(), v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::ParserTraits::ReportMessage(), v8::internal::ParserBase< ParserTraits >::ReportMessage(), v8::internal::Runtime::RUNTIME, and v8::internal::ParserBase< ParserTraits >::scope_.

Referenced by v8::internal::ParserTraits::ParseV8Intrinsic().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseVariableDeclarations()

Block * v8::internal::Parser::ParseVariableDeclarations ( VariableDeclarationContext  var_context,
VariableDeclarationProperties decl_props,
ZoneList< const AstRawString * > *  names,
const AstRawString **  out,
bool ok 
)
private

Definition at line 2076 of file parser.cc.

2081  {
2082  // VariableDeclarations ::
2083  // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2084  //
2085  // The ES6 Draft Rev3 specifies the following grammar for const declarations
2086  //
2087  // ConstDeclaration ::
2088  // const ConstBinding (',' ConstBinding)* ';'
2089  // ConstBinding ::
2090  // Identifier '=' AssignmentExpression
2091  //
2092  // TODO(ES6):
2093  // ConstBinding ::
2094  // BindingPattern '=' AssignmentExpression
2095 
2096  int pos = peek_position();
2097  VariableMode mode = VAR;
2098  // True if the binding needs initialization. 'let' and 'const' declared
2099  // bindings are created uninitialized by their declaration nodes and
2100  // need initialization. 'var' declared bindings are always initialized
2101  // immediately by their declaration nodes.
2102  bool needs_init = false;
2103  bool is_const = false;
2104  Token::Value init_op = Token::INIT_VAR;
2105  if (peek() == Token::VAR) {
2107  } else if (peek() == Token::CONST) {
2108  // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2109  //
2110  // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2111  //
2112  // * It is a Syntax Error if the code that matches this production is not
2113  // contained in extended code.
2114  //
2115  // However disallowing const in sloppy mode will break compatibility with
2116  // existing pages. Therefore we keep allowing const with the old
2117  // non-harmony semantics in sloppy mode.
2119  switch (strict_mode()) {
2120  case SLOPPY:
2121  mode = CONST_LEGACY;
2122  init_op = Token::INIT_CONST_LEGACY;
2123  break;
2124  case STRICT:
2125  if (allow_harmony_scoping()) {
2126  if (var_context == kStatement) {
2127  // In strict mode 'const' declarations are only allowed in source
2128  // element positions.
2129  ReportMessage("unprotected_const");
2130  *ok = false;
2131  return NULL;
2132  }
2133  mode = CONST;
2134  init_op = Token::INIT_CONST;
2135  } else {
2136  ReportMessage("strict_const");
2137  *ok = false;
2138  return NULL;
2139  }
2140  }
2141  is_const = true;
2142  needs_init = true;
2143  } else if (peek() == Token::LET && strict_mode() == STRICT) {
2146  if (var_context == kStatement) {
2147  // Let declarations are only allowed in source element positions.
2148  ReportMessage("unprotected_let");
2149  *ok = false;
2150  return NULL;
2151  }
2152  mode = LET;
2153  needs_init = true;
2154  init_op = Token::INIT_LET;
2155  } else {
2156  UNREACHABLE(); // by current callers
2157  }
2158 
2159  Scope* declaration_scope = DeclarationScope(mode);
2160 
2161  // The scope of a var/const declared variable anywhere inside a function
2162  // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2163  // transform a source-level var/const declaration into a (Function)
2164  // Scope declaration, and rewrite the source-level initialization into an
2165  // assignment statement. We use a block to collect multiple assignments.
2166  //
2167  // We mark the block as initializer block because we don't want the
2168  // rewriter to add a '.result' assignment to such a block (to get compliant
2169  // behavior for code such as print(eval('var x = 7')), and for cosmetic
2170  // reasons when pretty-printing. Also, unless an assignment (initialization)
2171  // is inside an initializer block, it is ignored.
2172  //
2173  // Create new block with one expected declaration.
2174  Block* block = factory()->NewBlock(NULL, 1, true, pos);
2175  int nvars = 0; // the number of variables declared
2176  const AstRawString* name = NULL;
2177  do {
2178  if (fni_ != NULL) fni_->Enter();
2179 
2180  // Parse variable name.
2181  if (nvars > 0) Consume(Token::COMMA);
2183  if (fni_ != NULL) fni_->PushVariableName(name);
2184 
2185  // Declare variable.
2186  // Note that we *always* must treat the initial value via a separate init
2187  // assignment for variables and constants because the value must be assigned
2188  // when the variable is encountered in the source. But the variable/constant
2189  // is declared (and set to 'undefined') upon entering the function within
2190  // which the variable or constant is declared. Only function variables have
2191  // an initial value in the declaration (because they are initialized upon
2192  // entering the function).
2193  //
2194  // If we have a const declaration, in an inner scope, the proxy is always
2195  // bound to the declared variable (independent of possibly surrounding with
2196  // statements).
2197  // For let/const declarations in harmony mode, we can also immediately
2198  // pre-resolve the proxy because it resides in the same scope as the
2199  // declaration.
2200  Interface* interface =
2201  is_const ? Interface::NewConst() : Interface::NewValue();
2202  VariableProxy* proxy = NewUnresolved(name, mode, interface);
2203  Declaration* declaration =
2204  factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2205  Declare(declaration, mode != VAR, CHECK_OK);
2206  nvars++;
2207  if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2208  ReportMessage("too_many_variables");
2209  *ok = false;
2210  return NULL;
2211  }
2212  if (names) names->Add(name, zone());
2213 
2214  // Parse initialization expression if present and/or needed. A
2215  // declaration of the form:
2216  //
2217  // var v = x;
2218  //
2219  // is syntactic sugar for:
2220  //
2221  // var v; v = x;
2222  //
2223  // In particular, we need to re-lookup 'v' (in scope_, not
2224  // declaration_scope) as it may be a different 'v' than the 'v' in the
2225  // declaration (e.g., if we are inside a 'with' statement or 'catch'
2226  // block).
2227  //
2228  // However, note that const declarations are different! A const
2229  // declaration of the form:
2230  //
2231  // const c = x;
2232  //
2233  // is *not* syntactic sugar for:
2234  //
2235  // const c; c = x;
2236  //
2237  // The "variable" c initialized to x is the same as the declared
2238  // one - there is no re-lookup (see the last parameter of the
2239  // Declare() call above).
2240 
2241  Scope* initialization_scope = is_const ? declaration_scope : scope_;
2242  Expression* value = NULL;
2243  int pos = -1;
2244  // Harmony consts have non-optional initializers.
2245  if (peek() == Token::ASSIGN || mode == CONST) {
2246  Expect(Token::ASSIGN, CHECK_OK);
2247  pos = position();
2248  value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2249  // Don't infer if it is "a = function(){...}();"-like expression.
2250  if (fni_ != NULL &&
2251  value->AsCall() == NULL &&
2252  value->AsCallNew() == NULL) {
2253  fni_->Infer();
2254  } else {
2256  }
2257  if (decl_props != NULL) *decl_props = kHasInitializers;
2258  }
2259 
2260  // Record the end position of the initializer.
2261  if (proxy->var() != NULL) {
2262  proxy->var()->set_initializer_position(position());
2263  }
2264 
2265  // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2266  if (value == NULL && needs_init) {
2267  value = GetLiteralUndefined(position());
2268  }
2269 
2270  // Global variable declarations must be compiled in a specific
2271  // way. When the script containing the global variable declaration
2272  // is entered, the global variable must be declared, so that if it
2273  // doesn't exist (on the global object itself, see ES5 errata) it
2274  // gets created with an initial undefined value. This is handled
2275  // by the declarations part of the function representing the
2276  // top-level global code; see Runtime::DeclareGlobalVariable. If
2277  // it already exists (in the object or in a prototype), it is
2278  // *not* touched until the variable declaration statement is
2279  // executed.
2280  //
2281  // Executing the variable declaration statement will always
2282  // guarantee to give the global object an own property.
2283  // This way, global variable declarations can shadow
2284  // properties in the prototype chain, but only after the variable
2285  // declaration statement has been executed. This is important in
2286  // browsers where the global object (window) has lots of
2287  // properties defined in prototype objects.
2288  if (initialization_scope->is_global_scope() &&
2290  // Compute the arguments for the runtime call.
2291  ZoneList<Expression*>* arguments =
2292  new(zone()) ZoneList<Expression*>(3, zone());
2293  // We have at least 1 parameter.
2294  arguments->Add(factory()->NewStringLiteral(name, pos), zone());
2295  CallRuntime* initialize;
2296 
2297  if (is_const) {
2298  arguments->Add(value, zone());
2299  value = NULL; // zap the value to avoid the unnecessary assignment
2300 
2301  // Construct the call to Runtime_InitializeConstGlobal
2302  // and add it to the initialization statement block.
2303  // Note that the function does different things depending on
2304  // the number of arguments (1 or 2).
2305  initialize = factory()->NewCallRuntime(
2306  ast_value_factory()->initialize_const_global_string(),
2307  Runtime::FunctionForId(Runtime::kInitializeConstGlobal), arguments,
2308  pos);
2309  } else {
2310  // Add strict mode.
2311  // We may want to pass singleton to avoid Literal allocations.
2312  StrictMode strict_mode = initialization_scope->strict_mode();
2313  arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone());
2314 
2315  // Be careful not to assign a value to the global variable if
2316  // we're in a with. The initialization value should not
2317  // necessarily be stored in the global object in that case,
2318  // which is why we need to generate a separate assignment node.
2319  if (value != NULL && !inside_with()) {
2320  arguments->Add(value, zone());
2321  value = NULL; // zap the value to avoid the unnecessary assignment
2322  // Construct the call to Runtime_InitializeVarGlobal
2323  // and add it to the initialization statement block.
2324  initialize = factory()->NewCallRuntime(
2325  ast_value_factory()->initialize_var_global_string(),
2326  Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments,
2327  pos);
2328  } else {
2329  initialize = NULL;
2330  }
2331  }
2332 
2333  if (initialize != NULL) {
2334  block->AddStatement(factory()->NewExpressionStatement(
2335  initialize, RelocInfo::kNoPosition),
2336  zone());
2337  }
2338  } else if (needs_init) {
2339  // Constant initializations always assign to the declared constant which
2340  // is always at the function scope level. This is only relevant for
2341  // dynamically looked-up variables and constants (the start context for
2342  // constant lookups is always the function context, while it is the top
2343  // context for var declared variables). Sigh...
2344  // For 'let' and 'const' declared variables in harmony mode the
2345  // initialization also always assigns to the declared variable.
2346  DCHECK(proxy != NULL);
2347  DCHECK(proxy->var() != NULL);
2348  DCHECK(value != NULL);
2349  Assignment* assignment =
2350  factory()->NewAssignment(init_op, proxy, value, pos);
2351  block->AddStatement(
2352  factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2353  zone());
2354  value = NULL;
2355  }
2356 
2357  // Add an assignment node to the initialization statement block if we still
2358  // have a pending initialization value.
2359  if (value != NULL) {
2360  DCHECK(mode == VAR);
2361  // 'var' initializations are simply assignments (with all the consequences
2362  // if they are inside a 'with' statement - they may change a 'with' object
2363  // property).
2364  VariableProxy* proxy =
2365  initialization_scope->NewUnresolved(factory(), name, interface);
2366  Assignment* assignment =
2367  factory()->NewAssignment(init_op, proxy, value, pos);
2368  block->AddStatement(
2369  factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2370  zone());
2371  }
2372 
2373  if (fni_ != NULL) fni_->Leave();
2374  } while (peek() == Token::COMMA);
2375 
2376  // If there was a single non-const declaration, return it in the output
2377  // parameter for possible use by for/in.
2378  if (nvars == 1 && !is_const) {
2379  *out = name;
2380  }
2381 
2382  return block;
2383 }
void PushVariableName(const AstRawString *name)
ExpressionT ParseAssignmentExpression(bool accept_IN, bool *ok)
Definition: preparser.h:2137
bool inside_with() const
Definition: parser.h:692
static const int kMaxNumFunctionLocals
Definition: parser.h:658
#define UNREACHABLE()
Definition: logging.h:30

References v8::internal::List< T, AllocationPolicy >::Add(), v8::internal::ParserBase< ParserTraits >::allow_harmony_scoping(), ast_value_factory(), CHECK_OK, COMMA, v8::internal::CONST, v8::internal::CONST_LEGACY, v8::internal::ParserBase< ParserTraits >::Consume(), DCHECK, DeclarationScope(), Declare(), v8::internal::FuncNameInferrer::Enter(), v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), v8::internal::ParserBase< ParserTraits >::fni_, v8::internal::Runtime::FunctionForId(), GetLiteralUndefined(), v8::internal::FuncNameInferrer::Infer(), inside_with(), v8::internal::Scope::is_global_scope(), v8::internal::IsLexicalVariableMode(), v8::internal::ParserBase< ParserTraits >::kDontAllowEvalOrArguments, kForStatement, kHasInitializers, kMaxNumFunctionLocals, v8::internal::RelocInfo::kNoPosition, kStatement, v8::internal::FuncNameInferrer::Leave(), v8::internal::LET, v8::internal::ParserBase< ParserTraits >::mode(), name, v8::internal::Scope::NewUnresolved(), NewUnresolved(), v8::internal::Interface::NewValue(), NULL, v8::internal::ParserBase< ParserTraits >::ParseAssignmentExpression(), v8::internal::ParserBase< ParserTraits >::ParseIdentifier(), v8::internal::ParserBase< ParserTraits >::peek_position(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::FuncNameInferrer::PushVariableName(), v8::internal::FuncNameInferrer::RemoveLastFunction(), v8::internal::ParserBase< ParserTraits >::ReportMessage(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::SLOPPY, v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), v8::internal::Scope::strict_mode(), UNREACHABLE, v8::internal::VAR, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by ParseForStatement(), and ParseVariableStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseVariableStatement()

Block * v8::internal::Parser::ParseVariableStatement ( VariableDeclarationContext  var_context,
ZoneList< const AstRawString * > *  names,
bool ok 
)
private

Definition at line 2057 of file parser.cc.

2059  {
2060  // VariableStatement ::
2061  // VariableDeclarations ';'
2062 
2063  const AstRawString* ignore;
2064  Block* result =
2065  ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
2067  return result;
2068 }

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::ExpectSemicolon(), NULL, and ParseVariableDeclarations().

Referenced by ParseBlockElement(), ParseExportDeclaration(), ParseModuleElement(), and ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseWhileStatement()

WhileStatement * v8::internal::Parser::ParseWhileStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 2837 of file parser.cc.

2838  {
2839  // WhileStatement ::
2840  // 'while' '(' Expression ')' Statement
2841 
2842  WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
2843  Target target(&this->target_stack_, loop);
2844 
2845  Expect(Token::WHILE, CHECK_OK);
2846  Expect(Token::LPAREN, CHECK_OK);
2847  Expression* cond = ParseExpression(true, CHECK_OK);
2848  Expect(Token::RPAREN, CHECK_OK);
2849  Statement* body = ParseStatement(NULL, CHECK_OK);
2850 
2851  if (loop != NULL) loop->Initialize(cond, body);
2852  return loop;
2853 }

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), ParseStatement(), v8::internal::ParserBase< ParserTraits >::peek_position(), and target_stack_.

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseWithStatement()

Statement * v8::internal::Parser::ParseWithStatement ( ZoneList< const AstRawString * > *  labels,
bool ok 
)
private

Definition at line 2594 of file parser.cc.

2595  {
2596  // WithStatement ::
2597  // 'with' '(' Expression ')' Statement
2598 
2599  Expect(Token::WITH, CHECK_OK);
2600  int pos = position();
2601 
2602  if (strict_mode() == STRICT) {
2603  ReportMessage("strict_mode_with");
2604  *ok = false;
2605  return NULL;
2606  }
2607 
2608  Expect(Token::LPAREN, CHECK_OK);
2609  Expression* expr = ParseExpression(true, CHECK_OK);
2610  Expect(Token::RPAREN, CHECK_OK);
2611 
2612  scope_->DeclarationScope()->RecordWithStatement();
2613  Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2614  Statement* stmt;
2615  { BlockState block_state(&scope_, with_scope);
2616  with_scope->set_start_position(scanner()->peek_location().beg_pos);
2617  stmt = ParseStatement(labels, CHECK_OK);
2618  with_scope->set_end_position(scanner()->location().end_pos);
2619  }
2620  return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2621 }

References CHECK_OK, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParserBase< ParserTraits >::factory(), NewScope(), NULL, v8::internal::ParserBase< ParserTraits >::ParseExpression(), ParseStatement(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::ParserBase< ParserTraits >::ReportMessage(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Scope::set_end_position(), v8::internal::Scope::set_start_position(), v8::internal::STRICT, v8::internal::ParserBase< ParserTraits >::strict_mode(), and v8::internal::WITH_SCOPE.

Referenced by ParseStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RegisterTargetUse()

void v8::internal::Parser::RegisterTargetUse ( Label *  target,
Target *  stop 
)
private

Definition at line 3982 of file parser.cc.

3982  {
3983  // Register that a break target found at the given stop in the
3984  // target stack has been used from the top of the target stack. Add
3985  // the break target to any TargetCollectors passed on the stack.
3986  for (Target* t = target_stack_; t != stop; t = t->previous()) {
3987  TargetCollector* collector = t->node()->AsTargetCollector();
3988  if (collector != NULL) collector->AddTarget(target, zone());
3989  }
3990 }

References NULL, target_stack_, and v8::internal::ParserBase< ParserTraits >::zone().

Referenced by LookupBreakTarget(), and LookupContinueTarget().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ script()

Handle<Script> v8::internal::Parser::script ( ) const
inlineprivate

Definition at line 681 of file parser.h.

681 { return info_->script(); }

References info_, and v8::internal::CompilationInfo::script().

Referenced by ParseLazy(), ParseProgram(), Parser(), and ThrowPendingError().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SetCachedData()

void v8::internal::Parser::SetCachedData ( )
private

Definition at line 257 of file parser.cc.

257  {
260  } else {
261  DCHECK(info_->cached_data() != NULL);
263  cached_parse_data_ = new ParseData(*info_->cached_data());
264  }
265  }
266 }
@ kNoCompileOptions
Definition: v8.h:1160

References v8::internal::CompilationInfo::cached_data(), cached_parse_data_, compile_options(), DCHECK, info_, v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kNoCompileOptions, and NULL.

Referenced by Parse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SkipLazyFunctionBody()

void v8::internal::Parser::SkipLazyFunctionBody ( const AstRawString function_name,
int materialized_literal_count,
int expected_property_count,
bool ok 
)
private

Definition at line 3701 of file parser.cc.

3704  {
3705  int function_block_pos = position();
3707  // If we have cached data, we use it to skip parsing the function body. The
3708  // data contains the information we need to construct the lazy function.
3709  FunctionEntry entry =
3710  cached_parse_data_->GetFunctionEntry(function_block_pos);
3711  // Check that cached data is valid.
3712  CHECK(entry.is_valid());
3713  // End position greater than end of stream is safe, and hard to check.
3714  CHECK(entry.end_pos() > function_block_pos);
3715  scanner()->SeekForward(entry.end_pos() - 1);
3716 
3717  scope_->set_end_position(entry.end_pos());
3718  Expect(Token::RBRACE, ok);
3719  if (!*ok) {
3720  return;
3721  }
3722  total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3723  *materialized_literal_count = entry.literal_count();
3724  *expected_property_count = entry.property_count();
3725  scope_->SetStrictMode(entry.strict_mode());
3726  } else {
3727  // With no cached data, we partially parse the function, without building an
3728  // AST. This gathers the data needed to build a lazy function.
3729  SingletonLogger logger;
3730  PreParser::PreParseResult result =
3732  if (result == PreParser::kPreParseStackOverflow) {
3733  // Propagate stack overflow.
3735  *ok = false;
3736  return;
3737  }
3738  if (logger.has_error()) {
3740  Scanner::Location(logger.start(), logger.end()),
3741  logger.message(), logger.argument_opt(), logger.is_reference_error());
3742  *ok = false;
3743  return;
3744  }
3745  scope_->set_end_position(logger.end());
3746  Expect(Token::RBRACE, ok);
3747  if (!*ok) {
3748  return;
3749  }
3750  total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3751  *materialized_literal_count = logger.literals();
3752  *expected_property_count = logger.properties();
3753  scope_->SetStrictMode(logger.strict_mode());
3755  DCHECK(log_);
3756  // Position right after terminal '}'.
3757  int body_end = scanner()->location().end_pos;
3758  log_->LogFunction(function_block_pos, body_end,
3759  *materialized_literal_count,
3760  *expected_property_count,
3761  scope_->strict_mode());
3762  }
3763  }
3764 }
FunctionEntry GetFunctionEntry(int start)
Definition: parser.cc:186
virtual void LogFunction(int start, int end, int literals, int properties, StrictMode strict_mode)=0
PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(SingletonLogger *logger)
Definition: parser.cc:3826
void SeekForward(int pos)
Definition: scanner.cc:660
#define CHECK(condition)
Definition: logging.h:36

References v8::internal::SingletonLogger::argument_opt(), cached_parse_data_, CHECK, compile_options(), DCHECK, v8::internal::SingletonLogger::end(), v8::internal::Scanner::Location::end_pos, v8::internal::ParserBase< ParserTraits >::Expect(), v8::internal::ParseData::GetFunctionEntry(), v8::internal::SingletonLogger::has_error(), v8::internal::SingletonLogger::is_reference_error(), v8::ScriptCompiler::kConsumeParserCache, v8::internal::PreParser::kPreParseStackOverflow, v8::ScriptCompiler::kProduceParserCache, v8::internal::SingletonLogger::literals(), v8::internal::Scanner::location(), v8::internal::ParserBase< ParserTraits >::log_, v8::internal::ParserRecorder::LogFunction(), v8::internal::SingletonLogger::message(), ParseLazyFunctionBodyWithPreParser(), v8::internal::ParserBase< ParserTraits >::position(), v8::internal::SingletonLogger::properties(), v8::internal::ParserTraits::ReportMessageAt(), v8::internal::ParserBase< ParserTraits >::scanner(), v8::internal::ParserBase< ParserTraits >::scope_, v8::internal::Scanner::SeekForward(), v8::internal::ParserBase< ParserTraits >::set_stack_overflow(), v8::internal::SingletonLogger::start(), v8::internal::SingletonLogger::strict_mode(), and total_preparse_skipped_.

Referenced by ParseFunctionLiteral(), and v8::internal::ParserTraits::SkipLazyFunctionBody().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ TargetStackContainsLabel()

bool v8::internal::Parser::TargetStackContainsLabel ( const AstRawString label)
private

Definition at line 3939 of file parser.cc.

3939  {
3940  for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3941  BreakableStatement* stat = t->node()->AsBreakableStatement();
3942  if (stat != NULL && ContainsLabel(stat->labels(), label))
3943  return true;
3944  }
3945  return false;
3946 }

References v8::internal::BreakableStatement::AsBreakableStatement(), v8::internal::ContainsLabel(), v8::internal::BreakableStatement::labels(), NULL, and target_stack_.

Referenced by ParseExpressionOrLabelledStatement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ThrowPendingError()

void v8::internal::Parser::ThrowPendingError ( )
private

Definition at line 4006 of file parser.cc.

4006  {
4007  DCHECK(ast_value_factory()->IsInternalized());
4008  if (has_pending_error_) {
4009  MessageLocation location(script(), pending_error_location_.beg_pos,
4011  Factory* factory = isolate()->factory();
4012  bool has_arg =
4014  Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
4015  if (pending_error_arg_ != NULL) {
4016  Handle<String> arg_string = pending_error_arg_->string();
4017  elements->set(0, *arg_string);
4018  } else if (pending_error_char_arg_ != NULL) {
4019  Handle<String> arg_string =
4020  factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_))
4021  .ToHandleChecked();
4022  elements->set(0, *arg_string);
4023  }
4025 
4026  Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
4027  Handle<Object> error;
4028  MaybeHandle<Object> maybe_error =
4030  ? factory->NewReferenceError(pending_error_message_, array)
4031  : factory->NewSyntaxError(pending_error_message_, array);
4032  if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location);
4033  }
4034 }
Handle< String > string() const
void OnCompileError(Handle< Script > script)
Definition: debug.cc:2562
Object * Throw(Object *exception, MessageLocation *location=NULL)
Definition: isolate.cc:832
Factory * factory()
Definition: isolate.h:982
bool pending_error_is_reference_error_
Definition: parser.h:846
Scanner::Location pending_error_location_
Definition: parser.h:842

References ast_value_factory(), v8::internal::Scanner::Location::beg_pos, v8::internal::CStrVector(), DCHECK, v8::internal::Isolate::debug(), v8::internal::Scanner::Location::end_pos, v8::internal::Isolate::factory(), v8::internal::ParserBase< ParserTraits >::factory(), has_pending_error_, isolate(), NULL, v8::internal::Debug::OnCompileError(), pending_error_arg_, pending_error_char_arg_, pending_error_is_reference_error_, pending_error_location_, pending_error_message_, script(), v8::internal::AstString::string(), and v8::internal::Isolate::Throw().

Referenced by Internalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Friends And Related Function Documentation

◆ ParserTraits

friend class ParserTraits
friend

Definition at line 649 of file parser.h.

Member Data Documentation

◆ cached_parse_data_

ParseData* v8::internal::Parser::cached_parse_data_
private

Definition at line 836 of file parser.h.

Referenced by ParseProgram(), SetCachedData(), SkipLazyFunctionBody(), and ~Parser().

◆ has_pending_error_

bool v8::internal::Parser::has_pending_error_
private

Definition at line 841 of file parser.h.

Referenced by v8::internal::ParserTraits::ReportMessageAt(), and ThrowPendingError().

◆ info_

◆ kMaxNumFunctionLocals

const int v8::internal::Parser::kMaxNumFunctionLocals = 4194303
staticprivate

Definition at line 658 of file parser.h.

Referenced by ParseVariableDeclarations().

◆ original_scope_

Scope* v8::internal::Parser::original_scope_
private

Definition at line 834 of file parser.h.

Referenced by DoParseProgram(), ParseFunctionLiteral(), and ParseLazy().

◆ pending_error_arg_

const AstRawString* v8::internal::Parser::pending_error_arg_
private

Definition at line 844 of file parser.h.

Referenced by v8::internal::ParserTraits::ReportMessageAt(), and ThrowPendingError().

◆ pending_error_char_arg_

const char* v8::internal::Parser::pending_error_char_arg_
private

Definition at line 845 of file parser.h.

Referenced by v8::internal::ParserTraits::ReportMessageAt(), and ThrowPendingError().

◆ pending_error_is_reference_error_

bool v8::internal::Parser::pending_error_is_reference_error_
private

Definition at line 846 of file parser.h.

Referenced by v8::internal::ParserTraits::ReportMessageAt(), and ThrowPendingError().

◆ pending_error_location_

Scanner::Location v8::internal::Parser::pending_error_location_
private

Definition at line 842 of file parser.h.

Referenced by v8::internal::ParserTraits::ReportMessageAt(), and ThrowPendingError().

◆ pending_error_message_

const char* v8::internal::Parser::pending_error_message_
private

Definition at line 843 of file parser.h.

Referenced by v8::internal::ParserTraits::ReportMessageAt(), and ThrowPendingError().

◆ pre_parse_timer_

HistogramTimer* v8::internal::Parser::pre_parse_timer_
private

Definition at line 852 of file parser.h.

Referenced by Parse(), and ParseLazyFunctionBodyWithPreParser().

◆ reusable_preparser_

PreParser* v8::internal::Parser::reusable_preparser_
private

Definition at line 833 of file parser.h.

Referenced by ParseLazyFunctionBodyWithPreParser(), and ~Parser().

◆ scanner_

Scanner v8::internal::Parser::scanner_
private

◆ target_stack_

◆ total_preparse_skipped_

int v8::internal::Parser::total_preparse_skipped_
private

Definition at line 851 of file parser.h.

Referenced by Internalize(), and SkipLazyFunctionBody().

◆ use_counts_

int v8::internal::Parser::use_counts_[v8::Isolate::kUseCounterFeatureCount]
private

Definition at line 850 of file parser.h.

Referenced by Internalize(), Parser(), and ParseSourceElements().


The documentation for this class was generated from the following files: