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:
parent
180a57a272
commit
c6bb497437
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
31
test/mjsunit/regress/regress-2243.js
Normal file
31
test/mjsunit/regress/regress-2243.js
Normal 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);
|
Loading…
Reference in New Issue
Block a user