Home | History | Annotate | Download | only in strong
      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: --strong-mode --allow-natives-syntax
      6 
      7 function getSloppyArguments() {
      8   return arguments;
      9 }
     10 
     11 function getObjects() {
     12   "use strict";
     13   return [
     14     {},
     15     Object(""),
     16     [],
     17     (function(){}),
     18     (class Foo {}),
     19     getSloppyArguments(),
     20     arguments,
     21     new Date(),
     22     // TODO(conradw): uncomment once Object.defineProperty is fixed.
     23     // new Uint32Array(0)
     24   ];
     25 }
     26 
     27 function readFromObjectSloppy(o) {
     28     return o.foo;
     29 }
     30 
     31 function readFromObjectKeyedSloppy(o) {
     32     return o["foo"];
     33 }
     34 
     35 function readFromObjectKeyedVarSloppy(o) {
     36   var a = "foo";
     37   return o[a];
     38 }
     39 
     40 function readFromObjectKeyedComputedSloppy(o) {
     41   var a = "o";
     42   return o["fo" + a];
     43 }
     44 
     45 function readFromObjectStrong(o) {
     46   "use strong";
     47   return o.foo;
     48 }
     49 
     50 function readFromObjectKeyedStrong(o) {
     51   "use strong";
     52   return o["foo"];
     53 }
     54 
     55 function readFromObjectKeyedLetStrong(o) {
     56   "use strong";
     57   let a = "foo";
     58   return o[a];
     59 }
     60 
     61 function readFromObjectKeyedComputedStrong(o) {
     62   "use strong";
     63   let a = "o";
     64   return o["fo" + a];
     65 }
     66 
     67 function getDescs(x) {
     68   return [
     69     {value: x},
     70     {configurable: true, enumerable: true, writable: true, value: x},
     71     {configurable: true, enumerable: true, get: (function() {return x}) },
     72   ];
     73 }
     74 
     75 function assertStrongSemantics(func, object) {
     76   %DeoptimizeFunction(func);
     77   %ClearFunctionTypeFeedback(func);
     78   assertThrows(function(){func(object)}, TypeError);
     79   assertThrows(function(){func(object)}, TypeError);
     80   assertThrows(function(){func(object)}, TypeError);
     81   %OptimizeFunctionOnNextCall(func);
     82   assertThrows(function(){func(object)}, TypeError);
     83   %DeoptimizeFunction(func);
     84   assertThrows(function(){func(object)}, TypeError);
     85 }
     86 
     87 function assertSloppySemantics(func, object) {
     88   %DeoptimizeFunction(func);
     89   %ClearFunctionTypeFeedback(func);
     90   assertDoesNotThrow(function(){func(object)});
     91   assertDoesNotThrow(function(){func(object)});
     92   assertDoesNotThrow(function(){func(object)});
     93   %OptimizeFunctionOnNextCall(func);
     94   assertDoesNotThrow(function(){func(object)});
     95   %DeoptimizeFunction(func);
     96   assertDoesNotThrow(function(){func(object)});
     97 }
     98 
     99 (function () {
    100   "use strict";
    101 
    102   let goodKeys = [
    103     "foo"
    104   ]
    105 
    106   let badKeys = [
    107     "bar",
    108     "1",
    109     "100001",
    110     "3000000001",
    111     "5000000001"
    112   ];
    113 
    114   let values = [
    115     "string",
    116     1,
    117     100001,
    118     30000000001,
    119     50000000001,
    120     NaN,
    121     {},
    122     undefined
    123   ];
    124 
    125   let badAccessorDescs = [
    126     { set: (function(){}) },
    127     { configurable: true, enumerable: true, set: (function(){}) }
    128   ];
    129 
    130   let readSloppy = [
    131     readFromObjectSloppy,
    132     readFromObjectKeyedSloppy,
    133     readFromObjectKeyedVarSloppy,
    134     readFromObjectKeyedComputedSloppy
    135   ];
    136 
    137   let readStrong = [
    138     readFromObjectStrong,
    139     readFromObjectKeyedStrong,
    140     readFromObjectKeyedLetStrong,
    141     readFromObjectKeyedComputedStrong
    142   ];
    143 
    144   let dummyProto = {};
    145   for (let key of goodKeys) {
    146     Object.defineProperty(dummyProto, key, { value: undefined });
    147   }
    148 
    149   // After altering the backing store, accessing a missing property should still
    150   // throw.
    151   for (let key of badKeys) {
    152     for (let value of values) {
    153       for (let desc of getDescs(value)) {
    154         for (let object of getObjects()) {
    155           Object.defineProperty(object, key, desc);
    156           for (let func of readStrong) {
    157             assertStrongSemantics(func, object);
    158           }
    159           for (let func of readSloppy) {
    160             assertSloppySemantics(func, object);
    161           }
    162           // Accessing a property which is on the prototype chain of the object
    163           // should not throw.
    164           object.__proto__ = dummyProto;
    165           for (let key of goodKeys) {
    166             for (let func of readStrong.concat(readSloppy)) {
    167               assertSloppySemantics(func, object);
    168             }
    169           }
    170         }
    171       }
    172     }
    173   }
    174 })();
    175