Author: [EMAIL PROTECTED]
Date: Thu Sep 25 00:35:45 2008
New Revision: 370

Modified:
    branches/bleeding_edge/src/compiler.cc
    branches/bleeding_edge/src/compiler.h
    branches/bleeding_edge/src/debug-delay.js
    branches/bleeding_edge/src/runtime.cc
    branches/bleeding_edge/src/runtime.h
    branches/bleeding_edge/src/v8natives.js
    branches/bleeding_edge/test/mjsunit/function.js

Log:
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

Modified: branches/bleeding_edge/src/compiler.cc
==============================================================================
--- branches/bleeding_edge/src/compiler.cc      (original)
+++ branches/bleeding_edge/src/compiler.cc      Thu Sep 25 00:35:45 2008
@@ -202,8 +202,9 @@
  }


-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 @@
    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);

Modified: branches/bleeding_edge/src/compiler.h
==============================================================================
--- branches/bleeding_edge/src/compiler.h       (original)
+++ branches/bleeding_edge/src/compiler.h       Thu Sep 25 00:35:45 2008
@@ -57,7 +57,9 @@
                                      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

Modified: branches/bleeding_edge/src/debug-delay.js
==============================================================================
--- branches/bleeding_edge/src/debug-delay.js   (original)
+++ branches/bleeding_edge/src/debug-delay.js   Thu Sep 25 00:35:45 2008
@@ -1230,7 +1230,7 @@
  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 @@
    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.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;

Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc       (original)
+++ branches/bleeding_edge/src/runtime.cc       Thu Sep 25 00:35:45 2008
@@ -726,6 +726,17 @@
  }


+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_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 @@
    // 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 @@
        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 @@
    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,

Modified: branches/bleeding_edge/src/runtime.h
==============================================================================
--- branches/bleeding_edge/src/runtime.h        (original)
+++ branches/bleeding_edge/src/runtime.h        Thu Sep 25 00:35:45 2008
@@ -157,6 +157,7 @@
    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 @@
    F(NumberIsFinite, 1) \
    \
    /* Globals */ \
-  F(CompileString, 2) \
+  F(CompileString, 3) \
    F(CompileScript, 4) \
    F(GlobalPrint, 1) \
    \

Modified: branches/bleeding_edge/src/v8natives.js
==============================================================================
--- branches/bleeding_edge/src/v8natives.js     (original)
+++ branches/bleeding_edge/src/v8natives.js     Thu Sep 25 00:35:45 2008
@@ -201,7 +201,7 @@
  %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 @@
  %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 @@
      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);

Modified: branches/bleeding_edge/test/mjsunit/function.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/function.js     (original)
+++ branches/bleeding_edge/test/mjsunit/function.js     Thu Sep 25 00:35:45 2008
@@ -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')
+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 // 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));

-var f = Function('x', 'y', 'return x+y');
+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 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));


--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to