Commit a6e45ce7 authored by rossberg@chromium.org's avatar rossberg@chromium.org

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
parent 5419ee7b
......@@ -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
......
......@@ -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:
......
......@@ -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);
......
......@@ -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
......
......@@ -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
......
......@@ -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());
......
......@@ -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();
}
......
......@@ -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_ ||
......
......@@ -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
......
......@@ -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();
}
......
......@@ -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;
}
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment