Revision: 23157
Author:   [email protected]
Date:     Mon Aug 18 12:35:34 2014 UTC
Log:      Parse 'super' keyword.

BUG=v8:3330
LOG=N
[email protected], [email protected]

Review URL: https://codereview.chromium.org/480543002
http://code.google.com/p/v8/source/detail?r=23157

Modified:
 /branches/bleeding_edge/src/ast.cc
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/compiler/ast-graph-builder.cc
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/full-codegen.cc
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/messages.js
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/preparser.h
 /branches/bleeding_edge/src/prettyprinter.cc
 /branches/bleeding_edge/src/scanner.cc
 /branches/bleeding_edge/src/scanner.h
 /branches/bleeding_edge/src/token.h
 /branches/bleeding_edge/src/typing.cc
 /branches/bleeding_edge/test/cctest/test-parsing.cc

=======================================
--- /branches/bleeding_edge/src/ast.cc  Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/ast.cc  Mon Aug 18 12:35:34 2014 UTC
@@ -1097,6 +1097,7 @@
 DONT_OPTIMIZE_NODE(TryFinallyStatement)
 DONT_OPTIMIZE_NODE(DebuggerStatement)
 DONT_OPTIMIZE_NODE(NativeFunctionLiteral)
+DONT_OPTIMIZE_NODE(SuperReference)

 DONT_OPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(Yield)

=======================================
--- /branches/bleeding_edge/src/ast.h   Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/ast.h   Mon Aug 18 12:35:34 2014 UTC
@@ -94,6 +94,7 @@
   V(BinaryOperation)                            \
   V(CompareOperation)                           \
   V(ThisFunction)                               \
+  V(SuperReference)                             \
   V(CaseClause)

 #define AST_NODE_LIST(V)                        \
@@ -1709,6 +1710,10 @@
   void set_is_string_access(bool b) { is_string_access_ = b; }
   void mark_for_call() { is_for_call_ = true; }
   bool IsForCall() { return is_for_call_; }
+
+  bool IsSuperAccess() {
+    return obj()->IsSuperReference();
+  }

   TypeFeedbackId PropertyFeedbackId() { return reuse(id()); }

@@ -2554,6 +2559,25 @@
   explicit ThisFunction(Zone* zone, int pos): Expression(zone, pos) {}
 };

+
+class SuperReference V8_FINAL : public Expression {
+ public:
+  DECLARE_NODE_TYPE(SuperReference)
+
+  VariableProxy* this_var() const { return this_var_; }
+
+  TypeFeedbackId HomeObjectFeedbackId() { return reuse(id()); }
+
+ protected:
+  explicit SuperReference(Zone* zone, VariableProxy* this_var, int pos)
+      : Expression(zone, pos), this_var_(this_var) {
+      DCHECK(this_var->is_this());
+  }
+
+  VariableProxy* this_var_;
+};
+
+
 #undef DECLARE_NODE_TYPE


@@ -3471,6 +3495,11 @@
     ThisFunction* fun = new(zone_) ThisFunction(zone_, pos);
     VISIT_AND_RETURN(ThisFunction, fun)
   }
+
+  SuperReference* NewSuperReference(VariableProxy* this_var, int pos) {
+ SuperReference* super = new (zone_) SuperReference(zone_, this_var, pos);
+    VISIT_AND_RETURN(SuperReference, super);
+  }

 #undef VISIT_AND_RETURN

=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Wed Aug 13 10:22:53 2014 UTC +++ /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Mon Aug 18 12:35:34 2014 UTC
@@ -1538,6 +1538,11 @@
   Node* value = GetFunctionClosure();
   ast_context()->ProduceValue(value);
 }
+
+
+void AstGraphBuilder::VisitSuperReference(SuperReference* expr) {
+  UNREACHABLE();
+}


 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); }
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Fri Aug 8 11:42:59 2014 UTC +++ /branches/bleeding_edge/src/flag-definitions.h Mon Aug 18 12:35:34 2014 UTC
@@ -160,6 +160,7 @@
 DEFINE_BOOL(harmony_strings, false, "enable harmony string")
 DEFINE_BOOL(harmony_arrays, false, "enable harmony arrays")
DEFINE_BOOL(harmony_arrow_functions, false, "enable harmony arrow functions")
+DEFINE_BOOL(harmony_classes, false, "enable harmony classes")
 DEFINE_BOOL(harmony, false, "enable all harmony features (except proxies)")

 DEFINE_IMPLICATION(harmony, harmony_scoping)
@@ -171,6 +172,7 @@
 DEFINE_IMPLICATION(harmony, harmony_strings)
 DEFINE_IMPLICATION(harmony, harmony_arrays)
 DEFINE_IMPLICATION(harmony, harmony_arrow_functions)
+DEFINE_IMPLICATION(harmony, harmony_classes)
 DEFINE_IMPLICATION(harmony_modules, harmony_scoping)

 DEFINE_IMPLICATION(harmony, es_staging)
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/full-codegen.cc Mon Aug 18 12:35:34 2014 UTC
@@ -283,6 +283,9 @@

 void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
 }
+
+
+void BreakableStatementChecker::VisitSuperReference(SuperReference* expr) {}


 #define __ ACCESS_MASM(masm())
@@ -817,6 +820,12 @@
     }
   }
 }
+
+
+void FullCodeGenerator::VisitSuperReference(SuperReference* super) {
+  DCHECK(FLAG_harmony_classes);
+  UNIMPLEMENTED();
+}


 void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Mon Aug 18 07:54:19 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Mon Aug 18 12:35:34 2014 UTC
@@ -11183,6 +11183,11 @@
   HInstruction* instr = BuildThisFunction();
   return ast_context()->ReturnInstruction(instr, expr->id());
 }
+
+
+void HOptimizedGraphBuilder::VisitSuperReference(SuperReference* expr) {
+  UNREACHABLE();
+}


 void HOptimizedGraphBuilder::VisitDeclarations(
=======================================
--- /branches/bleeding_edge/src/messages.js     Mon Aug 11 19:24:05 2014 UTC
+++ /branches/bleeding_edge/src/messages.js     Mon Aug 18 12:35:34 2014 UTC
@@ -167,7 +167,8 @@
symbol_to_number: ["Cannot convert a Symbol value to a number"], invalid_module_path: ["Module does not export '", "%0", "', or export is not itself a module"],
   module_type_error:             ["Module '", "%0", "' used improperly"],
- module_export_undefined: ["Export '", "%0", "' is not defined in module"] + module_export_undefined: ["Export '", "%0", "' is not defined in module"],
+  unexpected_super:              ["'super' keyword unexpected here"]
 };


=======================================
--- /branches/bleeding_edge/src/objects.h       Thu Aug 14 10:24:19 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Mon Aug 18 12:35:34 2014 UTC
@@ -1022,7 +1022,7 @@
   V(OrderedHashTable)


-#define ERROR_MESSAGES_LIST(V) \
+#define ERROR_MESSAGES_LIST(V) \ V(kNoReason, "no reason") \ \ V(k32BitValueInRegisterIsNotZeroExtended, \
@@ -1089,24 +1089,17 @@
V(kExpectedNonIdenticalObjects, "Expected non-identical objects") \ V(kExpectedNonNullContext, "Expected non-null context") \ V(kExpectedPositiveZero, "Expected +0.0") \ - V(kExpectedAllocationSiteInCell, \ - "Expected AllocationSite in property cell") \ + V(kExpectedAllocationSiteInCell, "Expected AllocationSite in property cell")\ V(kExpectedFixedArrayInFeedbackVector, \ "Expected fixed array in feedback vector") \ - V(kExpectedFixedArrayInRegisterA2, \ - "Expected fixed array in register a2") \ - V(kExpectedFixedArrayInRegisterEbx, \ - "Expected fixed array in register ebx") \ - V(kExpectedFixedArrayInRegisterR2, \ - "Expected fixed array in register r2") \ - V(kExpectedFixedArrayInRegisterRbx, \ - "Expected fixed array in register rbx") \ + V(kExpectedFixedArrayInRegisterA2, "Expected fixed array in register a2") \ + V(kExpectedFixedArrayInRegisterEbx, "Expected fixed array in register ebx") \ + V(kExpectedFixedArrayInRegisterR2, "Expected fixed array in register r2") \ + V(kExpectedFixedArrayInRegisterRbx, "Expected fixed array in register rbx") \ V(kExpectedNewSpaceObject, "Expected new space object") \ V(kExpectedSmiOrHeapNumber, "Expected smi or HeapNumber") \ - V(kExpectedUndefinedOrCell, \ - "Expected undefined or cell in register") \ - V(kExpectingAlignmentForCopyBytes, \ - "Expecting alignment for CopyBytes") \ + V(kExpectedUndefinedOrCell, "Expected undefined or cell in register") \ + V(kExpectingAlignmentForCopyBytes, "Expecting alignment for CopyBytes") \ V(kExportDeclaration, "Export declaration") \ V(kExternalStringExpectedButNotFound, \ "External string expected, but not found") \
@@ -1179,8 +1172,7 @@
V(kLhsHasBeenClobbered, "lhs has been clobbered") \ V(kLiveBytesCountOverflowChunkSize, "Live Bytes Count overflow chunk size") \ V(kLiveEdit, "LiveEdit") \ - V(kLookupVariableInCountOperation, \ - "Lookup variable in count operation") \ + V(kLookupVariableInCountOperation, "Lookup variable in count operation") \ V(kMapBecameDeprecated, "Map became deprecated") \ V(kMapBecameUnstable, "Map became unstable") \ V(kMapIsNoLongerInEax, "Map is no longer in eax") \
@@ -1191,25 +1183,23 @@
V(kModuleVariable, "Module variable") \ V(kModuleUrl, "Module url") \ V(kNativeFunctionLiteral, "Native function literal") \ + V(kSuperReference, "Super reference") \ V(kNeedSmiLiteral, "Need a Smi literal here") \ V(kNoCasesLeft, "No cases left") \ V(kNoEmptyArraysHereInEmitFastAsciiArrayJoin, \ "No empty arrays here in EmitFastAsciiArrayJoin") \ - V(kNonInitializerAssignmentToConst, \ - "Non-initializer assignment to const") \ + V(kNonInitializerAssignmentToConst, "Non-initializer assignment to const") \ V(kNonSmiIndex, "Non-smi index") \ V(kNonSmiKeyInArrayLiteral, "Non-smi key in array literal") \ V(kNonSmiValue, "Non-smi value") \ V(kNonObject, "Non-object value") \ V(kNotEnoughVirtualRegistersForValues, \ "Not enough virtual registers for values") \ - V(kNotEnoughSpillSlotsForOsr, \ - "Not enough spill slots for OSR") \ + V(kNotEnoughSpillSlotsForOsr, "Not enough spill slots for OSR") \ V(kNotEnoughVirtualRegistersRegalloc, \ "Not enough virtual registers (regalloc)") \ V(kObjectFoundInSmiOnlyArray, "Object found in smi-only array") \ - V(kObjectLiteralWithComplexProperty, \ - "Object literal with complex property") \ + V(kObjectLiteralWithComplexProperty, "Object literal with complex property")\ V(kOddballInStringTableIsNotUndefinedOrTheHole, \ "Oddball in string table is not undefined or the hole") \ V(kOffsetOutOfRange, "Offset out of range") \
@@ -1235,12 +1225,11 @@
V(kReceivedInvalidReturnAddress, "Received invalid return address") \ V(kReferenceToAVariableWhichRequiresDynamicLookup, \ "Reference to a variable which requires dynamic lookup") \ - V(kReferenceToGlobalLexicalVariable, \ - "Reference to global lexical variable") \ + V(kReferenceToGlobalLexicalVariable, "Reference to global lexical variable")\ V(kReferenceToUninitializedVariable, "Reference to uninitialized variable") \ V(kRegisterDidNotMatchExpectedRoot, "Register did not match expected root") \ V(kRegisterWasClobbered, "Register was clobbered") \ - V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space") \ + V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space")\ V(kReturnAddressNotFoundInFrame, "Return address not found in frame") \ V(kRhsHasBeenClobbered, "Rhs has been clobbered") \ V(kScopedBlock, "ScopedBlock") \
=======================================
--- /branches/bleeding_edge/src/parser.cc       Thu Aug  7 16:42:14 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Mon Aug 18 12:35:34 2014 UTC
@@ -619,6 +619,12 @@
   return factory->NewVariableProxy(scope->receiver(), pos);
 }

+Expression* ParserTraits::SuperReference(
+ Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
+  return factory->NewSuperReference(
+      ThisExpression(scope, factory, pos)->AsVariableProxy(),
+      pos);
+}

 Literal* ParserTraits::ExpressionFromLiteral(
     Token::Value token, int pos,
@@ -731,6 +737,7 @@
   set_allow_generators(FLAG_harmony_generators);
   set_allow_arrow_functions(FLAG_harmony_arrow_functions);
   set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
+  set_allow_classes(FLAG_harmony_classes);
   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
        ++feature) {
     use_counts_[feature] = 0;
=======================================
--- /branches/bleeding_edge/src/parser.h        Wed Aug  6 12:05:39 2014 UTC
+++ /branches/bleeding_edge/src/parser.h        Mon Aug 18 12:35:34 2014 UTC
@@ -549,6 +549,9 @@
   Expression* ThisExpression(Scope* scope,
AstNodeFactory<AstConstructionVisitor>* factory,
                              int pos = RelocInfo::kNoPosition);
+  Expression* SuperReference(Scope* scope,
+ AstNodeFactory<AstConstructionVisitor>* factory,
+                             int pos = RelocInfo::kNoPosition);
   Literal* ExpressionFromLiteral(
       Token::Value token, int pos, Scanner* scanner,
       AstNodeFactory<AstConstructionVisitor>* factory);
=======================================
--- /branches/bleeding_edge/src/preparser.h     Thu Aug  7 16:42:14 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h     Mon Aug 18 12:35:34 2014 UTC
@@ -95,6 +95,7 @@
   bool allow_harmony_numeric_literals() const {
     return scanner()->HarmonyNumericLiterals();
   }
+  bool allow_classes() const { return scanner()->HarmonyClasses(); }

   // Setters that determine whether certain syntactical constructs are
   // allowed to be parsed by this instance of the parser.
@@ -109,6 +110,9 @@
   void set_allow_harmony_numeric_literals(bool allow) {
     scanner()->SetHarmonyNumericLiterals(allow);
   }
+  void set_allow_classes(bool allow) {
+    scanner()->SetHarmonyClasses(allow);
+  }

  protected:
   friend class Traits::Type::Checkpoint;
@@ -676,6 +680,10 @@
   static PreParserExpression This() {
     return PreParserExpression(kThisExpression);
   }
+
+  static PreParserExpression Super() {
+    return PreParserExpression(kSuperExpression);
+  }

   static PreParserExpression ThisProperty() {
     return PreParserExpression(kThisPropertyExpression);
@@ -798,7 +806,8 @@
     kThisExpression = (1 << 4),
     kThisPropertyExpression = (2 << 4),
     kPropertyExpression = (3 << 4),
-    kCallExpression = (4 << 4)
+    kCallExpression = (4 << 4),
+    kSuperExpression = (5 << 4)
   };

explicit PreParserExpression(int expression_code) : code_(expression_code) {}
@@ -1247,6 +1256,11 @@
                                             PreParserFactory* factory) {
     return PreParserExpression::This();
   }
+
+  static PreParserExpression SuperReference(PreParserScope* scope,
+                                            PreParserFactory* factory) {
+    return PreParserExpression::Super();
+  }

   static PreParserExpression ExpressionFromLiteral(
       Token::Value token, int pos, Scanner* scanner,
@@ -2383,7 +2397,12 @@
   if (peek() == Token::NEW) {
     Consume(Token::NEW);
     int new_pos = position();
- ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
+    ExpressionT result = this->EmptyExpression();
+    if (Check(Token::SUPER)) {
+      result = this->SuperReference(scope_, factory());
+    } else {
+      result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
+    }
     if (peek() == Token::LPAREN) {
       // NewExpression with arguments.
       typename Traits::Type::ExpressionList args =
@@ -2397,7 +2416,7 @@
     return factory()->NewCallNew(result, this->NewExpressionList(0, zone_),
                                  new_pos);
   }
-  // No 'new' keyword.
+  // No 'new' or 'super' keyword.
   return this->ParseMemberExpression(ok);
 }

@@ -2438,6 +2457,19 @@
                                         function_type,
                                         FunctionLiteral::NORMAL_ARITY,
                                         CHECK_OK);
+  } else if (peek() == Token::SUPER) {
+    int beg_pos = position();
+    Consume(Token::SUPER);
+    Token::Value next = peek();
+    if (next == Token::PERIOD || next == Token::LBRACK ||
+        next == Token::LPAREN) {
+      result = this->SuperReference(scope_, factory());
+    } else {
+      ReportMessageAt(Scanner::Location(beg_pos, position()),
+                      "unexpected_super");
+      *ok = false;
+      return this->EmptyExpression();
+    }
   } else {
     result = ParsePrimaryExpression(CHECK_OK);
   }
=======================================
--- /branches/bleeding_edge/src/prettyprinter.cc Mon Aug 4 11:34:54 2014 UTC +++ /branches/bleeding_edge/src/prettyprinter.cc Mon Aug 18 12:35:34 2014 UTC
@@ -445,6 +445,11 @@
 void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
   Print("<this-function>");
 }
+
+
+void PrettyPrinter::VisitSuperReference(SuperReference* node) {
+  Print("<super-reference>");
+}


 const char* PrettyPrinter::Print(AstNode* node) {
@@ -1144,6 +1149,11 @@
 void AstPrinter::VisitThisFunction(ThisFunction* node) {
   IndentedScope indent(this, "THIS-FUNCTION");
 }
+
+
+void AstPrinter::VisitSuperReference(SuperReference* node) {
+  IndentedScope indent(this, "SUPER-REFERENCE");
+}

 #endif  // DEBUG

=======================================
--- /branches/bleeding_edge/src/scanner.cc      Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/scanner.cc      Mon Aug 18 12:35:34 2014 UTC
@@ -36,7 +36,8 @@
       octal_pos_(Location::invalid()),
       harmony_scoping_(false),
       harmony_modules_(false),
-      harmony_numeric_literals_(false) { }
+      harmony_numeric_literals_(false),
+      harmony_classes_(false) { }


 void Scanner::Initialize(Utf16CharacterStream* source) {
@@ -901,76 +902,78 @@
// ----------------------------------------------------------------------------
 // Keyword Matcher

-#define KEYWORDS(KEYWORD_GROUP, KEYWORD)                            \
-  KEYWORD_GROUP('b')                                                \
-  KEYWORD("break", Token::BREAK)                                    \
-  KEYWORD_GROUP('c')                                                \
-  KEYWORD("case", Token::CASE)                                      \
-  KEYWORD("catch", Token::CATCH)                                    \
-  KEYWORD("class", Token::FUTURE_RESERVED_WORD)                     \
-  KEYWORD("const", Token::CONST)                                    \
-  KEYWORD("continue", Token::CONTINUE)                              \
-  KEYWORD_GROUP('d')                                                \
-  KEYWORD("debugger", Token::DEBUGGER)                              \
-  KEYWORD("default", Token::DEFAULT)                                \
-  KEYWORD("delete", Token::DELETE)                                  \
-  KEYWORD("do", Token::DO)                                          \
-  KEYWORD_GROUP('e')                                                \
-  KEYWORD("else", Token::ELSE)                                      \
-  KEYWORD("enum", Token::FUTURE_RESERVED_WORD)                      \
-  KEYWORD("export", harmony_modules                                 \
-                    ? Token::EXPORT : Token::FUTURE_RESERVED_WORD)  \
-  KEYWORD("extends", Token::FUTURE_RESERVED_WORD)                   \
-  KEYWORD_GROUP('f')                                                \
-  KEYWORD("false", Token::FALSE_LITERAL)                            \
-  KEYWORD("finally", Token::FINALLY)                                \
-  KEYWORD("for", Token::FOR)                                        \
-  KEYWORD("function", Token::FUNCTION)                              \
-  KEYWORD_GROUP('i')                                                \
-  KEYWORD("if", Token::IF)                                          \
-  KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD)         \
-  KEYWORD("import", harmony_modules                                 \
-                    ? Token::IMPORT : Token::FUTURE_RESERVED_WORD)  \
-  KEYWORD("in", Token::IN)                                          \
-  KEYWORD("instanceof", Token::INSTANCEOF)                          \
-  KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD)          \
-  KEYWORD_GROUP('l')                                                \
-  KEYWORD("let", harmony_scoping                                    \
-                 ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \
-  KEYWORD_GROUP('n')                                                \
-  KEYWORD("new", Token::NEW)                                        \
-  KEYWORD("null", Token::NULL_LITERAL)                              \
-  KEYWORD_GROUP('p')                                                \
-  KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD)            \
-  KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD)            \
-  KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD)          \
-  KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD)             \
-  KEYWORD_GROUP('r')                                                \
-  KEYWORD("return", Token::RETURN)                                  \
-  KEYWORD_GROUP('s')                                                \
-  KEYWORD("static", Token::FUTURE_STRICT_RESERVED_WORD)             \
-  KEYWORD("super", Token::FUTURE_RESERVED_WORD)                     \
-  KEYWORD("switch", Token::SWITCH)                                  \
-  KEYWORD_GROUP('t')                                                \
-  KEYWORD("this", Token::THIS)                                      \
-  KEYWORD("throw", Token::THROW)                                    \
-  KEYWORD("true", Token::TRUE_LITERAL)                              \
-  KEYWORD("try", Token::TRY)                                        \
-  KEYWORD("typeof", Token::TYPEOF)                                  \
-  KEYWORD_GROUP('v')                                                \
-  KEYWORD("var", Token::VAR)                                        \
-  KEYWORD("void", Token::VOID)                                      \
-  KEYWORD_GROUP('w')                                                \
-  KEYWORD("while", Token::WHILE)                                    \
-  KEYWORD("with", Token::WITH)                                      \
-  KEYWORD_GROUP('y')                                                \
+#define KEYWORDS(KEYWORD_GROUP, KEYWORD) \ + KEYWORD_GROUP('b') \ + KEYWORD("break", Token::BREAK) \ + KEYWORD_GROUP('c') \ + KEYWORD("case", Token::CASE) \ + KEYWORD("catch", Token::CATCH) \ + KEYWORD("class", Token::FUTURE_RESERVED_WORD) \ + KEYWORD("const", Token::CONST) \ + KEYWORD("continue", Token::CONTINUE) \ + KEYWORD_GROUP('d') \ + KEYWORD("debugger", Token::DEBUGGER) \ + KEYWORD("default", Token::DEFAULT) \ + KEYWORD("delete", Token::DELETE) \ + KEYWORD("do", Token::DO) \ + KEYWORD_GROUP('e') \ + KEYWORD("else", Token::ELSE) \ + KEYWORD("enum", Token::FUTURE_RESERVED_WORD) \ + KEYWORD("export", \ + harmony_modules ? Token::EXPORT : Token::FUTURE_RESERVED_WORD) \ + KEYWORD("extends", Token::FUTURE_RESERVED_WORD) \ + KEYWORD_GROUP('f') \ + KEYWORD("false", Token::FALSE_LITERAL) \ + KEYWORD("finally", Token::FINALLY) \ + KEYWORD("for", Token::FOR) \ + KEYWORD("function", Token::FUNCTION) \ + KEYWORD_GROUP('i') \ + KEYWORD("if", Token::IF) \ + KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD) \ + KEYWORD("import", \ + harmony_modules ? Token::IMPORT : Token::FUTURE_RESERVED_WORD) \ + KEYWORD("in", Token::IN) \ + KEYWORD("instanceof", Token::INSTANCEOF) \ + KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD) \ + KEYWORD_GROUP('l') \ + KEYWORD("let", \ + harmony_scoping ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \ + KEYWORD_GROUP('n') \ + KEYWORD("new", Token::NEW) \ + KEYWORD("null", Token::NULL_LITERAL) \ + KEYWORD_GROUP('p') \ + KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD) \ + KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD) \ + KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD) \ + KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD) \ + KEYWORD_GROUP('r') \ + KEYWORD("return", Token::RETURN) \ + KEYWORD_GROUP('s') \ + KEYWORD("static", Token::FUTURE_STRICT_RESERVED_WORD) \ + KEYWORD("super", \ + harmony_classes ? Token::SUPER : Token::FUTURE_RESERVED_WORD) \ + KEYWORD("switch", Token::SWITCH) \ + KEYWORD_GROUP('t') \ + KEYWORD("this", Token::THIS) \ + KEYWORD("throw", Token::THROW) \ + KEYWORD("true", Token::TRUE_LITERAL) \ + KEYWORD("try", Token::TRY) \ + KEYWORD("typeof", Token::TYPEOF) \ + KEYWORD_GROUP('v') \ + KEYWORD("var", Token::VAR) \ + KEYWORD("void", Token::VOID) \ + KEYWORD_GROUP('w') \ + KEYWORD("while", Token::WHILE) \ + KEYWORD("with", Token::WITH) \ + KEYWORD_GROUP('y') \
   KEYWORD("yield", Token::YIELD)


 static Token::Value KeywordOrIdentifierToken(const uint8_t* input,
                                              int input_length,
                                              bool harmony_scoping,
-                                             bool harmony_modules) {
+                                             bool harmony_modules,
+                                             bool harmony_classes) {
   DCHECK(input_length >= 1);
   const int kMinLength = 2;
   const int kMaxLength = 10;
@@ -1014,7 +1017,8 @@
   return string->is_one_byte() &&
          Token::FUTURE_STRICT_RESERVED_WORD ==
              KeywordOrIdentifierToken(string->raw_data(), string->length(),
-                                      harmony_scoping_, harmony_modules_);
+                                      harmony_scoping_, harmony_modules_,
+                                      harmony_classes_);
 }


@@ -1057,7 +1061,8 @@
     return KeywordOrIdentifierToken(chars.start(),
                                     chars.length(),
                                     harmony_scoping_,
-                                    harmony_modules_);
+                                    harmony_modules_,
+                                    harmony_classes_);
   }

   return Token::IDENTIFIER;
=======================================
--- /branches/bleeding_edge/src/scanner.h       Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/scanner.h       Mon Aug 18 12:35:34 2014 UTC
@@ -438,6 +438,12 @@
   void SetHarmonyNumericLiterals(bool numeric_literals) {
     harmony_numeric_literals_ = numeric_literals;
   }
+  bool HarmonyClasses() const {
+    return harmony_classes_;
+  }
+  void SetHarmonyClasses(bool classes) {
+    harmony_classes_ = classes;
+  }

   // Returns true if there was a line terminator before the peek'ed token,
   // possibly inside a multi-line comment.
@@ -647,6 +653,8 @@
   bool harmony_modules_;
   // Whether we scan 0o777 and 0b111 as numbers.
   bool harmony_numeric_literals_;
+  // Whether we scan 'super' as keyword.
+  bool harmony_classes_;
 };

 } }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/token.h Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/token.h Mon Aug 18 12:35:34 2014 UTC
@@ -153,6 +153,7 @@
   K(IMPORT, "import", 0)                                             \
   K(LET, "let", 0)                                                   \
   K(YIELD, "yield", 0)                                               \
+  K(SUPER, "super", 0)                                               \
                                                                      \
   /* Illegal token - not able to scan. */                            \
   T(ILLEGAL, "ILLEGAL", 0)                                           \
=======================================
--- /branches/bleeding_edge/src/typing.cc       Mon Aug  4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/typing.cc       Mon Aug 18 12:35:34 2014 UTC
@@ -721,6 +721,9 @@

 void AstTyper::VisitThisFunction(ThisFunction* expr) {
 }
+
+
+void AstTyper::VisitSuperReference(SuperReference* expr) {}


 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
=======================================
--- /branches/bleeding_edge/test/cctest/test-parsing.cc Thu Aug 7 16:42:14 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-parsing.cc Mon Aug 18 12:35:34 2014 UTC
@@ -72,6 +72,7 @@
       // The scanner should parse Harmony keywords for this test.
       scanner.SetHarmonyScoping(true);
       scanner.SetHarmonyModules(true);
+      scanner.SetHarmonyClasses(true);
       scanner.Initialize(&stream);
       CHECK_EQ(key_token.token, scanner.Next());
       CHECK_EQ(i::Token::EOS, scanner.Next());
@@ -1209,7 +1210,8 @@
   kAllowModules,
   kAllowGenerators,
   kAllowHarmonyNumericLiterals,
-  kAllowArrowFunctions
+  kAllowArrowFunctions,
+  kAllowClasses
 };


@@ -1230,6 +1232,7 @@
   parser->set_allow_harmony_numeric_literals(
       flags.Contains(kAllowHarmonyNumericLiterals));
   parser->set_allow_arrow_functions(flags.Contains(kAllowArrowFunctions));
+  parser->set_allow_classes(flags.Contains(kAllowClasses));
 }


@@ -1512,7 +1515,8 @@

   static const ParserFlag default_flags[] = {
       kAllowLazy,       kAllowHarmonyScoping, kAllowModules,
-      kAllowGenerators, kAllowNativesSyntax,  kAllowArrowFunctions};
+      kAllowGenerators, kAllowNativesSyntax,  kAllowArrowFunctions,
+      kAllowClasses};
   ParserFlag* generated_flags = NULL;
   if (flags == NULL) {
     flags = default_flags;
@@ -3343,3 +3347,47 @@
   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
                     always_flags, ARRAY_SIZE(always_flags));
 }
+
+
+TEST(NoErrorsSuper) {
+ // Tests that parser and preparser accept 'super' keyword in right places.
+  const char* context_data[][2] = {{"", ";"},
+                                   {"k = ", ";"},
+                                   {"foo(", ");"},
+                                   {NULL, NULL}};
+
+  const char* statement_data[] = {
+    "super.x",
+    "super[27]",
+    "new super",
+    "new super()",
+    "new super(12, 45)",
+    "new new super",
+    "new new super()",
+    "new new super()()",
+    "z.super",  // Ok, property lookup.
+    NULL};
+
+  static const ParserFlag always_flags[] = {kAllowClasses};
+  RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+                    always_flags, ARRAY_SIZE(always_flags));
+}
+
+
+TEST(ErrorsSuper) {
+  // Tests that parser and preparser generate same errors for 'super'.
+  const char* context_data[][2] = {{"", ";"},
+                                   {"k = ", ";"},
+                                   {"foo(", ");"},
+                                   {NULL, NULL}};
+
+  const char* statement_data[] = {
+    "super = x",
+    "y = super",
+    "f(super)",
+    NULL};
+
+  static const ParserFlag always_flags[] = {kAllowClasses};
+  RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
+                    always_flags, ARRAY_SIZE(always_flags));
+}

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to