blob: e458e1d537806bd8924b88457339ff2349f4d972 [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 = {
31 enumerate(target) {
32 if (deopt_enum) {
33 %DeoptimizeFunction(f2);
34 deopt_enum = false;
35 }
36 return keys[Symbol.iterator]();
37 },
38
39 has(target, k) {
40 if (deopt_has) {
41 %DeoptimizeFunction(f2);
42 deopt_has = false;
43 }
44 has_keys.push(k);
45 return {value: 10, configurable: true, writable: false, enumerable: true};
46 }
47};
48
49
50var proxy = new Proxy({}, handler);
51var o = {__proto__: proxy};
52
53function f2(o) {
54 var result = [];
55 for (var i in o) {
56 result.push(i);
57 }
58 return result;
59}
60
61function check_f2() {
62 assertEquals(keys, f2(o));
63 assertEquals(keys, has_keys);
64 has_keys.length = 0;
65}
66
67check_f2();
68check_f2();
69
70// Test lazy deopt after GetPropertyNamesFast
71%OptimizeFunctionOnNextCall(f2);
72deopt_enum = true;
73check_f2();
74
75// Test lazy deopt after FILTER_KEY
76%OptimizeFunctionOnNextCall(f2);
77deopt_has = true;
78check_f2();
79
80function f3(o) {
81 for (var i in o) {
82 }
83}
84
85f3({__proto__:{x:1}});
86f3({__proto__:{x:1}});
87
88%OptimizeFunctionOnNextCall(f3);
89f3(undefined);
90f3(null);
91
92// Reliable repro for an issue previously flushed out by GC stress.
93var handler2 = {
94 getPropertyDescriptor(target, k) {
95 has_keys.push(k);
96 return {value: 10, configurable: true, writable: false, enumerable: true};
97 }
98}
99var proxy2 = new Proxy({}, handler2);
100var o2 = {__proto__: proxy2};
101var p = {x: "x"}
102
103function f4(o, p) {
104 var result = [];
105 for (var i in o) {
106 var j = p.x + "str";
107 result.push(i);
108 }
109 return result;
110}
111
112function check_f4() {
113 assertEquals(keys, f4(o, p));
114 assertEquals(keys, has_keys);
115 has_keys.length = 0;
116}
117
118check_f4();
119check_f4();
120
121%OptimizeFunctionOnNextCall(f4);
122
123p.y = "y"; // Change map, cause eager deopt.
124check_f4();
125
126// Repro for Turbofan equivalent.
127var x;
128var count = 0;
129
130var Debug = debug.Debug;
131
132function listener(event, exec_state, event_data, data) {
133 if (event == Debug.DebugEvent.Break) {
134 %DeoptimizeFunction(f5);
135 }
136}
137
138var handler3 = {
139 enumerate(target) {
140 return ["a", "b"][Symbol.iterator]();
141 },
142
143 has(target, k) {
144 if (k == "a") count++;
145 if (x) %ScheduleBreak();
146 return {value: 10, configurable: true, writable: false, enumerable: true};
147 }
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);