diff options
| author | Ben Murdoch <benm@google.com> | 2012-04-11 10:23:59 +0100 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2012-04-11 15:40:41 +0100 |
| commit | 5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b (patch) | |
| tree | 7b717e53b80c4a64bf9b723aabcf7c909ae3c243 /src/scopes.cc | |
| parent | c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9 (diff) | |
| download | android_external_v8-5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b.tar.gz android_external_v8-5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b.tar.bz2 android_external_v8-5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b.zip | |
Merge V8 3.9 at 3.9.24.9
http://v8.googlecode.com/svn/branches/3.9@11260
Bug: 5688872
Change-Id: Iddd944e82189d92df3fc427dc5f0d3f1b2f0c6c8
Diffstat (limited to 'src/scopes.cc')
| -rw-r--r-- | src/scopes.cc | 162 |
1 files changed, 92 insertions, 70 deletions
diff --git a/src/scopes.cc b/src/scopes.cc index a7ff2878..859cbd1a 100644 --- a/src/scopes.cc +++ b/src/scopes.cc @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 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: @@ -40,26 +40,6 @@ namespace v8 { namespace internal { // ---------------------------------------------------------------------------- -// A Zone allocator for use with LocalsMap. - -// TODO(isolates): It is probably worth it to change the Allocator class to -// take a pointer to an isolate. -class ZoneAllocator: public Allocator { - public: - /* nothing to do */ - virtual ~ZoneAllocator() {} - - virtual void* New(size_t size) { return ZONE->New(static_cast<int>(size)); } - - /* ignored - Zone is freed in one fell swoop */ - virtual void Delete(void* p) {} -}; - - -static ZoneAllocator* LocalsMapAllocator = ::new ZoneAllocator(); - - -// ---------------------------------------------------------------------------- // Implementation of LocalsMap // // Note: We are storing the handle locations as key values in the hash map. @@ -77,7 +57,7 @@ static bool Match(void* key1, void* key2) { } -VariableMap::VariableMap() : HashMap(Match, LocalsMapAllocator, 8) {} +VariableMap::VariableMap() : ZoneHashMap(Match, 8) {} VariableMap::~VariableMap() {} @@ -87,8 +67,9 @@ Variable* VariableMap::Declare( VariableMode mode, bool is_valid_lhs, Variable::Kind kind, - InitializationFlag initialization_flag) { - HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true); + InitializationFlag initialization_flag, + Interface* interface) { + Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true); if (p->value == NULL) { // The variable has not been declared yet -> insert it. ASSERT(p->key == name.location()); @@ -97,14 +78,15 @@ Variable* VariableMap::Declare( mode, is_valid_lhs, kind, - initialization_flag); + initialization_flag, + interface); } return reinterpret_cast<Variable*>(p->value); } Variable* VariableMap::Lookup(Handle<String> name) { - HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false); + Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false); if (p != NULL) { ASSERT(*reinterpret_cast<String**>(p->key) == *name); ASSERT(p->value != NULL); @@ -125,6 +107,9 @@ Scope::Scope(Scope* outer_scope, ScopeType type) params_(4), unresolved_(16), decls_(4), + interface_(FLAG_harmony_modules && + (type == MODULE_SCOPE || type == GLOBAL_SCOPE) + ? Interface::NewModule() : NULL), already_resolved_(false) { SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); // At some point we might want to provide outer scopes to @@ -145,6 +130,7 @@ Scope::Scope(Scope* inner_scope, params_(4), unresolved_(16), decls_(4), + interface_(NULL), already_resolved_(true) { SetDefaults(type, NULL, scope_info); if (!scope_info.is_null()) { @@ -165,6 +151,7 @@ Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) params_(0), unresolved_(0), decls_(0), + interface_(NULL), already_resolved_(true) { SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); AddInnerScope(inner_scope); @@ -272,8 +259,11 @@ bool Scope::Analyze(CompilationInfo* info) { top = top->outer_scope(); } - // Allocated the variables. - top->AllocateVariables(info->global_scope()); + // Allocate the variables. + { + AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate()); + if (!top->AllocateVariables(info, &ast_node_factory)) return false; + } #ifdef DEBUG if (info->isolate()->bootstrapper()->IsActive() @@ -281,6 +271,11 @@ bool Scope::Analyze(CompilationInfo* info) { : FLAG_print_scopes) { scope->Print(); } + + if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) { + PrintF("global : "); + top->interface()->Print(); + } #endif if (FLAG_harmony_scoping) { @@ -415,7 +410,8 @@ Variable* Scope::LocalLookup(Handle<String> name) { } -Variable* Scope::LookupFunctionVar(Handle<String> name) { +Variable* Scope::LookupFunctionVar(Handle<String> name, + AstNodeFactory<AstNullVisitor>* factory) { if (function_ != NULL && function_->name().is_identical_to(name)) { return function_->var(); } else if (!scope_info_.is_null()) { @@ -423,7 +419,7 @@ Variable* Scope::LookupFunctionVar(Handle<String> name) { VariableMode mode; int index = scope_info_->FunctionContextSlotIndex(*name, &mode); if (index < 0) return NULL; - Variable* var = DeclareFunctionVar(name, mode); + Variable* var = DeclareFunctionVar(name, mode, factory); var->AllocateTo(Variable::CONTEXT, index); return var; } else { @@ -443,15 +439,6 @@ Variable* Scope::Lookup(Handle<String> name) { } -Variable* Scope::DeclareFunctionVar(Handle<String> name, VariableMode mode) { - ASSERT(is_function_scope() && function_ == NULL); - Variable* function_var = new Variable( - this, name, mode, true, Variable::NORMAL, kCreatedInitialized); - function_ = new(isolate_->zone()) VariableProxy(isolate_, function_var); - return function_var; -} - - void Scope::DeclareParameter(Handle<String> name, VariableMode mode) { ASSERT(!already_resolved()); ASSERT(is_function_scope()); @@ -463,7 +450,8 @@ void Scope::DeclareParameter(Handle<String> name, VariableMode mode) { Variable* Scope::DeclareLocal(Handle<String> name, VariableMode mode, - InitializationFlag init_flag) { + InitializationFlag init_flag, + Interface* interface) { ASSERT(!already_resolved()); // This function handles VAR and CONST modes. DYNAMIC variables are // introduces during variable allocation, INTERNAL variables are allocated @@ -473,8 +461,8 @@ Variable* Scope::DeclareLocal(Handle<String> name, mode == CONST_HARMONY || mode == LET); ++num_var_or_const_; - return - variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag); + return variables_.Declare( + this, name, mode, true, Variable::NORMAL, init_flag, interface); } @@ -489,18 +477,6 @@ Variable* Scope::DeclareGlobal(Handle<String> name) { } -VariableProxy* Scope::NewUnresolved(Handle<String> name, int position) { - // Note that we must not share the unresolved variables with - // the same name because they may be removed selectively via - // RemoveUnresolved(). - ASSERT(!already_resolved()); - VariableProxy* proxy = new(isolate_->zone()) VariableProxy( - isolate_, name, false, position); - 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. @@ -623,7 +599,8 @@ void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, } -void Scope::AllocateVariables(Scope* global_scope) { +bool Scope::AllocateVariables(CompilationInfo* info, + AstNodeFactory<AstNullVisitor>* factory) { // 1) Propagate scope information. bool outer_scope_calls_non_strict_eval = false; if (outer_scope_ != NULL) { @@ -634,10 +611,12 @@ void Scope::AllocateVariables(Scope* global_scope) { PropagateScopeInfo(outer_scope_calls_non_strict_eval); // 2) Resolve variables. - ResolveVariablesRecursively(global_scope); + if (!ResolveVariablesRecursively(info, factory)) return false; // 3) Allocate variables. AllocateVariablesRecursively(); + + return true; } @@ -720,6 +699,7 @@ static const char* Header(ScopeType type) { switch (type) { case EVAL_SCOPE: return "eval"; case FUNCTION_SCOPE: return "function"; + case MODULE_SCOPE: return "module"; case GLOBAL_SCOPE: return "global"; case CATCH_SCOPE: return "catch"; case BLOCK_SCOPE: return "block"; @@ -897,7 +877,8 @@ Variable* Scope::NonLocal(Handle<String> name, VariableMode mode) { Variable* Scope::LookupRecursive(Handle<String> name, - BindingKind* binding_kind) { + BindingKind* binding_kind, + AstNodeFactory<AstNullVisitor>* factory) { ASSERT(binding_kind != NULL); // Try to find the variable in this scope. Variable* var = LocalLookup(name); @@ -914,11 +895,11 @@ Variable* Scope::LookupRecursive(Handle<String> name, // if any. We can do this for all scopes, since the function variable is // only present - if at all - for function scopes. *binding_kind = UNBOUND; - var = LookupFunctionVar(name); + var = LookupFunctionVar(name, factory); if (var != NULL) { *binding_kind = BOUND; } else if (outer_scope_ != NULL) { - var = outer_scope_->LookupRecursive(name, binding_kind); + var = outer_scope_->LookupRecursive(name, binding_kind, factory); if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { var->ForceContextAllocation(); } @@ -950,17 +931,18 @@ Variable* Scope::LookupRecursive(Handle<String> name, } -void Scope::ResolveVariable(Scope* global_scope, - VariableProxy* proxy) { - ASSERT(global_scope == NULL || global_scope->is_global_scope()); +bool Scope::ResolveVariable(CompilationInfo* info, + VariableProxy* proxy, + AstNodeFactory<AstNullVisitor>* factory) { + ASSERT(info->global_scope()->is_global_scope()); // If the proxy is already resolved there's nothing to do // (functions and consts may be resolved by the parser). - if (proxy->var() != NULL) return; + if (proxy->var() != NULL) return true; // Otherwise, try to resolve the variable. BindingKind binding_kind; - Variable* var = LookupRecursive(proxy->name(), &binding_kind); + Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory); switch (binding_kind) { case BOUND: // We found a variable binding. @@ -980,8 +962,7 @@ void Scope::ResolveVariable(Scope* global_scope, case UNBOUND: // No binding has been found. Declare a variable in global scope. - ASSERT(global_scope != NULL); - var = global_scope->DeclareGlobal(proxy->name()); + var = info->global_scope()->DeclareGlobal(proxy->name()); break; case UNBOUND_EVAL_SHADOWED: @@ -998,21 +979,62 @@ void Scope::ResolveVariable(Scope* global_scope, ASSERT(var != NULL); proxy->BindTo(var); + + if (FLAG_harmony_modules) { + bool ok; +#ifdef DEBUG + if (FLAG_print_interface_details) + PrintF("# Resolve %s:\n", var->name()->ToAsciiArray()); +#endif + proxy->interface()->Unify(var->interface(), &ok); + if (!ok) { +#ifdef DEBUG + if (FLAG_print_interfaces) { + PrintF("SCOPES TYPE ERROR\n"); + PrintF("proxy: "); + proxy->interface()->Print(); + PrintF("var: "); + var->interface()->Print(); + } +#endif + + // Inconsistent use of module. Throw a syntax error. + // TODO(rossberg): generate more helpful error message. + MessageLocation location(info->script(), + proxy->position(), + proxy->position()); + Isolate* isolate = Isolate::Current(); + Factory* factory = isolate->factory(); + Handle<JSArray> array = factory->NewJSArray(1); + USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode)); + Handle<Object> result = + factory->NewSyntaxError("module_type_error", array); + isolate->Throw(*result, &location); + return false; + } + } + + return true; } -void Scope::ResolveVariablesRecursively(Scope* global_scope) { - ASSERT(global_scope == NULL || global_scope->is_global_scope()); +bool Scope::ResolveVariablesRecursively( + CompilationInfo* info, + AstNodeFactory<AstNullVisitor>* factory) { + ASSERT(info->global_scope()->is_global_scope()); // Resolve unresolved variables for this scope. for (int i = 0; i < unresolved_.length(); i++) { - ResolveVariable(global_scope, unresolved_[i]); + if (!ResolveVariable(info, unresolved_[i], factory)) return false; } // Resolve unresolved variables for inner scopes. for (int i = 0; i < inner_scopes_.length(); i++) { - inner_scopes_[i]->ResolveVariablesRecursively(global_scope); + if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) + return false; } + + return true; } |
