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 11namespace v8 { 12namespace internal { 13 14FuncNameInferrer::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 23void 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 34void 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 42void 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 50Handle<String> FuncNameInferrer::MakeNameFromStack() { 51 return MakeNameFromStackHelper(0, isolate()->factory()->empty_string()); 52} 53 54 55Handle<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 79void 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