您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > JS引擎V8-Parser源码分析
JSJSJSJS引擎V8V8V8V8ParserParserParserParser源码分析V8版本号:2.2.14版本号:0.01版本更新、技术讨论请前往作者:暗夜之眸版权所有:作者邮箱:androidresearcher@gmail.com1111V8V8V8V8parserparserparserparser在V8V8V8V8架构中的地位V8对js的脚本的处理流程大体分为本文所研究的正是这个流程第一步。1.11.11.11.1VVVV8888parserparserparserparser处理脚本的层次1进入FunctionLiteral*MakeAST(…),这里分辨出要处理时json还是普通的js脚本,普通的js脚本通过调用parser.ParseProgram(…)处理2进入FunctionLiteral*Parser::ParseProgram(…),这是个wrapper,主要工作是2.1构建该脚本运行时所需要的scope,以及编译时需要的Scanner,2.2对该脚本语法抽象树的生成工作主要由void*Parser::ParseSourceElements(…)完成,生成的结果放在准备的容器:ZoneListWrapperStatementbody(16)中。2.3根据生成结果生成FunctionLiteral类型的返回结果3进入void*Parser::ParseSourceElements(…),这里的逻辑很简单,就是用Statement*parser生成抽象语法树,这里将每一句js语句(statement)生成为一个节点本地代码引擎将抽象语法树生成对应的二进制代码,依次取出每个节点,不同类型的节点有着不同代码生成方法执行,遇到新的函数调用再次启动这个过程(这时是lazy_parser)Parser::ParseStatement(…)将每行js语句分析出来,每条js语句被解析成Statement。代码分析如下:classAstBuildingParser:publicParser{HandleScriptscript_;Scannerscanner_Scope*top_scope_;INLINE(Token::Valuepeek()){returnscanner_.peek();}INLINE(Token::ValueNext()){returnscanner_.Next();}voidExpect(Token::Valuetoken,bool*ok);AstBuildingParserFactoryfactory_;}voidParser::Expect(Token::Valuetoken,bool*ok){Token::Valuenext=Next();if(next==token)return;ReportUnexpectedToken(next);*ok=false;}ClassParser的Expect函数实际上将scanner的指针往后移动。FunctionLiteral*Parser::ParseProgram(HandleStringsource,boolin_global_context){CompilationZoneScopezone_scope(DONT_DELETE_ON_EXIT);HistogramTimerScopetimer(&Counters::parse);Counters::total_parse_size.Increment(source-length());//Initializeparserstate.source-TryFlatten();//Scannerscanner_初始化scanner_.Initialize(source,JAVASCRIPT);//Computetheparsingmode.mode_=FLAG_lazy?PARSE_LAZILY:PARSE_EAGERLY;if(allow_natives_syntax_||extension_!=NULL)mode_=PARSE_EAGERLY;Scope::Typetype=in_global_context?Scope::GLOBAL_SCOPE:Scope::EVAL_SCOPE;HandleStringno_name=factory()-EmptySymbol();FunctionLiteral*result=NULL;//这里top_scope_还为NULL{//生成一个新的classScope其parent为NULLScope*scope=factory()-NewScope(top_scope_,type,inside_with());//LexicalScope的构造函数里将classparser的top_scope_指针指向刚生成scopeLexicalScopelexical_scope(this,scope);TemporaryScopetemp_scope(this);ZoneListWrapperStatementbody(16);boolok=true;//对于最上层topscope,其结束标志是Token::EOSParseSourceElements(&body,Token::EOS,&ok);if(ok){result=NEW(FunctionLiteral(no_name,top_scope_,body.elements(),temp_scope.materialized_literal_count(),temp_scope.expected_property_count(),temp_scope.only_simple_this_property_assignments(),temp_scope.this_property_assignments(),0,0,source-length(),false));}elseif(scanner().stack_overflow()){Top::StackOverflow();}}if(result==NULL)zone_scope.DeleteOnExit();returnresult;}//对于一个js函数的分析FunctionLiteral*Parser::ParseFunctionLiteral(HandleStringvar_name,intfunction_token_position,FunctionLiteralTypetype,bool*ok){seen_loop_stmt_=false;boolis_named=!var_name.is_null();HandleStringname=is_named?var_name:factory()-EmptySymbol();//Thefunctionname,ifany.HandleStringfunction_name=factory()-EmptySymbol();if(is_named&&(type==EXPRESSION||type==NESTED)){function_name=name;}intnum_parameters=0;//Parsefunctionbody.{Scope::Typetype=Scope::FUNCTION_SCOPE;//进入一个函数体中,为这个函数体新生成一个classScope的实例,其父scope为top_scope_。Scope*scope=factory()-NewScope(top_scope_,type,inside_with());//对于本层次classLexicalScope在其构造函数里的将其prev_scope_指针记录着上一层的top_scope_,而classparser的top_scope_被指向新生成的scope,而在classLexicalScope析构函数里将恢复classparser的top_scope_为构造函数里记录的prev_scope_。LexicalScopelexical_scope(this,scope);TemporaryScopetemp_scope(this);top_scope_-SetScopeName(name);//FormalParameterList:://'('(Identifier)*[',']')'//出现“(”:函数声明的开始Expect(Token::LPAREN,CHECK_OK);intstart_pos=scanner_.location().beg_pos;booldone=(peek()==Token::RPAREN);//如果紧接着出现“)”:那么这个函数没有参数,否则分析其参数while(!done){//分析该函数参数HandleStringparam_name=ParseIdentifier(CHECK_OK);if(!is_pre_parsing_){//把参数加入到该scope中top_scope_-AddParameter(top_scope_-DeclareLocal(param_name,Variable::VAR));num_parameters++;}done=(peek()==Token::RPAREN);if(!done)Expect(Token::COMMA,CHECK_OK);}//终于出现“)”,该函数参数列表分析完毕Expect(Token::RPAREN,CHECK_OK);//出现“{”,一个函数体的开始Expect(Token::LBRACE,CHECK_OK);//ClassZoneListWrapper实际上是容纳其模板类型实例的一个列表,这里其容纳的是Statement列表ZoneListWrapperStatementbody=factory()-NewListStatement(8);...if(!function_name.is_null()&&function_name-length()0){//生成一个变量,其名字为该函数名Variable*fvar=top_scope_-DeclareFunctionVar(function_name);//生成一个变量代理VariableProxy*fproxy=top_scope_-NewUnresolved(function_name,inside_with());//将变量及变量代理绑定起来fproxy-BindTo(fvar);//首先生成一个Assignment表达式的实例,其target_为fproxy,其value_为classThisFunction的实例,classThisFunction本身就是一个表达式:classThisFunction:publicExpression。body.Add(newExpressionStatement(newAssignment(Token::INIT_CONST,fproxy,NEW(ThisFunction()),RelocInfo::kNoPosition)));}...if(is_lazily_compiled&&pre_data()!=NULL){...}else{//这里逐语句分析ParseSourceElements(&body,ParseSourceElements(&body,ParseSourceElements(&body,ParseSourceElements(&body,Token::RBRACE,Token::RBRACE,Token::RBRACE,Token::RBRACE,CHECK_OK);CHECK_OK);CHECK_OK);
本文标题:JS引擎V8-Parser源码分析
链接地址:https://www.777doc.com/doc-3330208 .html