| Index: src/scopes.cc
|
| diff --git a/src/scopes.cc b/src/scopes.cc
|
| index be991a1a17bc78acc8ae85aae36b4c9e45987979..b8f7eb8698632e95f6bf3c5801298d1d34b88cd8 100644
|
| --- a/src/scopes.cc
|
| +++ b/src/scopes.cc
|
| @@ -371,6 +371,7 @@ Scope* Scope::FinalizeBlockScope() {
|
| if (uses_arguments()) outer_scope_->RecordArgumentsUsage();
|
| if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage();
|
| if (uses_this()) outer_scope_->RecordThisUsage();
|
| + if (scope_calls_eval_) outer_scope_->RecordEvalCall();
|
|
|
| return NULL;
|
| }
|
| @@ -381,13 +382,13 @@ Variable* Scope::LookupLocal(const AstRawString* name) {
|
| if (result != NULL || scope_info_.is_null()) {
|
| return result;
|
| }
|
| + Handle<String> name_handle = name->string();
|
| // The Scope is backed up by ScopeInfo. This means it cannot operate in a
|
| // heap-independent mode, and all strings must be internalized immediately. So
|
| // it's ok to get the Handle<String> here.
|
| - Handle<String> name_handle = name->string();
|
| // If we have a serialized scope info, we might find the variable there.
|
| // There should be no local slot with the given name.
|
| - DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0);
|
| + DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope());
|
|
|
| // Check context slot lookup.
|
| VariableMode mode;
|
| @@ -706,6 +707,7 @@ bool Scope::HasLazyCompilableOuterContext() const {
|
| bool found_non_trivial_declarations = false;
|
| for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) {
|
| if (scope->is_with_scope() && !found_non_trivial_declarations) return false;
|
| + if (scope->is_block_scope() && !scope->decls_.is_empty()) return false;
|
| if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
|
| found_non_trivial_declarations = true;
|
| }
|
| @@ -1288,7 +1290,7 @@ bool Scope::MustAllocateInContext(Variable* var) {
|
| if (has_forced_context_allocation()) return true;
|
| if (var->mode() == TEMPORARY) return false;
|
| if (var->mode() == INTERNAL) return true;
|
| - if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
|
| + if (is_catch_scope() || is_module_scope()) return true;
|
| if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true;
|
| return var->has_forced_context_allocation() ||
|
| scope_calls_eval_ ||
|
| @@ -1309,7 +1311,11 @@ bool Scope::HasArgumentsParameter(Isolate* isolate) {
|
|
|
|
|
| void Scope::AllocateStackSlot(Variable* var) {
|
| - var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
|
| + if (is_block_scope()) {
|
| + DeclarationScope()->AllocateStackSlot(var);
|
| + } else {
|
| + var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
|
| + }
|
| }
|
|
|
|
|
| @@ -1434,6 +1440,9 @@ void Scope::AllocateNonParameterLocals(Isolate* isolate) {
|
|
|
|
|
| void Scope::AllocateVariablesRecursively(Isolate* isolate) {
|
| + if (!already_resolved()) {
|
| + num_stack_slots_ = 0;
|
| + }
|
| // Allocate variables for inner scopes.
|
| for (int i = 0; i < inner_scopes_.length(); i++) {
|
| inner_scopes_[i]->AllocateVariablesRecursively(isolate);
|
| @@ -1443,7 +1452,6 @@ void Scope::AllocateVariablesRecursively(Isolate* isolate) {
|
| // variables in inner scopes which might not had been resolved yet.
|
| if (already_resolved()) return;
|
| // The number of slots required for variables.
|
| - num_stack_slots_ = 0;
|
| num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
|
|
|
| // Allocate variables for this scope.
|
|
|