Fix DebugEvaluate on properties defined on Object.prototype
authoraandrey@chromium.org <aandrey@chromium.org>
Mon, 22 Sep 2014 12:45:47 +0000 (12:45 +0000)
committeraandrey@chromium.org <aandrey@chromium.org>
Mon, 22 Sep 2014 12:45:47 +0000 (12:45 +0000)
BUG=415499
R=yangguo
LOG=N

Review URL: https://codereview.chromium.org/592033002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24119 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/runtime.cc
test/cctest/test-debug.cc

index f5789f6..3ecf044 100644 (file)
@@ -13007,6 +13007,16 @@ static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
 }
 
 
+static Handle<JSObject> NewJSObjectWithNullProto(Isolate* isolate) {
+  Handle<JSObject> result =
+      isolate->factory()->NewJSObject(isolate->object_function());
+  Handle<Map> new_map = Map::Copy(Handle<Map>(result->map()));
+  new_map->set_prototype(*isolate->factory()->null_value());
+  JSObject::MigrateToMap(result, new_map);
+  return result;
+}
+
+
 // Evaluate a piece of JavaScript in the context of a stack frame for
 // debugging.  Things that need special attention are:
 // - Parameters and stack-allocated locals need to be materialized.  Altered
@@ -13049,8 +13059,7 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
   DCHECK(!context.is_null());
 
   // Materialize stack locals and the arguments object.
-  Handle<JSObject> materialized =
-      isolate->factory()->NewJSObject(isolate->object_function());
+  Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate);
 
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, materialized,
index 69c10c2..2f0674a 100644 (file)
@@ -765,6 +765,7 @@ static void DebugEventEvaluate(
   CHECK_NE(debug->break_id(), 0);
 
   if (event == v8::Break) {
+    break_point_hit_count++;
     for (int i = 0; checks[i].expr != NULL; i++) {
       const int argc = 3;
       v8::Handle<v8::Value> argv[argc] = {
@@ -2406,7 +2407,7 @@ TEST(DebugEvaluate) {
   };
 
   // Simple test function. The "y=0" is in the function foo to provide a break
-  // location. For "y=0" the "y" is at position 15 in the barbar function
+  // location. For "y=0" the "y" is at position 15 in the foo function
   // therefore setting breakpoint at position 15 will break at "y=0" and
   // setting it higher will break after.
   v8::Local<v8::Function> foo = CompileFunction(&env,
@@ -2439,6 +2440,34 @@ TEST(DebugEvaluate) {
   checks = checks_hh;
   foo->Call(env->Global(), 1, argv_foo);
 
+  // Test that overriding Object.prototype will not interfere into evaluation
+  // on call frame.
+  v8::Local<v8::Function> zoo =
+      CompileFunction(&env,
+                      "x = undefined;"
+                      "function zoo(t) {"
+                      "  var a=x;"
+                      "  Object.prototype.x = 42;"
+                      "  x=t;"
+                      "  y=0;"  // To ensure break location.
+                      "  delete Object.prototype.x;"
+                      "  x=a;"
+                      "}",
+                      "zoo");
+  const int zoo_break_position = 50;
+
+  // Arguments with one parameter "Hello, world!"
+  v8::Handle<v8::Value> argv_zoo[1] = {
+      v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")};
+
+  // Call zoo with breakpoint set at y=0.
+  DebugEventCounterClear();
+  bp = SetBreakPoint(zoo, zoo_break_position);
+  checks = checks_hu;
+  zoo->Call(env->Global(), 1, argv_zoo);
+  CHECK_EQ(1, break_point_hit_count);
+  ClearBreakPoint(bp);
+
   // Test function with an inner function. The "y=0" is in function barbar
   // to provide a break location. For "y=0" the "y" is at position 8 in the
   // barbar function therefore setting breakpoint at position 8 will break at