blob: 8f735393825446e52a91f9e8ec156c7ba3f04870 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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: --harmony-proxies --allow-natives-syntax --expose-debug-as debug
6
7"use strict";
8
9// Test non-JSObject receiver.
10function f(o) {
11 var result = [];
12 for (var i in o) {
13 result.push(i);
14 }
15 return result;
16}
17
18assertEquals(["0"], f("a"));
19assertEquals(["0"], f("a"));
20
21%OptimizeFunctionOnNextCall(f);
22assertEquals(["0","1","2"], f("bla"));
23
24// Test the lazy deopt points.
25var keys = ["a", "b", "c", "d"];
26var has_keys = [];
27var deopt_has = false;
28var deopt_enum = false;
29
30var handler = {
Ben Murdoch097c5b22016-05-18 11:27:45 +010031 ownKeys() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032 if (deopt_enum) {
33 %DeoptimizeFunction(f2);
34 deopt_enum = false;
35 }
Ben Murdoch097c5b22016-05-18 11:27:45 +010036 return keys;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 },
Ben Murdoch097c5b22016-05-18 11:27:45 +010038 getOwnPropertyDescriptor() { return { enumerable: true, configurable: true }},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039
40 has(target, k) {
41 if (deopt_has) {
42 %DeoptimizeFunction(f2);
43 deopt_has = false;
44 }
45 has_keys.push(k);
Ben Murdoch097c5b22016-05-18 11:27:45 +010046 return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047 }
48};
49
50
51var proxy = new Proxy({}, handler);
52var o = {__proto__: proxy};
53
54function f2(o) {
55 var result = [];
56 for (var i in o) {
57 result.push(i);
58 }
59 return result;
60}
61
62function check_f2() {
63 assertEquals(keys, f2(o));
64 assertEquals(keys, has_keys);
65 has_keys.length = 0;
66}
67
68check_f2();
69check_f2();
70
Ben Murdoch097c5b22016-05-18 11:27:45 +010071// Test lazy deopt after ForInEnumerate
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000072%OptimizeFunctionOnNextCall(f2);
73deopt_enum = true;
74check_f2();
75
76// Test lazy deopt after FILTER_KEY
77%OptimizeFunctionOnNextCall(f2);
78deopt_has = true;
79check_f2();
80
81function f3(o) {
82 for (var i in o) {
83 }
84}
85
86f3({__proto__:{x:1}});
87f3({__proto__:{x:1}});
88
89%OptimizeFunctionOnNextCall(f3);
90f3(undefined);
91f3(null);
92
93// Reliable repro for an issue previously flushed out by GC stress.
94var handler2 = {
95 getPropertyDescriptor(target, k) {
96 has_keys.push(k);
97 return {value: 10, configurable: true, writable: false, enumerable: true};
98 }
99}
100var proxy2 = new Proxy({}, handler2);
101var o2 = {__proto__: proxy2};
102var p = {x: "x"}
103
104function f4(o, p) {
105 var result = [];
106 for (var i in o) {
107 var j = p.x + "str";
108 result.push(i);
109 }
110 return result;
111}
112
113function check_f4() {
114 assertEquals(keys, f4(o, p));
115 assertEquals(keys, has_keys);
116 has_keys.length = 0;
117}
118
119check_f4();
120check_f4();
121
122%OptimizeFunctionOnNextCall(f4);
123
124p.y = "y"; // Change map, cause eager deopt.
125check_f4();
126
127// Repro for Turbofan equivalent.
128var x;
129var count = 0;
130
131var Debug = debug.Debug;
132
133function listener(event, exec_state, event_data, data) {
134 if (event == Debug.DebugEvent.Break) {
135 %DeoptimizeFunction(f5);
136 }
137}
138
139var handler3 = {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100140 ownKeys() { return ["a", "b"] },
141 getOwnPropertyDescriptor() { return { enumerable: true, configurable: true }},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142
143 has(target, k) {
144 if (k == "a") count++;
145 if (x) %ScheduleBreak();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100146 return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147 }
148};
149
150var proxy3 = new Proxy({}, handler3);
151var o3 = {__proto__: proxy3};
152
153function f5() {
154 for (var p in o3) {
155 print(p);
156 }
157}
158
159x = false;
160
161f5(); f5(); f5();
162%OptimizeFunctionOnNextCall(f5);
163x = true;
164count = 0;
165Debug.setListener(listener);
166f5();
167Debug.setListener(null);
168assertEquals(1, count);