iv-phonic 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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",