v8源码分析
版本:v8-0.1.5,
下载地址: https://chromium.googlesource.com/v8/v8.git
入口文件:由于版本太低,没有sample,我们下载了一个0.2.5,提取了里面的shell.cc 删改些代码,用于0.1.5版本
带sample的地址:https://github.com/8427003/v8-0.1.5-mirror
工具:clion , 主要靠全文搜索关键字从入口开始分析函数调用路径
环境:用了虚拟机i386 centos 6,由于低版本只支持arm + i386, mac 上docker i386编译会出问题(放弃)
编译工具:scons 用的v1.0.0 源码编译安装,高版本的scons 是无法编译v8-0.1.5的
入口文件:shell.cc (带sample的地址里才会有shell.cc 文件)
关键字:
v8::Handle<v8::Script> script = v8::Script::Compile(source);
Local<Script> Script::Compile(v8::Handle<String> source,
Handle<JSFunction> Compiler::Compile(Handle<String> source,
MakeFunction(true, false, script, extension, pre_data);
static Handle<JSFunction> MakeFunction(bool is_global,
FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data);
//这里很重要,会为每个函数分配一个parser,parser.cc 里会有一个top_scope成员变量
// 这个top_scope会存放函数里的约束变量
FunctionLiteral* MakeAST(bool compile_in_global_context,
FunctionLiteral* result = parser.ParseProgram(source,
FunctionLiteral* Parser::ParseProgram(Handle<String> source,
scanner_.Init(source, stream, 0);
void Scanner::Init(Handle<String> source, unibrow::CharacterStream* stream,
ParseSourceElements(&body, Token::EOS, &ok);
void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor,
Statement* stat = ParseStatement(NULL, CHECK_OK);
Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
// 开始扫描 变量申明
Block* Parser::ParseVariableStatement(bool* ok) {
// var a = 1; 赋值表达式分析
Block* Parser::ParseVariableDeclarations(bool accept_IN,
// left as proxy, 变量name与proxy绑定
VariableProxy* AstBuildingParser::Declare(Handle<String> name,
Variable* Scope::Declare(Handle<String> name, Variable::Mode mode) {
// right value, 简单的var a = 1; 在分析=号右边值时比较复杂,是一个漫长过程
value = ParseAssignmentExpression(accept_IN, CHECK_OK);
Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
Expression* x = ParseUnaryExpression(CHECK_OK);
Expression* Parser::ParseUnaryExpression(bool* ok) {
return ParsePostfixExpression(ok);
Expression* Parser::ParsePostfixExpression(bool* ok) {
Expression* result = ParseLeftHandSideExpression(CHECK_OK);
Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
result = ParseMemberExpression(CHECK_OK);
Expression* Parser::ParseMemberExpression(bool* ok) {
return ParseMemberWithNewPrefixesExpression(&new_positions, ok);
Expression* Parser::ParseMemberWithNewPrefixesExpression(
result = ParsePrimaryExpression(CHECK_OK);
Expression* Parser::ParsePrimaryExpression(bool* ok) {
case Token::NUMBER: {
result = NewNumberLiteral(value);
Literal* Parser::NewNumberLiteral(double number) {
// left + right
// block -> ExpressionStatement -> Assignment -> target: VariableProxy + value: express
Assignment* assignment = NEW(Assignment(op, last_var, value, position));
// 函数申明
return ParseFunctionDeclaration(ok);
Statement* Parser::ParseFunctionDeclaration(bool* ok) {
Handle<Code> code = MakeCode(lit, script, is_eval);
static Handle<Code> MakeCode(FunctionLiteral* literal,
Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval);
Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* fun,
Handle<Code> Ia32CodeGenerator::MakeCode(FunctionLiteral* flit,
cgen.GenCode(flit);
void Ia32CodeGenerator::GenCode(FunctionLiteral* fun) {
VisitStatements(body);
void Visitor::VisitStatements(ZoneList<Statement*>* statements) {
void Visit(Node* node) { node->Accept(this); }
#define DECL_ACCEPT(type)
// var a = 1; 赋值表达式分析
void Ia32CodeGenerator::VisitBlock(Block* node) {
void Visitor::VisitStatements(ZoneList<Statement*>* statements) {
void Ia32CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
void Ia32CodeGenerator::Load(Expression* x, CodeGenState::AccessType access) {
void Ia32CodeGenerator::LoadCondition(Expression* x,
Visit(x);
void Ia32CodeGenerator::VisitCallRuntime(CallRuntime* node) {
Load(args->at(i));
void Ia32CodeGenerator::VisitLiteral(Literal* node) {
void Ia32CodeGenerator::VisitLiteral(Literal* node) {
__ CallRuntime(function, args->length());
void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
void MacroAssembler::CallStub(CodeStub* stub) {
Handle<Code> CodeStub::GetCode() {
virtual void Generate(MacroAssembler* masm) = 0;
void RuntimeStub::Generate(MacroAssembler* masm) {
// void Ia32CodeGenerator::VisitVariableProxy(VariableProxy* proxy_node) {
void Ia32CodeGenerator::VisitAssignment(Assignment* node) {
void SetValue(Reference* ref) { AccessReference(ref, CodeGenState::STORE); }
void Ia32CodeGenerator::AccessReference(Reference* ref,