Introduce some predicates over variable modes.
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 Aug 2012 09:19:53 +0000 (09:19 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 Aug 2012 09:19:53 +0000 (09:19 +0000)
These should be handy when we add more declaration forms for Harmony.

R=svenpanne@chromium.org
BUG=

Review URL: https://chromiumcodereview.appspot.com/10897010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12404 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

12 files changed:
src/arm/full-codegen-arm.cc
src/ast.h
src/hydrogen.cc
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/parser.cc
src/parser.h
src/scopes.cc
src/v8globals.h
src/variables.cc
src/variables.h
src/x64/full-codegen-x64.cc

index a26c596051f8b92d2e2230d13e28d3c126f7d554..85e94f29649dacf999f1fbf7afd4415a6f48bfb0 100644 (file)
@@ -832,10 +832,9 @@ void FullCodeGenerator::VisitVariableDeclaration(
       Comment cmnt(masm_, "[ VariableDeclaration");
       __ mov(r2, Operand(variable->name()));
       // Declaration nodes are always introduced in one of four modes.
-      ASSERT(mode == VAR || mode == LET ||
-             mode == CONST || mode == CONST_HARMONY);
-      PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
-          ? READ_ONLY : NONE;
+      ASSERT(IsDeclaredVariableMode(mode));
+      PropertyAttributes attr =
+          IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
       __ mov(r1, Operand(Smi::FromInt(attr)));
       // Push initial value, if any.
       // Note: For variables we must not push an initial value (such as
index 32d87bd732d07c33318a7c8631a8487bdf9e7ea5..79c95fbb7e4b8bccdba5923db55a590e9404aad5 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -454,10 +454,7 @@ class Declaration: public AstNode {
       : proxy_(proxy),
         mode_(mode),
         scope_(scope) {
-    ASSERT(mode == VAR ||
-           mode == CONST ||
-           mode == CONST_HARMONY ||
-           mode == LET);
+    ASSERT(IsDeclaredVariableMode(mode));
   }
 
  private:
index 0c223501b71e6e3237993ba402e1a4b362421e5a..d2aba123922e05452c7bd2b65e8048137110b382 100644 (file)
@@ -4815,8 +4815,9 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
   Variable* variable = expr->var();
   switch (variable->location()) {
     case Variable::UNALLOCATED: {
-      if (variable->mode() == LET || variable->mode() == CONST_HARMONY) {
-        return Bailout("reference to global harmony declared variable");
+      if (IsLexicalVariableMode(variable->mode())) {
+        // TODO(rossberg): should this be an ASSERT?
+        return Bailout("reference to global lexical variable");
       }
       // Handle known global constants like 'undefined' specially to avoid a
       // load from a global cell for them.
@@ -4861,9 +4862,8 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
     case Variable::LOCAL: {
       HValue* value = environment()->Lookup(variable);
       if (value == graph()->GetConstantHole()) {
-        ASSERT(variable->mode() == CONST ||
-               variable->mode() == CONST_HARMONY ||
-               variable->mode() == LET);
+        ASSERT(IsDeclaredVariableMode(variable->mode()) &&
+               variable->mode() != VAR);
         return Bailout("reference to uninitialized variable");
       }
       return ast_context()->ReturnValue(value);
@@ -8115,8 +8115,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
         }
 
         HValue* context = BuildContextChainWalk(var);
-        HStoreContextSlot::Mode mode =
-            (var->mode() == LET || var->mode() == CONST_HARMONY)
+        HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
             ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
         HStoreContextSlot* instr =
             new(zone()) HStoreContextSlot(context, var->index(), mode, after);
index 64400de81d1f1eeca8f8c950b53a5b60ab17c9b4..de8e490d2873c87cc4c43c46b7326eafcb0411fb 100644 (file)
@@ -810,10 +810,9 @@ void FullCodeGenerator::VisitVariableDeclaration(
       __ push(esi);
       __ push(Immediate(variable->name()));
       // VariableDeclaration nodes are always introduced in one of four modes.
-      ASSERT(mode == VAR || mode == LET ||
-             mode == CONST || mode == CONST_HARMONY);
-      PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
-          ? READ_ONLY : NONE;
+      ASSERT(IsDeclaredVariableMode(mode));
+      PropertyAttributes attr =
+          IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
       __ push(Immediate(Smi::FromInt(attr)));
       // Push initial value, if any.
       // Note: For variables we must not push an initial value (such as
index b78c78332eb5370df91969b841df1dfd18eb45ed..d691a1230894e074a140a53f53d8d58453160a78 100644 (file)
@@ -849,10 +849,9 @@ void FullCodeGenerator::VisitVariableDeclaration(
       Comment cmnt(masm_, "[ VariableDeclaration");
       __ li(a2, Operand(variable->name()));
       // Declaration nodes are always introduced in one of four modes.
-      ASSERT(mode == VAR || mode == LET ||
-             mode == CONST || mode == CONST_HARMONY);
-      PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
-        ? READ_ONLY : NONE;
+      ASSERT(IsDeclaredVariableMode(mode));
+      PropertyAttributes attr =
+          IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
       __ li(a1, Operand(Smi::FromInt(attr)));
       // Push initial value, if any.
       // Note: For variables we must not push an initial value (such as
index 1ec133876c07cc20e5a084b101edeef36cb6a4e3..37e903aac9c1e9a249718f61351800e3edc9464f 100644 (file)
@@ -1802,8 +1802,8 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
           name, mode, declaration->initialization(), proxy->interface());
     } else if ((mode != VAR || var->mode() != VAR) &&
                (!declaration_scope->is_global_scope() ||
-                (mode != VAR && mode != CONST) ||
-                (var->mode() != VAR && var->mode() != CONST))) {
+                IsLexicalVariableMode(mode) ||
+                IsLexicalVariableMode(var->mode()))) {
       // The name was declared in this scope before; check for conflicting
       // re-declarations. We have a conflict if either of the declarations is
       // not a var (in the global scope, we also have to ignore legacy const for
@@ -1817,11 +1817,7 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
       //
       // because the var declaration is hoisted to the function scope where 'x'
       // is already bound.
-      // We only have vars, consts and lets in declarations.
-      ASSERT(var->mode() == VAR ||
-             var->mode() == CONST ||
-             var->mode() == CONST_HARMONY ||
-             var->mode() == LET);
+      ASSERT(IsDeclaredVariableMode(var->mode()));
       if (is_extended_mode()) {
         // In harmony mode we treat re-declarations as early errors. See
         // ES5 16 for a definition of early errors.
@@ -2341,7 +2337,7 @@ Block* Parser::ParseVariableDeclarations(
     // browsers where the global object (window) has lots of
     // properties defined in prototype objects.
     if (initialization_scope->is_global_scope() &&
-        mode != LET && mode != CONST_HARMONY) {
+        !IsLexicalVariableMode(mode)) {
       // Compute the arguments for the runtime call.
       ZoneList<Expression*>* arguments =
           new(zone()) ZoneList<Expression*>(3, zone());
index 3315b56201de9687b0995464069ea4c725f2ee3e..1ab7a141be72b526f2a7433e22009050357210a5 100644 (file)
@@ -579,7 +579,7 @@ class Parser {
     return top_scope_->is_extended_mode();
   }
   Scope* DeclarationScope(VariableMode mode) {
-    return (mode == LET || mode == CONST_HARMONY)
+    return IsLexicalVariableMode(mode)
         ? top_scope_ : top_scope_->DeclarationScope();
   }
 
index be9c9b6857397d633c50fb0eb5684c56108a73cd..c9612577afa22c56e5461e543c8edcb3a9adeb63 100644 (file)
@@ -485,10 +485,7 @@ Variable* Scope::DeclareLocal(Handle<String> name,
   // This function handles VAR and CONST modes.  DYNAMIC variables are
   // introduces during variable allocation, INTERNAL variables are allocated
   // explicitly, and TEMPORARY variables are allocated via NewTemporary().
-  ASSERT(mode == VAR ||
-         mode == CONST ||
-         mode == CONST_HARMONY ||
-         mode == LET);
+  ASSERT(IsDeclaredVariableMode(mode));
   ++num_var_or_const_;
   return variables_.Declare(
       this, name, mode, true, Variable::NORMAL, init_flag, interface);
@@ -1179,8 +1176,7 @@ bool Scope::MustAllocateInContext(Variable* var) {
   // catch-bound variables are always allocated in a context.
   if (var->mode() == TEMPORARY) return false;
   if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
-  if (is_global_scope() && (var->mode() == LET || var->mode() == CONST_HARMONY))
-    return true;
+  if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true;
   return var->has_forced_context_allocation() ||
       scope_calls_eval_ ||
       inner_scope_calls_eval_ ||
index af1d3aaa1fbf1ba2cae11a3a541a121425f8dc96..3d214f8dd3a99bf781547c5666dba840fbc13116 100644 (file)
@@ -479,16 +479,17 @@ const uint64_t kLastNonNaNInt64 =
     (static_cast<uint64_t>(kNaNOrInfinityLowerBoundUpper32) << 32);
 
 
+// The order of this enum has to be kept in sync with the predicates below.
 enum VariableMode {
   // User declared variables:
   VAR,             // declared via 'var', and 'function' declarations
 
   CONST,           // declared via 'const' declarations
 
-  CONST_HARMONY,   // declared via 'const' declarations in harmony mode
-
   LET,             // declared via 'let' declarations
 
+  CONST_HARMONY,   // declared via 'const' declarations in harmony mode
+
   // Variables introduced by the compiler:
   DYNAMIC,         // always require dynamic lookup (we don't know
                    // the declaration)
@@ -510,6 +511,26 @@ enum VariableMode {
 };
 
 
+inline bool IsDynamicVariableMode(VariableMode mode) {
+  return mode >= DYNAMIC && mode <= DYNAMIC_LOCAL;
+}
+
+
+inline bool IsDeclaredVariableMode(VariableMode mode) {
+  return mode >= VAR && mode <= CONST_HARMONY;
+}
+
+
+inline bool IsLexicalVariableMode(VariableMode mode) {
+  return mode >= LET && mode <= CONST_HARMONY;
+}
+
+
+inline bool IsImmutableVariableMode(VariableMode mode) {
+  return mode == CONST || mode == CONST_HARMONY;
+}
+
+
 // ES6 Draft Rev3 10.2 specifies declarative environment records with mutable
 // and immutable bindings that can be in two states: initialized and
 // uninitialized. In ES5 only immutable bindings have these two states. When
index 64311d925d92c16bd04a6a2316a69b1db0e7d814..0416f3a3908d321b35d2c647145e2ce7173ac4e0 100644 (file)
@@ -41,7 +41,7 @@ const char* Variable::Mode2String(VariableMode mode) {
   switch (mode) {
     case VAR: return "VAR";
     case CONST: return "CONST";
-    case CONST_HARMONY: return "CONST";
+    case CONST_HARMONY: return "CONST_HARMONY";
     case LET: return "LET";
     case DYNAMIC: return "DYNAMIC";
     case DYNAMIC_GLOBAL: return "DYNAMIC_GLOBAL";
@@ -84,7 +84,7 @@ Variable::Variable(Scope* scope,
 bool Variable::IsGlobalObjectProperty() const {
   // Temporaries are never global, they must always be allocated in the
   // activation frame.
-  return mode_ != TEMPORARY && mode_ != LET && mode_ != CONST_HARMONY
+  return mode_ != TEMPORARY && !IsLexicalVariableMode(mode_)
       && scope_ != NULL && scope_->is_global_scope();
 }
 
index c49bab95da2a7aa9cfab87432bd4089ce2b3349f..ba26b80472c0b409f28074e46638824cc79543f8 100644 (file)
@@ -120,15 +120,8 @@ class Variable: public ZoneObject {
   bool IsLookupSlot() const { return location_ == LOOKUP; }
   bool IsGlobalObjectProperty() const;
 
-  bool is_dynamic() const {
-    return (mode_ == DYNAMIC ||
-            mode_ == DYNAMIC_GLOBAL ||
-            mode_ == DYNAMIC_LOCAL);
-  }
-  bool is_const_mode() const {
-    return (mode_ == CONST ||
-            mode_ == CONST_HARMONY);
-  }
+  bool is_dynamic() const { return IsDynamicVariableMode(mode_); }
+  bool is_const_mode() const { return IsImmutableVariableMode(mode_); }
   bool binding_needs_init() const {
     return initialization_flag_ == kNeedsInitialization;
   }
index acef06c9c3de568bf7c78e217e458d6f323956f9..5e306dda57dc5b694281d2240174e522744f4958 100644 (file)
@@ -816,10 +816,9 @@ void FullCodeGenerator::VisitVariableDeclaration(
       __ push(rsi);
       __ Push(variable->name());
       // Declaration nodes are always introduced in one of four modes.
-      ASSERT(mode == VAR || mode == LET ||
-             mode == CONST || mode == CONST_HARMONY);
+      ASSERT(IsDeclaredVariableMode(mode));
       PropertyAttributes attr =
-          (mode == CONST || mode == CONST_HARMONY) ? READ_ONLY : NONE;
+          IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
       __ Push(Smi::FromInt(attr));
       // Push initial value, if any.
       // Note: For variables we must not push an initial value (such as