Version 3.5.5.

Fixed bugs involving negative zero and the optimizing compiler.
Fixed optimized version of Function.apply(x, arguments). (issue 1592)
Eliminated uses of deprecated ARM instructions.
Sped up Math.floor by using SSE 4.1 roundsd instruction on ia32.
Removed restriction on the size of disassembled code that is printed.
Review URL: http://codereview.chromium.org/7618040

git-svn-id: http://v8.googlecode.com/svn/trunk@8933 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/scopes.cc b/src/scopes.cc
index 390a0b6..eb0deb4 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -146,7 +146,9 @@
 }
 
 
-Scope::Scope(Scope* inner_scope, Handle<SerializedScopeInfo> scope_info)
+Scope::Scope(Scope* inner_scope,
+             Type type,
+             Handle<SerializedScopeInfo> scope_info)
     : isolate_(Isolate::Current()),
       inner_scopes_(4),
       variables_(),
@@ -156,7 +158,7 @@
       decls_(4),
       already_resolved_(true) {
   ASSERT(!scope_info.is_null());
-  SetDefaults(FUNCTION_SCOPE, NULL, scope_info);
+  SetDefaults(type, NULL, scope_info);
   if (scope_info->HasHeapAllocatedLocals()) {
     num_heap_slots_ = scope_info_->NumberOfContextSlots();
   }
@@ -232,8 +234,13 @@
       if (context->IsFunctionContext()) {
         SerializedScopeInfo* scope_info =
             context->closure()->shared()->scope_info();
-        current_scope =
-            new Scope(current_scope, Handle<SerializedScopeInfo>(scope_info));
+        current_scope = new Scope(current_scope, FUNCTION_SCOPE,
+            Handle<SerializedScopeInfo>(scope_info));
+      } else if (context->IsBlockContext()) {
+        SerializedScopeInfo* scope_info =
+            SerializedScopeInfo::cast(context->extension());
+        current_scope = new Scope(current_scope, BLOCK_SCOPE,
+            Handle<SerializedScopeInfo>(scope_info));
       } else {
         ASSERT(context->IsCatchContext());
         String* name = String::cast(context->extension());
@@ -294,10 +301,13 @@
   // 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_block_scope()) {
     ASSERT(outer_scope() != NULL);
     receiver_ = outer_scope()->receiver();
   } else {
+    ASSERT(is_function_scope() ||
+           is_global_scope() ||
+           is_eval_scope());
     Variable* var =
         variables_.Declare(this,
                            isolate_->factory()->this_symbol(),
@@ -559,13 +569,22 @@
 
 Scope* Scope::DeclarationScope() {
   Scope* scope = this;
-  while (scope->is_catch_scope()) {
+  while (scope->is_catch_scope() ||
+         scope->is_block_scope()) {
     scope = scope->outer_scope();
   }
   return scope;
 }
 
 
+Handle<SerializedScopeInfo> Scope::GetSerializedScopeInfo() {
+  if (scope_info_.is_null()) {
+    scope_info_ = SerializedScopeInfo::Create(this);
+  }
+  return scope_info_;
+}
+
+
 #ifdef DEBUG
 static const char* Header(Scope::Type type) {
   switch (type) {
@@ -573,6 +592,7 @@
     case Scope::FUNCTION_SCOPE: return "function";
     case Scope::GLOBAL_SCOPE: return "global";
     case Scope::CATCH_SCOPE: return "catch";
+    case Scope::BLOCK_SCOPE: return "block";
   }
   UNREACHABLE();
   return NULL;
@@ -598,9 +618,11 @@
     PrintF(";  // ");
     if (var->rewrite() != NULL) {
       PrintF("%s, ", printer->Print(var->rewrite()));
-      if (var->is_accessed_from_inner_scope()) PrintF(", ");
+      if (var->is_accessed_from_inner_function_scope()) PrintF(", ");
     }
-    if (var->is_accessed_from_inner_scope()) PrintF("inner scope access");
+    if (var->is_accessed_from_inner_function_scope()) {
+      PrintF("inner scope access");
+    }
     PrintF("\n");
   }
 }
@@ -721,7 +743,7 @@
 // another variable that is introduced dynamically via an 'eval' call
 // or a 'with' statement).
 Variable* Scope::LookupRecursive(Handle<String> name,
-                                 bool inner_lookup,
+                                 bool from_inner_function,
                                  Variable** invalidated_local) {
   // If we find a variable, but the current scope calls 'eval', the found
   // variable may not be the correct one (the 'eval' may introduce a
@@ -737,7 +759,7 @@
     // (Even if there is an 'eval' in this scope which introduces the
     // same variable again, the resulting variable remains the same.
     // Note that enclosing 'with' statements are handled at the call site.)
-    if (!inner_lookup)
+    if (!from_inner_function)
       return var;
 
   } else {
@@ -753,7 +775,10 @@
       var = function_;
 
     } else if (outer_scope_ != NULL) {
-      var = outer_scope_->LookupRecursive(name, true, invalidated_local);
+      var = outer_scope_->LookupRecursive(
+          name,
+          is_function_scope() || from_inner_function,
+          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
@@ -770,8 +795,8 @@
   ASSERT(var != NULL);
 
   // If this is a lookup from an inner scope, mark the variable.
-  if (inner_lookup) {
-    var->MarkAsAccessedFromInnerScope();
+  if (from_inner_function) {
+    var->MarkAsAccessedFromInnerFunctionScope();
   }
 
   // If the variable we have found is just a guess, invalidate the
@@ -922,11 +947,12 @@
   // via an eval() call.  This is only possible if the variable has a
   // visible name.
   if ((var->is_this() || var->name()->length() > 0) &&
-      (var->is_accessed_from_inner_scope() ||
+      (var->is_accessed_from_inner_function_scope() ||
        scope_calls_eval_ ||
        inner_scope_calls_eval_ ||
        scope_contains_with_ ||
-       is_catch_scope())) {
+       is_catch_scope() ||
+       is_block_scope())) {
     var->set_is_used(true);
   }
   // Global variables do not need to be allocated.
@@ -943,8 +969,8 @@
   // 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() ||
+  if (is_catch_scope() || is_block_scope()) return true;
+  return var->is_accessed_from_inner_function_scope() ||
       scope_calls_eval_ ||
       inner_scope_calls_eval_ ||
       scope_contains_with_ ||
@@ -1010,7 +1036,7 @@
     if (uses_nonstrict_arguments) {
       // Give the parameter a use from an inner scope, to force allocation
       // to the context.
-      var->MarkAsAccessedFromInnerScope();
+      var->MarkAsAccessedFromInnerFunctionScope();
     }
 
     if (MustAllocate(var)) {