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 ]; 23} 24 25// TODO(conradw): add tests for non-inheritance once semantics are implemented. 26function getNonInheritingObjects() { 27 "use strong"; 28 return [ 29 Object(""), 30 [], 31 // TODO(conradw): uncomment and correct test once Object.defineProperty is 32 // fixed. 33 // new Uint32Array(0) 34 ]; 35} 36 37function readFromObjectElementSloppy(o) { 38 return o[0]; 39} 40 41function readFromObjectElementSparseSloppy(o) { 42 return o[100000]; 43} 44 45function readFromObjectElementNonSmiSloppy(o) { 46 return o[3000000000]; 47} 48 49function readFromObjectNonIndexSloppy(o) { 50 return o[5000000000]; 51} 52 53function readFromObjectElementVarSloppy(o) { 54 var a = 0; 55 return o[a]; 56} 57 58function readFromObjectElementSparseVarSloppy(o) { 59 var a = 100000; 60 return o[a]; 61} 62 63function readFromObjectElementNonSmiVarSloppy(o) { 64 var a = 3000000000; 65 return o[a]; 66} 67 68function readFromObjectNonIndexVarSloppy(o) { 69 var a = 5000000000; 70 return o[a]; 71} 72 73function readFromObjectElementStrong(o) { 74 "use strong"; 75 return o[0]; 76} 77 78function readFromObjectElementSparseStrong(o) { 79 "use strong"; 80 return o[100000]; 81} 82 83function readFromObjectElementNonSmiStrong(o) { 84 "use strong"; 85 return o[3000000000]; 86} 87 88function readFromObjectNonIndexStrong(o) { 89 "use strong"; 90 return o[5000000000]; 91} 92 93function readFromObjectElementLetStrong(o) { 94 "use strong"; 95 let a = 0; 96 return o[a]; 97} 98 99function readFromObjectElementSparseLetStrong(o) { 100 "use strong"; 101 let a = 100000; 102 return o[a]; 103} 104 105function readFromObjectElementNonSmiLetStrong(o) { 106 "use strong"; 107 let a = 3000000000; 108 return o[a]; 109} 110 111function readFromObjectNonIndexLetStrong(o) { 112 "use strong"; 113 let a = 5000000000; 114 return o[a]; 115} 116 117function getDescs(x) { 118 return [ 119 {value: x}, 120 {configurable: true, enumerable: true, writable: true, value: x}, 121 {configurable: true, enumerable: true, get: (function() {return x}) }, 122 ]; 123} 124 125function assertStrongSemantics(func, object) { 126 %DeoptimizeFunction(func); 127 %ClearFunctionTypeFeedback(func); 128 assertThrows(function(){func(object)}, TypeError); 129 assertThrows(function(){func(object)}, TypeError); 130 assertThrows(function(){func(object)}, TypeError); 131 %OptimizeFunctionOnNextCall(func); 132 assertThrows(function(){func(object)}, TypeError); 133 %DeoptimizeFunction(func); 134 assertThrows(function(){func(object)}, TypeError); 135} 136 137function assertSloppySemantics(func, object) { 138 %DeoptimizeFunction(func); 139 %ClearFunctionTypeFeedback(func); 140 assertDoesNotThrow(function(){func(object)}); 141 assertDoesNotThrow(function(){func(object)}); 142 assertDoesNotThrow(function(){func(object)}); 143 %OptimizeFunctionOnNextCall(func); 144 assertDoesNotThrow(function(){func(object)}); 145 %DeoptimizeFunction(func); 146 assertDoesNotThrow(function(){func(object)}); 147} 148 149(function () { 150 "use strict"; 151 152 let goodKeys = [ 153 "0", 154 "100000", 155 "3000000000", 156 "5000000000" 157 ] 158 159 let badKeys = [ 160 "bar", 161 "1", 162 "100001", 163 "3000000001", 164 "5000000001" 165 ]; 166 167 let values = [ 168 "string", 169 1, 170 100001, 171 30000000001, 172 50000000001, 173 NaN, 174 {}, 175 undefined 176 ]; 177 178 let badAccessorDescs = [ 179 { set: (function(){}) }, 180 { configurable: true, enumerable: true, set: (function(){}) } 181 ]; 182 183 let readSloppy = [ 184 readFromObjectElementSloppy, 185 readFromObjectElementSparseSloppy, 186 readFromObjectElementNonSmiSloppy, 187 readFromObjectNonIndexSloppy, 188 readFromObjectElementVarSloppy, 189 readFromObjectElementSparseVarSloppy, 190 readFromObjectElementNonSmiVarSloppy, 191 readFromObjectNonIndexVarSloppy 192 ]; 193 194 let readStrong = [ 195 readFromObjectElementStrong, 196 readFromObjectElementSparseStrong, 197 readFromObjectElementNonSmiStrong, 198 readFromObjectNonIndexStrong, 199 readFromObjectElementLetStrong, 200 readFromObjectElementSparseLetStrong, 201 readFromObjectElementNonSmiLetStrong, 202 readFromObjectNonIndexLetStrong 203 ]; 204 205 let dummyProto = {}; 206 for (let key of goodKeys) { 207 Object.defineProperty(dummyProto, key, { value: undefined }); 208 } 209 210 // After altering the backing store, accessing a missing property should still 211 // throw. 212 for (let key of badKeys) { 213 for (let value of values) { 214 for (let desc of getDescs(value)) { 215 let objects = getObjects(); 216 let nonInheritingObjects = getNonInheritingObjects(); 217 for (let object of objects.concat(nonInheritingObjects)) { 218 Object.defineProperty(object, key, desc); 219 for (let func of readStrong) { 220 assertStrongSemantics(func, object); 221 } 222 for (let func of readSloppy) { 223 assertSloppySemantics(func, object); 224 } 225 } 226 for (let object of objects) { 227 // Accessing a property which is on the prototype chain of the object 228 // should not throw. 229 object.__proto__ = dummyProto; 230 for (let key of goodKeys) { 231 for (let func of readStrong.concat(readSloppy)) { 232 assertSloppySemantics(func, object); 233 } 234 } 235 } 236 } 237 } 238 } 239})(); 240