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 7function getSloppyArguments() { 8 return arguments; 9} 10 11function 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 27function readFromObjectSloppy(o) { 28 return o.foo; 29} 30 31function readFromObjectKeyedSloppy(o) { 32 return o["foo"]; 33} 34 35function readFromObjectKeyedVarSloppy(o) { 36 var a = "foo"; 37 return o[a]; 38} 39 40function readFromObjectKeyedComputedSloppy(o) { 41 var a = "o"; 42 return o["fo" + a]; 43} 44 45function readFromObjectStrong(o) { 46 "use strong"; 47 return o.foo; 48} 49 50function readFromObjectKeyedStrong(o) { 51 "use strong"; 52 return o["foo"]; 53} 54 55function readFromObjectKeyedLetStrong(o) { 56 "use strong"; 57 let a = "foo"; 58 return o[a]; 59} 60 61function readFromObjectKeyedComputedStrong(o) { 62 "use strong"; 63 let a = "o"; 64 return o["fo" + a]; 65} 66 67function 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 75function 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 87function 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