| Index: src/scopes.cc
|
| ===================================================================
|
| --- src/scopes.cc (revision 7948)
|
| +++ src/scopes.cc (working copy)
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2010 the V8 project authors. All rights reserved.
|
| +// Copyright 2011 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:
|
| @@ -199,9 +199,11 @@
|
| // Inherit the strict mode from the parent scope.
|
| strict_mode_ = (outer_scope != NULL) && outer_scope->strict_mode_;
|
| outer_scope_calls_eval_ = false;
|
| + outer_scope_calls_non_strict_eval_ = false;
|
| inner_scope_calls_eval_ = false;
|
| outer_scope_is_eval_scope_ = false;
|
| force_eager_compilation_ = false;
|
| + num_var_or_const_ = 0;
|
| num_stack_slots_ = 0;
|
| num_heap_slots_ = 0;
|
| scope_info_ = scope_info;
|
| @@ -364,12 +366,17 @@
|
| }
|
|
|
|
|
| -Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) {
|
| +Variable* Scope::DeclareLocal(Handle<String> name,
|
| + Variable::Mode mode,
|
| + LocalType type) {
|
| // DYNAMIC variables are introduces during variable allocation,
|
| // INTERNAL variables are allocated explicitly, and TEMPORARY
|
| // variables are allocated via NewTemporary().
|
| ASSERT(!resolved());
|
| ASSERT(mode == Variable::VAR || mode == Variable::CONST);
|
| + if (type == VAR_OR_CONST) {
|
| + num_var_or_const_++;
|
| + }
|
| return variables_.Declare(this, name, mode, true, Variable::NORMAL);
|
| }
|
|
|
| @@ -483,8 +490,17 @@
|
| // and assume they may invoke eval themselves. Eventually we could capture
|
| // this information in the ScopeInfo and then use it here (by traversing
|
| // the call chain stack, at compile time).
|
| +
|
| bool eval_scope = is_eval_scope();
|
| - PropagateScopeInfo(eval_scope, eval_scope);
|
| + bool outer_scope_calls_eval = false;
|
| + bool outer_scope_calls_non_strict_eval = false;
|
| + if (!is_global_scope()) {
|
| + context->ComputeEvalScopeInfo(&outer_scope_calls_eval,
|
| + &outer_scope_calls_non_strict_eval);
|
| + }
|
| + PropagateScopeInfo(outer_scope_calls_eval,
|
| + outer_scope_calls_non_strict_eval,
|
| + eval_scope);
|
|
|
| // 2) Resolve variables.
|
| Scope* global_scope = NULL;
|
| @@ -616,10 +632,14 @@
|
| if (HasTrivialOuterContext()) {
|
| Indent(n1, "// scope has trivial outer context\n");
|
| }
|
| + if (is_strict_mode()) Indent(n1, "// strict mode scope\n");
|
| if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
|
| if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
|
| if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
|
| if (outer_scope_calls_eval_) Indent(n1, "// outer scope calls 'eval'\n");
|
| + if (outer_scope_calls_non_strict_eval_) {
|
| + Indent(n1, "// outer scope calls 'eval' in non-strict context\n");
|
| + }
|
| if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
|
| if (outer_scope_is_eval_scope_) {
|
| Indent(n1, "// outer scope is 'eval' scope\n");
|
| @@ -846,20 +866,30 @@
|
|
|
|
|
| bool Scope::PropagateScopeInfo(bool outer_scope_calls_eval,
|
| + bool outer_scope_calls_non_strict_eval,
|
| bool outer_scope_is_eval_scope) {
|
| if (outer_scope_calls_eval) {
|
| outer_scope_calls_eval_ = true;
|
| }
|
|
|
| + if (outer_scope_calls_non_strict_eval) {
|
| + outer_scope_calls_non_strict_eval_ = true;
|
| + }
|
| +
|
| if (outer_scope_is_eval_scope) {
|
| outer_scope_is_eval_scope_ = true;
|
| }
|
|
|
| bool calls_eval = scope_calls_eval_ || outer_scope_calls_eval_;
|
| bool is_eval = is_eval_scope() || outer_scope_is_eval_scope_;
|
| + bool calls_non_strict_eval =
|
| + (scope_calls_eval_ && !is_strict_mode()) ||
|
| + outer_scope_calls_non_strict_eval_;
|
| for (int i = 0; i < inner_scopes_.length(); i++) {
|
| Scope* inner_scope = inner_scopes_[i];
|
| - if (inner_scope->PropagateScopeInfo(calls_eval, is_eval)) {
|
| + if (inner_scope->PropagateScopeInfo(calls_eval,
|
| + calls_non_strict_eval,
|
| + is_eval)) {
|
| inner_scope_calls_eval_ = true;
|
| }
|
| if (inner_scope->force_eager_compilation_) {
|
|
|