Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2009 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_FUNC_NAME_INFERRER_H_
      6 #define V8_FUNC_NAME_INFERRER_H_
      7 
      8 #include "src/handles.h"
      9 #include "src/zone.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 class FunctionLiteral;
     15 class Isolate;
     16 
     17 // FuncNameInferrer is a stateful class that is used to perform name
     18 // inference for anonymous functions during static analysis of source code.
     19 // Inference is performed in cases when an anonymous function is assigned
     20 // to a variable or a property (see test-func-name-inference.cc for examples.)
     21 //
     22 // The basic idea is that during parsing of LHSs of certain expressions
     23 // (assignments, declarations, object literals) we collect name strings,
     24 // and during parsing of the RHS, a function literal can be collected. After
     25 // parsing the RHS we can infer a name for function literals that do not have
     26 // a name.
     27 class FuncNameInferrer : public ZoneObject {
     28  public:
     29   FuncNameInferrer(Isolate* isolate, Zone* zone);
     30 
     31   // Returns whether we have entered name collection state.
     32   bool IsOpen() const { return !entries_stack_.is_empty(); }
     33 
     34   // Pushes an enclosing the name of enclosing function onto names stack.
     35   void PushEnclosingName(Handle<String> name);
     36 
     37   // Enters name collection state.
     38   void Enter() {
     39     entries_stack_.Add(names_stack_.length(), zone());
     40   }
     41 
     42   // Pushes an encountered name onto names stack when in collection state.
     43   void PushLiteralName(Handle<String> name);
     44 
     45   void PushVariableName(Handle<String> name);
     46 
     47   // Adds a function to infer name for.
     48   void AddFunction(FunctionLiteral* func_to_infer) {
     49     if (IsOpen()) {
     50       funcs_to_infer_.Add(func_to_infer, zone());
     51     }
     52   }
     53 
     54   void RemoveLastFunction() {
     55     if (IsOpen() && !funcs_to_infer_.is_empty()) {
     56       funcs_to_infer_.RemoveLast();
     57     }
     58   }
     59 
     60   // Infers a function name and leaves names collection state.
     61   void Infer() {
     62     ASSERT(IsOpen());
     63     if (!funcs_to_infer_.is_empty()) {
     64       InferFunctionsNames();
     65     }
     66   }
     67 
     68   // Leaves names collection state.
     69   void Leave() {
     70     ASSERT(IsOpen());
     71     names_stack_.Rewind(entries_stack_.RemoveLast());
     72     if (entries_stack_.is_empty())
     73       funcs_to_infer_.Clear();
     74   }
     75 
     76  private:
     77   enum NameType {
     78     kEnclosingConstructorName,
     79     kLiteralName,
     80     kVariableName
     81   };
     82   struct Name {
     83     Name(Handle<String> name, NameType type) : name(name), type(type) { }
     84     Handle<String> name;
     85     NameType type;
     86   };
     87 
     88   Isolate* isolate() { return isolate_; }
     89   Zone* zone() const { return zone_; }
     90 
     91   // Constructs a full name in dotted notation from gathered names.
     92   Handle<String> MakeNameFromStack();
     93 
     94   // A helper function for MakeNameFromStack.
     95   Handle<String> MakeNameFromStackHelper(int pos, Handle<String> prev);
     96 
     97   // Performs name inferring for added functions.
     98   void InferFunctionsNames();
     99 
    100   Isolate* isolate_;
    101   ZoneList<int> entries_stack_;
    102   ZoneList<Name> names_stack_;
    103   ZoneList<FunctionLiteral*> funcs_to_infer_;
    104   Zone* zone_;
    105 
    106   DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
    107 };
    108 
    109 
    110 } }  // namespace v8::internal
    111 
    112 #endif  // V8_FUNC_NAME_INFERRER_H_
    113