PreParser fix: propagate reference erros properly.
authormarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Apr 2014 14:17:43 +0000 (14:17 +0000)
committermarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Apr 2014 14:17:43 +0000 (14:17 +0000)
For example, invalid left hand sides are reference errors. PreParser didn't use
to produce this error ever, so the code for propagating reference errors
properly was missing, and reference errors turned into syntax errors.

R=rossberg@chromium.org
BUG=

Review URL: https://codereview.chromium.org/220233006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20408 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/parser.cc
src/parser.h
src/preparse-data-format.h
src/preparse-data.cc
src/preparse-data.h
src/preparser.cc

index a00adb8..16a1028 100644 (file)
@@ -304,20 +304,25 @@ const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
 }
 
 
-Scanner::Location ScriptDataImpl::MessageLocation() {
+Scanner::Location ScriptDataImpl::MessageLocation() const {
   int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
   int end_pos = Read(PreparseDataConstants::kMessageEndPos);
   return Scanner::Location(beg_pos, end_pos);
 }
 
 
-const char* ScriptDataImpl::BuildMessage() {
+bool ScriptDataImpl::IsReferenceError() const {
+  return Read(PreparseDataConstants::kIsReferenceErrorPos);
+}
+
+
+const char* ScriptDataImpl::BuildMessage() const {
   unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
   return ReadString(start, NULL);
 }
 
 
-Vector<const char*> ScriptDataImpl::BuildArgs() {
+Vector<const char*> ScriptDataImpl::BuildArgs() const {
   int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
   const char** array = NewArray<const char*>(arg_count);
   // Position after text found by skipping past length field and
@@ -333,12 +338,12 @@ Vector<const char*> ScriptDataImpl::BuildArgs() {
 }
 
 
-unsigned ScriptDataImpl::Read(int position) {
+unsigned ScriptDataImpl::Read(int position) const {
   return store_[PreparseDataConstants::kHeaderSize + position];
 }
 
 
-unsigned* ScriptDataImpl::ReadAddress(int position) {
+unsigned* ScriptDataImpl::ReadAddress(int position) const {
   return &store_[PreparseDataConstants::kHeaderSize + position];
 }
 
@@ -3385,8 +3390,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
           }
           ParserTraits::ReportMessageAt(
               Scanner::Location(logger.start(), logger.end()),
-              logger.message(),
-              args);
+              logger.message(), args, logger.is_reference_error());
           *ok = false;
           return NULL;
         }
@@ -4688,7 +4692,8 @@ bool Parser::Parse() {
       Scanner::Location loc = cached_data->MessageLocation();
       const char* message = cached_data->BuildMessage();
       Vector<const char*> args = cached_data->BuildArgs();
-      ParserTraits::ReportMessageAt(loc, message, args);
+      ParserTraits::ReportMessageAt(loc, message, args,
+                                    cached_data->IsReferenceError());
       DeleteArray(message);
       for (int i = 0; i < args.length(); i++) {
         DeleteArray(args[i]);
index 4bb9aad..287dfa4 100644 (file)
@@ -104,9 +104,10 @@ class ScriptDataImpl : public ScriptData {
   int GetSymbolIdentifier();
   bool SanityCheck();
 
-  Scanner::Location MessageLocation();
-  const char* BuildMessage();
-  Vector<const char*> BuildArgs();
+  Scanner::Location MessageLocation() const;
+  bool IsReferenceError() const;
+  const char* BuildMessage() const;
+  Vector<const char*> BuildArgs() const;
 
   int symbol_count() {
     return (store_.length() > PreparseDataConstants::kHeaderSize)
@@ -127,8 +128,8 @@ class ScriptDataImpl : public ScriptData {
   int function_index_;
   bool owns_store_;
 
-  unsigned Read(int position);
-  unsigned* ReadAddress(int position);
+  unsigned Read(int position) const;
+  unsigned* ReadAddress(int position) const;
   // Reads a number from the current symbols
   int ReadNumber(byte** source);
 
index e2cf0a1..f5c3a5f 100644 (file)
@@ -51,7 +51,8 @@ struct PreparseDataConstants {
   static const int kMessageStartPos = 0;
   static const int kMessageEndPos = 1;
   static const int kMessageArgCountPos = 2;
-  static const int kMessageTextPos = 3;
+  static const int kIsReferenceErrorPos = 3;
+  static const int kMessageTextPos = 4;
 
   static const unsigned char kNumberTerminator = 0x80u;
 };
index 9f585a9..5bc6173 100644 (file)
@@ -88,9 +88,10 @@ CompleteParserRecorder::CompleteParserRecorder()
 
 
 void CompleteParserRecorder::LogMessage(int start_pos,
-                                               int end_pos,
-                                               const char* message,
-                                               const char* arg_opt) {
+                                        int end_pos,
+                                        const char* message,
+                                        const char* arg_opt,
+                                        bool is_reference_error) {
   if (has_error()) return;
   preamble_[PreparseDataConstants::kHasErrorOffset] = true;
   function_store_.Reset();
@@ -100,7 +101,9 @@ void CompleteParserRecorder::LogMessage(int start_pos,
   function_store_.Add(end_pos);
   STATIC_ASSERT(PreparseDataConstants::kMessageArgCountPos == 2);
   function_store_.Add((arg_opt == NULL) ? 0 : 1);
-  STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 3);
+  STATIC_ASSERT(PreparseDataConstants::kIsReferenceErrorPos == 3);
+  function_store_.Add(is_reference_error ? 1 : 0);
+  STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 4);
   WriteString(CStrVector(message));
   if (arg_opt != NULL) WriteString(CStrVector(arg_opt));
   should_log_symbols_ = false;
index 6a968e3..cfc33fe 100644 (file)
@@ -55,7 +55,8 @@ class ParserRecorder {
   virtual void LogMessage(int start,
                           int end,
                           const char* message,
-                          const char* argument_opt) = 0;
+                          const char* argument_opt,
+                          bool is_reference_error) = 0;
 
   // Logs a symbol creation of a literal or identifier.
   bool ShouldLogSymbols() { return should_log_symbols_; }
@@ -80,8 +81,9 @@ class ParserRecorder {
 
 class SingletonLogger : public ParserRecorder {
  public:
-  SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
-  virtual ~SingletonLogger() { }
+  SingletonLogger()
+      : has_error_(false), start_(-1), end_(-1), is_reference_error_(false) {}
+  virtual ~SingletonLogger() {}
 
   void Reset() { has_error_ = false; }
 
@@ -104,36 +106,39 @@ class SingletonLogger : public ParserRecorder {
   virtual void LogMessage(int start,
                           int end,
                           const char* message,
-                          const char* argument_opt) {
+                          const char* argument_opt,
+                          bool is_reference_error) {
     if (has_error_) return;
     has_error_ = true;
     start_ = start;
     end_ = end;
     message_ = message;
     argument_opt_ = argument_opt;
+    is_reference_error_ = is_reference_error;
   }
 
-  bool has_error() { return has_error_; }
+  bool has_error() const { return has_error_; }
 
-  int start() { return start_; }
-  int end() { return end_; }
-  int literals() {
+  int start() const { return start_; }
+  int end() const { return end_; }
+  int literals() const {
     ASSERT(!has_error_);
     return literals_;
   }
-  int properties() {
+  int properties() const {
     ASSERT(!has_error_);
     return properties_;
   }
-  StrictMode strict_mode() {
+  StrictMode strict_mode() const {
     ASSERT(!has_error_);
     return strict_mode_;
   }
+  int is_reference_error() const { return is_reference_error_; }
   const char* message() {
     ASSERT(has_error_);
     return message_;
   }
-  const char* argument_opt() {
+  const char* argument_opt() const {
     ASSERT(has_error_);
     return argument_opt_;
   }
@@ -149,6 +154,7 @@ class SingletonLogger : public ParserRecorder {
   // For error messages.
   const char* message_;
   const char* argument_opt_;
+  bool is_reference_error_;
 };
 
 
@@ -180,7 +186,8 @@ class CompleteParserRecorder : public ParserRecorder {
   virtual void LogMessage(int start,
                           int end,
                           const char* message,
-                          const char* argument_opt);
+                          const char* argument_opt,
+                          bool is_reference_error_);
 
   virtual void PauseRecording() {
     ASSERT(should_log_symbols_);
index 9bcc880..4995ed9 100644 (file)
@@ -83,8 +83,8 @@ void PreParserTraits::ReportMessageAt(Scanner::Location location,
                                       const char* type,
                                       const char* name_opt,
                                       bool is_reference_error) {
-  pre_parser_->log_
-      ->LogMessage(location.beg_pos, location.end_pos, type, name_opt);
+  pre_parser_->log_->LogMessage(location.beg_pos, location.end_pos, type,
+                                name_opt, is_reference_error);
 }
 
 
@@ -93,7 +93,8 @@ void PreParserTraits::ReportMessageAt(int start_pos,
                                       const char* type,
                                       const char* name_opt,
                                       bool is_reference_error) {
-  pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt);
+  pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt,
+                                is_reference_error);
 }