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