Commit e9acdc7a authored by ager@chromium.org's avatar ager@chromium.org

Follow the spec in disallowing function declarations without a name. We

used to allow these for compatibility, but both Safari and Firefox now
disallow them.
Review URL: http://codereview.chromium.org/242124

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3009 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5ec767d0
...@@ -348,7 +348,7 @@ ScriptBreakPoint.prototype.set = function (script) { ...@@ -348,7 +348,7 @@ ScriptBreakPoint.prototype.set = function (script) {
if (!script.sourceColumnStart_) { if (!script.sourceColumnStart_) {
script.sourceColumnStart_ = new Array(script.lineCount()); script.sourceColumnStart_ = new Array(script.lineCount());
} }
// Fill cache if needed and get column where the actual source starts. // Fill cache if needed and get column where the actual source starts.
if (IS_UNDEFINED(script.sourceColumnStart_[line])) { if (IS_UNDEFINED(script.sourceColumnStart_[line])) {
script.sourceColumnStart_[line] = script.sourceColumnStart_[line] =
...@@ -359,11 +359,11 @@ ScriptBreakPoint.prototype.set = function (script) { ...@@ -359,11 +359,11 @@ ScriptBreakPoint.prototype.set = function (script) {
// Convert the line and column into an absolute position within the script. // Convert the line and column into an absolute position within the script.
var pos = Debug.findScriptSourcePosition(script, this.line(), column); var pos = Debug.findScriptSourcePosition(script, this.line(), column);
// If the position is not found in the script (the script might be shorter // If the position is not found in the script (the script might be shorter
// than it used to be) just ignore it. // than it used to be) just ignore it.
if (pos === null) return; if (pos === null) return;
// Create a break point object and set the break point. // Create a break point object and set the break point.
break_point = MakeBreakPoint(pos, this.line(), this.column(), this); break_point = MakeBreakPoint(pos, this.line(), this.column(), this);
break_point.setIgnoreCount(this.ignoreCount()); break_point.setIgnoreCount(this.ignoreCount());
...@@ -490,7 +490,7 @@ Debug.findFunctionSourceLocation = function(func, opt_line, opt_column) { ...@@ -490,7 +490,7 @@ Debug.findFunctionSourceLocation = function(func, opt_line, opt_column) {
// Returns the character position in a script based on a line number and an // Returns the character position in a script based on a line number and an
// optional position within that line. // optional position within that line.
Debug.findScriptSourcePosition = function(script, opt_line, opt_column) { Debug.findScriptSourcePosition = function(script, opt_line, opt_column) {
var location = script.locationFromLine(opt_line, opt_column); var location = script.locationFromLine(opt_line, opt_column);
return location ? location.position : null; return location ? location.position : null;
} }
...@@ -942,7 +942,7 @@ ExceptionEvent.prototype.toJSONProtocol = function() { ...@@ -942,7 +942,7 @@ ExceptionEvent.prototype.toJSONProtocol = function() {
o.body = { uncaught: this.uncaught_, o.body = { uncaught: this.uncaught_,
exception: MakeMirror(this.exception_) exception: MakeMirror(this.exception_)
}; };
// Exceptions might happen whithout any JavaScript frames. // Exceptions might happen whithout any JavaScript frames.
if (this.exec_state_.frameCount() > 0) { if (this.exec_state_.frameCount() > 0) {
o.body.sourceLine = this.sourceLine(); o.body.sourceLine = this.sourceLine();
...@@ -1095,7 +1095,7 @@ DebugCommandProcessor.prototype.processDebugRequest = function (request) { ...@@ -1095,7 +1095,7 @@ DebugCommandProcessor.prototype.processDebugRequest = function (request) {
function ProtocolMessage(request) { function ProtocolMessage(request) {
// Update sequence number. // Update sequence number.
this.seq = next_response_seq++; this.seq = next_response_seq++;
if (request) { if (request) {
// If message is based on a request this is a response. Fill the initial // If message is based on a request this is a response. Fill the initial
// response from the request. // response from the request.
...@@ -1485,7 +1485,7 @@ DebugCommandProcessor.prototype.clearBreakPointGroupRequest_ = function(request, ...@@ -1485,7 +1485,7 @@ DebugCommandProcessor.prototype.clearBreakPointGroupRequest_ = function(request,
response.failed('Missing argument "groupId"'); response.failed('Missing argument "groupId"');
return; return;
} }
var cleared_break_points = []; var cleared_break_points = [];
var new_script_break_points = []; var new_script_break_points = [];
for (var i = 0; i < script_break_points.length; i++) { for (var i = 0; i < script_break_points.length; i++) {
...@@ -1601,7 +1601,7 @@ DebugCommandProcessor.prototype.frameRequest_ = function(request, response) { ...@@ -1601,7 +1601,7 @@ DebugCommandProcessor.prototype.frameRequest_ = function(request, response) {
if (index < 0 || this.exec_state_.frameCount() <= index) { if (index < 0 || this.exec_state_.frameCount() <= index) {
return response.failed('Invalid frame number'); return response.failed('Invalid frame number');
} }
this.exec_state_.setSelectedFrame(request.arguments.number); this.exec_state_.setSelectedFrame(request.arguments.number);
} }
response.body = this.exec_state_.frame(); response.body = this.exec_state_.frame();
...@@ -1631,7 +1631,7 @@ DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) { ...@@ -1631,7 +1631,7 @@ DebugCommandProcessor.prototype.scopesRequest_ = function(request, response) {
// Get the frame for which the scopes are requested. // Get the frame for which the scopes are requested.
var frame = this.frameForScopeRequest_(request); var frame = this.frameForScopeRequest_(request);
// Fill all scopes for this frame. // Fill all scopes for this frame.
var total_scopes = frame.scopeCount(); var total_scopes = frame.scopeCount();
var scopes = []; var scopes = [];
...@@ -1748,7 +1748,7 @@ DebugCommandProcessor.prototype.lookupRequest_ = function(request, response) { ...@@ -1748,7 +1748,7 @@ DebugCommandProcessor.prototype.lookupRequest_ = function(request, response) {
includeSource = %ToBoolean(request.arguments.includeSource); includeSource = %ToBoolean(request.arguments.includeSource);
response.setOption('includeSource', includeSource); response.setOption('includeSource', includeSource);
} }
// Lookup handles. // Lookup handles.
var mirrors = {}; var mirrors = {};
for (var i = 0; i < handles.length; i++) { for (var i = 0; i < handles.length; i++) {
......
...@@ -1924,31 +1924,20 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { ...@@ -1924,31 +1924,20 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
Statement* Parser::ParseFunctionDeclaration(bool* ok) { Statement* Parser::ParseFunctionDeclaration(bool* ok) {
// Parse a function literal. We may or may not have a function name. // FunctionDeclaration ::
// If we have a name we use it as the variable name for the function // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
// (a function declaration) and not as the function name of a function
// expression.
Expect(Token::FUNCTION, CHECK_OK); Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos; int function_token_position = scanner().location().beg_pos;
Handle<String> name = ParseIdentifier(CHECK_OK);
Handle<String> name; FunctionLiteral* fun = ParseFunctionLiteral(name,
if (peek() == Token::IDENTIFIER) name = ParseIdentifier(CHECK_OK); function_token_position,
FunctionLiteral* fun = ParseFunctionLiteral(name, function_token_position, DECLARATION,
DECLARATION, CHECK_OK); CHECK_OK);
// Even if we're not at the top-level of the global or a function
if (name.is_null()) { // scope, we treat is as such and introduce the function with it's
// We don't have a name - it is always an anonymous function // initial value upon entering the corresponding scope.
// expression. Declare(name, Variable::VAR, fun, true, CHECK_OK);
return NEW(ExpressionStatement(fun)); return factory()->EmptyStatement();
} else {
// We have a name so even if we're not at the top-level of the
// global or a function scope, we treat is as such and introduce
// the function with it's initial value upon entering the
// corresponding scope.
Declare(name, Variable::VAR, fun, true, CHECK_OK);
return factory()->EmptyStatement();
}
} }
......
...@@ -7148,7 +7148,7 @@ static Object* Runtime_DebugEvaluate(Arguments args) { ...@@ -7148,7 +7148,7 @@ static Object* Runtime_DebugEvaluate(Arguments args) {
// the function being debugged. // the function being debugged.
// function(arguments,__source__) {return eval(__source__);} // function(arguments,__source__) {return eval(__source__);}
static const char* source_str = static const char* source_str =
"function(arguments,__source__){return eval(__source__);}"; "(function(arguments,__source__){return eval(__source__);})";
static const int source_str_length = strlen(source_str); static const int source_str_length = strlen(source_str);
Handle<String> function_source = Handle<String> function_source =
Factory::NewStringFromAscii(Vector<const char>(source_str, Factory::NewStringFromAscii(Vector<const char>(source_str,
......
...@@ -4096,11 +4096,11 @@ v8::Handle<v8::Function> debugger_call_with_data; ...@@ -4096,11 +4096,11 @@ v8::Handle<v8::Function> debugger_call_with_data;
// passed it throws an exception. // passed it throws an exception.
static const char* debugger_call_with_closure_source = static const char* debugger_call_with_closure_source =
"var x = 3;" "var x = 3;"
"function (exec_state) {" "(function (exec_state) {"
" if (exec_state.y) return x - 1;" " if (exec_state.y) return x - 1;"
" exec_state.y = x;" " exec_state.y = x;"
" return exec_state.y" " return exec_state.y"
"}"; "})";
v8::Handle<v8::Function> debugger_call_with_closure; v8::Handle<v8::Function> debugger_call_with_closure;
// Function to retrieve the number of JavaScript frames by calling a JavaScript // Function to retrieve the number of JavaScript frames by calling a JavaScript
......
...@@ -35,7 +35,7 @@ var funs = { ...@@ -35,7 +35,7 @@ var funs = {
Boolean: [ Boolean ], Boolean: [ Boolean ],
Number: [ Number ], Number: [ Number ],
Date: [ Date ], Date: [ Date ],
RegExp: [ RegExp ], RegExp: [ RegExp ],
Error: [ Error, TypeError, RangeError, SyntaxError, ReferenceError, EvalError, URIError ] Error: [ Error, TypeError, RangeError, SyntaxError, ReferenceError, EvalError, URIError ]
} }
for (f in funs) { for (f in funs) {
......
...@@ -102,10 +102,10 @@ Debug.setListener(listener); ...@@ -102,10 +102,10 @@ Debug.setListener(listener);
// Compile different sources. // Compile different sources.
compileSource('a=1'); compileSource('a=1');
compileSource('function(){}'); compileSource('(function(){})');
compileSource('eval("a=2")'); compileSource('eval("a=2")');
source_count++; // Using eval causes additional compilation event. source_count++; // Using eval causes additional compilation event.
compileSource('eval("eval(\'function(){return a;}\')")'); compileSource('eval("eval(\'(function(){return a;})\')")');
source_count += 2; // Using eval causes additional compilation event. source_count += 2; // Using eval causes additional compilation event.
compileSource('JSON.parse("{a:1,b:2}")'); compileSource('JSON.parse("{a:1,b:2}")');
source_count++; // Using JSON.parse causes additional compilation event. source_count++; // Using JSON.parse causes additional compilation event.
......
// Copyright 2009 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.
// A function expression with no parenthesis around it is not a valid
// expression statement.
assertThrows("eval('function() {}')");
...@@ -85,16 +85,16 @@ function testScriptMirror(f, file_name, file_lines, type, compilation_type, ...@@ -85,16 +85,16 @@ function testScriptMirror(f, file_name, file_lines, type, compilation_type,
// Test the script mirror for different functions. // Test the script mirror for different functions.
testScriptMirror(function(){}, 'mirror-script.js', 100, 2, 0); testScriptMirror(function(){}, 'mirror-script.js', 100, 2, 0);
testScriptMirror(Math.sin, 'native math.js', -1, 0, 0); testScriptMirror(Math.sin, 'native math.js', -1, 0, 0);
testScriptMirror(eval('function(){}'), null, 1, 2, 1, 'function(){}', 87); testScriptMirror(eval('(function(){})'), null, 1, 2, 1, '(function(){})', 87);
testScriptMirror(eval('function(){\n }'), null, 2, 2, 1, 'function(){\n }', 88); testScriptMirror(eval('(function(){\n })'), null, 2, 2, 1, '(function(){\n })', 88);
testScriptMirror(%CompileString("({a:1,b:2})", true), null, 1, 2, 2, '({a:1,b:2})'); testScriptMirror(%CompileString("({a:1,b:2})", true), null, 1, 2, 2, '({a:1,b:2})');
testScriptMirror(%CompileString("({a:1,\n b:2})", true), null, 2, 2, 2, '({a:1,\n b:2})'); testScriptMirror(%CompileString("({a:1,\n b:2})", true), null, 2, 2, 2, '({a:1,\n b:2})');
// Test taking slices of source. // Test taking slices of source.
var mirror = debug.MakeMirror(eval('function(){\n 1;\n}')).script(); var mirror = debug.MakeMirror(eval('(function(){\n 1;\n})')).script();
assertEquals('function(){\n', mirror.sourceSlice(0, 1).sourceText()); assertEquals('(function(){\n', mirror.sourceSlice(0, 1).sourceText());
assertEquals(' 1;\n', mirror.sourceSlice(1, 2).sourceText()); assertEquals(' 1;\n', mirror.sourceSlice(1, 2).sourceText());
assertEquals('}', mirror.sourceSlice(2, 3).sourceText()); assertEquals('})', mirror.sourceSlice(2, 3).sourceText());
assertEquals('function(){\n 1;\n', mirror.sourceSlice(0, 2).sourceText()); assertEquals('(function(){\n 1;\n', mirror.sourceSlice(0, 2).sourceText());
assertEquals(' 1;\n}', mirror.sourceSlice(1, 3).sourceText()); assertEquals(' 1;\n})', mirror.sourceSlice(1, 3).sourceText());
assertEquals('function(){\n 1;\n}', mirror.sourceSlice(0, 3).sourceText()); assertEquals('(function(){\n 1;\n})', mirror.sourceSlice(0, 3).sourceText());
...@@ -28,4 +28,4 @@ ...@@ -28,4 +28,4 @@
function foo(f) { eval(f); } function foo(f) { eval(f); }
// Ensure that compiling a declaration of a function does not crash. // Ensure that compiling a declaration of a function does not crash.
foo("function (x) { with ({x: []}) function x(){} }"); foo("(function (x) { with ({x: []}) function x(){} })");
...@@ -269,7 +269,7 @@ assertEquals("A", f7((170/16)-(170%16/16)), "0-1-switch.heapnum"); ...@@ -269,7 +269,7 @@ assertEquals("A", f7((170/16)-(170%16/16)), "0-1-switch.heapnum");
function makeVeryLong(length) { function makeVeryLong(length) {
var res = "function() {\n" + var res = "(function () {\n" +
" var res = 0;\n" + " var res = 0;\n" +
" for (var i = 0; i <= " + length + "; i++) {\n" + " for (var i = 0; i <= " + length + "; i++) {\n" +
" switch(i) {\n"; " switch(i) {\n";
...@@ -280,7 +280,7 @@ function makeVeryLong(length) { ...@@ -280,7 +280,7 @@ function makeVeryLong(length) {
" }\n" + " }\n" +
" }\n" + " }\n" +
" return res;\n" + " return res;\n" +
"}"; "})";
return eval(res); return eval(res);
} }
var verylong_size = 1000; var verylong_size = 1000;
......
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