Bug 1385843 - Handle nested eval-in-frame better in ThrowUninitializedThis. r=tcampbell
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 11 Oct 2017 10:57:41 +0200
changeset 428089 6a54320bbbc014b62ab59acf0f82c68e2a721322
parent 428088 c42f60eda84571f66cf6467822f56df7807fcff8
child 428090 c7c66aac19da126fee814dcf6b22f38bc1ed60e0
push id97
push userfmarier@mozilla.com
push dateSat, 14 Oct 2017 01:12:59 +0000
reviewerstcampbell
bugs1385843
milestone58.0a1
Bug 1385843 - Handle nested eval-in-frame better in ThrowUninitializedThis. r=tcampbell
js/src/jit-test/tests/debug/bug1385843.js
js/src/vm/Interpreter.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/bug1385843.js
@@ -0,0 +1,22 @@
+var g = newGlobal();
+g.parent = this;
+g.count = 0;
+g.eval("(" + function() {
+    var dbg = new Debugger(parent);
+    dbg.onEnterFrame = function(frame) {
+        if (count === 5)
+            dbg.onEnterFrame = undefined;
+        count++;
+        var ex = frame.eval("this").throw.unsafeDereference();
+        assertEq(ex.message.includes("uninitialized"), true);
+        assertEq(ex.message.includes("Foo2"), true);
+    }
+} + ")()");
+class Foo1 {};
+class Foo2 extends Foo1 {
+    constructor() {
+        super();
+    }
+};
+new Foo2();
+assertEq(g.count, 6);
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -5187,16 +5187,18 @@ js::ThrowUninitializedThis(JSContext* cx
 {
     RootedFunction fun(cx);
     if (frame.isFunctionFrame()) {
         fun = frame.callee();
     } else {
         Scope* startingScope;
         if (frame.isDebuggerEvalFrame()) {
             AbstractFramePtr evalInFramePrev = frame.asInterpreterFrame()->evalInFramePrev();
+            while (evalInFramePrev.isDebuggerEvalFrame())
+                evalInFramePrev = evalInFramePrev.asInterpreterFrame()->evalInFramePrev();
             startingScope = evalInFramePrev.script()->bodyScope();
         } else {
             MOZ_ASSERT(frame.isEvalFrame());
             MOZ_ASSERT(frame.script()->isDirectEvalInFunction());
             startingScope = frame.script()->enclosingScope();
         }
 
         for (ScopeIter si(startingScope); si; si++) {