1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --expose-debug-as debug
6
7// Test that debug-evaluate can find the correct this value for an arrow
8// function, if "this" is referenced within the arrow function scope.
9
10Debug = debug.Debug
11
12var break_count = 0;
13var exception = null;
14
15function listener(event, exec_state, event_data, data) {
16  if (event != Debug.DebugEvent.Break) return;
17  try {
18    for (var i = 0; i < exec_state.frameCount() - 1; i++) {
19      var frame = exec_state.frame(i);
20      var this_value = frame.evaluate("this").value();
21      var expected = frame.sourceLineText().match(/\/\/ (.*$)/)[1];
22      print(expected, this_value, frame.sourceLineText());
23      assertEquals(String(expected), String(this_value));
24    }
25    break_count++;
26  } catch (e) {
27    exception = e;
28    print(e + e.stack);
29  }
30}
31
32// Context-allocated receiver.
33function f() {
34  debugger;                          // foo
35  return () => {
36    debugger;                        // foo
37    with ({}) {
38      return () => {
39        debugger;                    // foo
40        try {
41          throw new Error();
42        } catch (e) {
43          return () => {
44            (() => this);            // bind this.
45            debugger;                // foo
46            return () => {
47              debugger;              // undefined
48              return g.call("goo");  // undefined
49            }
50          };
51        }
52      };
53    }
54  };
55}
56
57// Stack-allocated receiver.
58function g() {
59  debugger;                        // goo
60  return () => {
61    debugger;                      // undefined
62    with ({}) {
63      return () => {
64        debugger;                  // undefined
65        try {
66          throw new Error();
67        } catch (e) {
68          return () => {
69            debugger;              // undefined
70            return f.call("foo");  // undefined
71          };
72        }
73      };
74    }
75  };
76}
77
78Debug.setListener(listener);
79
80var h = f.call("foo");
81for (var i = 0; i < 20; i++) h = h();
82var h = g.call("goo");
83for (var i = 0; i < 20; i++) h = h();
84
85function x() {
86  (() => this);      // bind this.
87  function y() {
88    (() => {
89      (() => this);  // bind this.
90      debugger;      // Y
91     })();           // Y
92  }
93  y.call("Y");       // X
94}
95x.call("X");
96
97function u() {
98  (() => this);
99  function v() {
100    (() => {
101      debugger;      // undefined
102     })();           // V
103  }
104  v.call("V");       // U
105}
106u.call("U");
107
108(() => {
109  (() => this);
110  debugger;          // [object global]
111})();
112
113Debug.setListener(null);
114
115assertEquals(55, break_count);
116assertNull(exception);
117