Handle null receiver in sloppy mode in %GetFrameDetails.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 22 Aug 2014 12:55:23 +0000 (12:55 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 22 Aug 2014 12:55:23 +0000 (12:55 +0000)
R=jarin@chromium.org
BUG=405922
LOG=N

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

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

src/runtime.cc
test/mjsunit/regress/regress-crbug-405922.js [new file with mode: 0644]

index 2a58b07..1616434 100644 (file)
@@ -11500,11 +11500,13 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
     if (receiver->IsUndefined()) {
       receiver = handle(function->global_proxy());
     } else {
-      DCHECK(!receiver->IsNull());
       Context* context = Context::cast(it.frame()->context());
       Handle<Context> native_context(Context::cast(context->native_context()));
-      receiver = Object::ToObject(
-          isolate, receiver, native_context).ToHandleChecked();
+      if (!Object::ToObject(isolate, receiver, native_context)
+               .ToHandle(&receiver)) {
+        // This only happens if the receiver is forcibly set in %_CallFunction.
+        return heap->undefined_value();
+      }
     }
   }
   details->set(kFrameDetailsReceiverIndex, *receiver);
diff --git a/test/mjsunit/regress/regress-crbug-405922.js b/test/mjsunit/regress/regress-crbug-405922.js
new file mode 100644 (file)
index 0000000..9f76a86
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --expose-debug-as debug
+
+Debug = debug.Debug
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      exec_state.prepareStep(Debug.StepAction.StepIn, 3);
+    }
+  } catch (e) {
+  }
+}
+
+Debug.setListener(listener);
+
+function f(x) {
+  if (x > 0) %_CallFunction(null, x-1, f);
+}
+
+debugger;
+f(2);
+
+Debug.setListener(null);