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

Unified Diff: src/scopes.cc

Issue 7523027: Provisional implementation of stack allocated catch variables. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 5 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
« no previous file with comments | « src/scopes.h ('k') | src/v8globals.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/scopes.cc
diff --git a/src/scopes.cc b/src/scopes.cc
index 390a0b6e11ba8f1ccd4081fda789f582c8bc1554..658194c0b4bf3d72f18a9fb28790ebefc2d73861 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -207,9 +207,17 @@ void Scope::SetDefaults(Type type,
outer_scope_is_eval_scope_ = false;
force_eager_compilation_ = false;
num_var_or_const_ = 0;
+ num_stack_allocs_ = 0;
num_stack_slots_ = 0;
num_heap_slots_ = 0;
scope_info_ = scope_info;
+ if (!scope_info_.is_null()) {
+ source_beg_statement_pos_ = scope_info_->SourceBegStatementPos();
+ source_end_statement_pos_ = scope_info_->SourceEndStatementPos();
+ } else {
+ source_beg_statement_pos_ = -1;
+ source_end_statement_pos_ = -1;
+ }
}
@@ -294,7 +302,7 @@ 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
- if (is_catch_scope()) {
+ if (is_catch_scope() || is_with_scope()) {
ASSERT(outer_scope() != NULL);
receiver_ = outer_scope()->receiver();
} else {
@@ -547,11 +555,16 @@ bool Scope::HasTrivialOuterContext() const {
}
+bool Scope::HasContext() const {
+ return num_heap_slots() > 0 || is_with_scope();
+}
+
+
int Scope::ContextChainLength(Scope* scope) {
int n = 0;
for (Scope* s = this; s != scope; s = s->outer_scope_) {
ASSERT(s != NULL); // scope must be in the scope chain
- if (s->num_heap_slots() > 0) n++;
+ if (s->HasContext()) n++;
}
return n;
}
@@ -559,7 +572,7 @@ int Scope::ContextChainLength(Scope* scope) {
Scope* Scope::DeclarationScope() {
Scope* scope = this;
- while (scope->is_catch_scope()) {
+ while (scope->is_catch_scope() || scope->is_with_scope()) {
scope = scope->outer_scope();
}
return scope;
@@ -573,6 +586,7 @@ static const char* Header(Scope::Type type) {
case Scope::FUNCTION_SCOPE: return "function";
case Scope::GLOBAL_SCOPE: return "global";
case Scope::CATCH_SCOPE: return "catch";
+ case Scope::WITH_SCOPE: return "with";
}
UNREACHABLE();
return NULL;
@@ -664,6 +678,8 @@ void Scope::Print(int n) {
PrintF("%d stack slots\n", num_stack_slots_); }
if (num_heap_slots_ > 0) { Indent(n1, "// ");
PrintF("%d heap slots\n", num_heap_slots_); }
+ if (num_stack_allocs_ > 0) { Indent(n1, "// ");
+ PrintF("%d stack allocs\n", num_stack_allocs_); }
// Print locals.
PrettyPrinter printer;
@@ -753,7 +769,9 @@ Variable* Scope::LookupRecursive(Handle<String> name,
var = function_;
} else if (outer_scope_ != NULL) {
- var = outer_scope_->LookupRecursive(name, true, invalidated_local);
+ var = outer_scope_->LookupRecursive(name,
+ inner_lookup || is_function_scope(),
+ invalidated_local);
// We may have found a variable in an outer scope. However, if
// the current scope is inside a 'with', the actual variable may
// be a property introduced via the 'with' statement. Then, the
@@ -943,7 +961,7 @@ bool Scope::MustAllocateInContext(Variable* var) {
// 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;
+ if (is_catch_scope() && !DeclarationScope()->is_function_scope()) return true;
return var->is_accessed_from_inner_scope() ||
scope_calls_eval_ ||
inner_scope_calls_eval_ ||
@@ -964,7 +982,9 @@ bool Scope::HasArgumentsParameter() {
void Scope::AllocateStackSlot(Variable* var) {
- var->set_rewrite(NewSlot(var, Slot::LOCAL, num_stack_slots_++));
+ Scope* scope = DeclarationScope();
+ var->set_rewrite(NewSlot(var, Slot::LOCAL, scope->num_stack_allocs_++));
+ num_stack_slots_++;
}
@@ -1070,43 +1090,47 @@ void Scope::AllocateNonParameterLocals() {
void Scope::AllocateVariablesRecursively() {
- // Allocate variables for inner scopes.
- for (int i = 0; i < inner_scopes_.length(); i++) {
- inner_scopes_[i]->AllocateVariablesRecursively();
- }
-
// If scope is already resolved, we still need to allocate
// 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.
- // Parameters must be allocated first, if any.
- if (is_function_scope()) AllocateParameterLocals();
- AllocateNonParameterLocals();
-
- // Allocate context if necessary.
- bool must_have_local_context = false;
- if (scope_calls_eval_ || scope_contains_with_) {
- // The context for the eval() call or 'with' statement in this scope.
- // Unless we are in the global or an eval scope, we need a local
- // context even if we didn't statically allocate any locals in it,
- // and the compiler will access the context variable. If we are
- // not in an inner scope, the scope is provided from the outside.
- must_have_local_context = is_function_scope();
- }
+ if (!already_resolved()) {
+ // The number of slots required for variables.
+ num_stack_slots_ = 0;
+ num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
+
+ // Allocate variables for this scope.
+ // Parameters must be allocated first, if any.
+ if (is_function_scope()) AllocateParameterLocals();
+ AllocateNonParameterLocals();
+
+ // Allocate context if necessary.
+ bool must_have_local_context = false;
+ if (scope_calls_eval_ || scope_contains_with_) {
+ // The context for the eval() call or 'with' statement in this scope.
+ // Unless we are in the global or an eval scope, we need a local
+ // context even if we didn't statically allocate any locals in it,
+ // and the compiler will access the context variable. If we are
+ // not in an inner scope, the scope is provided from the outside.
+ must_have_local_context = is_function_scope();
+ }
+
+ // If we didn't allocate any locals in the local context, then we only
+ // need the minimal number of slots if we must have a local context.
+ if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
+ !must_have_local_context) {
+ num_heap_slots_ = 0;
+ }
- // If we didn't allocate any locals in the local context, then we only
- // need the minimal number of slots if we must have a local context.
- if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
- !must_have_local_context) {
- num_heap_slots_ = 0;
+ // Allocation done.
+ ASSERT(num_heap_slots_ == 0 ||
+ num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
}
- // Allocation done.
- ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
+ // Allocate variables for inner scopes. Must be done after parameters and
+ // local variables to allow reservation of stack slots for variables from
+ // nested blocks.
+ for (int i = 0; i < inner_scopes_.length(); i++) {
+ inner_scopes_[i]->AllocateVariablesRecursively();
+ }
}
} } // namespace v8::internal
« no previous file with comments | « src/scopes.h ('k') | src/v8globals.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698