Home | History | Annotate | Download | only in parsing
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_PARSING_PREPARSE_DATA_H_
      6 #define V8_PARSING_PREPARSE_DATA_H_
      7 
      8 #include "src/allocation.h"
      9 #include "src/base/hashmap.h"
     10 #include "src/collector.h"
     11 #include "src/messages.h"
     12 #include "src/parsing/preparse-data-format.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 class ScriptData {
     18  public:
     19   ScriptData(const byte* data, int length);
     20   ~ScriptData() {
     21     if (owns_data_) DeleteArray(data_);
     22   }
     23 
     24   const byte* data() const { return data_; }
     25   int length() const { return length_; }
     26   bool rejected() const { return rejected_; }
     27 
     28   void Reject() { rejected_ = true; }
     29 
     30   void AcquireDataOwnership() {
     31     DCHECK(!owns_data_);
     32     owns_data_ = true;
     33   }
     34 
     35   void ReleaseDataOwnership() {
     36     DCHECK(owns_data_);
     37     owns_data_ = false;
     38   }
     39 
     40  private:
     41   bool owns_data_ : 1;
     42   bool rejected_ : 1;
     43   const byte* data_;
     44   int length_;
     45 
     46   DISALLOW_COPY_AND_ASSIGN(ScriptData);
     47 };
     48 
     49 // Abstract interface for preparse data recorder.
     50 class ParserRecorder {
     51  public:
     52   ParserRecorder() { }
     53   virtual ~ParserRecorder() { }
     54 
     55   // Logs the scope and some details of a function literal in the source.
     56   virtual void LogFunction(int start, int end, int literals, int properties,
     57                            LanguageMode language_mode, bool uses_super_property,
     58                            bool calls_eval) = 0;
     59 
     60   // Logs an error message and marks the log as containing an error.
     61   // Further logging will be ignored, and ExtractData will return a vector
     62   // representing the error only.
     63   virtual void LogMessage(int start, int end, MessageTemplate::Template message,
     64                           const char* argument_opt,
     65                           ParseErrorType error_type) = 0;
     66 
     67  private:
     68   DISALLOW_COPY_AND_ASSIGN(ParserRecorder);
     69 };
     70 
     71 
     72 class SingletonLogger : public ParserRecorder {
     73  public:
     74   SingletonLogger()
     75       : has_error_(false), start_(-1), end_(-1), error_type_(kSyntaxError) {}
     76   virtual ~SingletonLogger() {}
     77 
     78   void Reset() { has_error_ = false; }
     79 
     80   virtual void LogFunction(int start, int end, int literals, int properties,
     81                            LanguageMode language_mode, bool uses_super_property,
     82                            bool calls_eval) {
     83     DCHECK(!has_error_);
     84     start_ = start;
     85     end_ = end;
     86     literals_ = literals;
     87     properties_ = properties;
     88     language_mode_ = language_mode;
     89     uses_super_property_ = uses_super_property;
     90     calls_eval_ = calls_eval;
     91   }
     92 
     93   // Logs an error message and marks the log as containing an error.
     94   // Further logging will be ignored, and ExtractData will return a vector
     95   // representing the error only.
     96   virtual void LogMessage(int start, int end, MessageTemplate::Template message,
     97                           const char* argument_opt, ParseErrorType error_type) {
     98     if (has_error_) return;
     99     has_error_ = true;
    100     start_ = start;
    101     end_ = end;
    102     message_ = message;
    103     argument_opt_ = argument_opt;
    104     error_type_ = error_type;
    105   }
    106 
    107   bool has_error() const { return has_error_; }
    108 
    109   int start() const { return start_; }
    110   int end() const { return end_; }
    111   int literals() const {
    112     DCHECK(!has_error_);
    113     return literals_;
    114   }
    115   int properties() const {
    116     DCHECK(!has_error_);
    117     return properties_;
    118   }
    119   LanguageMode language_mode() const {
    120     DCHECK(!has_error_);
    121     return language_mode_;
    122   }
    123   bool uses_super_property() const {
    124     DCHECK(!has_error_);
    125     return uses_super_property_;
    126   }
    127   bool calls_eval() const {
    128     DCHECK(!has_error_);
    129     return calls_eval_;
    130   }
    131   ParseErrorType error_type() const {
    132     DCHECK(has_error_);
    133     return error_type_;
    134   }
    135   MessageTemplate::Template message() {
    136     DCHECK(has_error_);
    137     return message_;
    138   }
    139   const char* argument_opt() const {
    140     DCHECK(has_error_);
    141     return argument_opt_;
    142   }
    143 
    144  private:
    145   bool has_error_;
    146   int start_;
    147   int end_;
    148   // For function entries.
    149   int literals_;
    150   int properties_;
    151   LanguageMode language_mode_;
    152   bool uses_super_property_;
    153   bool calls_eval_;
    154   // For error messages.
    155   MessageTemplate::Template message_;
    156   const char* argument_opt_;
    157   ParseErrorType error_type_;
    158 };
    159 
    160 
    161 class CompleteParserRecorder : public ParserRecorder {
    162  public:
    163   struct Key {
    164     bool is_one_byte;
    165     Vector<const byte> literal_bytes;
    166   };
    167 
    168   CompleteParserRecorder();
    169   virtual ~CompleteParserRecorder() {}
    170 
    171   virtual void LogFunction(int start, int end, int literals, int properties,
    172                            LanguageMode language_mode, bool uses_super_property,
    173                            bool calls_eval) {
    174     function_store_.Add(start);
    175     function_store_.Add(end);
    176     function_store_.Add(literals);
    177     function_store_.Add(properties);
    178     function_store_.Add(language_mode);
    179     function_store_.Add(uses_super_property);
    180     function_store_.Add(calls_eval);
    181   }
    182 
    183   // Logs an error message and marks the log as containing an error.
    184   // Further logging will be ignored, and ExtractData will return a vector
    185   // representing the error only.
    186   virtual void LogMessage(int start, int end, MessageTemplate::Template message,
    187                           const char* argument_opt, ParseErrorType error_type);
    188   ScriptData* GetScriptData();
    189 
    190   bool HasError() {
    191     return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]);
    192   }
    193   Vector<unsigned> ErrorMessageData() {
    194     DCHECK(HasError());
    195     return function_store_.ToVector();
    196   }
    197 
    198  private:
    199   void WriteString(Vector<const char> str);
    200 
    201   Collector<unsigned> function_store_;
    202   unsigned preamble_[PreparseDataConstants::kHeaderSize];
    203 
    204 #ifdef DEBUG
    205   int prev_start_;
    206 #endif
    207 };
    208 
    209 
    210 }  // namespace internal
    211 }  // namespace v8.
    212 
    213 #endif  // V8_PARSING_PREPARSE_DATA_H_
    214