⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scopes.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "prettyprinter.h"#include "scopeinfo.h"#include "scopes.h"namespace v8 { namespace internal {// ----------------------------------------------------------------------------// A Zone allocator for use with LocalsMap.class ZoneAllocator: public Allocator { public:  /* nothing to do */  virtual ~ZoneAllocator()  {}  virtual void* New(size_t size)  { return Zone::New(size); }  /* ignored - Zone is freed in one fell swoop */  virtual void Delete(void* p)  {}};static ZoneAllocator LocalsMapAllocator;// ----------------------------------------------------------------------------// Implementation of LocalsMap//// Note: We are storing the handle locations as key values in the hash map.//       When inserting a new variable via Declare(), we rely on the fact that//       the handle location remains alive for the duration of that variable//       use. Because a Variable holding a handle with the same location exists//       this is ensured.static bool Match(void* key1, void* key2) {  String* name1 = *reinterpret_cast<String**>(key1);  String* name2 = *reinterpret_cast<String**>(key2);  ASSERT(name1->IsSymbol());  ASSERT(name2->IsSymbol());  return name1 == name2;}// Dummy constructorLocalsMap::LocalsMap(bool gotta_love_static_overloading) : HashMap()  {}LocalsMap::LocalsMap() : HashMap(Match, &LocalsMapAllocator, 8)  {}LocalsMap::~LocalsMap()  {}Variable* LocalsMap::Declare(Scope* scope,                             Handle<String> name,                             Variable::Mode mode,                             bool is_valid_LHS,                             bool is_this) {  HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true);  if (p->value == NULL) {    // The variable has not been declared yet -> insert it.    ASSERT(p->key == name.location());    p->value = new Variable(scope, name, mode, is_valid_LHS, is_this);  }  return reinterpret_cast<Variable*>(p->value);}Variable* LocalsMap::Lookup(Handle<String> name) {  HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false);  if (p != NULL) {    ASSERT(*reinterpret_cast<String**>(p->key) == *name);    ASSERT(p->value != NULL);    return reinterpret_cast<Variable*>(p->value);  }  return NULL;}// ----------------------------------------------------------------------------// Implementation of Scope// Dummy constructorScope::Scope()  : inner_scopes_(0),    locals_(false),    temps_(0),    params_(0),    nonlocals_(0),    unresolved_(0),    decls_(0) {}Scope::Scope(Scope* outer_scope, Type type)  : outer_scope_(outer_scope),    inner_scopes_(4),    type_(type),    scope_name_(Factory::empty_symbol()),    locals_(),    temps_(4),    params_(4),    nonlocals_(4),    unresolved_(16),    decls_(4),    receiver_(NULL),    function_(NULL),    arguments_(NULL),    arguments_shadow_(NULL),    illegal_redecl_(NULL),    scope_inside_with_(false),    scope_contains_with_(false),    scope_calls_eval_(false),    outer_scope_calls_eval_(false),    inner_scope_calls_eval_(false),    force_eager_compilation_(false),    num_stack_slots_(0),    num_heap_slots_(0) {  // At some point we might want to provide outer scopes to  // eval scopes (by walking the stack and reading the scope info).  // In that case, the ASSERT below needs to be adjusted.  ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL));  ASSERT(!HasIllegalRedeclaration());}void Scope::Initialize(bool inside_with) {  // Add this scope as a new inner scope of the outer scope.  if (outer_scope_ != NULL) {    outer_scope_->inner_scopes_.Add(this);    scope_inside_with_ = outer_scope_->scope_inside_with_ || inside_with;  } else {    scope_inside_with_ = inside_with;  }  // Declare convenience variables.  // Declare and allocate receiver (even for the global scope, and even  // if naccesses_ == 0).  // NOTE: When loading parameters in the global scope, we must take  // care not to access them as properties of the global object, but  // instead load them directly from the stack. Currently, the only  // such parameter is 'this' which is passed on the stack when  // invoking scripts  { Variable* var =      locals_.Declare(this, Factory::this_symbol(), Variable::VAR, false, true);    var->rewrite_ = new Slot(var, Slot::PARAMETER, -1);    receiver_ = new VariableProxy(Factory::this_symbol(), true, false);    receiver_->BindTo(var);  }  if (is_function_scope()) {    // Declare 'arguments' variable which exists in all functions.    // Note that it may never be accessed, in which case it won't    // be allocated during variable allocation.    Declare(Factory::arguments_symbol(), Variable::VAR);  }}Variable* Scope::Lookup(Handle<String> name) {  return locals_.Lookup(name);}Variable* Scope::DeclareFunctionVar(Handle<String> name) {  ASSERT(is_function_scope() && function_ == NULL);  function_ = new Variable(this, name, Variable::CONST, true, false);  return function_;}Variable* Scope::Declare(Handle<String> name, Variable::Mode mode) {  // DYNAMIC variables are introduces during variable allocation,  // INTERNAL variables are allocated explicitly, and TEMPORARY  // variables are allocated via NewTemporary().  ASSERT(mode == Variable::VAR || mode == Variable::CONST);  return locals_.Declare(this, name, mode, true, false);}void Scope::AddParameter(Variable* var) {  ASSERT(is_function_scope());  ASSERT(Lookup(var->name()) == var);  params_.Add(var);}VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) {  // Note that we must not share the unresolved variables with  // the same name because they may be removed selectively via  // RemoveUnresolved().  VariableProxy* proxy = new VariableProxy(name, false, inside_with);  unresolved_.Add(proxy);  return proxy;}void Scope::RemoveUnresolved(VariableProxy* var) {  // Most likely (always?) any variable we want to remove  // was just added before, so we search backwards.  for (int i = unresolved_.length(); i-- > 0;) {    if (unresolved_[i] == var) {      unresolved_.Remove(i);      return;    }  }}VariableProxy* Scope::NewTemporary(Handle<String> name) {  Variable* var = new Variable(this, name, Variable::TEMPORARY, true, false);  VariableProxy* tmp = new VariableProxy(name, false, false);  tmp->BindTo(var);  temps_.Add(var);  return tmp;}void Scope::AddDeclaration(Declaration* declaration) {  decls_.Add(declaration);}void Scope::SetIllegalRedeclaration(Expression* expression) {  // Only set the illegal redeclaration expression the  // first time the function is called.  if (!HasIllegalRedeclaration()) {    illegal_redecl_ = expression;  }  ASSERT(HasIllegalRedeclaration());}void Scope::VisitIllegalRedeclaration(Visitor* visitor) {  ASSERT(HasIllegalRedeclaration());  illegal_redecl_->Accept(visitor);}template<class Allocator>void Scope::CollectUsedVariables(List<Variable*, Allocator>* locals) {  // Collect variables in this scope.  // Note that the function_ variable - if present - is not  // collected here but handled separately in ScopeInfo  // which is the current user of this function).  for (int i = 0; i < temps_.length(); i++) {    Variable* var = temps_[i];    if (var->var_uses()->is_used()) {      locals->Add(var);    }  }  for (LocalsMap::Entry* p = locals_.Start(); p != NULL; p = locals_.Next(p)) {    Variable* var = reinterpret_cast<Variable*>(p->value);    if (var->var_uses()->is_used()) {      locals->Add(var);    }  }}// Make sure the method gets instantiated by the template system.template void Scope::CollectUsedVariables(    List<Variable*, FreeStoreAllocationPolicy>* locals);template void Scope::CollectUsedVariables(    List<Variable*, PreallocatedStorage>* locals);void Scope::AllocateVariables() {  ASSERT(outer_scope_ == NULL);  // eval or global scopes only  // 1) Propagate scope information.  // If we are in an eval scope, we may have other outer scopes about

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -