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

Simplify implementation of assignment-to-const checks.

Also, add test that assignment to function name is a syntax error with harmony scoping.

Does not fix issue 2243 directly, but with ES6, the required behaviour will change to what is implemented already anyway.

R=yangguo@chromium.org
BUG=v8:2243

Review URL: https://codereview.chromium.org/11607016

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13234 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 180a57a2
...@@ -2031,7 +2031,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, ...@@ -2031,7 +2031,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
void FullCodeGenerator::EmitAssignment(Expression* expr) { void FullCodeGenerator::EmitAssignment(Expression* expr) {
// Invalid left-hand sides are rewritten to have a 'throw // Invalid left-hand sides are rewritten by the parser to have a 'throw
// ReferenceError' on the left-hand side. // ReferenceError' on the left-hand side.
if (!expr->IsValidLeftHandSide()) { if (!expr->IsValidLeftHandSide()) {
VisitForEffect(expr); VisitForEffect(expr);
......
...@@ -1977,7 +1977,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, ...@@ -1977,7 +1977,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
void FullCodeGenerator::EmitAssignment(Expression* expr) { void FullCodeGenerator::EmitAssignment(Expression* expr) {
// Invalid left-hand sides are rewritten to have a 'throw // Invalid left-hand sides are rewritten by the parser to have a 'throw
// ReferenceError' on the left-hand side. // ReferenceError' on the left-hand side.
if (!expr->IsValidLeftHandSide()) { if (!expr->IsValidLeftHandSide()) {
VisitForEffect(expr); VisitForEffect(expr);
......
...@@ -2047,7 +2047,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, ...@@ -2047,7 +2047,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
void FullCodeGenerator::EmitAssignment(Expression* expr) { void FullCodeGenerator::EmitAssignment(Expression* expr) {
// Invalid left-hand sides are rewritten to have a 'throw // Invalid left-hand sides are rewritten by the parser to have a 'throw
// ReferenceError' on the left-hand side. // ReferenceError' on the left-hand side.
if (!expr->IsValidLeftHandSide()) { if (!expr->IsValidLeftHandSide()) {
VisitForEffect(expr); VisitForEffect(expr);
......
...@@ -3006,6 +3006,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { ...@@ -3006,6 +3006,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
// side expression. We could report this as a syntax error here but // side expression. We could report this as a syntax error here but
// for compatibility with JSC we choose to report the error at // for compatibility with JSC we choose to report the error at
// runtime. // runtime.
// TODO(ES5): Should change parsing for spec conformance.
if (expression == NULL || !expression->IsValidLeftHandSide()) { if (expression == NULL || !expression->IsValidLeftHandSide()) {
Handle<String> type = Handle<String> type =
isolate()->factory()->invalid_lhs_in_assignment_symbol(); isolate()->factory()->invalid_lhs_in_assignment_symbol();
......
...@@ -308,23 +308,6 @@ bool Scope::Analyze(CompilationInfo* info) { ...@@ -308,23 +308,6 @@ bool Scope::Analyze(CompilationInfo* info) {
} }
#endif #endif
if (FLAG_harmony_scoping) {
VariableProxy* proxy = scope->CheckAssignmentToConst();
if (proxy != NULL) {
// Found an assignment to const. Throw a syntax error.
MessageLocation location(info->script(),
proxy->position(),
proxy->position());
Isolate* isolate = info->isolate();
Factory* factory = isolate->factory();
Handle<JSArray> array = factory->NewJSArray(0);
Handle<Object> result =
factory->NewSyntaxError("harmony_const_assign", array);
isolate->Throw(*result, &location);
return false;
}
}
info->SetScope(scope); info->SetScope(scope);
return true; return true;
} }
...@@ -591,29 +574,6 @@ Declaration* Scope::CheckConflictingVarDeclarations() { ...@@ -591,29 +574,6 @@ Declaration* Scope::CheckConflictingVarDeclarations() {
} }
VariableProxy* Scope::CheckAssignmentToConst() {
// Check this scope.
if (is_extended_mode()) {
for (int i = 0; i < unresolved_.length(); i++) {
ASSERT(unresolved_[i]->var() != NULL);
if (unresolved_[i]->var()->is_const_mode() &&
unresolved_[i]->IsLValue()) {
return unresolved_[i];
}
}
}
// Check inner scopes.
for (int i = 0; i < inner_scopes_.length(); i++) {
VariableProxy* proxy = inner_scopes_[i]->CheckAssignmentToConst();
if (proxy != NULL) return proxy;
}
// No assignments to const found.
return NULL;
}
class VarAndOrder { class VarAndOrder {
public: public:
VarAndOrder(Variable* var, int order) : var_(var), order_(order) { } VarAndOrder(Variable* var, int order) : var_(var), order_(order) { }
...@@ -1102,6 +1062,20 @@ bool Scope::ResolveVariable(CompilationInfo* info, ...@@ -1102,6 +1062,20 @@ bool Scope::ResolveVariable(CompilationInfo* info,
ASSERT(var != NULL); ASSERT(var != NULL);
if (FLAG_harmony_scoping && is_extended_mode() &&
var->is_const_mode() && proxy->IsLValue()) {
// Assignment to const. Throw a syntax error.
MessageLocation location(
info->script(), proxy->position(), proxy->position());
Isolate* isolate = Isolate::Current();
Factory* factory = isolate->factory();
Handle<JSArray> array = factory->NewJSArray(0);
Handle<Object> result =
factory->NewSyntaxError("harmony_const_assign", array);
isolate->Throw(*result, &location);
return false;
}
if (FLAG_harmony_modules) { if (FLAG_harmony_modules) {
bool ok; bool ok;
#ifdef DEBUG #ifdef DEBUG
...@@ -1122,9 +1096,8 @@ bool Scope::ResolveVariable(CompilationInfo* info, ...@@ -1122,9 +1096,8 @@ bool Scope::ResolveVariable(CompilationInfo* info,
// Inconsistent use of module. Throw a syntax error. // Inconsistent use of module. Throw a syntax error.
// TODO(rossberg): generate more helpful error message. // TODO(rossberg): generate more helpful error message.
MessageLocation location(info->script(), MessageLocation location(
proxy->position(), info->script(), proxy->position(), proxy->position());
proxy->position());
Isolate* isolate = Isolate::Current(); Isolate* isolate = Isolate::Current();
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Handle<JSArray> array = factory->NewJSArray(1); Handle<JSArray> array = factory->NewJSArray(1);
......
...@@ -224,11 +224,6 @@ class Scope: public ZoneObject { ...@@ -224,11 +224,6 @@ class Scope: public ZoneObject {
// scope over a let binding of the same name. // scope over a let binding of the same name.
Declaration* CheckConflictingVarDeclarations(); Declaration* CheckConflictingVarDeclarations();
// For harmony block scoping mode: Check if the scope has variable proxies
// that are used as lvalues and point to const variables. Assumes that scopes
// have been analyzed and variables been resolved.
VariableProxy* CheckAssignmentToConst();
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Scope-specific info. // Scope-specific info.
......
...@@ -1965,7 +1965,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, ...@@ -1965,7 +1965,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
void FullCodeGenerator::EmitAssignment(Expression* expr) { void FullCodeGenerator::EmitAssignment(Expression* expr) {
// Invalid left-hand sides are rewritten to have a 'throw // Invalid left-hand sides are rewritten by the parser to have a 'throw
// ReferenceError' on the left-hand side. // ReferenceError' on the left-hand side.
if (!expr->IsValidLeftHandSide()) { if (!expr->IsValidLeftHandSide()) {
VisitForEffect(expr); VisitForEffect(expr);
......
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --harmony-scoping
assertThrows("'use strict'; (function f() { f = 123; })", SyntaxError);
assertThrows("(function f() { 'use strict'; f = 123; })", SyntaxError);
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