From: rossberg@chromium.org Date: Wed, 29 Aug 2012 09:19:53 +0000 (+0000) Subject: Introduce some predicates over variable modes. X-Git-Tag: upstream/4.7.83~16081 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a6e45ce7b86a460da576fdbe08e2c6ce07c94710;p=platform%2Fupstream%2Fv8.git Introduce some predicates over variable modes. 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 --- diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index a26c59605..85e94f296 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -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 diff --git a/src/ast.h b/src/ast.h index 32d87bd73..79c95fbb7 100644 --- 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: diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 0c223501b..d2aba1239 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -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); diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 64400de81..de8e490d2 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -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 diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index b78c78332..d691a1230 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -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 diff --git a/src/parser.cc b/src/parser.cc index 1ec133876..37e903aac 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -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* arguments = new(zone()) ZoneList(3, zone()); diff --git a/src/parser.h b/src/parser.h index 3315b5620..1ab7a141b 100644 --- a/src/parser.h +++ b/src/parser.h @@ -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(); } diff --git a/src/scopes.cc b/src/scopes.cc index be9c9b685..c9612577a 100644 --- a/src/scopes.cc +++ b/src/scopes.cc @@ -485,10 +485,7 @@ Variable* Scope::DeclareLocal(Handle 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_ || diff --git a/src/v8globals.h b/src/v8globals.h index af1d3aaa1..3d214f8dd 100644 --- a/src/v8globals.h +++ b/src/v8globals.h @@ -479,16 +479,17 @@ const uint64_t kLastNonNaNInt64 = (static_cast(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 diff --git a/src/variables.cc b/src/variables.cc index 64311d925..0416f3a39 100644 --- a/src/variables.cc +++ b/src/variables.cc @@ -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(); } diff --git a/src/variables.h b/src/variables.h index c49bab95d..ba26b8047 100644 --- a/src/variables.h +++ b/src/variables.h @@ -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; } diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index acef06c9c..5e306dda5 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -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