Merge revisions r3393 - r3394 to trunk

This is on order to try out the changes related to http://crbug.com/23058 on
chromium trunk separate from other changes.

BUG=http://crbug.com/23058, http://code.google.com/p/v8/issues/detail?id=528
TEST=cctest/test-api/Regress528
Review URL: http://codereview.chromium.org/460013

git-svn-id: http://v8.googlecode.com/svn/trunk@3395 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/accessors.cc b/src/accessors.cc
index 09a3886..56cf135 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -349,29 +349,38 @@
 
 
 //
-// Accessors::ScriptGetEvalFromFunction
+// Accessors::ScriptGetEvalFromScript
 //
 
 
-Object* Accessors::ScriptGetEvalFromFunction(Object* object, void*) {
+Object* Accessors::ScriptGetEvalFromScript(Object* object, void*) {
   Object* script = JSValue::cast(object)->value();
-  return Script::cast(script)->eval_from_function();
+  if (!Script::cast(script)->eval_from_shared()->IsUndefined()) {
+    Handle<SharedFunctionInfo> eval_from_shared(
+        SharedFunctionInfo::cast(Script::cast(script)->eval_from_shared()));
+
+    if (eval_from_shared->script()->IsScript()) {
+      Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
+      return *GetScriptWrapper(eval_from_script);
+    }
+  }
+  return Heap::undefined_value();
 }
 
 
-const AccessorDescriptor Accessors::ScriptEvalFromFunction = {
-  ScriptGetEvalFromFunction,
+const AccessorDescriptor Accessors::ScriptEvalFromScript = {
+  ScriptGetEvalFromScript,
   IllegalSetter,
   0
 };
 
 
 //
-// Accessors::ScriptGetEvalFromPosition
+// Accessors::ScriptGetEvalFromScriptPosition
 //
 
 
-Object* Accessors::ScriptGetEvalFromPosition(Object* object, void*) {
+Object* Accessors::ScriptGetEvalFromScriptPosition(Object* object, void*) {
   HandleScope scope;
   Handle<Script> script(Script::cast(JSValue::cast(object)->value()));
 
@@ -383,14 +392,42 @@
 
   // Get the function from where eval was called and find the source position
   // from the instruction offset.
-  Handle<Code> code(JSFunction::cast(script->eval_from_function())->code());
+  Handle<Code> code(SharedFunctionInfo::cast(
+      script->eval_from_shared())->code());
   return Smi::FromInt(code->SourcePosition(code->instruction_start() +
                       script->eval_from_instructions_offset()->value()));
 }
 
 
-const AccessorDescriptor Accessors::ScriptEvalFromPosition = {
-  ScriptGetEvalFromPosition,
+const AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
+  ScriptGetEvalFromScriptPosition,
+  IllegalSetter,
+  0
+};
+
+
+//
+// Accessors::ScriptGetEvalFromFunctionName
+//
+
+
+Object* Accessors::ScriptGetEvalFromFunctionName(Object* object, void*) {
+  Object* script = JSValue::cast(object)->value();
+  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(
+      Script::cast(script)->eval_from_shared()));
+
+
+  // Find the name of the function calling eval.
+  if (!shared->name()->IsUndefined()) {
+    return shared->name();
+  } else {
+    return shared->inferred_name();
+  }
+}
+
+
+const AccessorDescriptor Accessors::ScriptEvalFromFunctionName = {
+  ScriptGetEvalFromFunctionName,
   IllegalSetter,
   0
 };
diff --git a/src/accessors.h b/src/accessors.h
index 51d322e..7a840a1 100644
--- a/src/accessors.h
+++ b/src/accessors.h
@@ -51,8 +51,9 @@
   V(ScriptCompilationType)          \
   V(ScriptLineEnds)                 \
   V(ScriptContextData)              \
-  V(ScriptEvalFromFunction)         \
-  V(ScriptEvalFromPosition)         \
+  V(ScriptEvalFromScript)           \
+  V(ScriptEvalFromScriptPosition)   \
+  V(ScriptEvalFromFunctionName)     \
   V(ObjectPrototype)
 
 // Accessors contains all predefined proxy accessors.
@@ -95,8 +96,9 @@
   static Object* ScriptGetCompilationType(Object* object, void*);
   static Object* ScriptGetLineEnds(Object* object, void*);
   static Object* ScriptGetContextData(Object* object, void*);
-  static Object* ScriptGetEvalFromFunction(Object* object, void*);
-  static Object* ScriptGetEvalFromPosition(Object* object, void*);
+  static Object* ScriptGetEvalFromScript(Object* object, void*);
+  static Object* ScriptGetEvalFromScriptPosition(Object* object, void*);
+  static Object* ScriptGetEvalFromFunctionName(Object* object, void*);
   static Object* ObjectGetPrototype(Object* receiver, void*);
   static Object* ObjectSetPrototype(JSObject* receiver, Object* value, void*);
 
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 4491962..6918464 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1111,21 +1111,29 @@
             Factory::LookupAsciiSymbol("context_data"),
             proxy_context_data,
             common_attributes);
-    Handle<Proxy> proxy_eval_from_function =
-        Factory::NewProxy(&Accessors::ScriptEvalFromFunction);
+    Handle<Proxy> proxy_eval_from_script =
+        Factory::NewProxy(&Accessors::ScriptEvalFromScript);
     script_descriptors =
         Factory::CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("eval_from_function"),
-            proxy_eval_from_function,
+            Factory::LookupAsciiSymbol("eval_from_script"),
+            proxy_eval_from_script,
             common_attributes);
-    Handle<Proxy> proxy_eval_from_position =
-        Factory::NewProxy(&Accessors::ScriptEvalFromPosition);
+    Handle<Proxy> proxy_eval_from_script_position =
+        Factory::NewProxy(&Accessors::ScriptEvalFromScriptPosition);
     script_descriptors =
         Factory::CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("eval_from_position"),
-            proxy_eval_from_position,
+            Factory::LookupAsciiSymbol("eval_from_script_position"),
+            proxy_eval_from_script_position,
+            common_attributes);
+    Handle<Proxy> proxy_eval_from_function_name =
+        Factory::NewProxy(&Accessors::ScriptEvalFromFunctionName);
+    script_descriptors =
+        Factory::CopyAppendProxyDescriptor(
+            script_descriptors,
+            Factory::LookupAsciiSymbol("eval_from_function_name"),
+            proxy_eval_from_function_name,
             common_attributes);
 
     Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
diff --git a/src/compiler.cc b/src/compiler.cc
index 4e80a24..d3c031c 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -176,7 +176,8 @@
     // called.
     if (is_eval) {
       JavaScriptFrameIterator it;
-      script->set_eval_from_function(it.frame()->function());
+      script->set_eval_from_shared(
+          JSFunction::cast(it.frame()->function())->shared());
       int offset = static_cast<int>(
           it.frame()->pc() - it.frame()->code()->instruction_start());
       script->set_eval_from_instructions_offset(Smi::FromInt(offset));
diff --git a/src/factory.cc b/src/factory.cc
index c63e005..83775ef 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -189,7 +189,7 @@
   script->set_compilation_type(Smi::FromInt(Script::COMPILATION_TYPE_HOST));
   script->set_wrapper(*wrapper);
   script->set_line_ends(Heap::undefined_value());
-  script->set_eval_from_function(Heap::undefined_value());
+  script->set_eval_from_shared(Heap::undefined_value());
   script->set_eval_from_instructions_offset(Smi::FromInt(0));
 
   return script;
diff --git a/src/messages.js b/src/messages.js
index b0004b1..1e5053d 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -629,10 +629,7 @@
 
 CallSite.prototype.getEvalOrigin = function () {
   var script = %FunctionGetScript(this.fun);
-  if (!script || script.compilation_type != 1)
-    return null;
-  return new CallSite(null, script.eval_from_function,
-      script.eval_from_position);
+  return FormatEvalOrigin(script);
 };
 
 CallSite.prototype.getFunction = function () {
@@ -700,7 +697,7 @@
   if (script) {
     location = script.locationFromPosition(this.pos, true);
   }
-  return location ? location.column : null;
+  return location ? location.column + 1: null;
 };
 
 CallSite.prototype.isNative = function () {
@@ -719,12 +716,44 @@
   return this.fun === constructor;
 };
 
+function FormatEvalOrigin(script) {
+  var eval_origin = "";
+  if (script.eval_from_function_name) {
+    eval_origin += script.eval_from_function_name;
+  } else {
+    eval_origin +=  "<anonymous>";
+  }
+  
+  var eval_from_script = script.eval_from_script;
+  if (eval_from_script) {
+    if (eval_from_script.compilation_type == 1) {
+      // eval script originated from another eval.
+      eval_origin += " (eval at " + FormatEvalOrigin(eval_from_script) + ")";
+    } else {
+      // eval script originated from "real" scource.
+      if (eval_from_script.name) {
+        eval_origin += " (" + eval_from_script.name;
+        var location = eval_from_script.locationFromPosition(script.eval_from_script_position, true);
+        if (location) {
+          eval_origin += ":" + (location.line + 1);
+          eval_origin += ":" + (location.column + 1);
+        }
+        eval_origin += ")"
+      } else {
+        eval_origin += " (unknown source)";
+      }
+    }
+  }
+  
+  return eval_origin;
+};
+
 function FormatSourcePosition(frame) {
   var fileLocation = "";
   if (frame.isNative()) {
     fileLocation = "native";
   } else if (frame.isEval()) {
-    fileLocation = "eval at " + FormatSourcePosition(frame.getEvalOrigin());
+    fileLocation = "eval at " + frame.getEvalOrigin();
   } else {
     var fileName = frame.getFileName();
     if (fileName) {
diff --git a/src/mirror-delay.js b/src/mirror-delay.js
index 82fb9c2..ba663b2 100644
--- a/src/mirror-delay.js
+++ b/src/mirror-delay.js
@@ -1793,16 +1793,21 @@
 };
 
 
-ScriptMirror.prototype.evalFromFunction = function() {
-  return MakeMirror(this.script_.eval_from_function);
+ScriptMirror.prototype.evalFromScript = function() {
+  return MakeMirror(this.script_.eval_from_script);
+};
+
+
+ScriptMirror.prototype.evalFromFunctionName = function() {
+  return MakeMirror(this.script_.eval_from_function_name);
 };
 
 
 ScriptMirror.prototype.evalFromLocation = function() {
-  var eval_from_function = this.evalFromFunction();
-  if (!eval_from_function.isUndefined()) {
-    var position = this.script_.eval_from_position;
-    return eval_from_function.script().locationFromPosition(position, true);
+  var eval_from_script = this.evalFromScript();
+  if (!eval_from_script.isUndefined()) {
+    var position = this.script_.eval_from_script_position;
+    return eval_from_script.locationFromPosition(position, true);
   }
 };
 
@@ -2080,12 +2085,15 @@
       // For compilation type eval emit information on the script from which
       // eval was called if a script is present.
       if (mirror.compilationType() == 1 &&
-          mirror.evalFromFunction().script()) {
+          mirror.evalFromScript()) {
         content.evalFromScript =
-            this.serializeReference(mirror.evalFromFunction().script());
+            this.serializeReference(mirror.evalFromScript());
         var evalFromLocation = mirror.evalFromLocation()
         content.evalFromLocation = { line: evalFromLocation.line,
                                      column: evalFromLocation.column}
+        if (mirror.evalFromFunctionName()) {
+          content.evalFromFunctionName = mirror.evalFromFunctionName();
+        }
       }
       if (mirror.context()) {
         content.context = this.serializeReference(mirror.context());
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 52c1613..a259ca9 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -1169,8 +1169,8 @@
   compilation_type()->ShortPrint();
   PrintF("\n - line ends: ");
   line_ends()->ShortPrint();
-  PrintF("\n - eval from function: ");
-  eval_from_function()->ShortPrint();
+  PrintF("\n - eval from shared: ");
+  eval_from_shared()->ShortPrint();
   PrintF("\n - eval from instructions offset: ");
   eval_from_instructions_offset()->ShortPrint();
   PrintF("\n");
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 069a675..6919620 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2442,7 +2442,7 @@
 ACCESSORS(Script, type, Smi, kTypeOffset)
 ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
 ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
-ACCESSORS(Script, eval_from_function, Object, kEvalFromFunctionOffset)
+ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
 ACCESSORS(Script, eval_from_instructions_offset, Smi,
           kEvalFrominstructionsOffsetOffset)
 
diff --git a/src/objects.h b/src/objects.h
index 3d928cd..0dc3a1e 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -3184,9 +3184,9 @@
   // [line_ends]: FixedArray of line ends positions.
   DECL_ACCESSORS(line_ends, Object)
 
-  // [eval_from_function]: for eval scripts the funcion from which eval was
-  // called.
-  DECL_ACCESSORS(eval_from_function, Object)
+  // [eval_from_shared]: for eval scripts the shared funcion info for the
+  // function from which eval was called.
+  DECL_ACCESSORS(eval_from_shared, Object)
 
   // [eval_from_instructions_offset]: the instruction offset in the code for the
   // function from which eval was called where eval was called.
@@ -3214,9 +3214,9 @@
   static const int kCompilationTypeOffset = kTypeOffset + kPointerSize;
   static const int kLineEndsOffset = kCompilationTypeOffset + kPointerSize;
   static const int kIdOffset = kLineEndsOffset + kPointerSize;
-  static const int kEvalFromFunctionOffset = kIdOffset + kPointerSize;
+  static const int kEvalFromSharedOffset = kIdOffset + kPointerSize;
   static const int kEvalFrominstructionsOffsetOffset =
-      kEvalFromFunctionOffset + kPointerSize;
+      kEvalFromSharedOffset + kPointerSize;
   static const int kSize = kEvalFrominstructionsOffsetOffset + kPointerSize;
 
  private:
diff --git a/src/version.cc b/src/version.cc
index 7db59c8..c9ff9f7 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     2
 #define MINOR_VERSION     0
 #define BUILD_NUMBER      2
-#define PATCH_LEVEL       1
+#define PATCH_LEVEL       2
 #define CANDIDATE_VERSION false
 
 // Define SONAME to have the SCons build the put a specific SONAME into the
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 675ce56..f2787d7 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -8427,7 +8427,7 @@
 }
 
 
-TEST(Bug528) {
+TEST(Regress528) {
   v8::V8::Initialize();
 
   v8::HandleScope scope;
@@ -8469,8 +8469,8 @@
     v8::internal::Heap::CollectAllGarbage(false);
     if (GetGlobalObjectsCount() == 0) break;
   }
-  CHECK_EQ(0, GetGlobalObjectsCount());
-  CHECK_EQ(2, gc_count);
+  CHECK_GE(2, gc_count);
+  CHECK_EQ(1, GetGlobalObjectsCount());
 
   // Looking up the line number for an exception creates reference from the
   // compilation cache to the global object.