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