📄 parser.cc.svn-base
字号:
virtual Handle<String> EmptySymbol() { return Factory::empty_symbol(); } virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { return new Property(obj, key, pos); } virtual Expression* NewCall(Expression* expression, ZoneList<Expression*>* arguments, bool is_eval, int pos) { return new Call(expression, arguments, is_eval, pos); } virtual Statement* EmptyStatement() { // Use a statically allocated empty statement singleton to avoid // allocating lots and lots of empty statements. static v8::internal::EmptyStatement empty; return ∅ }};class ParserRecorder: public ParserLog { public: ParserRecorder(); virtual FunctionEntry LogFunction(int start); virtual void LogError() { } virtual void LogMessage(Scanner::Location loc, const char* message, Vector<const char*> args); void WriteString(Vector<const char> str); static const char* ReadString(unsigned* start, int* chars); List<unsigned>* store() { return &store_; } private: bool has_error_; List<unsigned> store_;};FunctionEntry ScriptDataImpl::GetFunctionEnd(int start) { if (nth(last_entry_).start_pos() > start) { // If the last entry we looked up is higher than what we're // looking for then it's useless and we reset it. last_entry_ = 0; } for (int i = last_entry_; i < EntryCount(); i++) { FunctionEntry entry = nth(i); if (entry.start_pos() == start) { last_entry_ = i; return entry; } } return FunctionEntry();}bool ScriptDataImpl::SanityCheck() { if (store_.length() < static_cast<int>(ScriptDataImpl::kHeaderSize)) return false; if (magic() != ScriptDataImpl::kMagicNumber) return false; if (version() != ScriptDataImpl::kCurrentVersion) return false; return true;}int ScriptDataImpl::EntryCount() { return (store_.length() - kHeaderSize) / FunctionEntry::kSize;}FunctionEntry ScriptDataImpl::nth(int n) { int offset = kHeaderSize + n * FunctionEntry::kSize; return FunctionEntry(Vector<unsigned>(store_.start() + offset, FunctionEntry::kSize));}ParserRecorder::ParserRecorder() : has_error_(false), store_(4) { Vector<unsigned> preamble = store()->AddBlock(0, ScriptDataImpl::kHeaderSize); preamble[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; preamble[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; preamble[ScriptDataImpl::kHasErrorOffset] = false;}void ParserRecorder::WriteString(Vector<const char> str) { store()->Add(str.length()); for (int i = 0; i < str.length(); i++) store()->Add(str[i]);}const char* ParserRecorder::ReadString(unsigned* start, int* chars) { int length = start[0]; char* result = NewArray<char>(length + 1); for (int i = 0; i < length; i++) result[i] = start[i + 1]; result[length] = '\0'; if (chars != NULL) *chars = length; return result;}void ParserRecorder::LogMessage(Scanner::Location loc, const char* message, Vector<const char*> args) { if (has_error_) return; store()->Rewind(ScriptDataImpl::kHeaderSize); store()->at(ScriptDataImpl::kHasErrorOffset) = true; store()->Add(loc.beg_pos); store()->Add(loc.end_pos); store()->Add(args.length()); WriteString(CStrVector(message)); for (int i = 0; i < args.length(); i++) WriteString(CStrVector(args[i]));}Scanner::Location ScriptDataImpl::MessageLocation() { int beg_pos = Read(0); int end_pos = Read(1); return Scanner::Location(beg_pos, end_pos);}const char* ScriptDataImpl::BuildMessage() { unsigned* start = ReadAddress(3); return ParserRecorder::ReadString(start, NULL);}Vector<const char*> ScriptDataImpl::BuildArgs() { int arg_count = Read(2); const char** array = NewArray<const char*>(arg_count); int pos = ScriptDataImpl::kHeaderSize + Read(3); for (int i = 0; i < arg_count; i++) { int count = 0; array[i] = ParserRecorder::ReadString(ReadAddress(pos), &count); pos += count + 1; } return Vector<const char*>(array, arg_count);}unsigned ScriptDataImpl::Read(int position) { return store_[ScriptDataImpl::kHeaderSize + position];}unsigned* ScriptDataImpl::ReadAddress(int position) { return &store_[ScriptDataImpl::kHeaderSize + position];}FunctionEntry ParserRecorder::LogFunction(int start) { if (has_error_) return FunctionEntry(); FunctionEntry result(store()->AddBlock(0, FunctionEntry::kSize)); result.set_start_pos(start); return result;}class AstBuildingParser : public Parser { public: AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, v8::Extension* extension, ScriptDataImpl* pre_data) : Parser(script, allow_natives_syntax, extension, false, factory(), log(), pre_data) { } virtual void ReportMessageAt(Scanner::Location loc, const char* message, Vector<const char*> args); virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, FunctionLiteral* fun, bool resolve, bool* ok); AstBuildingParserFactory* factory() { return &factory_; } ParserLog* log() { return &log_; } private: ParserLog log_; AstBuildingParserFactory factory_;};class PreParser : public Parser { public: PreParser(Handle<Script> script, bool allow_natives_syntax, v8::Extension* extension) : Parser(script, allow_natives_syntax, extension, true, factory(), recorder(), NULL) , factory_(true) { } virtual void ReportMessageAt(Scanner::Location loc, const char* message, Vector<const char*> args); virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, FunctionLiteral* fun, bool resolve, bool* ok); ParserFactory* factory() { return &factory_; } ParserRecorder* recorder() { return &recorder_; } private: ParserRecorder recorder_; ParserFactory factory_;};Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type, bool inside_with) { Scope* result = new Scope(parent, type); result->Initialize(inside_with); return result;}Scope* ParserFactory::NewScope(Scope* parent, Scope::Type type, bool inside_with) { ASSERT(parent != NULL); parent->type_ = type; return parent;}VariableProxy* PreParser::Declare(Handle<String> name, Variable::Mode mode, FunctionLiteral* fun, bool resolve, bool* ok) { return NULL;}// ----------------------------------------------------------------------------// Target is a support class to facilitate manipulation of the// Parser's target_stack_ (the stack of potential 'break' and// 'continue' statement targets). Upon construction, a new target is// added; it is removed upon destruction.class Target BASE_EMBEDDED { public: Target(Parser* parser, Node* node) : parser_(parser) { parser_->target_stack_->Add(node); } ~Target() { parser_->target_stack_->RemoveLast(); } private: Parser* parser_;};class TargetScope BASE_EMBEDDED { public: explicit TargetScope(Parser* parser) : parser_(parser), previous_(parser->target_stack_), stack_(0) { parser_->target_stack_ = &stack_; } ~TargetScope() { ASSERT(stack_.is_empty()); parser_->target_stack_ = previous_; } private: Parser* parser_; List<Node*>* previous_; List<Node*> stack_;};// ----------------------------------------------------------------------------// LexicalScope is a support class to facilitate manipulation of the// Parser's scope stack. The constructor sets the parser's top scope// to the incoming scope, and the destructor resets it.class LexicalScope BASE_EMBEDDED { public: LexicalScope(Parser* parser, Scope* scope) : parser_(parser), prev_scope_(parser->top_scope_), prev_level_(parser->with_nesting_level_) { parser_->top_scope_ = scope; parser_->with_nesting_level_ = 0; } ~LexicalScope() { parser_->top_scope_ = prev_scope_; parser_->with_nesting_level_ = prev_level_; } private: Parser* parser_; Scope* prev_scope_; int prev_level_;};// ----------------------------------------------------------------------------// The CHECK_OK macro is a convenient macro to enforce error// handling for functions that may fail (by returning !*ok).//// CAUTION: This macro appends extra statements after a call,// thus it must never be used where only a single statement// is correct (e.g. an if statement branch w/o braces)!#define CHECK_OK ok); \ if (!*ok) return NULL; \ ((void)0#define DUMMY ) // to make indentation work#undef DUMMY// ----------------------------------------------------------------------------// Implementation of ParserParser::Parser(Handle<Script> script, bool allow_natives_syntax, v8::Extension* extension, bool is_pre_parsing, ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data) : script_(script), scanner_(is_pre_parsing), top_scope_(NULL), with_nesting_level_(0), temp_scope_(NULL), target_stack_(NULL), allow_natives_syntax_(allow_natives_syntax), extension_(extension), factory_(factory), log_(log), is_pre_parsing_(is_pre_parsing), pre_data_(pre_data) {}bool Parser::PreParseProgram(unibrow::CharacterStream* stream) { StatsRateScope timer(&Counters::pre_parse); StackGuard guard; AssertNoZoneAllocation assert_no_zone_allocation; AssertNoAllocation assert_no_allocation; NoHandleAllocation no_handle_allocation; scanner_.Init(Handle<String>(), stream, 0); ASSERT(target_stack_ == NULL); mode_ = PARSE_EAGERLY; DummyScope top_scope; LexicalScope scope(this, &top_scope); TemporaryScope temp_scope(this); ZoneListWrapper<Statement> processor; bool ok = true; ParseSourceElements(&processor, Token::EOS, &ok); return !scanner().stack_overflow();}FunctionLiteral* Parser::ParseProgram(Handle<String> source, unibrow::CharacterStream* stream, bool in_global_context) { ZoneScope zone_scope(DONT_DELETE_ON_EXIT); StatsRateScope timer(&Counters::parse); Counters::total_parse_size.Increment(source->length()); // Initialize parser state. source->TryFlatten(); scanner_.Init(source, stream, 0); ASSERT(target_stack_ == NULL); // Compute the parsing mode. mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; Scope::Type type = in_global_context ? Scope::GLOBAL_SCOPE : Scope::EVAL_SCOPE; Handle<String> no_name = factory()->EmptySymbol(); FunctionLiteral* result = NULL; { Scope* scope = factory()->NewScope(top_scope_, type, inside_with());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -