Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / v8 / src / func-name-inferrer.cc
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 "v8.h"
6
7 #include "ast.h"
8 #include "func-name-inferrer.h"
9 #include "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