OLD | NEW |
| (Empty) |
1 // Copyright 2014 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-reflect | |
6 | |
7 | |
8 (function testReflectConstructArity() { | |
9 assertEquals(2, Reflect.construct.length); | |
10 })(); | |
11 | |
12 | |
13 (function testReflectConstructNonConstructor() { | |
14 assertThrows(function() { | |
15 new Reflect.construct(function(){}, []); | |
16 }, TypeError); | |
17 })(); | |
18 | |
19 | |
20 (function testReflectConstructBasic() { | |
21 function Constructor() { "use strict"; } | |
22 assertInstanceof(Reflect.construct(Constructor, []), Constructor); | |
23 })(); | |
24 | |
25 | |
26 (function testReflectConstructBasicSloppy() { | |
27 function Constructor() {} | |
28 assertInstanceof(Reflect.construct(Constructor, []), Constructor); | |
29 })(); | |
30 | |
31 | |
32 (function testReflectConstructReturnSomethingElseStrict() { | |
33 var R = {}; | |
34 function Constructor() { "use strict"; return R; } | |
35 assertSame(R, Reflect.construct(Constructor, [])); | |
36 })(); | |
37 | |
38 | |
39 (function testReflectConstructReturnSomethingElseSloppy() { | |
40 var R = {}; | |
41 function Constructor() { return R; } | |
42 assertSame(R, Reflect.construct(Constructor, [])); | |
43 })(); | |
44 | |
45 | |
46 (function testReflectConstructNewTargetStrict() { | |
47 "use strict"; | |
48 function Constructor() { this[9] = 1; } | |
49 var O = Reflect.construct(Constructor, [], Array); | |
50 assertEquals(1, O[9]); | |
51 // Ordinary object with Array.prototype --- no exotic Array magic | |
52 assertFalse(Array.isArray(O)); | |
53 assertEquals(0, O.length); | |
54 assertSame(Array.prototype, Object.getPrototypeOf(O)); | |
55 })(); | |
56 | |
57 | |
58 (function testReflectConstructNewTargetSloppy() { | |
59 function Constructor() { this[9] = 1; } | |
60 var O = Reflect.construct(Constructor, [], Array); | |
61 assertEquals(1, O[9]); | |
62 // Ordinary object with Array.prototype --- no exotic Array magic | |
63 assertFalse(Array.isArray(O)); | |
64 assertEquals(0, O.length); | |
65 assertSame(Array.prototype, Object.getPrototypeOf(O)); | |
66 })(); | |
67 | |
68 | |
69 (function testReflectConstructNewTargetStrict2() { | |
70 "use strict"; | |
71 function Constructor() { this[9] = 1; } | |
72 Constructor.prototype.add = function(x) { | |
73 this[this.length] = x; return this; | |
74 } | |
75 var O = Reflect.construct(Array, [1, 2, 3], Constructor); | |
76 // Exotic Array object with Constructor.prototype | |
77 assertTrue(Array.isArray(O)); | |
78 assertSame(Constructor.prototype, Object.getPrototypeOf(O)); | |
79 assertFalse(O instanceof Array); | |
80 assertEquals(3, O.length); | |
81 assertEquals(undefined, O[9]); | |
82 assertSame(O, O.add(4)); | |
83 assertEquals(4, O.length); | |
84 assertEquals(4, O[3]); | |
85 })(); | |
86 | |
87 | |
88 (function testReflectConstructNewTargetSloppy2() { | |
89 function Constructor() { this[9] = 1; } | |
90 Constructor.prototype.add = function(x) { | |
91 this[this.length] = x; return this; | |
92 } | |
93 var O = Reflect.construct(Array, [1, 2, 3], Constructor); | |
94 // Exotic Array object with Constructor.prototype | |
95 assertTrue(Array.isArray(O)); | |
96 assertSame(Constructor.prototype, Object.getPrototypeOf(O)); | |
97 assertFalse(O instanceof Array); | |
98 assertEquals(3, O.length); | |
99 assertEquals(undefined, O[9]); | |
100 assertSame(O, O.add(4)); | |
101 assertEquals(4, O.length); | |
102 assertEquals(4, O[3]); | |
103 })(); | |
104 | |
105 | |
106 (function testReflectConstructNewTargetStrict3() { | |
107 "use strict"; | |
108 function A() {} | |
109 function B() {} | |
110 var O = Reflect.construct(A, [], B); | |
111 // TODO(caitp): bug: newTarget prototype is not used if it is not | |
112 // explicitly set. | |
113 //assertSame(B.prototype, Object.getPrototypeOf(O)); | |
114 })(); | |
115 | |
116 | |
117 (function testReflectConstructNewTargetSloppy3() { | |
118 function A() {} | |
119 function B() {} | |
120 var O = Reflect.construct(A, [], B); | |
121 // TODO(caitp): bug: newTarget prototype is not used if it is not | |
122 // explicitly set. | |
123 //assertSame(B.prototype, Object.getPrototypeOf(O)); | |
124 })(); | |
125 | |
126 | |
127 (function testAppliedArgumentsLength() { | |
128 function lengthStrict() { 'use strict'; this.a = arguments.length; } | |
129 function lengthSloppy() { this.a = arguments.length; } | |
130 | |
131 assertEquals(0, Reflect.construct(lengthStrict, []).a); | |
132 assertEquals(0, Reflect.construct(lengthSloppy, []).a); | |
133 assertEquals(0, Reflect.construct(lengthStrict, {}).a); | |
134 assertEquals(0, Reflect.construct(lengthSloppy, {}).a); | |
135 | |
136 for (var i = 0; i < 256; ++i) { | |
137 assertEquals(i, Reflect.construct(lengthStrict, new Array(i)).a); | |
138 assertEquals(i, Reflect.construct(lengthSloppy, new Array(i)).a); | |
139 assertEquals(i, Reflect.construct(lengthStrict, { length: i }).a); | |
140 assertEquals(i, Reflect.construct(lengthSloppy, { length: i }).a); | |
141 } | |
142 })(); | |
143 | |
144 | |
145 (function testAppliedArgumentsLengthThrows() { | |
146 function noopStrict() { 'use strict'; } | |
147 function noopSloppy() { } | |
148 function MyError() {} | |
149 | |
150 var argsList = {}; | |
151 Object.defineProperty(argsList, "length", { | |
152 get: function() { throw new MyError(); } | |
153 }); | |
154 | |
155 assertThrows(function() { | |
156 Reflect.construct(noopStrict, argsList); | |
157 }, MyError); | |
158 | |
159 assertThrows(function() { | |
160 Reflect.construct(noopSloppy, argsList); | |
161 }, MyError); | |
162 })(); | |
163 | |
164 | |
165 (function testAppliedArgumentsElementThrows() { | |
166 function noopStrict() { 'use strict'; } | |
167 function noopSloppy() { } | |
168 function MyError() {} | |
169 | |
170 var argsList = { length: 1 }; | |
171 Object.defineProperty(argsList, "0", { | |
172 get: function() { throw new MyError(); } | |
173 }); | |
174 | |
175 assertThrows(function() { | |
176 Reflect.construct(noopStrict, argsList); | |
177 }, MyError); | |
178 | |
179 assertThrows(function() { | |
180 Reflect.construct(noopSloppy, argsList); | |
181 }, MyError); | |
182 })(); | |
183 | |
184 | |
185 (function testAppliedNonFunctionStrict() { | |
186 'use strict'; | |
187 assertThrows(function() { Reflect.construct(void 0, []); }, TypeError); | |
188 assertThrows(function() { Reflect.construct(null, []); }, TypeError); | |
189 assertThrows(function() { Reflect.construct(123, []); }, TypeError); | |
190 assertThrows(function() { Reflect.construct("str", []); }, TypeError); | |
191 assertThrows(function() { Reflect.construct(Symbol("x"), []); }, TypeError); | |
192 assertThrows(function() { Reflect.construct(/123/, []); }, TypeError); | |
193 assertThrows(function() { Reflect.construct(NaN, []); }, TypeError); | |
194 assertThrows(function() { Reflect.construct({}, []); }, TypeError); | |
195 assertThrows(function() { Reflect.construct([], []); }, TypeError); | |
196 })(); | |
197 | |
198 | |
199 (function testAppliedNonFunctionSloppy() { | |
200 assertThrows(function() { Reflect.construct(void 0, []); }, TypeError); | |
201 assertThrows(function() { Reflect.construct(null, []); }, TypeError); | |
202 assertThrows(function() { Reflect.construct(123, []); }, TypeError); | |
203 assertThrows(function() { Reflect.construct("str", []); }, TypeError); | |
204 assertThrows(function() { Reflect.construct(Symbol("x"), []); }, TypeError); | |
205 assertThrows(function() { Reflect.construct(/123/, []); }, TypeError); | |
206 assertThrows(function() { Reflect.construct(NaN, []); }, TypeError); | |
207 assertThrows(function() { Reflect.construct({}, []); }, TypeError); | |
208 assertThrows(function() { Reflect.construct([], []); }, TypeError); | |
209 })(); | |
210 | |
211 | |
212 (function testAppliedArgumentsNonList() { | |
213 function noopStrict() { 'use strict'; } | |
214 function noopSloppy() {} | |
215 assertThrows(function() { Reflect.construct(noopStrict, null); }, TypeError); | |
216 assertThrows(function() { Reflect.construct(noopSloppy, null); }, TypeError); | |
217 assertThrows(function() { Reflect.construct(noopStrict, 1); }, TypeError); | |
218 assertThrows(function() { Reflect.construct(noopSloppy, 1); }, TypeError); | |
219 assertThrows(function() { Reflect.construct(noopStrict, "BAD"); }, TypeError); | |
220 assertThrows(function() { Reflect.construct(noopSloppy, "BAD"); }, TypeError); | |
221 assertThrows(function() { Reflect.construct(noopStrict, true); }, TypeError); | |
222 assertThrows(function() { Reflect.construct(noopSloppy, true); }, TypeError); | |
223 var sym = Symbol("x"); | |
224 assertThrows(function() { Reflect.construct(noopStrict, sym); }, TypeError); | |
225 assertThrows(function() { Reflect.construct(noopSloppy, sym); }, TypeError); | |
226 })(); | |
227 | |
228 | |
229 (function testAppliedArgumentValue() { | |
230 function firstStrict(a) { 'use strict'; this.a = a; } | |
231 function firstSloppy(a) { this.a = a; } | |
232 function lastStrict(a) { | |
233 'use strict'; this.a = arguments[arguments.length - 1]; } | |
234 function lastSloppy(a) { this.a = arguments[arguments.length - 1]; } | |
235 function sumStrict() { | |
236 'use strict'; | |
237 var sum = arguments[0]; | |
238 for (var i = 1; i < arguments.length; ++i) { | |
239 sum += arguments[i]; | |
240 } | |
241 this.a = sum; | |
242 } | |
243 function sumSloppy() { | |
244 var sum = arguments[0]; | |
245 for (var i = 1; i < arguments.length; ++i) { | |
246 sum += arguments[i]; | |
247 } | |
248 this.a = sum; | |
249 } | |
250 | |
251 assertEquals("OK!", Reflect.construct(firstStrict, ["OK!"]).a); | |
252 assertEquals("OK!", Reflect.construct(firstSloppy, ["OK!"]).a); | |
253 assertEquals("OK!", Reflect.construct(firstStrict, | |
254 { 0: "OK!", length: 1 }).a); | |
255 assertEquals("OK!", Reflect.construct(firstSloppy, | |
256 { 0: "OK!", length: 1 }).a); | |
257 assertEquals("OK!", Reflect.construct(lastStrict, | |
258 [0, 1, 2, 3, 4, 5, 6, 7, 8, "OK!"]).a); | |
259 assertEquals("OK!", Reflect.construct(lastSloppy, | |
260 [0, 1, 2, 3, 4, 5, 6, 7, 8, "OK!"]).a); | |
261 assertEquals("OK!", Reflect.construct(lastStrict, | |
262 { 9: "OK!", length: 10 }).a); | |
263 assertEquals("OK!", Reflect.construct(lastSloppy, | |
264 { 9: "OK!", length: 10 }).a); | |
265 assertEquals("TEST", Reflect.construct(sumStrict, | |
266 ["T", "E", "S", "T"]).a); | |
267 assertEquals("TEST!!", Reflect.construct(sumStrict, | |
268 ["T", "E", "S", "T", "!", "!"]).a); | |
269 assertEquals(10, Reflect.construct(sumStrict, | |
270 { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 }).a); | |
271 assertEquals("TEST", Reflect.construct(sumSloppy, | |
272 ["T", "E", "S", "T"]).a); | |
273 assertEquals("TEST!!", Reflect.construct(sumSloppy, | |
274 ["T", "E", "S", "T", "!", "!"]).a); | |
275 assertEquals(10, Reflect.construct(sumSloppy, | |
276 { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 }).a); | |
277 })(); | |
278 | |
279 (function() { | |
280 function* f() { yield 1; yield 2; } | |
281 function* g() { yield 3; yield 4; } | |
282 assertThrows(()=>Reflect.construct(f, [], g)); | |
283 })(); | |
284 | |
285 (function () { | |
286 var realm1 = Realm.create(); | |
287 var realm2 = Realm.create(); | |
288 | |
289 var well_known_intrinsic_constructors = [ | |
290 "Array", | |
291 "ArrayBuffer", | |
292 "Boolean", | |
293 ["DataView", [new ArrayBuffer()]], | |
294 "Date", | |
295 "Error", | |
296 "EvalError", | |
297 "Float32Array", | |
298 "Float64Array", | |
299 ["Function", ["return 153;"]], | |
300 ["Function", ["'use strict'; return 153;"]], | |
301 ["Function", ["'use strong'; return 153;"]], | |
302 ["((function*(){}).constructor)", ["yield 153;"]], // GeneratorFunction | |
303 ["((function*(){}).constructor)", ["'use strict'; yield 153;"]], | |
304 ["((function*(){}).constructor)", ["'use strong'; yield 153;"]], | |
305 "Int8Array", | |
306 "Int16Array", | |
307 "Int32Array", | |
308 "Map", | |
309 "Number", | |
310 "Object", | |
311 ["Promise", [(resolve, reject)=>{}]], | |
312 "RangeError", | |
313 "ReferenceError", | |
314 "RegExp", | |
315 "Set", | |
316 "String", | |
317 "SyntaxError", | |
318 // %TypedArray%? | |
319 "TypeError", | |
320 "Uint8Array", | |
321 "Uint8ClampedArray", | |
322 "Uint16Array", | |
323 "Uint32Array", | |
324 "URIError", | |
325 "WeakMap", | |
326 "WeakSet" | |
327 ]; | |
328 | |
329 function getname(v) { | |
330 return typeof v === "string" ? v : v[0]; | |
331 } | |
332 | |
333 function getargs(v) { | |
334 return typeof v === "string" ? [] : v[1]; | |
335 } | |
336 | |
337 function test_intrinsic_prototype(name) { | |
338 var own = Realm.eval(realm1, name); | |
339 | |
340 // Ensure that constructor.prototype is non-writable, non-configurable. | |
341 var desc = Object.getOwnPropertyDescriptor(own, "prototype"); | |
342 assertFalse(desc.configurable, name); | |
343 assertFalse(desc.writable, name); | |
344 } | |
345 | |
346 for (var intrinsic of well_known_intrinsic_constructors) { | |
347 test_intrinsic_prototype(getname(intrinsic)); | |
348 } | |
349 | |
350 function function_with_non_instance_prototype(realm) { | |
351 var f = Realm.eval(realm, "(function(){})"); | |
352 f.prototype = 1; | |
353 return f; | |
354 } | |
355 | |
356 function test_intrinsic_default(realm, name, args, convert) { | |
357 var own = Realm.eval(realm1, name); | |
358 var other = Realm.eval(realm, name); | |
359 var o = Reflect.construct( | |
360 convert(own), args, function_with_non_instance_prototype(realm)); | |
361 | |
362 // Ensure the intrisicDefaultProto is fetched from the correct realm. | |
363 assertTrue(realm == realm1 || o.__proto__ !== own.prototype, [...arguments])
; | |
364 assertTrue(o.__proto__ === other.prototype, [...arguments]); | |
365 } | |
366 | |
367 function test_all(test, convert) { | |
368 for (var intrinsic of well_known_intrinsic_constructors) { | |
369 for (var realm of [realm1, realm2]) { | |
370 test(realm, getname(intrinsic), getargs(intrinsic), convert); | |
371 } | |
372 } | |
373 } | |
374 | |
375 test_all(test_intrinsic_default, (v)=>v); | |
376 test_all(test_intrinsic_default, | |
377 (v)=>{ "use strict"; return class extends v {}}); | |
378 })(); | |
OLD | NEW |