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 #include "src/v8.h" 6 7 #include "src/ast.h" 8 #include "src/func-name-inferrer.h" 9 #include "src/list-inl.h" 10 11 namespace v8 { 12 namespace internal { 13 14 FuncNameInferrer::FuncNameInferrer(Isolate* isolate, Zone* zone) 15 : isolate_(isolate), 16 entries_stack_(10, zone), 17 names_stack_(5, zone), 18 funcs_to_infer_(4, zone), 19 zone_(zone) { 20 } 21 22 23 void FuncNameInferrer::PushEnclosingName(Handle<String> name) { 24 // Enclosing name is a name of a constructor function. To check 25 // that it is really a constructor, we check that it is not empty 26 // and starts with a capital letter. 27 if (name->length() > 0 && Runtime::IsUpperCaseChar( 28 isolate()->runtime_state(), name->Get(0))) { 29 names_stack_.Add(Name(name, kEnclosingConstructorName), zone()); 30 } 31 } 32 33 34 void FuncNameInferrer::PushLiteralName(Handle<String> name) { 35 if (IsOpen() && 36 !String::Equals(isolate()->factory()->prototype_string(), name)) { 37 names_stack_.Add(Name(name, kLiteralName), zone()); 38 } 39 } 40 41 42 void FuncNameInferrer::PushVariableName(Handle<String> name) { 43 if (IsOpen() && 44 !String::Equals(isolate()->factory()->dot_result_string(), name)) { 45 names_stack_.Add(Name(name, kVariableName), zone()); 46 } 47 } 48 49 50 Handle<String> FuncNameInferrer::MakeNameFromStack() { 51 return MakeNameFromStackHelper(0, isolate()->factory()->empty_string()); 52 } 53 54 55 Handle<String> FuncNameInferrer::MakeNameFromStackHelper(int pos, 56 Handle<String> prev) { 57 if (pos >= names_stack_.length()) return prev; 58 if (pos < names_stack_.length() - 1 && 59 names_stack_.at(pos).type == kVariableName && 60 names_stack_.at(pos + 1).type == kVariableName) { 61 // Skip consecutive variable declarations. 62 return MakeNameFromStackHelper(pos + 1, prev); 63 } else { 64 if (prev->length() > 0) { 65 Handle<String> name = names_stack_.at(pos).name; 66 if (prev->length() + name->length() + 1 > String::kMaxLength) return prev; 67 Factory* factory = isolate()->factory(); 68 Handle<String> curr = 69 factory->NewConsString(factory->dot_string(), name).ToHandleChecked(); 70 curr = factory->NewConsString(prev, curr).ToHandleChecked(); 71 return MakeNameFromStackHelper(pos + 1, curr); 72 } else { 73 return MakeNameFromStackHelper(pos + 1, names_stack_.at(pos).name); 74 } 75 } 76 } 77 78 79 void FuncNameInferrer::InferFunctionsNames() { 80 Handle<String> func_name = MakeNameFromStack(); 81 for (int i = 0; i < funcs_to_infer_.length(); ++i) { 82 funcs_to_infer_[i]->set_inferred_name(func_name); 83 } 84 funcs_to_infer_.Rewind(0); 85 } 86 87 88 } } // namespace v8::internal 89