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
This commit is contained in:
rossberg@chromium.org 2012-12-18 12:00:50 +00:00
parent 180a57a272
commit c6bb497437
8 changed files with 52 additions and 52 deletions

View File

@ -2031,7 +2031,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* 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.
if (!expr->IsValidLeftHandSide()) {
VisitForEffect(expr);

View File

@ -1977,7 +1977,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* 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.
if (!expr->IsValidLeftHandSide()) {
VisitForEffect(expr);

View File

@ -2047,7 +2047,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* 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.
if (!expr->IsValidLeftHandSide()) {
VisitForEffect(expr);

View File

@ -3006,6 +3006,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
// side expression. We could report this as a syntax error here but
// for compatibility with JSC we choose to report the error at
// runtime.
// TODO(ES5): Should change parsing for spec conformance.
if (expression == NULL || !expression->IsValidLeftHandSide()) {
Handle<String> type =
isolate()->factory()->invalid_lhs_in_assignment_symbol();

View File

@ -308,23 +308,6 @@ bool Scope::Analyze(CompilationInfo* info) {
}
#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);
return true;
}
@ -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 {
public:
VarAndOrder(Variable* var, int order) : var_(var), order_(order) { }
@ -1102,6 +1062,20 @@ bool Scope::ResolveVariable(CompilationInfo* info,
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) {
bool ok;
#ifdef DEBUG
@ -1122,9 +1096,8 @@ bool Scope::ResolveVariable(CompilationInfo* info,
// Inconsistent use of module. Throw a syntax error.
// TODO(rossberg): generate more helpful error message.
MessageLocation location(info->script(),
proxy->position(),
proxy->position());
MessageLocation location(
info->script(), proxy->position(), proxy->position());
Isolate* isolate = Isolate::Current();
Factory* factory = isolate->factory();
Handle<JSArray> array = factory->NewJSArray(1);

View File

@ -224,11 +224,6 @@ class Scope: public ZoneObject {
// scope over a let binding of the same name.
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.

View File

@ -1965,7 +1965,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* 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.
if (!expr->IsValidLeftHandSide()) {
VisitForEffect(expr);

View File

@ -0,0 +1,31 @@
// 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);