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