⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
  // empty statements, e.g. 'l1: l2: l3: break l2;'  if (!label.is_null() && ContainsLabel(labels, label)) {    return factory()->EmptyStatement();  }  BreakableStatement* target = NULL;  if (!is_pre_parsing_) {    target = LookupBreakTarget(label, CHECK_OK);    if (target == NULL) {      // Illegal break statement.  To be consistent with KJS we delay      // reporting of the syntax error until runtime.      Handle<String> error_type = Factory::illegal_break_symbol();      if (!label.is_null()) error_type = Factory::unknown_label_symbol();      Expression* throw_error = NewThrowSyntaxError(error_type, label);      return NEW(ExpressionStatement(throw_error));    }  }  ExpectSemicolon(CHECK_OK);  return NEW(BreakStatement(target));}Statement* Parser::ParseReturnStatement(bool* ok) {  // ReturnStatement ::  //   'return' Expression? ';'  // Consume the return token. It is necessary to do the before  // reporting any errors on it, because of the way errors are  // reported (underlining).  Expect(Token::RETURN, CHECK_OK);  // An ECMAScript program is considered syntactically incorrect if it  // contains a return statement that is not within the body of a  // function. See ECMA-262, section 12.9, page 67.  //  // To be consistent with KJS we report the syntax error at runtime.  if (!is_pre_parsing_ && !top_scope_->is_function_scope()) {    Handle<String> type = Factory::illegal_return_symbol();    Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());    return NEW(ExpressionStatement(throw_error));  }  Token::Value tok = peek();  if (scanner_.has_line_terminator_before_next() ||      tok == Token::SEMICOLON ||      tok == Token::RBRACE ||      tok == Token::EOS) {    ExpectSemicolon(CHECK_OK);    return NEW(ReturnStatement(GetLiteralUndefined()));  }  Expression* expr = ParseExpression(true, CHECK_OK);  ExpectSemicolon(CHECK_OK);  return NEW(ReturnStatement(expr));}Block* Parser::WithHelper(Expression* obj, ZoneStringList* labels, bool* ok) {  // Parse the statement and collect escaping labels.  ZoneList<Label*>* label_list = NEW(ZoneList<Label*>(0));  LabelCollector collector(label_list);  Statement* stat;  { Target target(this, &collector);    with_nesting_level_++;    top_scope_->RecordWithStatement();    stat = ParseStatement(labels, CHECK_OK);    with_nesting_level_--;  }  // Create resulting block with two statements.  // 1: Evaluate the with expression.  // 2: The try-finally block evaluating the body.  Block* result = NEW(Block(NULL, 2, false));  if (result) {    result->AddStatement(NEW(WithEnterStatement(obj)));    // Create body block.    Block* body = NEW(Block(NULL, 1, false));    body->AddStatement(stat);    // Create exit block.    Block* exit = NEW(Block(NULL, 1, false));    exit->AddStatement(NEW(WithExitStatement()));    // Return a try-finally statement.    TryFinally* wrapper = NEW(TryFinally(body, NULL, exit));    wrapper->set_escaping_labels(collector.labels());    result->AddStatement(wrapper);    return result;  } else {    return NULL;  }}Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {  // WithStatement ::  //   'with' '(' Expression ')' Statement  // We do not allow the use of 'with' statements in the internal JS  // code. If 'with' statements were allowed, the simplified setup of  // the runtime context chain would allow access to properties in the  // global object from within a 'with' statement.  ASSERT(!Bootstrapper::IsActive());  Expect(Token::WITH, CHECK_OK);  Expect(Token::LPAREN, CHECK_OK);  Expression* expr = ParseExpression(true, CHECK_OK);  Expect(Token::RPAREN, CHECK_OK);  return WithHelper(expr, labels, CHECK_OK);}CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {  // CaseClause ::  //   'case' Expression ':' Statement*  //   'default' ':' Statement*  Expression* label = NULL;  // NULL expression indicates default case  if (peek() == Token::CASE) {    Expect(Token::CASE, CHECK_OK);    label = ParseExpression(true, CHECK_OK);  } else {    Expect(Token::DEFAULT, CHECK_OK);    if (*default_seen_ptr) {      ReportMessage("multiple_defaults_in_switch",                    Vector<const char*>::empty());      *ok = false;      return NULL;    }    *default_seen_ptr = true;  }  Expect(Token::COLON, CHECK_OK);  ZoneListWrapper<Statement> statements = factory()->NewList<Statement>(5);  while (peek() != Token::CASE &&         peek() != Token::DEFAULT &&         peek() != Token::RBRACE) {    Statement* stat = ParseStatement(NULL, CHECK_OK);    statements.Add(stat);  }  return NEW(CaseClause(label, statements.elements()));}SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,                                              bool* ok) {  // SwitchStatement ::  //   'switch' '(' Expression ')' '{' CaseClause* '}'  SwitchStatement* statement = NEW(SwitchStatement(labels));  Target target(this, statement);  Expect(Token::SWITCH, CHECK_OK);  Expect(Token::LPAREN, CHECK_OK);  Expression* tag = ParseExpression(true, CHECK_OK);  Expect(Token::RPAREN, CHECK_OK);  bool default_seen = false;  ZoneListWrapper<CaseClause> cases = factory()->NewList<CaseClause>(4);  Expect(Token::LBRACE, CHECK_OK);  while (peek() != Token::RBRACE) {    CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);    cases.Add(clause);  }  Expect(Token::RBRACE, CHECK_OK);  if (statement) statement->Initialize(tag, cases.elements());  return statement;}Statement* Parser::ParseThrowStatement(bool* ok) {  // ThrowStatement ::  //   'throw' Expression ';'  Expect(Token::THROW, CHECK_OK);  int pos = scanner().location().beg_pos;  if (scanner_.has_line_terminator_before_next()) {    ReportMessage("newline_after_throw", Vector<const char*>::empty());    *ok = false;    return NULL;  }  Expression* exception = ParseExpression(true, CHECK_OK);  ExpectSemicolon(CHECK_OK);  return NEW(ExpressionStatement(new Throw(exception, pos)));}Expression* Parser::MakeCatchContext(Handle<String> id, VariableProxy* value) {  ZoneListWrapper<ObjectLiteral::Property> properties =      factory()->NewList<ObjectLiteral::Property>(1);  Literal* key = NEW(Literal(id));  ObjectLiteral::Property* property = NEW(ObjectLiteral::Property(key, value));  properties.Add(property);  // This must be called always, even during pre-parsing!  // (Computation of literal index must happen before pre-parse bailout.)  int literal_index = temp_scope_->NextMaterializedLiteralIndex();  if (is_pre_parsing_) {    return NULL;  }  // Construct the expression for calling Runtime::CreateObjectLiteral  // with the literal array as argument.  Handle<FixedArray> constant_properties = Factory::empty_fixed_array();  ZoneList<Expression*>* arguments = new ZoneList<Expression*>(1);  arguments->Add(new Literal(constant_properties));  return new ObjectLiteral(constant_properties,                           properties.elements(),                           literal_index);}TryStatement* Parser::ParseTryStatement(bool* ok) {  // TryStatement ::  //   'try' Block Catch  //   'try' Block Finally  //   'try' Block Catch Finally  //  // Catch ::  //   'catch' '(' Identifier ')' Block  //  // Finally ::  //   'finally' Block  Expect(Token::TRY, CHECK_OK);  ZoneList<Label*>* label_list = NEW(ZoneList<Label*>(0));  LabelCollector collector(label_list);  Block* try_block;  { Target target(this, &collector);    try_block = ParseBlock(NULL, CHECK_OK);  }  Block* catch_block = NULL;  VariableProxy* catch_var = NULL;  Block* finally_block = NULL;  Token::Value tok = peek();  if (tok != Token::CATCH && tok != Token::FINALLY) {    ReportMessage("no_catch_or_finally", Vector<const char*>::empty());    *ok = false;    return NULL;  }  // If we can break out from the catch block and there is a finally block,  // then we will need to collect labels from the catch block. Since we don't  // know yet if there will be a finally block, we always collect the labels.  ZoneList<Label*>* catch_label_list = NEW(ZoneList<Label*>(0));  LabelCollector catch_collector(catch_label_list);  bool has_catch = false;  if (tok == Token::CATCH) {    has_catch = true;    Consume(Token::CATCH);    Expect(Token::LPAREN, CHECK_OK);    Handle<String> name = ParseIdentifier(CHECK_OK);    Expect(Token::RPAREN, CHECK_OK);    if (peek() == Token::LBRACE) {      // Allocate a temporary for holding the finally state while      // executing the finally block.      catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol());      Expression* obj = MakeCatchContext(name, catch_var);      { Target target(this, &catch_collector);        catch_block = WithHelper(obj, NULL, CHECK_OK);      }    } else {      Expect(Token::LBRACE, CHECK_OK);    }    tok = peek();  }  VariableProxy* finally_var = NULL;  if (tok == Token::FINALLY || !has_catch) {    Consume(Token::FINALLY);    // Declare a variable for holding the finally state while    // executing the finally block.    finally_var = top_scope_->NewTemporary(Factory::finally_state_symbol());    finally_block = ParseBlock(NULL, CHECK_OK);  }  // Simplify the AST nodes by converting:  //   'try { } catch { } finally { }'  // to:  //   'try { try { } catch { } } finally { }'  if (!is_pre_parsing_ && catch_block != NULL && finally_block != NULL) {    TryCatch* statement = NEW(TryCatch(try_block, catch_var, catch_block));    statement->set_escaping_labels(collector.labels());    try_block = NEW(Block(NULL, 1, false));    try_block->AddStatement(statement);    catch_block = NULL;  }  TryStatement* result = NULL;  if (!is_pre_parsing_) {    if (catch_block != NULL) {      ASSERT(finally_block == NULL);      result = NEW(TryCatch(try_block, catch_var, catch_block));      result->set_escaping_labels(collector.labels());    } else {      ASSERT(finally_block != NULL);      result = NEW(TryFinally(try_block, finally_var, finally_block));      // Add the labels of the try block and the catch block.      for (int i = 0; i < collector.labels()->length(); i++) {        catch_collector.labels()->Add(collector.labels()->at(i));      }      result->set_escaping_labels(catch_collector.labels());    }  }  return result;}LoopStatement* Parser::ParseDoStatement(ZoneStringList* labels, bool* ok) {  // DoStatement ::  //   'do' Statement 'while' '(' Expression ')' ';'  LoopStatement* loop = NEW(LoopStatement(labels, LoopStatement::DO_LOOP));  Target target(this, loop);  Expect(Token::DO, CHECK_OK);  Statement* body = ParseStatement(NULL, CHECK_OK);  Expect(Token::WHILE, CHECK_OK);  Expect(Token::LPAREN, CHECK_OK);  Expression* cond = ParseExpression(true, CHECK_OK);  Expect(Token::RPAREN, CHECK_OK);  // Allow do-statements to be terminated with and without  // semi-colons. This allows code such as 'do;while(0)return' to  // parse, which would not be the case if we had used the  // ExpectSemicolon() functionality here.  if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);  if (loop) loop->Initialize(NULL, cond, NULL, body);  return loop;}LoopStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {  // WhileStatement ::  //   'while' '(' Expression ')' Statement  LoopStatement* loop = NEW(LoopStatement(labels, LoopStatement::WHILE_LOOP));  Target target(this, loop);  Expect(Token::WHILE, CHECK_OK);  Expect(Token::LPAREN, CHECK_OK);  Expression* cond = ParseExpression(true, CHECK_OK);  Expect(Token::RPAREN, CHECK_OK);  Statement* body = ParseStatement(NULL, CHECK_OK);  if (loop) loop->Initialize(NULL, cond, NULL, body);  return loop;}Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {  // ForStatement ::  //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement  Statement* init = NULL;  Expect(Token::FOR, CHECK_OK);  Expect(Token::LPAREN, CHECK_OK);  if (peek() != Token::SEMICOLON) {    if (peek() == Token::VAR || peek() == Token::CONST) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -