summaryrefslogtreecommitdiffstats
path: root/src/ast
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2016-06-02 14:46:10 +0100
committerBen Murdoch <benm@google.com>2016-06-02 14:46:10 +0100
commit3b9bc31999c9787eb726ecdbfd5796bfdec32a18 (patch)
treeb521168bf78078bea1c0a9851e6ca7099318195e /src/ast
parentc007f9a1597810ec6ccf9b289e98fda574a0dde7 (diff)
downloadandroid_external_v8-3b9bc31999c9787eb726ecdbfd5796bfdec32a18.tar.gz
android_external_v8-3b9bc31999c9787eb726ecdbfd5796bfdec32a18.tar.bz2
android_external_v8-3b9bc31999c9787eb726ecdbfd5796bfdec32a18.zip
Upgrade V8 to 5.1.281.57
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
Diffstat (limited to 'src/ast')
-rw-r--r--src/ast/ast-numbering.cc14
-rw-r--r--src/ast/ast-value-factory.h1
-rw-r--r--src/ast/ast.cc55
-rw-r--r--src/ast/ast.h136
-rw-r--r--src/ast/prettyprinter.cc7
-rw-r--r--src/ast/scopes.cc68
-rw-r--r--src/ast/scopes.h32
7 files changed, 96 insertions, 217 deletions
diff --git a/src/ast/ast-numbering.cc b/src/ast/ast-numbering.cc
index 272f9bde..f54333ff 100644
--- a/src/ast/ast-numbering.cc
+++ b/src/ast/ast-numbering.cc
@@ -138,7 +138,6 @@ void AstNumberingVisitor::VisitNativeFunctionLiteral(
void AstNumberingVisitor::VisitDoExpression(DoExpression* node) {
IncrementNodeCount();
- DisableCrankshaft(kDoExpression);
node->set_base_id(ReserveIdRange(DoExpression::num_ids()));
Visit(node->block());
Visit(node->result());
@@ -267,10 +266,6 @@ void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) {
void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
IncrementNodeCount();
ReserveFeedbackSlots(node);
- if (node->is_jsruntime()) {
- // Don't try to optimize JS runtime calls because we bailout on them.
- DisableOptimization(kCallToAJavaScriptRuntimeFunction);
- }
node->set_base_id(ReserveIdRange(CallRuntime::num_ids()));
VisitArguments(node->arguments());
}
@@ -504,9 +499,6 @@ void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) {
void AstNumberingVisitor::VisitCall(Call* node) {
IncrementNodeCount();
- if (node->tail_call_mode() == TailCallMode::kAllow) {
- DisableOptimization(kTailCall);
- }
ReserveFeedbackSlots(node);
node->set_base_id(ReserveIdRange(Call::num_ids()));
Visit(node->expression());
@@ -571,12 +563,6 @@ bool AstNumberingVisitor::Finish(FunctionLiteral* node) {
bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
Scope* scope = node->scope();
-
- if (scope->HasIllegalRedeclaration()) {
- Visit(scope->GetIllegalRedeclaration());
- DisableOptimization(kFunctionWithIllegalRedeclaration);
- return Finish(node);
- }
if (scope->new_target_var()) DisableCrankshaft(kSuperReference);
if (scope->calls_eval()) DisableOptimization(kFunctionCallsEval);
if (scope->arguments() != NULL && !scope->arguments()->IsStackAllocated()) {
diff --git a/src/ast/ast-value-factory.h b/src/ast/ast-value-factory.h
index 85e8277d..8b3f0ed2 100644
--- a/src/ast/ast-value-factory.h
+++ b/src/ast/ast-value-factory.h
@@ -271,7 +271,6 @@ class AstValue : public ZoneObject {
F(throw, "throw") \
F(undefined, "undefined") \
F(use_asm, "use asm") \
- F(use_strong, "use strong") \
F(use_strict, "use strict") \
F(value, "value")
diff --git a/src/ast/ast.cc b/src/ast/ast.cc
index 9b2c6388..e8b62696 100644
--- a/src/ast/ast.cc
+++ b/src/ast/ast.cc
@@ -36,17 +36,11 @@ AST_NODE_LIST(DECL_ACCEPT)
#ifdef DEBUG
-void AstNode::Print() { Print(Isolate::Current()); }
-
-
void AstNode::Print(Isolate* isolate) {
AstPrinter::PrintOut(isolate, this);
}
-void AstNode::PrettyPrint() { PrettyPrint(Isolate::Current()); }
-
-
void AstNode::PrettyPrint(Isolate* isolate) {
PrettyPrinter::PrintOut(isolate, this);
}
@@ -68,8 +62,11 @@ bool Expression::IsNullLiteral() const {
return IsLiteral() && AsLiteral()->value()->IsNull();
}
+bool Expression::IsUndefinedLiteral() const {
+ if (IsLiteral() && AsLiteral()->value()->IsUndefined()) {
+ return true;
+ }
-bool Expression::IsUndefinedLiteral(Isolate* isolate) const {
const VariableProxy* var_proxy = AsVariableProxy();
if (var_proxy == NULL) return false;
Variable* var = var_proxy->var();
@@ -154,15 +151,11 @@ static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec,
}
}
-
-void ForEachStatement::AssignFeedbackVectorSlots(
- Isolate* isolate, FeedbackVectorSpec* spec,
- FeedbackVectorSlotCache* cache) {
- // TODO(adamk): for-of statements do not make use of this feedback slot.
- // The each_slot_ should be specific to ForInStatement, and this work moved
- // there.
- if (IsForOfStatement()) return;
+void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate,
+ FeedbackVectorSpec* spec,
+ FeedbackVectorSlotCache* cache) {
AssignVectorSlots(each(), spec, &each_slot_);
+ for_in_feedback_slot_ = spec->AddGeneralSlot();
}
@@ -475,18 +468,15 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
// much larger than the number of elements, creating an object
// literal with fast elements will be a waste of space.
uint32_t element_index = 0;
- if (key->IsString()
- && Handle<String>::cast(key)->AsArrayIndex(&element_index)
- && element_index > max_element_index) {
- max_element_index = element_index;
+ if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) {
+ max_element_index = Max(element_index, max_element_index);
elements++;
- } else if (key->IsSmi()) {
- int key_value = Smi::cast(*key)->value();
- if (key_value > 0
- && static_cast<uint32_t>(key_value) > max_element_index) {
- max_element_index = key_value;
- }
+ key = isolate->factory()->NewNumberFromUint(element_index);
+ } else if (key->ToArrayIndex(&element_index)) {
+ max_element_index = Max(element_index, max_element_index);
elements++;
+ } else if (key->IsNumber()) {
+ key = isolate->factory()->NumberToString(key);
}
// Add name, value pair to the fixed array.
@@ -513,7 +503,7 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
// Allocate a fixed array to hold all the object literals.
Handle<JSArray> array = isolate->factory()->NewJSArray(
FAST_HOLEY_SMI_ELEMENTS, constants_length, constants_length,
- Strength::WEAK, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
+ INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
// Fill in the literals.
bool is_simple = true;
@@ -678,24 +668,21 @@ static bool IsVoidOfLiteral(Expression* expr) {
static bool MatchLiteralCompareUndefined(Expression* left,
Token::Value op,
Expression* right,
- Expression** expr,
- Isolate* isolate) {
+ Expression** expr) {
if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
*expr = right;
return true;
}
- if (left->IsUndefinedLiteral(isolate) && Token::IsEqualityOp(op)) {
+ if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) {
*expr = right;
return true;
}
return false;
}
-
-bool CompareOperation::IsLiteralCompareUndefined(
- Expression** expr, Isolate* isolate) {
- return MatchLiteralCompareUndefined(left_, op_, right_, expr, isolate) ||
- MatchLiteralCompareUndefined(right_, op_, left_, expr, isolate);
+bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) {
+ return MatchLiteralCompareUndefined(left_, op_, right_, expr) ||
+ MatchLiteralCompareUndefined(right_, op_, left_, expr);
}
diff --git a/src/ast/ast.h b/src/ast/ast.h
index dcb440d7..52bac8ef 100644
--- a/src/ast/ast.h
+++ b/src/ast/ast.h
@@ -198,9 +198,7 @@ class AstNode: public ZoneObject {
#ifdef DEBUG
void PrettyPrint(Isolate* isolate);
- void PrettyPrint();
void Print(Isolate* isolate);
- void Print();
#endif // DEBUG
// Type testing & conversion functions overridden by concrete subclasses.
@@ -332,8 +330,9 @@ class Expression : public AstNode {
// True iff the expression is the null literal.
bool IsNullLiteral() const;
- // True if we can prove that the expression is the undefined literal.
- bool IsUndefinedLiteral(Isolate* isolate) const;
+ // True if we can prove that the expression is the undefined literal. Note
+ // that this also checks for loads of the global "undefined" variable.
+ bool IsUndefinedLiteral() const;
// True iff the expression is a valid target for an assignment.
bool IsValidReferenceExpressionOrThis() const;
@@ -792,10 +791,6 @@ class ForEachStatement : public IterationStatement {
void set_each(Expression* e) { each_ = e; }
void set_subject(Expression* e) { subject_ = e; }
- void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
- FeedbackVectorSlotCache* cache) override;
- FeedbackVectorSlot EachFeedbackSlot() const { return each_slot_; }
-
static const char* VisitModeString(VisitMode mode) {
return mode == ITERATE ? "for-of" : "for-in";
}
@@ -807,7 +802,6 @@ class ForEachStatement : public IterationStatement {
private:
Expression* each_;
Expression* subject_;
- FeedbackVectorSlot each_slot_;
};
@@ -821,11 +815,8 @@ class ForInStatement final : public ForEachStatement {
// Type feedback information.
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
- FeedbackVectorSlotCache* cache) override {
- ForEachStatement::AssignFeedbackVectorSlots(isolate, spec, cache);
- for_in_feedback_slot_ = spec->AddGeneralSlot();
- }
-
+ FeedbackVectorSlotCache* cache) override;
+ FeedbackVectorSlot EachFeedbackSlot() const { return each_slot_; }
FeedbackVectorSlot ForInFeedbackSlot() {
DCHECK(!for_in_feedback_slot_.IsInvalid());
return for_in_feedback_slot_;
@@ -854,6 +845,7 @@ class ForInStatement final : public ForEachStatement {
int local_id(int n) const { return base_id() + parent_num_ids() + n; }
ForInType for_in_type_;
+ FeedbackVectorSlot each_slot_;
FeedbackVectorSlot for_in_feedback_slot_;
};
@@ -1191,18 +1183,33 @@ class TryCatchStatement final : public TryStatement {
Block* catch_block() const { return catch_block_; }
void set_catch_block(Block* b) { catch_block_ = b; }
+ // The clear_pending_message flag indicates whether or not to clear the
+ // isolate's pending exception message before executing the catch_block. In
+ // the normal use case, this flag is always on because the message object
+ // is not needed anymore when entering the catch block and should not be kept
+ // alive.
+ // The use case where the flag is off is when the catch block is guaranteed to
+ // rethrow the caught exception (using %ReThrow), which reuses the pending
+ // message instead of generating a new one.
+ // (When the catch block doesn't rethrow but is guaranteed to perform an
+ // ordinary throw, not clearing the old message is safe but not very useful.)
+ bool clear_pending_message() { return clear_pending_message_; }
+
protected:
TryCatchStatement(Zone* zone, Block* try_block, Scope* scope,
- Variable* variable, Block* catch_block, int pos)
+ Variable* variable, Block* catch_block,
+ bool clear_pending_message, int pos)
: TryStatement(zone, try_block, pos),
scope_(scope),
variable_(variable),
- catch_block_(catch_block) {}
+ catch_block_(catch_block),
+ clear_pending_message_(clear_pending_message) {}
private:
Scope* scope_;
Variable* variable_;
Block* catch_block_;
+ bool clear_pending_message_;
};
@@ -1339,14 +1346,11 @@ class MaterializedLiteral : public Expression {
return depth_;
}
- bool is_strong() const { return is_strong_; }
-
protected:
- MaterializedLiteral(Zone* zone, int literal_index, bool is_strong, int pos)
+ MaterializedLiteral(Zone* zone, int literal_index, int pos)
: Expression(zone, pos),
literal_index_(literal_index),
is_simple_(false),
- is_strong_(is_strong),
depth_(0) {}
// A materialized literal is simple if the values consist of only
@@ -1375,7 +1379,6 @@ class MaterializedLiteral : public Expression {
private:
int literal_index_;
bool is_simple_;
- bool is_strong_;
int depth_;
friend class AstLiteralReindexer;
@@ -1463,7 +1466,6 @@ class ObjectLiteral final : public MaterializedLiteral {
ZoneList<Property*>* properties() const { return properties_; }
bool fast_elements() const { return fast_elements_; }
bool may_store_doubles() const { return may_store_doubles_; }
- bool has_function() const { return has_function_; }
bool has_elements() const { return has_elements_; }
bool has_shallow_properties() const {
return depth() == 1 && !has_elements() && !may_store_doubles();
@@ -1483,26 +1485,20 @@ class ObjectLiteral final : public MaterializedLiteral {
// Assemble bitfield of flags for the CreateObjectLiteral helper.
int ComputeFlags(bool disable_mementos = false) const {
int flags = fast_elements() ? kFastElements : kNoFlags;
- flags |= has_function() ? kHasFunction : kNoFlags;
if (has_shallow_properties()) {
flags |= kShallowProperties;
}
if (disable_mementos) {
flags |= kDisableMementos;
}
- if (is_strong()) {
- flags |= kIsStrong;
- }
return flags;
}
enum Flags {
kNoFlags = 0,
kFastElements = 1,
- kHasFunction = 1 << 1,
- kShallowProperties = 1 << 2,
- kDisableMementos = 1 << 3,
- kIsStrong = 1 << 4
+ kShallowProperties = 1 << 1,
+ kDisableMementos = 1 << 2
};
struct Accessors: public ZoneObject {
@@ -1534,15 +1530,13 @@ class ObjectLiteral final : public MaterializedLiteral {
protected:
ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
- int boilerplate_properties, bool has_function, bool is_strong,
- int pos)
- : MaterializedLiteral(zone, literal_index, is_strong, pos),
+ int boilerplate_properties, int pos)
+ : MaterializedLiteral(zone, literal_index, pos),
properties_(properties),
boilerplate_properties_(boilerplate_properties),
fast_elements_(false),
has_elements_(false),
- may_store_doubles_(false),
- has_function_(has_function) {}
+ may_store_doubles_(false) {}
static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
private:
@@ -1553,7 +1547,6 @@ class ObjectLiteral final : public MaterializedLiteral {
bool fast_elements_;
bool has_elements_;
bool may_store_doubles_;
- bool has_function_;
FeedbackVectorSlot slot_;
};
@@ -1589,8 +1582,8 @@ class RegExpLiteral final : public MaterializedLiteral {
protected:
RegExpLiteral(Zone* zone, const AstRawString* pattern, int flags,
- int literal_index, bool is_strong, int pos)
- : MaterializedLiteral(zone, literal_index, is_strong, pos),
+ int literal_index, int pos)
+ : MaterializedLiteral(zone, literal_index, pos),
pattern_(pattern),
flags_(flags) {
set_depth(1);
@@ -1635,9 +1628,6 @@ class ArrayLiteral final : public MaterializedLiteral {
if (disable_mementos) {
flags |= kDisableMementos;
}
- if (is_strong()) {
- flags |= kIsStrong;
- }
return flags;
}
@@ -1657,8 +1647,7 @@ class ArrayLiteral final : public MaterializedLiteral {
enum Flags {
kNoFlags = 0,
kShallowElements = 1,
- kDisableMementos = 1 << 1,
- kIsStrong = 1 << 2
+ kDisableMementos = 1 << 1
};
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
@@ -1667,9 +1656,8 @@ class ArrayLiteral final : public MaterializedLiteral {
protected:
ArrayLiteral(Zone* zone, ZoneList<Expression*>* values,
- int first_spread_index, int literal_index, bool is_strong,
- int pos)
- : MaterializedLiteral(zone, literal_index, is_strong, pos),
+ int first_spread_index, int literal_index, int pos)
+ : MaterializedLiteral(zone, literal_index, pos),
values_(values),
first_spread_index_(first_spread_index) {}
static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
@@ -2313,7 +2301,7 @@ class CompareOperation final : public Expression {
// Match special cases.
bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
- bool IsLiteralCompareUndefined(Expression** expr, Isolate* isolate);
+ bool IsLiteralCompareUndefined(Expression** expr);
bool IsLiteralCompareNull(Expression** expr);
protected:
@@ -2529,37 +2517,29 @@ class RewritableExpression : public Expression {
Expression* expr_;
};
-
+// Our Yield is different from the JS yield in that it "returns" its argument as
+// is, without wrapping it in an iterator result object. Such wrapping, if
+// desired, must be done beforehand (see the parser).
class Yield final : public Expression {
public:
DECLARE_NODE_TYPE(Yield)
- enum Kind {
- kInitial, // The initial yield that returns the unboxed generator object.
- kSuspend, // A normal yield: { value: EXPRESSION, done: false }
- kDelegating, // A yield*.
- kFinal // A return: { value: EXPRESSION, done: true }
- };
-
Expression* generator_object() const { return generator_object_; }
Expression* expression() const { return expression_; }
- Kind yield_kind() const { return yield_kind_; }
void set_generator_object(Expression* e) { generator_object_ = e; }
void set_expression(Expression* e) { expression_ = e; }
protected:
Yield(Zone* zone, Expression* generator_object, Expression* expression,
- Kind yield_kind, int pos)
+ int pos)
: Expression(zone, pos),
generator_object_(generator_object),
- expression_(expression),
- yield_kind_(yield_kind) {}
+ expression_(expression) {}
private:
Expression* generator_object_;
Expression* expression_;
- Kind yield_kind_;
};
@@ -3169,8 +3149,17 @@ class AstNodeFactory final BASE_EMBEDDED {
TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
Variable* variable,
Block* catch_block, int pos) {
- return new (local_zone_) TryCatchStatement(local_zone_, try_block, scope,
- variable, catch_block, pos);
+ return new (local_zone_) TryCatchStatement(
+ local_zone_, try_block, scope, variable, catch_block, true, pos);
+ }
+
+ TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block,
+ Scope* scope,
+ Variable* variable,
+ Block* catch_block,
+ int pos) {
+ return new (local_zone_) TryCatchStatement(
+ local_zone_, try_block, scope, variable, catch_block, false, pos);
}
TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
@@ -3243,12 +3232,9 @@ class AstNodeFactory final BASE_EMBEDDED {
ZoneList<ObjectLiteral::Property*>* properties,
int literal_index,
int boilerplate_properties,
- bool has_function,
- bool is_strong,
int pos) {
- return new (local_zone_)
- ObjectLiteral(local_zone_, properties, literal_index,
- boilerplate_properties, has_function, is_strong, pos);
+ return new (local_zone_) ObjectLiteral(
+ local_zone_, properties, literal_index, boilerplate_properties, pos);
}
ObjectLiteral::Property* NewObjectLiteralProperty(
@@ -3267,24 +3253,23 @@ class AstNodeFactory final BASE_EMBEDDED {
}
RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags,
- int literal_index, bool is_strong, int pos) {
- return new (local_zone_) RegExpLiteral(local_zone_, pattern, flags,
- literal_index, is_strong, pos);
+ int literal_index, int pos) {
+ return new (local_zone_)
+ RegExpLiteral(local_zone_, pattern, flags, literal_index, pos);
}
ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
int literal_index,
- bool is_strong,
int pos) {
return new (local_zone_)
- ArrayLiteral(local_zone_, values, -1, literal_index, is_strong, pos);
+ ArrayLiteral(local_zone_, values, -1, literal_index, pos);
}
ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
int first_spread_index, int literal_index,
- bool is_strong, int pos) {
+ int pos) {
return new (local_zone_) ArrayLiteral(
- local_zone_, values, first_spread_index, literal_index, is_strong, pos);
+ local_zone_, values, first_spread_index, literal_index, pos);
}
VariableProxy* NewVariableProxy(Variable* var,
@@ -3399,11 +3384,10 @@ class AstNodeFactory final BASE_EMBEDDED {
Yield* NewYield(Expression *generator_object,
Expression* expression,
- Yield::Kind yield_kind,
int pos) {
if (!expression) expression = NewUndefinedLiteral(pos);
return new (local_zone_)
- Yield(local_zone_, generator_object, expression, yield_kind, pos);
+ Yield(local_zone_, generator_object, expression, pos);
}
Throw* NewThrow(Expression* exception, int pos) {
diff --git a/src/ast/prettyprinter.cc b/src/ast/prettyprinter.cc
index 0e9986a4..2a79049b 100644
--- a/src/ast/prettyprinter.cc
+++ b/src/ast/prettyprinter.cc
@@ -471,7 +471,7 @@ static int FormatSlotNode(Vector<char>* buf, Expression* node,
const char* node_name, FeedbackVectorSlot slot) {
int pos = SNPrintF(*buf, "%s", node_name);
if (!slot.IsInvalid()) {
- pos = SNPrintF(*buf + pos, " Slot(%d)", slot.ToInt());
+ pos += SNPrintF(*buf + pos, " Slot(%d)", slot.ToInt());
}
return pos;
}
@@ -1563,6 +1563,7 @@ void AstPrinter::VisitVariableProxy(VariableProxy* node) {
Variable* var = node->var();
switch (var->location()) {
case VariableLocation::UNALLOCATED:
+ SNPrintF(buf + pos, " unallocated");
break;
case VariableLocation::PARAMETER:
SNPrintF(buf + pos, " parameter[%d]", var->index());
@@ -1593,9 +1594,7 @@ void AstPrinter::VisitAssignment(Assignment* node) {
void AstPrinter::VisitYield(Yield* node) {
- EmbeddedVector<char, 128> buf;
- SNPrintF(buf, "YIELD (kind %d)", node->yield_kind());
- IndentedScope indent(this, buf.start(), node->position());
+ IndentedScope indent(this, "YIELD", node->position());
Visit(node->expression());
}
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
index 7c87ce39..5d4b8098 100644
--- a/src/ast/scopes.cc
+++ b/src/ast/scopes.cc
@@ -100,7 +100,6 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
function_kind);
// The outermost scope must be a script scope.
DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL);
- DCHECK(!HasIllegalRedeclaration());
}
Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type,
@@ -169,9 +168,7 @@ void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope,
function_ = nullptr;
arguments_ = nullptr;
this_function_ = nullptr;
- illegal_redecl_ = nullptr;
scope_inside_with_ = false;
- scope_contains_with_ = false;
scope_calls_eval_ = false;
scope_uses_arguments_ = false;
scope_uses_super_property_ = false;
@@ -210,15 +207,14 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
// Reconstruct the outer scope chain from a closure's context chain.
Scope* current_scope = NULL;
Scope* innermost_scope = NULL;
- bool contains_with = false;
while (!context->IsNativeContext()) {
- if (context->IsWithContext()) {
+ if (context->IsWithContext() || context->IsDebugEvaluateContext()) {
+ // For scope analysis, debug-evaluate is equivalent to a with scope.
Scope* with_scope = new (zone)
Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null(),
script_scope->ast_value_factory_);
current_scope = with_scope;
// All the inner scopes are inside a with.
- contains_with = true;
for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
s->scope_inside_with_ = true;
}
@@ -252,13 +248,7 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
script_scope->ast_value_factory_->GetString(Handle<String>(name)),
script_scope->ast_value_factory_);
}
- if (contains_with) current_scope->RecordWithStatement();
if (innermost_scope == NULL) innermost_scope = current_scope;
-
- // Forget about a with when we move to a context for a different function.
- if (context->previous()->closure() != context->closure()) {
- contains_with = false;
- }
context = context->previous();
}
@@ -392,7 +382,6 @@ void Scope::PropagateUsageFlagsToScope(Scope* other) {
if (uses_arguments()) other->RecordArgumentsUsage();
if (uses_super_property()) other->RecordSuperPropertyUsage();
if (calls_eval()) other->RecordEvalCall();
- if (scope_contains_with_) other->RecordWithStatement();
}
@@ -583,21 +572,6 @@ void Scope::AddDeclaration(Declaration* declaration) {
}
-void Scope::SetIllegalRedeclaration(Expression* expression) {
- // Record only the first illegal redeclaration.
- if (!HasIllegalRedeclaration()) {
- illegal_redecl_ = expression;
- }
- DCHECK(HasIllegalRedeclaration());
-}
-
-
-Expression* Scope::GetIllegalRedeclaration() {
- DCHECK(HasIllegalRedeclaration());
- return illegal_redecl_;
-}
-
-
Declaration* Scope::CheckConflictingVarDeclarations() {
int length = decls_.length();
for (int i = 0; i < length; i++) {
@@ -817,25 +791,7 @@ Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) {
return scope_info_;
}
-
-void Scope::GetNestedScopeChain(Isolate* isolate,
- List<Handle<ScopeInfo> >* chain, int position) {
- if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo(isolate)));
-
- for (int i = 0; i < inner_scopes_.length(); i++) {
- Scope* scope = inner_scopes_[i];
- int beg_pos = scope->start_position();
- int end_pos = scope->end_position();
- DCHECK(beg_pos >= 0 && end_pos >= 0);
- if (beg_pos <= position && position < end_pos) {
- scope->GetNestedScopeChain(isolate, chain, position);
- return;
- }
- }
-}
-
-
-void Scope::CollectNonLocals(HashMap* non_locals) {
+Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) {
// Collect non-local variables referenced in the scope.
// TODO(yangguo): store non-local variables explicitly if we can no longer
// rely on unresolved_ to find them.
@@ -843,13 +799,12 @@ void Scope::CollectNonLocals(HashMap* non_locals) {
VariableProxy* proxy = unresolved_[i];
if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue;
Handle<String> name = proxy->name();
- void* key = reinterpret_cast<void*>(name.location());
- HashMap::Entry* entry = non_locals->LookupOrInsert(key, name->Hash());
- entry->value = key;
+ non_locals = StringSet::Add(non_locals, name);
}
for (int i = 0; i < inner_scopes_.length(); i++) {
- inner_scopes_[i]->CollectNonLocals(non_locals);
+ non_locals = inner_scopes_[i]->CollectNonLocals(non_locals);
}
+ return non_locals;
}
@@ -999,7 +954,6 @@ void Scope::Print(int n) {
Indent(n1, "// strict mode scope\n");
}
if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
- if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n");
if (scope_uses_super_property_)
@@ -1271,8 +1225,8 @@ bool Scope::MustAllocate(Variable* var) {
// visible name.
if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
(var->has_forced_context_allocation() || scope_calls_eval_ ||
- inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() ||
- is_block_scope() || is_module_scope() || is_script_scope())) {
+ inner_scope_calls_eval_ || is_catch_scope() || is_block_scope() ||
+ is_module_scope() || is_script_scope())) {
var->set_is_used();
if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned();
}
@@ -1295,10 +1249,8 @@ bool Scope::MustAllocateInContext(Variable* var) {
if (var->mode() == TEMPORARY) return false;
if (is_catch_scope() || is_module_scope()) return true;
if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true;
- return var->has_forced_context_allocation() ||
- scope_calls_eval_ ||
- inner_scope_calls_eval_ ||
- scope_contains_with_;
+ return var->has_forced_context_allocation() || scope_calls_eval_ ||
+ inner_scope_calls_eval_;
}
diff --git a/src/ast/scopes.h b/src/ast/scopes.h
index 76f761db..dae70c01 100644
--- a/src/ast/scopes.h
+++ b/src/ast/scopes.h
@@ -224,20 +224,7 @@ class Scope: public ZoneObject {
// ---------------------------------------------------------------------------
// Illegal redeclaration support.
- // Set an expression node that will be executed when the scope is
- // entered. We only keep track of one illegal redeclaration node per
- // scope - the first one - so if you try to set it multiple times
- // the additional requests will be silently ignored.
- void SetIllegalRedeclaration(Expression* expression);
-
- // Retrieve the illegal redeclaration expression. Do not call if the
- // scope doesn't have an illegal redeclaration node.
- Expression* GetIllegalRedeclaration();
-
- // Check if the scope has (at least) one illegal redeclaration.
- bool HasIllegalRedeclaration() const { return illegal_redecl_ != NULL; }
-
- // For harmony block scoping mode: Check if the scope has conflicting var
+ // Check if the scope has conflicting var
// declarations, i.e. a var declaration that has been hoisted from a nested
// scope over a let binding of the same name.
Declaration* CheckConflictingVarDeclarations();
@@ -245,9 +232,6 @@ class Scope: public ZoneObject {
// ---------------------------------------------------------------------------
// Scope-specific info.
- // Inform the scope that the corresponding code contains a with statement.
- void RecordWithStatement() { scope_contains_with_ = true; }
-
// Inform the scope that the corresponding code contains an eval call.
void RecordEvalCall() { scope_calls_eval_ = true; }
@@ -556,14 +540,7 @@ class Scope: public ZoneObject {
Handle<ScopeInfo> GetScopeInfo(Isolate* isolate);
- // Get the chain of nested scopes within this scope for the source statement
- // position. The scopes will be added to the list from the outermost scope to
- // the innermost scope. Only nested block, catch or with scopes are tracked
- // and will be returned, but no inner function scopes.
- void GetNestedScopeChain(Isolate* isolate, List<Handle<ScopeInfo> >* chain,
- int statement_position);
-
- void CollectNonLocals(HashMap* non_locals);
+ Handle<StringSet> CollectNonLocals(Handle<StringSet> non_locals);
// ---------------------------------------------------------------------------
// Strict mode support.
@@ -646,15 +623,10 @@ class Scope: public ZoneObject {
// Map of function names to lists of functions defined in sloppy blocks
SloppyBlockFunctionMap sloppy_block_function_map_;
- // Illegal redeclaration.
- Expression* illegal_redecl_;
-
// Scope-specific information computed during parsing.
//
// This scope is inside a 'with' of some outer scope.
bool scope_inside_with_;
- // This scope contains a 'with' statement.
- bool scope_contains_with_;
// This scope or a nested catch scope or with scope contain an 'eval' call. At
// the 'eval' call site this scope is the declaration scope.
bool scope_calls_eval_;