iv-phonic 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -262,7 +262,7 @@ class Lexer: private Noncopyable<Lexer<Source> >::type {
262
262
  Advance();
263
263
  if (Chars::IsDecimalDigit(c_)) {
264
264
  // float number parse
265
- token = ScanNumber(true);
265
+ token = ScanNumber<true>();
266
266
  } else {
267
267
  token = Token::PERIOD;
268
268
  }
@@ -342,7 +342,7 @@ class Lexer: private Noncopyable<Lexer<Source> >::type {
342
342
  if (Chars::IsIdentifierStart(c_)) {
343
343
  token = ScanIdentifier<LexType>(strict);
344
344
  } else if (Chars::IsDecimalDigit(c_)) {
345
- token = ScanNumber(false);
345
+ token = ScanNumber<false>();
346
346
  } else if (Chars::IsLineTerminator(c_)) {
347
347
  SkipLineTerminator();
348
348
  has_line_terminator_before_next_ = true;
@@ -733,7 +733,8 @@ class Lexer: private Noncopyable<Lexer<Source> >::type {
733
733
  return true;
734
734
  }
735
735
 
736
- Token::Type ScanNumber(const bool period) {
736
+ template<bool period>
737
+ Token::Type ScanNumber() {
737
738
  buffer8_.clear();
738
739
  State type = DECIMAL;
739
740
  if (period) {
@@ -798,16 +799,21 @@ class Lexer: private Noncopyable<Lexer<Source> >::type {
798
799
  return Token::ILLEGAL;
799
800
  }
800
801
 
801
- if (type == OCTAL) {
802
- double val = 0;
803
- for (typename std::vector<char>::const_iterator it = buffer8_.begin(),
804
- last = buffer8_.end(); it != last; ++it) {
805
- val = val * 8 + (*it - '0');
806
- }
807
- numeric_ = val;
808
- } else {
802
+
803
+ if (type == DECIMAL) {
809
804
  const std::string buf(buffer8_.begin(), buffer8_.end());
810
805
  numeric_ = std::atof(buf.c_str());
806
+ } else if (type == HEX) {
807
+ assert(buffer8_.size() > 2); // first 0x
808
+ numeric_ = ParseIntegerOverflow(buffer8_.begin() + 2,
809
+ buffer8_.end(),
810
+ 16);
811
+ } else {
812
+ assert(type == OCTAL);
813
+ assert(buffer8_.size() > 1); // first 0
814
+ numeric_ = ParseIntegerOverflow(buffer8_.begin() + 1,
815
+ buffer8_.end(),
816
+ 8);
811
817
  }
812
818
  type_ = type;
813
819
  return Token::NUMBER;
@@ -135,11 +135,16 @@ const UString ParserData<T>::kSet(
135
135
 
136
136
  typedef detail::ParserData<None> ParserData;
137
137
 
138
- template<typename Factory, typename Source, bool UseFunctionStatement>
138
+ template<typename Factory,
139
+ typename Source,
140
+ bool UseFunctionStatement,
141
+ bool ReduceExpressions>
139
142
  class Parser
140
- : private Noncopyable<Parser<Factory, Source, UseFunctionStatement> >::type {
143
+ : private Noncopyable<
144
+ Parser<Factory, Source, UseFunctionStatement, ReduceExpressions> >::type {
141
145
  public:
142
- typedef Parser<Factory, Source, UseFunctionStatement> this_type;
146
+ typedef Parser<Factory, Source,
147
+ UseFunctionStatement, ReduceExpressions> this_type;
143
148
  typedef this_type parser_type;
144
149
  typedef Lexer<Source> lexer_type;
145
150
  #define V(AST) typedef typename ast::AST<Factory> AST;
@@ -461,16 +466,17 @@ class Parser
461
466
  // | StatementList Statement
462
467
  Block* ParseBlock(bool *res) {
463
468
  assert(token_ == Token::LBRACE);
464
- Block* const block = factory_->NewBlock();
469
+ Statements* const body = factory_->template NewVector<Statement*>();
465
470
  Statement* stmt;
466
471
  Target target(this, Target::kNamedOnlyStatement);
467
472
 
468
473
  Next();
469
474
  while (token_ != Token::RBRACE) {
470
475
  stmt = ParseStatement(CHECK);
471
- block->AddStatement(stmt);
476
+ body->push_back(stmt);
472
477
  }
473
478
  Next();
479
+ Block* const block = factory_->NewBlock(body);
474
480
  target.set_node(block);
475
481
  return block;
476
482
  }
@@ -480,10 +486,10 @@ class Parser
480
486
  // : CONST VariableDeclarationList ';'
481
487
  Statement* ParseVariableStatement(bool *res) {
482
488
  assert(token_ == Token::VAR || token_ == Token::CONST);
483
- VariableStatement* const stmt = factory_->NewVariableStatement(token_);
484
- ParseVariableDeclarations(stmt, true, CHECK);
489
+ Declarations* const decls = factory_->template NewVector<Declaration*>();
490
+ ParseVariableDeclarations(decls, token_ == Token::CONST, true, CHECK);
485
491
  ExpectSemicolon(CHECK);
486
- return stmt;
492
+ return factory_->NewVariableStatement(token_, decls);
487
493
  }
488
494
 
489
495
  // VariableDeclarationList
@@ -499,9 +505,10 @@ class Parser
499
505
  //
500
506
  // Initialiser
501
507
  // : '=' AssignmentExpression
502
- Statement* ParseVariableDeclarations(VariableStatement* stmt,
503
- bool contains_in,
504
- bool *res) {
508
+ Declarations* ParseVariableDeclarations(Declarations* decls,
509
+ bool is_const,
510
+ bool contains_in,
511
+ bool *res) {
505
512
  Identifier* name;
506
513
  Expression* expr;
507
514
  Declaration* decl;
@@ -533,11 +540,11 @@ class Parser
533
540
  // Undefined Expression
534
541
  decl = factory_->NewDeclaration(name, factory_->NewUndefined());
535
542
  }
536
- stmt->AddDeclaration(decl);
537
- scope_->AddUnresolved(name, stmt->IsConst());
543
+ decls->push_back(decl);
544
+ scope_->AddUnresolved(name, is_const);
538
545
  } while (token_ == Token::COMMA);
539
546
 
540
- return stmt;
547
+ return decls;
541
548
  }
542
549
 
543
550
  // EmptyStatement
@@ -649,8 +656,11 @@ class Parser
649
656
 
650
657
  if (token_ != Token::SEMICOLON) {
651
658
  if (token_ == Token::VAR || token_ == Token::CONST) {
652
- VariableStatement* const var = factory_->NewVariableStatement(token_);
653
- ParseVariableDeclarations(var, false, CHECK);
659
+ Declarations* const decls =
660
+ factory_->template NewVector<Declaration*>();
661
+ ParseVariableDeclarations(decls, token_ == Token::CONST, false, CHECK);
662
+ VariableStatement* const var =
663
+ factory_->NewVariableStatement(token_, decls);
654
664
  init = var;
655
665
  if (token_ == Token::IN) {
656
666
  // for in loop
@@ -841,13 +851,13 @@ class Parser
841
851
  // | '{' CaseClauses_opt DefaultClause CaseClauses_opt '}'
842
852
  Statement* ParseSwitchStatement(bool *res) {
843
853
  assert(token_ == Token::SWITCH);
844
- CaseClause *case_clause;
854
+ CaseClause* case_clause;
845
855
  Next();
846
856
 
847
857
  EXPECT(Token::LPAREN);
848
858
 
849
- Expression *expr = ParseExpression(true, CHECK);
850
- SwitchStatement *switch_stmt = factory_->NewSwitchStatement(expr);
859
+ Expression* expr = ParseExpression(true, CHECK);
860
+ CaseClauses* clauses = factory_->template NewVector<CaseClause*>();
851
861
  Target target(this, Target::kSwitchStatement);
852
862
 
853
863
  EXPECT(Token::RPAREN);
@@ -869,10 +879,12 @@ class Parser
869
879
  default_found = true;
870
880
  }
871
881
  }
872
- switch_stmt->AddCaseClause(case_clause);
882
+ clauses->push_back(case_clause);
873
883
  }
874
884
  Next();
875
885
 
886
+ SwitchStatement* const switch_stmt =
887
+ factory_->NewSwitchStatement(expr, clauses);
876
888
  target.set_node(switch_stmt);
877
889
  return switch_stmt;
878
890
  }
@@ -888,16 +900,14 @@ class Parser
888
900
  // : DEFAULT ':' StatementList_opt
889
901
  CaseClause* ParseCaseClause(bool *res) {
890
902
  assert(token_ == Token::CASE || token_ == Token::DEFAULT);
891
- CaseClause* clause;
892
- Statement* stmt;
903
+ Expression* expr = NULL;
904
+ Statements* const body = factory_->template NewVector<Statement*>();
893
905
 
894
906
  if (token_ == Token::CASE) {
895
907
  Next();
896
- Expression* const expr = ParseExpression(true, CHECK);
897
- clause = factory_->NewCaseClause(false, expr);
908
+ expr = ParseExpression(true, CHECK);
898
909
  } else {
899
910
  EXPECT(Token::DEFAULT);
900
- clause = factory_->NewCaseClause(true, NULL);
901
911
  }
902
912
 
903
913
  EXPECT(Token::COLON);
@@ -905,11 +915,11 @@ class Parser
905
915
  while (token_ != Token::RBRACE &&
906
916
  token_ != Token::CASE &&
907
917
  token_ != Token::DEFAULT) {
908
- stmt = ParseStatement(CHECK);
909
- clause->AddStatement(stmt);
918
+ Statement* const stmt = ParseStatement(CHECK);
919
+ body->push_back(stmt);
910
920
  }
911
921
 
912
- return clause;
922
+ return factory_->NewCaseClause(expr == NULL, expr, body);
913
923
  }
914
924
 
915
925
  // ThrowStatement
@@ -1023,7 +1033,7 @@ class Parser
1023
1033
  Identifier* const label = expr->AsIdentifier();
1024
1034
  const bool exist_labels = labels;
1025
1035
  if (!exist_labels) {
1026
- labels = factory_->NewLabels();
1036
+ labels = factory_->template NewVector<Identifier*>();
1027
1037
  }
1028
1038
  if (ContainsLabel(labels, label) || TargetsContainsLabel(label)) {
1029
1039
  // duplicate label
@@ -1188,7 +1198,7 @@ class Parser
1188
1198
  op = token_;
1189
1199
  Next();
1190
1200
  right = ParseUnaryExpression(CHECK);
1191
- left = ReduceBinaryOperation(op, left, right);
1201
+ left = ReduceBinaryOperation<ReduceExpressions>(op, left, right);
1192
1202
  }
1193
1203
  if (prec < 1) return left;
1194
1204
 
@@ -1198,7 +1208,7 @@ class Parser
1198
1208
  op = token_;
1199
1209
  Next();
1200
1210
  right = ParseBinaryExpression(contains_in, 0, CHECK);
1201
- left = ReduceBinaryOperation(op, left, right);
1211
+ left = ReduceBinaryOperation<ReduceExpressions>(op, left, right);
1202
1212
  }
1203
1213
  if (prec < 2) return left;
1204
1214
 
@@ -1209,7 +1219,7 @@ class Parser
1209
1219
  op = token_;
1210
1220
  Next();
1211
1221
  right = ParseBinaryExpression(contains_in, 1, CHECK);
1212
- left = ReduceBinaryOperation(op, left, right);
1222
+ left = ReduceBinaryOperation<ReduceExpressions>(op, left, right);
1213
1223
  }
1214
1224
  if (prec < 3) return left;
1215
1225
 
@@ -1241,7 +1251,7 @@ class Parser
1241
1251
  op = token_;
1242
1252
  Next();
1243
1253
  right = ParseBinaryExpression(contains_in, 4, CHECK);
1244
- left = ReduceBinaryOperation(op, left, right);
1254
+ left = ReduceBinaryOperation<ReduceExpressions>(op, left, right);
1245
1255
  }
1246
1256
  if (prec < 6) return left;
1247
1257
 
@@ -1250,7 +1260,7 @@ class Parser
1250
1260
  op = token_;
1251
1261
  Next();
1252
1262
  right = ParseBinaryExpression(contains_in, 5, CHECK);
1253
- left = ReduceBinaryOperation(op, left, right);
1263
+ left = ReduceBinaryOperation<ReduceExpressions>(op, left, right);
1254
1264
  }
1255
1265
  if (prec < 7) return left;
1256
1266
 
@@ -1259,7 +1269,7 @@ class Parser
1259
1269
  op = token_;
1260
1270
  Next();
1261
1271
  right = ParseBinaryExpression(contains_in, 6, CHECK);
1262
- left = ReduceBinaryOperation(op, left, right);
1272
+ left = ReduceBinaryOperation<ReduceExpressions>(op, left, right);
1263
1273
  }
1264
1274
  if (prec < 8) return left;
1265
1275
 
@@ -1282,9 +1292,11 @@ class Parser
1282
1292
  return left;
1283
1293
  }
1284
1294
 
1295
+ template<bool Reduce>
1285
1296
  Expression* ReduceBinaryOperation(Token::Type op,
1286
1297
  Expression* left,
1287
- Expression* right) {
1298
+ Expression* right,
1299
+ typename enable_if_c<Reduce>::type* = 0) {
1288
1300
  if (left->AsNumberLiteral() &&
1289
1301
  right->AsNumberLiteral()) {
1290
1302
  const double l_val = left->AsNumberLiteral()->value();
@@ -1354,6 +1366,14 @@ class Parser
1354
1366
  }
1355
1367
  }
1356
1368
 
1369
+ template<bool Reduce>
1370
+ Expression* ReduceBinaryOperation(Token::Type op,
1371
+ Expression* left,
1372
+ Expression* right,
1373
+ typename enable_if_c<!Reduce>::type* = 0) {
1374
+ return factory_->NewBinaryOperation(op, left, right);
1375
+ }
1376
+
1357
1377
  // UnaryExpression
1358
1378
  // : PostfixExpression
1359
1379
  // | DELETE UnaryExpression
@@ -1511,11 +1531,11 @@ class Parser
1511
1531
  } else {
1512
1532
  Next();
1513
1533
  Expression* const target = ParseMemberExpression(false, CHECK);
1514
- ConstructorCall* const con = factory_->NewConstructorCall(target);
1534
+ Expressions* const args = factory_->template NewVector<Expression*>();
1515
1535
  if (token_ == Token::LPAREN) {
1516
- ParseArguments(con, CHECK);
1536
+ ParseArguments(args, CHECK);
1517
1537
  }
1518
- expr = con;
1538
+ expr = factory_->NewConstructorCall(target, args);
1519
1539
  }
1520
1540
  while (true) {
1521
1541
  switch (token_) {
@@ -1537,9 +1557,10 @@ class Parser
1537
1557
 
1538
1558
  case Token::LPAREN:
1539
1559
  if (allow_call) {
1540
- FunctionCall* const funcall = factory_->NewFunctionCall(expr);
1541
- ParseArguments(funcall, CHECK);
1542
- expr = funcall;
1560
+ Expressions* const args =
1561
+ factory_->template NewVector<Expression*>();
1562
+ ParseArguments(args, CHECK);
1563
+ expr = factory_->NewFunctionCall(expr, args);
1543
1564
  } else {
1544
1565
  return expr;
1545
1566
  }
@@ -1653,20 +1674,20 @@ class Parser
1653
1674
  // ArgumentList
1654
1675
  // : AssignmentExpression
1655
1676
  // | ArgumentList ',' AssignmentExpression
1656
- template<typename Callable>
1657
- Callable* ParseArguments(Callable* func, bool *res) {
1677
+ template<typename Container>
1678
+ Container* ParseArguments(Container* container, bool *res) {
1658
1679
  Next();
1659
1680
  if (token_ != Token::RPAREN) {
1660
1681
  Expression* const first = ParseAssignmentExpression(true, CHECK);
1661
- func->AddArgument(first);
1682
+ container->push_back(first);
1662
1683
  while (token_ == Token::COMMA) {
1663
1684
  Next();
1664
1685
  Expression* const expr = ParseAssignmentExpression(true, CHECK);
1665
- func->AddArgument(expr);
1686
+ container->push_back(expr);
1666
1687
  }
1667
1688
  }
1668
1689
  EXPECT(Token::RPAREN);
1669
- return func;
1690
+ return container;
1670
1691
  }
1671
1692
 
1672
1693
  Expression* ParseRegExpLiteral(bool contains_eq, bool *res) {
@@ -1700,23 +1721,22 @@ class Parser
1700
1721
  // : ','
1701
1722
  // | Elision ','
1702
1723
  Expression* ParseArrayLiteral(bool *res) {
1703
- ArrayLiteral* const array = factory_->NewArrayLiteral();
1704
- Expression* expr;
1724
+ Expressions* const items = factory_->template NewVector<Expression*>();
1705
1725
  Next();
1706
1726
  while (token_ != Token::RBRACK) {
1707
1727
  if (token_ == Token::COMMA) {
1708
1728
  // when Token::COMMA, only increment length
1709
- array->AddItem(NULL);
1729
+ items->push_back(NULL);
1710
1730
  } else {
1711
- expr = ParseAssignmentExpression(true, CHECK);
1712
- array->AddItem(expr);
1731
+ Expression* const expr = ParseAssignmentExpression(true, CHECK);
1732
+ items->push_back(expr);
1713
1733
  }
1714
1734
  if (token_ != Token::RBRACK) {
1715
1735
  EXPECT(Token::COMMA);
1716
1736
  }
1717
1737
  }
1718
1738
  Next();
1719
- return array;
1739
+ return factory_->NewArrayLiteral(items);
1720
1740
  }
1721
1741
 
1722
1742
 
@@ -1746,7 +1766,9 @@ class Parser
1746
1766
  // : IDENTIFIER
1747
1767
  Expression* ParseObjectLiteral(bool *res) {
1748
1768
  typedef std::tr1::unordered_map<IdentifierKey, int> ObjectMap;
1749
- ObjectLiteral* const object = factory_->NewObjectLiteral();
1769
+ typedef typename ObjectLiteral::Property Property;
1770
+ typedef typename ObjectLiteral::Properties Properties;
1771
+ Properties* const prop = factory_->template NewVector<Property>();
1750
1772
  ObjectMap map;
1751
1773
  Expression* expr;
1752
1774
  Identifier* ident;
@@ -1763,7 +1785,7 @@ class Parser
1763
1785
  ident = ParseIdentifier(
1764
1786
  is_get ? ParserData::kGet : ParserData::kSet);
1765
1787
  expr = ParseAssignmentExpression(true, CHECK);
1766
- object->AddDataProperty(ident, expr);
1788
+ ObjectLiteral::AddDataProperty(prop, ident, expr);
1767
1789
  typename ObjectMap::iterator it = map.find(ident);
1768
1790
  if (it == map.end()) {
1769
1791
  map.insert(std::make_pair(ident, ObjectLiteral::DATA));
@@ -1794,7 +1816,7 @@ class Parser
1794
1816
  FunctionLiteral::EXPRESSION,
1795
1817
  (is_get) ? FunctionLiteral::GETTER : FunctionLiteral::SETTER,
1796
1818
  CHECK);
1797
- object->AddAccessor(type, ident, expr);
1819
+ ObjectLiteral::AddAccessor(prop, type, ident, expr);
1798
1820
  typename ObjectMap::iterator it = map.find(ident);
1799
1821
  if (it == map.end()) {
1800
1822
  map.insert(std::make_pair(ident, type));
@@ -1823,7 +1845,7 @@ class Parser
1823
1845
  }
1824
1846
  EXPECT(Token::COLON);
1825
1847
  expr = ParseAssignmentExpression(true, CHECK);
1826
- object->AddDataProperty(ident, expr);
1848
+ ObjectLiteral::AddDataProperty(prop, ident, expr);
1827
1849
  typename ObjectMap::iterator it = map.find(ident);
1828
1850
  if (it == map.end()) {
1829
1851
  map.insert(std::make_pair(ident, ObjectLiteral::DATA));
@@ -1849,7 +1871,7 @@ class Parser
1849
1871
  }
1850
1872
  }
1851
1873
  Next();
1852
- return object;
1874
+ return factory_->NewObjectLiteral(prop);
1853
1875
  }
1854
1876
 
1855
1877
  FunctionLiteral* ParseFunctionLiteral(
@@ -1866,7 +1888,8 @@ class Parser
1866
1888
  kDetectArgumentsName,
1867
1889
  kDetectEvalParameter,
1868
1890
  kDetectArgumentsParameter,
1869
- kDetectDuplicateParameter
1891
+ kDetectDuplicateParameter,
1892
+ kDetectFutureReservedWords
1870
1893
  } throw_error_if_strict_code = kDetectNone;
1871
1894
 
1872
1895
  FunctionLiteral* const literal = factory_->NewFunctionLiteral(decl_type);
@@ -1874,15 +1897,23 @@ class Parser
1874
1897
 
1875
1898
  if (arg_type == FunctionLiteral::GENERAL) {
1876
1899
  assert(token_ == Token::FUNCTION);
1877
- Next();
1878
- if (token_ == Token::IDENTIFIER) {
1900
+ Next(true); // preparing for strict directive
1901
+ const Token::Type current = token_;
1902
+ if (current == Token::IDENTIFIER ||
1903
+ Token::IsAddedFutureReservedWordInStrictCode(current)) {
1879
1904
  Identifier* const name = ParseIdentifier(lexer_.Buffer());
1880
1905
  literal->SetName(name);
1881
- const EvalOrArguments val = IsEvalOrArguments(name);
1882
- if (val) {
1883
- throw_error_if_strict_code = (val == kEval) ?
1884
- kDetectEvalName : kDetectArgumentsName;
1906
+ if (Token::IsAddedFutureReservedWordInStrictCode(current)) {
1907
+ throw_error_if_strict_code = kDetectFutureReservedWords;
1885
1908
  throw_error_if_strict_code_line = lexer_.line_number();
1909
+ } else {
1910
+ assert(current == Token::IDENTIFIER);
1911
+ const EvalOrArguments val = IsEvalOrArguments(name);
1912
+ if (val) {
1913
+ throw_error_if_strict_code = (val == kEval) ?
1914
+ kDetectEvalName : kDetectArgumentsName;
1915
+ throw_error_if_strict_code_line = lexer_.line_number();
1916
+ }
1886
1917
  }
1887
1918
  } else if (decl_type == FunctionLiteral::DECLARATION ||
1888
1919
  decl_type == FunctionLiteral::STATEMENT) {
@@ -1895,21 +1926,32 @@ class Parser
1895
1926
  literal->set_start_position(lexer_.begin_position());
1896
1927
 
1897
1928
  // '(' FormalParameterList_opt ')'
1898
- EXPECT(Token::LPAREN);
1929
+ IS(Token::LPAREN);
1930
+ Next(true); // preparing for strict directive
1899
1931
 
1900
1932
  if (arg_type == FunctionLiteral::GETTER) {
1901
1933
  // if getter, parameter count is 0
1902
1934
  EXPECT(Token::RPAREN);
1903
1935
  } else if (arg_type == FunctionLiteral::SETTER) {
1904
1936
  // if setter, parameter count is 1
1905
- IS(Token::IDENTIFIER);
1937
+ const Token::Type current = token_;
1938
+ if (current != Token::IDENTIFIER &&
1939
+ !Token::IsAddedFutureReservedWordInStrictCode(current)) {
1940
+ IS(Token::IDENTIFIER);
1941
+ }
1906
1942
  Identifier* const ident = ParseIdentifier(lexer_.Buffer());
1907
1943
  if (!throw_error_if_strict_code) {
1908
- const EvalOrArguments val = IsEvalOrArguments(ident);
1909
- if (val) {
1910
- throw_error_if_strict_code = (val == kEval) ?
1911
- kDetectEvalParameter : kDetectArgumentsParameter;
1944
+ if (Token::IsAddedFutureReservedWordInStrictCode(current)) {
1945
+ throw_error_if_strict_code = kDetectFutureReservedWords;
1912
1946
  throw_error_if_strict_code_line = lexer_.line_number();
1947
+ } else {
1948
+ assert(current == Token::IDENTIFIER);
1949
+ const EvalOrArguments val = IsEvalOrArguments(ident);
1950
+ if (val) {
1951
+ throw_error_if_strict_code = (val == kEval) ?
1952
+ kDetectEvalName : kDetectArgumentsName;
1953
+ throw_error_if_strict_code_line = lexer_.line_number();
1954
+ }
1913
1955
  }
1914
1956
  }
1915
1957
  literal->AddParameter(ident);
@@ -1917,14 +1959,24 @@ class Parser
1917
1959
  } else {
1918
1960
  if (token_ != Token::RPAREN) {
1919
1961
  do {
1920
- IS(Token::IDENTIFIER);
1962
+ const Token::Type current = token_;
1963
+ if (current != Token::IDENTIFIER &&
1964
+ !Token::IsAddedFutureReservedWordInStrictCode(current)) {
1965
+ IS(Token::IDENTIFIER);
1966
+ }
1921
1967
  Identifier* const ident = ParseIdentifier(lexer_.Buffer());
1922
1968
  if (!throw_error_if_strict_code) {
1923
- const EvalOrArguments val = IsEvalOrArguments(ident);
1924
- if (val) {
1925
- throw_error_if_strict_code = (val == kEval) ?
1926
- kDetectEvalParameter : kDetectArgumentsParameter;
1969
+ if (Token::IsAddedFutureReservedWordInStrictCode(current)) {
1970
+ throw_error_if_strict_code = kDetectFutureReservedWords;
1927
1971
  throw_error_if_strict_code_line = lexer_.line_number();
1972
+ } else {
1973
+ assert(current == Token::IDENTIFIER);
1974
+ const EvalOrArguments val = IsEvalOrArguments(ident);
1975
+ if (val) {
1976
+ throw_error_if_strict_code = (val == kEval) ?
1977
+ kDetectEvalName : kDetectArgumentsName;
1978
+ throw_error_if_strict_code_line = lexer_.line_number();
1979
+ }
1928
1980
  }
1929
1981
  if ((!throw_error_if_strict_code) &&
1930
1982
  (param_set.find(ident) != param_set.end())) {
@@ -1935,7 +1987,7 @@ class Parser
1935
1987
  literal->AddParameter(ident);
1936
1988
  param_set.insert(ident);
1937
1989
  if (token_ == Token::COMMA) {
1938
- Next();
1990
+ Next(true);
1939
1991
  } else {
1940
1992
  break;
1941
1993
  }
@@ -1983,6 +2035,11 @@ class Parser
1983
2035
  "duplicate parameter not allowed in strict code",
1984
2036
  throw_error_if_strict_code_line);
1985
2037
  break;
2038
+ case kDetectFutureReservedWords:
2039
+ RAISE_WITH_NUMBER(
2040
+ "FutureReservedWords is found in strict code",
2041
+ throw_error_if_strict_code_line);
2042
+ break;
1986
2043
  }
1987
2044
  }
1988
2045
  literal->set_end_position(lexer_.end_position());
@@ -2136,6 +2193,9 @@ class Parser
2136
2193
  inline Token::Type Next() {
2137
2194
  return token_ = lexer_.Next<IdentifyReservedWords>(strict_);
2138
2195
  }
2196
+ inline Token::Type Next(bool strict) {
2197
+ return token_ = lexer_.Next<IdentifyReservedWords>(strict);
2198
+ }
2139
2199
  inline Token::Type Peek() const {
2140
2200
  return token_;
2141
2201
  }
@@ -125,29 +125,32 @@ class Token {
125
125
  FINAL, // final
126
126
  FLOAT, // float
127
127
  GOTO, // goto
128
- IMPLEMENTS, // implements
129
128
  IMPORT, // import
130
129
  INT, // int
131
- INTERFACE, // interface
132
130
  LONG, // long
133
131
  NATIVE, // native
134
- PACKAGE, // package
135
- PRIVATE, // private
136
- PROTECTED, // protected
137
- PUBLIC, // public
138
132
  SHORT, // short
139
- STATIC, // static
140
133
  SUPER, // super
141
134
  SYNCHRONIZED, // synchronized
142
135
  THROWS, // throws
143
136
  TRANSIENT, // transient
144
137
  VOLATILE, // volatile
145
- LET, // let
146
- YIELD, // yield
147
138
 
148
139
  GET, // get
149
140
  SET, // set
150
141
 
142
+ STRICT_FIRST, // STRICT FIRST
143
+ IMPLEMENTS, // implements
144
+ LET, // let
145
+ PRIVATE, // private
146
+ PUBLIC, // public
147
+ YIELD, // yield
148
+ INTERFACE, // interface
149
+ PACKAGE, // package
150
+ PROTECTED, // protected
151
+ STATIC, // static
152
+ STRICT_LAST, // STRICT LAST
153
+
151
154
  NULL_LITERAL, // NULL LITERAL
152
155
  FALSE_LITERAL, // FALSE LITERAL
153
156
  TRUE_LITERAL, // TRUE LITERAL
@@ -165,12 +168,19 @@ class Token {
165
168
  static inline bool IsAssignOp(Token::Type type) {
166
169
  return Token::ASSIGN_FIRST < type && type < Token::ASSIGN_LAST;
167
170
  }
171
+
172
+ static inline bool IsAddedFutureReservedWordInStrictCode(Token::Type type) {
173
+ return Token::STRICT_FIRST < type && type < Token::STRICT_LAST;
174
+ }
175
+
168
176
  static inline const char* ToString(Token::Type type) {
169
177
  assert(0 <= type && type < NUM_TOKENS);
170
178
  assert(type != Token::ASSIGN_FIRST &&
171
179
  type != Token::ASSIGN_LAST &&
172
180
  type != Token::REL_FIRST &&
173
181
  type != Token::REL_LAST &&
182
+ type != Token::STRICT_FIRST &&
183
+ type != Token::STRICT_LAST &&
174
184
  type != Token::STRING &&
175
185
  type != Token::NUMBER &&
176
186
  type != Token::IDENTIFIER &&
@@ -278,27 +288,29 @@ const char* TokenContents<T>::kContents[Token::NUM_TOKENS] = {
278
288
  "final",
279
289
  "float",
280
290
  "goto",
281
- "implements",
282
291
  "import",
283
292
  "int",
284
- "interface",
285
293
  "long",
286
294
  "native",
287
- "package",
288
- "private",
289
- "protected",
290
- "public",
291
295
  "short",
292
- "static",
293
296
  "super",
294
297
  "synchronized",
295
298
  "throws",
296
299
  "transient",
297
300
  "volatile",
298
- "let",
299
- "yield",
300
301
  "get",
301
302
  "set",
303
+ NULL,
304
+ "implements",
305
+ "let",
306
+ "private",
307
+ "public",
308
+ "yield",
309
+ "interface",
310
+ "package",
311
+ "protected",
312
+ "static",
313
+ NULL,
302
314
  "null",
303
315
  "false",
304
316
  "true",