Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_PARSER_H_
     29 #define V8_PARSER_H_
     30 
     31 #include "scanner.h"
     32 #include "allocation.h"
     33 
     34 namespace v8 {
     35 namespace internal {
     36 
     37 
     38 class ParserMessage : public Malloced {
     39  public:
     40   ParserMessage(Scanner::Location loc, const char* message,
     41                 Vector<const char*> args)
     42       : loc_(loc),
     43         message_(message),
     44         args_(args) { }
     45   ~ParserMessage();
     46   Scanner::Location location() { return loc_; }
     47   const char* message() { return message_; }
     48   Vector<const char*> args() { return args_; }
     49  private:
     50   Scanner::Location loc_;
     51   const char* message_;
     52   Vector<const char*> args_;
     53 };
     54 
     55 
     56 class FunctionEntry BASE_EMBEDDED {
     57  public:
     58   explicit FunctionEntry(Vector<unsigned> backing) : backing_(backing) { }
     59   FunctionEntry() : backing_(Vector<unsigned>::empty()) { }
     60 
     61   int start_pos() { return backing_[kStartPosOffset]; }
     62   void set_start_pos(int value) { backing_[kStartPosOffset] = value; }
     63 
     64   int end_pos() { return backing_[kEndPosOffset]; }
     65   void set_end_pos(int value) { backing_[kEndPosOffset] = value; }
     66 
     67   int literal_count() { return backing_[kLiteralCountOffset]; }
     68   void set_literal_count(int value) { backing_[kLiteralCountOffset] = value; }
     69 
     70   int property_count() { return backing_[kPropertyCountOffset]; }
     71   void set_property_count(int value) { backing_[kPropertyCountOffset] = value; }
     72 
     73   bool is_valid() { return backing_.length() > 0; }
     74 
     75   static const int kSize = 4;
     76 
     77  private:
     78   Vector<unsigned> backing_;
     79   static const int kStartPosOffset = 0;
     80   static const int kEndPosOffset = 1;
     81   static const int kLiteralCountOffset = 2;
     82   static const int kPropertyCountOffset = 3;
     83 };
     84 
     85 
     86 class ScriptDataImpl : public ScriptData {
     87  public:
     88   explicit ScriptDataImpl(Vector<unsigned> store)
     89       : store_(store),
     90         last_entry_(0) { }
     91   virtual ~ScriptDataImpl();
     92   virtual int Length();
     93   virtual unsigned* Data();
     94   virtual bool HasError();
     95   FunctionEntry GetFunctionEnd(int start);
     96   bool SanityCheck();
     97 
     98   Scanner::Location MessageLocation();
     99   const char* BuildMessage();
    100   Vector<const char*> BuildArgs();
    101 
    102   bool has_error() { return store_[kHasErrorOffset]; }
    103   unsigned magic() { return store_[kMagicOffset]; }
    104   unsigned version() { return store_[kVersionOffset]; }
    105 
    106   static const unsigned kMagicNumber = 0xBadDead;
    107   static const unsigned kCurrentVersion = 1;
    108 
    109   static const unsigned kMagicOffset = 0;
    110   static const unsigned kVersionOffset = 1;
    111   static const unsigned kHasErrorOffset = 2;
    112   static const unsigned kSizeOffset = 3;
    113   static const unsigned kHeaderSize = 4;
    114 
    115  private:
    116   unsigned Read(int position);
    117   unsigned* ReadAddress(int position);
    118   int EntryCount();
    119   FunctionEntry nth(int n);
    120 
    121   Vector<unsigned> store_;
    122 
    123   // The last entry returned.  This is used to make lookup faster:
    124   // the next entry to return is typically the next entry so lookup
    125   // will usually be much faster if we start from the last entry.
    126   int last_entry_;
    127 };
    128 
    129 
    130 // The parser: Takes a script and and context information, and builds a
    131 // FunctionLiteral AST node. Returns NULL and deallocates any allocated
    132 // AST nodes if parsing failed.
    133 FunctionLiteral* MakeAST(bool compile_in_global_context,
    134                          Handle<Script> script,
    135                          v8::Extension* extension,
    136                          ScriptDataImpl* pre_data,
    137                          bool is_json = false);
    138 
    139 
    140 ScriptDataImpl* PreParse(Handle<String> source,
    141                          unibrow::CharacterStream* stream,
    142                          v8::Extension* extension);
    143 
    144 
    145 bool ParseRegExp(FlatStringReader* input,
    146                  bool multiline,
    147                  RegExpCompileData* result);
    148 
    149 
    150 // Support for doing lazy compilation. The script is the script containing full
    151 // source of the script where the function is declared. The start_position and
    152 // end_position specifies the part of the script source which has the source
    153 // for the function declaration in the form:
    154 //
    155 //    (<formal parameters>) { <function body> }
    156 //
    157 // without any function keyword or name.
    158 //
    159 FunctionLiteral* MakeLazyAST(Handle<Script> script,
    160                              Handle<String> name,
    161                              int start_position,
    162                              int end_position,
    163                              bool is_expression);
    164 
    165 
    166 // Support for handling complex values (array and object literals) that
    167 // can be fully handled at compile time.
    168 class CompileTimeValue: public AllStatic {
    169  public:
    170   enum Type {
    171     OBJECT_LITERAL,
    172     ARRAY_LITERAL
    173   };
    174 
    175   static bool IsCompileTimeValue(Expression* expression);
    176 
    177   // Get the value as a compile time value.
    178   static Handle<FixedArray> GetValue(Expression* expression);
    179 
    180   // Get the type of a compile time value returned by GetValue().
    181   static Type GetType(Handle<FixedArray> value);
    182 
    183   // Get the elements array of a compile time value returned by GetValue().
    184   static Handle<FixedArray> GetElements(Handle<FixedArray> value);
    185 
    186  private:
    187   static const int kTypeSlot = 0;
    188   static const int kElementsSlot = 1;
    189 
    190   DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
    191 };
    192 
    193 
    194 } }  // namespace v8::internal
    195 
    196 #endif  // V8_PARSER_H_
    197