Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Unified Diff: src/scopes.cc

Issue 7280012: Introduce scopes to keep track of catch blocks at compile time. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update to HEAD. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/scopes.cc
diff --git a/src/scopes.cc b/src/scopes.cc
index 74d0c2a2e258f4140fa7f0b344b4eadfa8172854..c20c85214f014b9ac033db8eee8820deb10af056 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -256,11 +256,16 @@ void Scope::Initialize(bool inside_with) {
// 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 =
- variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR,
- false, Variable::THIS);
- var->set_rewrite(new Slot(var, Slot::PARAMETER, -1));
- receiver_ = var;
+ if (is_catch_scope()) {
+ ASSERT(outer_scope() != NULL);
+ receiver_ = outer_scope()->receiver();
+ } else {
+ Variable* var =
+ variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR,
+ false, Variable::THIS);
+ var->set_rewrite(new Slot(var, Slot::PARAMETER, -1));
+ receiver_ = var;
+ }
if (is_function_scope()) {
// Declare 'arguments' variable which exists in all functions.
@@ -514,6 +519,7 @@ static const char* Header(Scope::Type type) {
case Scope::EVAL_SCOPE: return "eval";
case Scope::FUNCTION_SCOPE: return "function";
case Scope::GLOBAL_SCOPE: return "global";
+ case Scope::CATCH_SCOPE: return "catch";
}
UNREACHABLE();
return NULL;
@@ -864,8 +870,10 @@ bool Scope::MustAllocate(Variable* var) {
// visible name.
if ((var->is_this() || var->name()->length() > 0) &&
(var->is_accessed_from_inner_scope() ||
- scope_calls_eval_ || inner_scope_calls_eval_ ||
- scope_contains_with_)) {
+ scope_calls_eval_ ||
+ inner_scope_calls_eval_ ||
+ scope_contains_with_ ||
+ is_catch_scope())) {
var->set_is_used(true);
}
// Global variables do not need to be allocated.
@@ -874,16 +882,20 @@ bool Scope::MustAllocate(Variable* var) {
bool Scope::MustAllocateInContext(Variable* var) {
- // If var is accessed from an inner scope, or if there is a
- // possibility that it might be accessed from the current or an inner
- // scope (through an eval() call), it must be allocated in the
- // context. Exception: temporary variables are not allocated in the
+ // If var is accessed from an inner scope, or if there is a possibility
+ // that it might be accessed from the current or an inner scope (through
+ // an eval() call or a runtime with lookup), it must be allocated in the
// context.
- return
- var->mode() != Variable::TEMPORARY &&
- (var->is_accessed_from_inner_scope() ||
- scope_calls_eval_ || inner_scope_calls_eval_ ||
- scope_contains_with_ || var->is_global());
+ //
+ // Exceptions: temporary variables are never allocated in a context;
+ // catch-bound variables are always allocated in a context.
+ if (var->mode() == Variable::TEMPORARY) return false;
+ if (is_catch_scope()) return true;
+ return var->is_accessed_from_inner_scope() ||
+ scope_calls_eval_ ||
+ inner_scope_calls_eval_ ||
+ scope_contains_with_ ||
+ var->is_global();
}

Powered by Google App Engine
This is Rietveld 408576698