Home | History | Annotate | Download | only in mjsunit
      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: --harmony-proxies --allow-natives-syntax --expose-debug-as debug
      6 
      7 "use strict";
      8 
      9 // Test non-JSObject receiver.
     10 function f(o) {
     11   var result = [];
     12   for (var i in o) {
     13     result.push(i);
     14   }
     15   return result;
     16 }
     17 
     18 assertEquals(["0"], f("a"));
     19 assertEquals(["0"], f("a"));
     20 
     21 %OptimizeFunctionOnNextCall(f);
     22 assertEquals(["0","1","2"], f("bla"));
     23 
     24 // Test the lazy deopt points.
     25 var keys = ["a", "b", "c", "d"];
     26 var has_keys = [];
     27 var deopt_has = false;
     28 var deopt_enum = false;
     29 
     30 var 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 
     50 var proxy = new Proxy({}, handler);
     51 var o = {__proto__: proxy};
     52 
     53 function f2(o) {
     54   var result = [];
     55   for (var i in o) {
     56     result.push(i);
     57   }
     58   return result;
     59 }
     60 
     61 function check_f2() {
     62   assertEquals(keys, f2(o));
     63   assertEquals(keys, has_keys);
     64   has_keys.length = 0;
     65 }
     66 
     67 check_f2();
     68 check_f2();
     69 
     70 // Test lazy deopt after GetPropertyNamesFast
     71 %OptimizeFunctionOnNextCall(f2);
     72 deopt_enum = true;
     73 check_f2();
     74 
     75 // Test lazy deopt after FILTER_KEY
     76 %OptimizeFunctionOnNextCall(f2);
     77 deopt_has = true;
     78 check_f2();
     79 
     80 function f3(o) {
     81   for (var i in o) {
     82   }
     83 }
     84 
     85 f3({__proto__:{x:1}});
     86 f3({__proto__:{x:1}});
     87 
     88 %OptimizeFunctionOnNextCall(f3);
     89 f3(undefined);
     90 f3(null);
     91 
     92 // Reliable repro for an issue previously flushed out by GC stress.
     93 var handler2 = {
     94   getPropertyDescriptor(target, k) {
     95     has_keys.push(k);
     96     return {value: 10, configurable: true, writable: false, enumerable: true};
     97   }
     98 }
     99 var proxy2 = new Proxy({}, handler2);
    100 var o2 = {__proto__: proxy2};
    101 var p = {x: "x"}
    102 
    103 function 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 
    112 function check_f4() {
    113   assertEquals(keys, f4(o, p));
    114   assertEquals(keys, has_keys);
    115   has_keys.length = 0;
    116 }
    117 
    118 check_f4();
    119 check_f4();
    120 
    121 %OptimizeFunctionOnNextCall(f4);
    122 
    123 p.y = "y";  // Change map, cause eager deopt.
    124 check_f4();
    125 
    126 // Repro for Turbofan equivalent.
    127 var x;
    128 var count = 0;
    129 
    130 var Debug = debug.Debug;
    131 
    132 function listener(event, exec_state, event_data, data) {
    133   if (event == Debug.DebugEvent.Break) {
    134     %DeoptimizeFunction(f5);
    135   }
    136 }
    137 
    138 var 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 
    150 var proxy3 = new Proxy({}, handler3);
    151 var o3 = {__proto__: proxy3};
    152 
    153 function f5() {
    154   for (var p in o3) {
    155     print(p);
    156   }
    157 }
    158 
    159 x = false;
    160 
    161 f5(); f5(); f5();
    162 %OptimizeFunctionOnNextCall(f5);
    163 x = true;
    164 count = 0;
    165 Debug.setListener(listener);
    166 f5();
    167 Debug.setListener(null);
    168 assertEquals(1, count);
    169