1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ast.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "func-name-inferrer.h"
32257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "list-inl.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochFuncNameInferrer::FuncNameInferrer(Isolate* isolate)
383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    : isolate_(isolate),
393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      entries_stack_(10),
403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      names_stack_(5),
413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      funcs_to_infer_(4) {
423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FuncNameInferrer::PushEnclosingName(Handle<String> name) {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Enclosing name is a name of a constructor function. To check
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // that it is really a constructor, we check that it is not empty
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and starts with a capital letter.
4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (name->length() > 0 && Runtime::IsUpperCaseChar(
503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          isolate()->runtime_state(), name->Get(0))) {
513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    names_stack_.Add(Name(name, kEnclosingConstructorName));
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid FuncNameInferrer::PushLiteralName(Handle<String> name) {
573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (IsOpen() && !isolate()->heap()->prototype_symbol()->Equals(*name)) {
583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    names_stack_.Add(Name(name, kLiteralName));
5980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
6080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
6180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
6280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
6380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid FuncNameInferrer::PushVariableName(Handle<String> name) {
643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (IsOpen() && !isolate()->heap()->result_symbol()->Equals(*name)) {
653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    names_stack_.Add(Name(name, kVariableName));
6680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
6780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
6880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
6980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> FuncNameInferrer::MakeNameFromStack() {
713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return MakeNameFromStackHelper(0, isolate()->factory()->empty_string());
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> FuncNameInferrer::MakeNameFromStackHelper(int pos,
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                         Handle<String> prev) {
773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (pos >= names_stack_.length()) return prev;
783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (pos < names_stack_.length() - 1 &&
793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      names_stack_.at(pos).type == kVariableName &&
803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      names_stack_.at(pos + 1).type == kVariableName) {
813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Skip consecutive variable declarations.
823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return MakeNameFromStackHelper(pos + 1, prev);
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (prev->length() > 0) {
853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Factory* factory = isolate()->factory();
863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Handle<String> curr = factory->NewConsString(
873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          factory->dot_symbol(), names_stack_.at(pos).name);
883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return MakeNameFromStackHelper(pos + 1,
893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                     factory->NewConsString(prev, curr));
903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else {
913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return MakeNameFromStackHelper(pos + 1, names_stack_.at(pos).name);
923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FuncNameInferrer::InferFunctionsNames() {
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> func_name = MakeNameFromStack();
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < funcs_to_infer_.length(); ++i) {
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    funcs_to_infer_[i]->set_inferred_name(func_name);
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  funcs_to_infer_.Rewind(0);
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
107