1d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org// Copyright 2006-2009 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
4d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
5d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org#ifndef V8_FUNC_NAME_INFERRER_H_
6d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org#define V8_FUNC_NAME_INFERRER_H_
7d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/handles.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/zone.h"
10486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
1171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
13d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
1408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgclass AstRawString;
1508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgclass AstString;
1608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.orgclass AstValueFactory;
17486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgclass FunctionLiteral;
1804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
19d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org// FuncNameInferrer is a stateful class that is used to perform name
20d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org// inference for anonymous functions during static analysis of source code.
21d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org// Inference is performed in cases when an anonymous function is assigned
22d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org// to a variable or a property (see test-func-name-inference.cc for examples.)
2371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org//
2465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// The basic idea is that during parsing of LHSs of certain expressions
2565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// (assignments, declarations, object literals) we collect name strings,
2665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// and during parsing of the RHS, a function literal can be collected. After
2765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// parsing the RHS we can infer a name for function literals that do not have
2865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// a name.
2965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgclass FuncNameInferrer : public ZoneObject {
30d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org public:
3108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  FuncNameInferrer(AstValueFactory* ast_value_factory, Zone* zone);
32d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
3371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Returns whether we have entered name collection state.
34d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  bool IsOpen() const { return !entries_stack_.is_empty(); }
35d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
3671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Pushes an enclosing the name of enclosing function onto names stack.
3708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  void PushEnclosingName(const AstRawString* name);
38d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
3971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Enters name collection state.
40d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  void Enter() {
417028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    entries_stack_.Add(names_stack_.length(), zone());
42d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  }
43d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
4471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Pushes an encountered name onto names stack when in collection state.
4508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  void PushLiteralName(const AstRawString* name);
4665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
4708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  void PushVariableName(const AstRawString* name);
48d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
4971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Adds a function to infer name for.
5065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  void AddFunction(FunctionLiteral* func_to_infer) {
51d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org    if (IsOpen()) {
527028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      funcs_to_infer_.Add(func_to_infer, zone());
53d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org    }
54d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  }
55d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
56c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RemoveLastFunction() {
57c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (IsOpen() && !funcs_to_infer_.is_empty()) {
58c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      funcs_to_infer_.RemoveLast();
59c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
60c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
61c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Infers a function name and leaves names collection state.
6365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  void Infer() {
64e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsOpen());
6565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    if (!funcs_to_infer_.is_empty()) {
6665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org      InferFunctionsNames();
6765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    }
6865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
6965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
7004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  // Leaves names collection state.
7165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  void Leave() {
72e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsOpen());
7365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    names_stack_.Rewind(entries_stack_.RemoveLast());
74830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (entries_stack_.is_empty())
75830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org      funcs_to_infer_.Clear();
76d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  }
77d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
78d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org private:
7904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  enum NameType {
8004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    kEnclosingConstructorName,
8104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    kLiteralName,
8204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    kVariableName
8304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  };
8404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  struct Name {
8508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    Name(const AstRawString* name, NameType type) : name(name), type(type) {}
8608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    const AstRawString* name;
8704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    NameType type;
8804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  };
8904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone() const { return zone_; }
9104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
9271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Constructs a full name in dotted notation from gathered names.
9308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstString* MakeNameFromStack();
943ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org
953ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org  // A helper function for MakeNameFromStack.
9608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstString* MakeNameFromStackHelper(int pos,
9708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                               const AstString* prev);
9871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
9971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  // Performs name inferring for added functions.
10065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  void InferFunctionsNames();
101d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
10208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  AstValueFactory* ast_value_factory_;
10371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  ZoneList<int> entries_stack_;
10404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  ZoneList<Name> names_stack_;
10571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  ZoneList<FunctionLiteral*> funcs_to_infer_;
1067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone_;
107d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
108d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org  DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
109d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org};
110d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
111d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
112d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org} }  // namespace v8::internal
113d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org
114d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org#endif  // V8_FUNC_NAME_INFERRER_H_
115