Make sure that the body of the function created by calling Function is
on a line of its own. This allows the body to be terminated by a single-line comment. Also, make sure to set the name of the function to anonymous after the fact so that recursion through the name anonymous is not allowed and so that global variables called anonymous are not shadowed. This is a fix for http://code.google.com/p/v8/issues/detail?id=85 Review URL: http://codereview.chromium.org/4248 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@370 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
222c7cd957
commit
ff4e9ea134
@ -202,8 +202,9 @@ Handle<JSFunction> Compiler::Compile(Handle<String> source,
|
||||
}
|
||||
|
||||
|
||||
Handle<JSFunction> Compiler::CompileEval(bool is_global,
|
||||
Handle<String> source) {
|
||||
Handle<JSFunction> Compiler::CompileEval(Handle<String> source,
|
||||
int line_offset,
|
||||
bool is_global) {
|
||||
Counters::total_eval_size.Increment(source->length());
|
||||
Counters::total_compile_size.Increment(source->length());
|
||||
|
||||
@ -219,6 +220,7 @@ Handle<JSFunction> Compiler::CompileEval(bool is_global,
|
||||
if (result.is_null()) {
|
||||
// Create a script object describing the script to be compiled.
|
||||
Handle<Script> script = Factory::NewScript(source);
|
||||
script->set_line_offset(Smi::FromInt(line_offset));
|
||||
result = MakeFunction(is_global, true, script, NULL, NULL);
|
||||
if (!result.is_null()) {
|
||||
CompilationCache::Associate(source, entry, result);
|
||||
|
@ -57,7 +57,9 @@ class Compiler : public AllStatic {
|
||||
ScriptDataImpl* script_Data);
|
||||
|
||||
// Compile a String source within a context for Eval.
|
||||
static Handle<JSFunction> CompileEval(bool is_global, Handle<String> source);
|
||||
static Handle<JSFunction> CompileEval(Handle<String> source,
|
||||
int line_offset,
|
||||
bool is_global);
|
||||
|
||||
// Compile from function info (used for lazy compilation). Returns
|
||||
// true on success and false if the compilation resulted in a stack
|
||||
|
@ -1230,7 +1230,7 @@ DebugCommandProcessor.prototype.scriptsCommandToJSONRequest_ = function(args) {
|
||||
DebugCommandProcessor.prototype.responseToText = function(json_response) {
|
||||
try {
|
||||
// Convert the JSON string to an object.
|
||||
response = %CompileString('(' + json_response + ')', false)();
|
||||
response = %CompileString('(' + json_response + ')', 0, false)();
|
||||
|
||||
if (!response.success) {
|
||||
return response.message;
|
||||
@ -1436,7 +1436,7 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(json_request,
|
||||
try {
|
||||
try {
|
||||
// Convert the JSON string to an object.
|
||||
request = %CompileString('(' + json_request + ')', false)();
|
||||
request = %CompileString('(' + json_request + ')', 0, false)();
|
||||
|
||||
// Create an initial response.
|
||||
response = this.createResponse(request);
|
||||
@ -1889,7 +1889,7 @@ DebugCommandProcessor.prototype.scriptsRequest_ = function(request, response) {
|
||||
DebugCommandProcessor.prototype.isRunning = function(json_response) {
|
||||
try {
|
||||
// Convert the JSON string to an object.
|
||||
response = %CompileString('(' + json_response + ')', false)();
|
||||
response = %CompileString('(' + json_response + ')', 0, false)();
|
||||
|
||||
// Return whether VM should be running after this request.
|
||||
return response.running;
|
||||
|
@ -726,6 +726,17 @@ static Object* Runtime_FunctionGetName(Arguments args) {
|
||||
}
|
||||
|
||||
|
||||
static Object* Runtime_FunctionSetName(Arguments args) {
|
||||
NoHandleAllocation ha;
|
||||
ASSERT(args.length() == 2);
|
||||
|
||||
CONVERT_CHECKED(JSFunction, f, args[0]);
|
||||
CONVERT_CHECKED(String, name, args[1]);
|
||||
f->shared()->set_name(name);
|
||||
return Heap::undefined_value();
|
||||
}
|
||||
|
||||
|
||||
static Object* Runtime_FunctionGetScript(Arguments args) {
|
||||
HandleScope scope;
|
||||
ASSERT(args.length() == 1);
|
||||
@ -3361,10 +3372,11 @@ static Object* Runtime_EvalReceiver(Arguments args) {
|
||||
|
||||
static Object* Runtime_CompileString(Arguments args) {
|
||||
HandleScope scope;
|
||||
ASSERT(args.length() == 2);
|
||||
ASSERT(args.length() == 3);
|
||||
CONVERT_ARG_CHECKED(String, source, 0);
|
||||
bool contextual = args[1]->IsTrue();
|
||||
RUNTIME_ASSERT(contextual || args[1]->IsFalse());
|
||||
CONVERT_ARG_CHECKED(Smi, line_offset, 1);
|
||||
bool contextual = args[2]->IsTrue();
|
||||
RUNTIME_ASSERT(contextual || args[2]->IsFalse());
|
||||
|
||||
// Compute the eval context.
|
||||
Handle<Context> context;
|
||||
@ -3383,7 +3395,7 @@ static Object* Runtime_CompileString(Arguments args) {
|
||||
// Compile source string.
|
||||
bool is_global = context->IsGlobalContext();
|
||||
Handle<JSFunction> boilerplate =
|
||||
Compiler::CompileEval(is_global, source);
|
||||
Compiler::CompileEval(source, line_offset->value(), is_global);
|
||||
if (boilerplate.is_null()) return Failure::Exception();
|
||||
Handle<JSFunction> fun =
|
||||
Factory::NewFunctionFromBoilerplate(boilerplate, context);
|
||||
@ -4502,7 +4514,7 @@ static Object* Runtime_DebugEvaluate(Arguments args) {
|
||||
Factory::NewStringFromAscii(Vector<const char>(source_str,
|
||||
source_str_length));
|
||||
Handle<JSFunction> boilerplate =
|
||||
Compiler::CompileEval(context->IsGlobalContext(), function_source);
|
||||
Compiler::CompileEval(function_source, 0, context->IsGlobalContext());
|
||||
if (boilerplate.is_null()) return Failure::Exception();
|
||||
Handle<JSFunction> compiled_function =
|
||||
Factory::NewFunctionFromBoilerplate(boilerplate, context);
|
||||
@ -4558,7 +4570,7 @@ static Object* Runtime_DebugEvaluateGlobal(Arguments args) {
|
||||
Handle<Context> context = Top::global_context();
|
||||
|
||||
// Compile the source to be evaluated.
|
||||
Handle<JSFunction> boilerplate(Compiler::CompileEval(true, source));
|
||||
Handle<JSFunction> boilerplate(Compiler::CompileEval(source, 0, true));
|
||||
if (boilerplate.is_null()) return Failure::Exception();
|
||||
Handle<JSFunction> compiled_function =
|
||||
Handle<JSFunction>(Factory::NewFunctionFromBoilerplate(boilerplate,
|
||||
|
@ -157,6 +157,7 @@ namespace v8 { namespace internal {
|
||||
F(FunctionSetLength, 2) \
|
||||
F(FunctionSetPrototype, 2) \
|
||||
F(FunctionGetName, 1) \
|
||||
F(FunctionSetName, 2) \
|
||||
F(FunctionGetSourceCode, 1) \
|
||||
F(FunctionGetScript, 1) \
|
||||
F(FunctionGetScriptSourcePosition, 1) \
|
||||
@ -180,7 +181,7 @@ namespace v8 { namespace internal {
|
||||
F(NumberIsFinite, 1) \
|
||||
\
|
||||
/* Globals */ \
|
||||
F(CompileString, 2) \
|
||||
F(CompileString, 3) \
|
||||
F(CompileScript, 4) \
|
||||
F(GlobalPrint, 1) \
|
||||
\
|
||||
|
@ -201,7 +201,7 @@ $Object.prototype.constructor = $Object;
|
||||
%AddProperty(global, "eval", function(x) {
|
||||
if (!IS_STRING(x)) return x;
|
||||
|
||||
var f = %CompileString(x, true);
|
||||
var f = %CompileString(x, 0, true);
|
||||
if (!IS_FUNCTION(f)) return f;
|
||||
|
||||
return f.call(%EvalReceiver(this));
|
||||
@ -212,7 +212,7 @@ $Object.prototype.constructor = $Object;
|
||||
%AddProperty(global, "execScript", function(expr, lang) {
|
||||
// NOTE: We don't care about the character casing.
|
||||
if (!lang || /javascript/i.test(lang)) {
|
||||
var f = %CompileString(ToString(expr), false);
|
||||
var f = %CompileString(ToString(expr), 0, false);
|
||||
f.call(global);
|
||||
}
|
||||
return null;
|
||||
@ -406,11 +406,13 @@ function NewFunction(arg1) { // length == 1
|
||||
if (p.indexOf(')') != -1) throw MakeSyntaxError('unable_to_parse',[]);
|
||||
}
|
||||
var body = (n > 0) ? ToString(%_Arguments(n - 1)) : '';
|
||||
var source = '(function anonymous(' + p + ') { ' + body + ' })';
|
||||
var source = '(function(' + p + ') {\n' + body + '\n})';
|
||||
|
||||
// The call to SetNewFunctionAttributes will ensure the prototype
|
||||
// property of the resulting function is enumerable (ECMA262, 15.3.5.2).
|
||||
return %SetNewFunctionAttributes(%CompileString(source, false)());
|
||||
var f = %CompileString(source, -1, false)();
|
||||
%FunctionSetName(f, "anonymous");
|
||||
return %SetNewFunctionAttributes(f);
|
||||
};
|
||||
|
||||
%SetCode($Function, NewFunction);
|
||||
|
@ -27,36 +27,47 @@
|
||||
|
||||
var f = Function();
|
||||
assertTrue(typeof f() == 'undefined');
|
||||
var f = new Function();
|
||||
f = new Function();
|
||||
assertTrue(typeof f() == 'undefined');
|
||||
|
||||
var f = Function('return 1');
|
||||
f = Function('return 1');
|
||||
assertEquals(1, f());
|
||||
var f = new Function('return 1');
|
||||
f = new Function('return 1');
|
||||
assertEquals(1, f());
|
||||
|
||||
var f = Function('return true');
|
||||
f = Function('return true');
|
||||
assertTrue(f());
|
||||
var f = new Function('return true');
|
||||
f = new Function('return true');
|
||||
assertTrue(f());
|
||||
|
||||
var f = Function('x', 'return x')
|
||||
assertEquals(1, f(1));
|
||||
assertEquals('bar', f('bar'));
|
||||
assertTrue(typeof f() == 'undefined');
|
||||
var x = {};
|
||||
assertTrue(x === f(x));
|
||||
var f = new Function('x', 'return x')
|
||||
f = Function('x', 'return x');
|
||||
assertEquals(1, f(1));
|
||||
assertEquals('bar', f('bar'));
|
||||
assertTrue(typeof f() == 'undefined');
|
||||
var x = {};
|
||||
assertTrue(x === f(x));
|
||||
|
||||
var f = Function('x', 'y', 'return x+y');
|
||||
f = Function('x', 'return x // comment');
|
||||
assertEquals(1, f(1));
|
||||
|
||||
f = Function('return typeof anonymous');
|
||||
assertEquals('undefined', f());
|
||||
|
||||
var anonymous = 42;
|
||||
f = Function('return anonymous;');
|
||||
assertEquals(42, f());
|
||||
|
||||
f = new Function('x', 'return x')
|
||||
assertEquals(1, f(1));
|
||||
assertEquals('bar', f('bar'));
|
||||
assertTrue(typeof f() == 'undefined');
|
||||
var x = {};
|
||||
assertTrue(x === f(x));
|
||||
|
||||
f = Function('x', 'y', 'return x+y');
|
||||
assertEquals(5, f(2, 3));
|
||||
assertEquals('foobar', f('foo', 'bar'));
|
||||
var f = new Function('x', 'y', 'return x+y');
|
||||
f = new Function('x', 'y', 'return x+y');
|
||||
assertEquals(5, f(2, 3));
|
||||
assertEquals('foobar', f('foo', 'bar'));
|
||||
|
||||
@ -66,7 +77,7 @@ var z = {}; z.toString = function() { return 'return x*y'; }
|
||||
var f = Function(x, y, z);
|
||||
assertEquals(25, f(5, 5));
|
||||
assertEquals(42, f(2, 21));
|
||||
var f = new Function(x, y, z);
|
||||
f = new Function(x, y, z);
|
||||
assertEquals(25, f(5, 5));
|
||||
assertEquals(42, f(2, 21));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user