See Horkeychen wrote the article "[WebKit] javascriptcore Analysis--Basic article (c) from script code to JIT compiled code implementation ", written very well, deeply inspired. I would like to add some details such as how bytecode is generated, and so on, written by Horkey.
JSC's handling of JavaScript, in fact, is similar to WebKit's handling of CSS in many places, and it has so few parts:
(1) Lexical analysis--out of the word (Token);
(2) Grammar analysis, abstract syntax tree (ast:abstract Syntax trees);
(3) Traversal of the abstract syntax tree-generated bytecode (bytecode);
(4) Execute byte code with interpreter (Llint:low level interpreter);
(5) If the performance is not good enough to use baseline JIT compiled bytecode generation machine code, and then execute this machine code;
(6) If performance is not good enough, use DFG JIT recompile bytecode to generate better machine code, and then execute this machine code;
(7) Finally, if it is not good, the Llvm:low-virtual machine to compile the middle of the DFG code, to generate higher-optimized machines and execution. Next, I'll use a series of articles to describe this process.
Among them, steps 1, 2 is similar, 3, 4, 5 steps of the idea, CSS JIT is also a similar approach, please refer to [1]. Want to write JSC article, with rookie and Yugong Yishan Way, open the JSC tip of the iceberg.
This article mainly describes the details of lexical and syntactic parsing.
First, javascriptcore analysis of the lexical analyzer workflow
This explains the lexical and grammatical workflow:
The working process of the tokenizer is to constantly look for a word (Token) from a string, such as to find a continuous "true" string, creating a tokentrue. The process of working with the lexical device is as follows:
Javascriptcore/interpreter/interpreter.cpp:
Template <typename chartype>
Template <parsermode mode> tokentype Literalparser<chartype>::lexer::lex (literalparsertoken< chartype>& token) {while (M_ptr < m_end && Isjsonwhitespace (*m_ptr)) ++m_ptr; if (m_ptr >= m_end) {token.type = Tokend; Token.start = Token.end = m_ptr; return tokend; } token.type = Tokerror; Token.start = m_ptr; Switch (*m_ptr) {case ' [': Token.type = toklbracket; Token.end = ++m_ptr; return toklbracket; Case '] ': Token.type = tokrbracket; Token.end = ++m_ptr; return tokrbracket; Case ' (': Token.type = Toklparen; Token.end = ++m_ptr; return toklparen; Case ') ': Token.type = Tokrparen; Token.end = ++m_ptr; return tokrparen; Case ', ': Token.type = Tokcomma; Token.end = ++m_ptr; return tokcomma; Case ': ': Token.type = Tokcolon; Token.end = ++m_ptr; return Tokcolon; Case ' "': Return Lexstring<mode, '" > (token); Case ' t ': if (m_end-m_ptr >= 4 && m_ptr[1] = = ' R ' && m_ptr[2] = = ' u ' && m_ptr[3] = = ' E ') {m_ptr + = 4; Token.type = Toktrue; Token.end = m_ptr; return toktrue; } break; Case '-': Case ' 0 ':
<span style= "font-family:arial, Helvetica, Sans-serif;" > Through this process, a complete JSC world of tokens is generated. Then, parse the syntax to generate the abstract syntax tree .</span></span>
Ustring parser<lexertype>::p Arseinner ()
{ ustring parseerror = ustring (); unsigned oldfunctioncachesize = M_functioncache? M_functioncache->bytesize (): 0; Abstract Syntax Tree Builder: astbuilder context (const_cast<jsglobaldata*> (m_globaldata), const_cast<sourcecode* > (M_source)); if (m_lexer->isreparsing ()) m_statementdepth--; Scoperef scope = CurrentScope (); Begins parsing a node of the build syntax tree: sourceelements* sourceelements = parsesourceelements<checkforstrictmode> (context); if (!sourceelements | |!consume (EOFTOK))
}
For example, according to the token type, JSC that the input token is a constant declaration, the syntax node is generated using the following template function, and then placed inside the Astbuilder:
Next, the bytecodegenerator::generate is called to generate bytecode, which is divided into section analysis. Let's take a look at the following syntax tree nodes from JavaScript to generate bytecode:
Javascriptcore/bytecompiler/nodecodegen.cpp:
registerid* Booleannode::emitbytecode (bytecodegenerator& generator, registerid* DST)
The first time to get blog update reminders, as well as more technical information sharing, welcome to the personal public platform: Programmer Interaction Alliance (Coder_online)
1. To help you answer Wekit technical doubt directly
2. First time access to more than ten industry technical articles
3. To ask questions in the article, the first time to reply to you, to help you patiently answer
4. Let you and the original author become very good friends, expand their network resources
Sweep the QR code below or search number Coder_online can be followed, we are able to communicate online.
Learn more about the WebKit kernel first: JavaScript engine depth parsing