Commits
Christoph Iserlohn authored bf3dae828f1
1 + | diff -urN a/deps/v8/test/torque/test-torque.tq b/deps/v8/test/torque/test-torque.tq |
2 + | --- /dev/null |
3 + | +++ deps/v8/test/torque/test-torque.tq |
4 + | |
5 + | +// Copyright 2018 the V8 project authors. All rights reserved. |
6 + | +// Use of this source code is governed by a BSD-style license that can be |
7 + | +// found in the LICENSE file. |
8 + | + |
9 + | +namespace test { |
10 + | + macro ElementsKindTestHelper1(kind: constexpr ElementsKind): bool { |
11 + | + if constexpr ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)) { |
12 + | + return true; |
13 + | + } else { |
14 + | + return false; |
15 + | + } |
16 + | + } |
17 + | + |
18 + | + macro ElementsKindTestHelper2(kind: constexpr ElementsKind): constexpr bool { |
19 + | + return ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)); |
20 + | + } |
21 + | + |
22 + | + macro LabelTestHelper1(): never |
23 + | + labels Label1 { |
24 + | + goto Label1; |
25 + | + } |
26 + | + |
27 + | + macro LabelTestHelper2(): never |
28 + | + labels Label2(Smi) { |
29 + | + goto Label2(42); |
30 + | + } |
31 + | + |
32 + | + macro LabelTestHelper3(): never |
33 + | + labels Label3(Oddball, Smi) { |
34 + | + goto Label3(Null, 7); |
35 + | + } |
36 + | + |
37 + | + @export |
38 + | + macro TestConstexpr1() { |
39 + | + check(FromConstexpr<bool>(IsFastElementsKind(PACKED_SMI_ELEMENTS))); |
40 + | + } |
41 + | + |
42 + | + @export |
43 + | + macro TestConstexprIf() { |
44 + | + check(ElementsKindTestHelper1(UINT8_ELEMENTS)); |
45 + | + check(ElementsKindTestHelper1(UINT16_ELEMENTS)); |
46 + | + check(!ElementsKindTestHelper1(UINT32_ELEMENTS)); |
47 + | + } |
48 + | + |
49 + | + @export |
50 + | + macro TestConstexprReturn() { |
51 + | + check(FromConstexpr<bool>(ElementsKindTestHelper2(UINT8_ELEMENTS))); |
52 + | + check(FromConstexpr<bool>(ElementsKindTestHelper2(UINT16_ELEMENTS))); |
53 + | + check(!FromConstexpr<bool>(ElementsKindTestHelper2(UINT32_ELEMENTS))); |
54 + | + check(FromConstexpr<bool>(!ElementsKindTestHelper2(UINT32_ELEMENTS))); |
55 + | + } |
56 + | + |
57 + | + @export |
58 + | + macro TestGotoLabel(): Boolean { |
59 + | + try { |
60 + | + LabelTestHelper1() otherwise Label1; |
61 + | + } |
62 + | + label Label1 { |
63 + | + return True; |
64 + | + } |
65 + | + } |
66 + | + |
67 + | + @export |
68 + | + macro TestGotoLabelWithOneParameter(): Boolean { |
69 + | + try { |
70 + | + LabelTestHelper2() otherwise Label2; |
71 + | + } |
72 + | + label Label2(smi: Smi) { |
73 + | + check(smi == 42); |
74 + | + return True; |
75 + | + } |
76 + | + } |
77 + | + |
78 + | + @export |
79 + | + macro TestGotoLabelWithTwoParameters(): Boolean { |
80 + | + try { |
81 + | + LabelTestHelper3() otherwise Label3; |
82 + | + } |
83 + | + label Label3(o: Oddball, smi: Smi) { |
84 + | + check(o == Null); |
85 + | + check(smi == 7); |
86 + | + return True; |
87 + | + } |
88 + | + } |
89 + | + |
90 + | + builtin GenericBuiltinTest<T: type>(_c: Context, _param: T): Object { |
91 + | + return Null; |
92 + | + } |
93 + | + |
94 + | + GenericBuiltinTest<Object>(_c: Context, param: Object): Object { |
95 + | + return param; |
96 + | + } |
97 + | + |
98 + | + @export |
99 + | + macro TestBuiltinSpecialization(c: Context) { |
100 + | + check(GenericBuiltinTest<Smi>(c, 0) == Null); |
101 + | + check(GenericBuiltinTest<Smi>(c, 1) == Null); |
102 + | + check(GenericBuiltinTest<Object>(c, Undefined) == Undefined); |
103 + | + check(GenericBuiltinTest<Object>(c, Undefined) == Undefined); |
104 + | + } |
105 + | + |
106 + | + macro LabelTestHelper4(flag: constexpr bool): never |
107 + | + labels Label4, Label5 { |
108 + | + if constexpr (flag) { |
109 + | + goto Label4; |
110 + | + } else { |
111 + | + goto Label5; |
112 + | + } |
113 + | + } |
114 + | + |
115 + | + macro CallLabelTestHelper4(flag: constexpr bool): bool { |
116 + | + try { |
117 + | + LabelTestHelper4(flag) otherwise Label4, Label5; |
118 + | + } |
119 + | + label Label4 { |
120 + | + return true; |
121 + | + } |
122 + | + label Label5 { |
123 + | + return false; |
124 + | + } |
125 + | + } |
126 + | + |
127 + | + @export |
128 + | + macro TestPartiallyUnusedLabel(): Boolean { |
129 + | + const r1: bool = CallLabelTestHelper4(true); |
130 + | + const r2: bool = CallLabelTestHelper4(false); |
131 + | + |
132 + | + if (r1 && !r2) { |
133 + | + return True; |
134 + | + } else { |
135 + | + return False; |
136 + | + } |
137 + | + } |
138 + | + |
139 + | + macro GenericMacroTest<T: type>(_param: T): Object { |
140 + | + return Undefined; |
141 + | + } |
142 + | + |
143 + | + GenericMacroTest<Object>(param2: Object): Object { |
144 + | + return param2; |
145 + | + } |
146 + | + |
147 + | + macro GenericMacroTestWithLabels<T: type>(_param: T): Object |
148 + | + labels _X { |
149 + | + return Undefined; |
150 + | + } |
151 + | + |
152 + | + GenericMacroTestWithLabels<Object>(param2: Object): Object |
153 + | + labels Y { |
154 + | + return Cast<Smi>(param2) otherwise Y; |
155 + | + } |
156 + | + |
157 + | + @export |
158 + | + macro TestMacroSpecialization() { |
159 + | + try { |
160 + | + const _smi0: Smi = 0; |
161 + | + check(GenericMacroTest<Smi>(0) == Undefined); |
162 + | + check(GenericMacroTest<Smi>(1) == Undefined); |
163 + | + check(GenericMacroTest<Object>(Null) == Null); |
164 + | + check(GenericMacroTest<Object>(False) == False); |
165 + | + check(GenericMacroTest<Object>(True) == True); |
166 + | + check((GenericMacroTestWithLabels<Smi>(0) otherwise Fail) == Undefined); |
167 + | + check((GenericMacroTestWithLabels<Smi>(0) otherwise Fail) == Undefined); |
168 + | + try { |
169 + | + GenericMacroTestWithLabels<Object>(False) otherwise Expected; |
170 + | + } |
171 + | + label Expected {} |
172 + | + } |
173 + | + label Fail { |
174 + | + unreachable; |
175 + | + } |
176 + | + } |
177 + | + |
178 + | + builtin TestHelperPlus1(_context: Context, x: Smi): Smi { |
179 + | + return x + 1; |
180 + | + } |
181 + | + builtin TestHelperPlus2(_context: Context, x: Smi): Smi { |
182 + | + return x + 2; |
183 + | + } |
184 + | + |
185 + | + @export |
186 + | + macro TestFunctionPointers(implicit context: Context)(): Boolean { |
187 + | + let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1; |
188 + | + check(fptr(context, 42) == 43); |
189 + | + fptr = TestHelperPlus2; |
190 + | + check(fptr(context, 42) == 44); |
191 + | + return True; |
192 + | + } |
193 + | + |
194 + | + @export |
195 + | + macro TestVariableRedeclaration(implicit context: Context)(): Boolean { |
196 + | + let _var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1; |
197 + | + let _var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0; |
198 + | + return True; |
199 + | + } |
200 + | + |
201 + | + @export |
202 + | + macro TestTernaryOperator(x: Smi): Smi { |
203 + | + const b: bool = x < 0 ? true : false; |
204 + | + return b ? x - 10 : x + 100; |
205 + | + } |
206 + | + |
207 + | + @export |
208 + | + macro TestFunctionPointerToGeneric(c: Context) { |
209 + | + const fptr1: builtin(Context, Smi) => Object = GenericBuiltinTest<Smi>; |
210 + | + const fptr2: builtin(Context, Object) => Object = |
211 + | + GenericBuiltinTest<Object>; |
212 + | + |
213 + | + check(fptr1(c, 0) == Null); |
214 + | + check(fptr1(c, 1) == Null); |
215 + | + check(fptr2(c, Undefined) == Undefined); |
216 + | + check(fptr2(c, Undefined) == Undefined); |
217 + | + } |
218 + | + |
219 + | + type ObjectToObject = builtin(Context, Object) => Object; |
220 + | + @export |
221 + | + macro TestTypeAlias(x: ObjectToObject): BuiltinPtr { |
222 + | + return x; |
223 + | + } |
224 + | + |
225 + | + @export |
226 + | + macro TestUnsafeCast(implicit context: Context)(n: Number): Boolean { |
227 + | + if (TaggedIsSmi(n)) { |
228 + | + const m: Smi = UnsafeCast<Smi>(n); |
229 + | + |
230 + | + check(TestHelperPlus1(context, m) == 11); |
231 + | + return True; |
232 + | + } |
233 + | + return False; |
234 + | + } |
235 + | + |
236 + | + @export |
237 + | + macro TestHexLiteral() { |
238 + | + check(Convert<intptr>(0xffff) + 1 == 0x10000); |
239 + | + check(Convert<intptr>(-0xffff) == -65535); |
240 + | + } |
241 + | + |
242 + | + @export |
243 + | + macro TestLargeIntegerLiterals(implicit c: Context)() { |
244 + | + let _x: int32 = 0x40000000; |
245 + | + let _y: int32 = 0x7fffffff; |
246 + | + } |
247 + | + |
248 + | + @export |
249 + | + macro TestMultilineAssert() { |
250 + | + const someVeryLongVariableNameThatWillCauseLineBreaks: Smi = 5; |
251 + | + check( |
252 + | + someVeryLongVariableNameThatWillCauseLineBreaks > 0 && |
253 + | + someVeryLongVariableNameThatWillCauseLineBreaks < 10); |
254 + | + } |
255 + | + |
256 + | + @export |
257 + | + macro TestNewlineInString() { |
258 + | + Print('Hello, World!\n'); |
259 + | + } |
260 + | + |
261 + | + const kConstexprConst: constexpr int31 = 5; |
262 + | + const kIntptrConst: intptr = 4; |
263 + | + const kSmiConst: Smi = 3; |
264 + | + |
265 + | + @export |
266 + | + macro TestModuleConstBindings() { |
267 + | + check(kConstexprConst == Int32Constant(5)); |
268 + | + check(kIntptrConst == 4); |
269 + | + check(kSmiConst == 3); |
270 + | + } |
271 + | + |
272 + | + @export |
273 + | + macro TestLocalConstBindings() { |
274 + | + const x: constexpr int31 = 3; |
275 + | + const xSmi: Smi = x; |
276 + | + { |
277 + | + const x: Smi = x + FromConstexpr<Smi>(1); |
278 + | + check(x == xSmi + 1); |
279 + | + const xSmi: Smi = x; |
280 + | + check(x == xSmi); |
281 + | + check(x == 4); |
282 + | + } |
283 + | + check(xSmi == 3); |
284 + | + check(x == xSmi); |
285 + | + } |
286 + | + |
287 + | + struct TestStructA { |
288 + | + indexes: FixedArray; |
289 + | + i: Smi; |
290 + | + k: Number; |
291 + | + } |
292 + | + |
293 + | + struct TestStructB { |
294 + | + x: TestStructA; |
295 + | + y: Smi; |
296 + | + } |
297 + | + |
298 + | + @export |
299 + | + macro TestStruct1(i: TestStructA): Smi { |
300 + | + return i.i; |
301 + | + } |
302 + | + |
303 + | + @export |
304 + | + macro TestStruct2(implicit context: Context)(): TestStructA { |
305 + | + return TestStructA{ |
306 + | + indexes: UnsafeCast<FixedArray>(kEmptyFixedArray), |
307 + | + i: 27, |
308 + | + k: 31 |
309 + | + }; |
310 + | + } |
311 + | + |
312 + | + @export |
313 + | + macro TestStruct3(implicit context: Context)(): TestStructA { |
314 + | + let a: TestStructA = |
315 + | + TestStructA{indexes: UnsafeCast<FixedArray>(kEmptyFixedArray), i: 13, k: 5}; |
316 + | + let _b: TestStructA = a; |
317 + | + const c: TestStructA = TestStruct2(); |
318 + | + a.i = TestStruct1(c); |
319 + | + a.k = a.i; |
320 + | + let d: TestStructB; |
321 + | + d.x = a; |
322 + | + d = TestStructB{x: a, y: 7}; |
323 + | + let _e: TestStructA = d.x; |
324 + | + let f: Smi = TestStructA{ |
325 + | + indexes: UnsafeCast<FixedArray>(kEmptyFixedArray), |
326 + | + i: 27, |
327 + | + k: 31 |
328 + | + }.i; |
329 + | + f = TestStruct2().i; |
330 + | + return a; |
331 + | + } |
332 + | + |
333 + | + struct TestStructC { |
334 + | + x: TestStructA; |
335 + | + y: TestStructA; |
336 + | + } |
337 + | + |
338 + | + @export |
339 + | + macro TestStruct4(implicit context: Context)(): TestStructC { |
340 + | + return TestStructC{x: TestStruct2(), y: TestStruct2()}; |
341 + | + } |
342 + | + |
343 + | + macro TestStructInLabel(implicit context: Context)(): never labels |
344 + | + Foo(TestStructA) { |
345 + | + goto Foo(TestStruct2()); |
346 + | + } |
347 + | + @export // Silence unused warning. |
348 + | + macro CallTestStructInLabel(implicit context: Context)() { |
349 + | + try { |
350 + | + TestStructInLabel() otherwise Foo; |
351 + | + } |
352 + | + label Foo(_s: TestStructA) {} |
353 + | + } |
354 + | + |
355 + | + // This macro tests different versions of the for-loop where some parts |
356 + | + // are (not) present. |
357 + | + @export |
358 + | + macro TestForLoop() { |
359 + | + let sum: Smi = 0; |
360 + | + for (let i: Smi = 0; i < 5; ++i) sum += i; |
361 + | + check(sum == 10); |
362 + | + |
363 + | + sum = 0; |
364 + | + let j: Smi = 0; |
365 + | + for (; j < 5; ++j) sum += j; |
366 + | + check(sum == 10); |
367 + | + |
368 + | + sum = 0; |
369 + | + j = 0; |
370 + | + for (; j < 5;) sum += j++; |
371 + | + check(sum == 10); |
372 + | + |
373 + | + // Check that break works. No test expression. |
374 + | + sum = 0; |
375 + | + for (let i: Smi = 0;; ++i) { |
376 + | + if (i == 5) break; |
377 + | + sum += i; |
378 + | + } |
379 + | + check(sum == 10); |
380 + | + |
381 + | + sum = 0; |
382 + | + j = 0; |
383 + | + for (;;) { |
384 + | + if (j == 5) break; |
385 + | + sum += j; |
386 + | + j++; |
387 + | + } |
388 + | + check(sum == 10); |
389 + | + |
390 + | + // The following tests are the same as above, but use continue to skip |
391 + | + // index 3. |
392 + | + sum = 0; |
393 + | + for (let i: Smi = 0; i < 5; ++i) { |
394 + | + if (i == 3) continue; |
395 + | + sum += i; |
396 + | + } |
397 + | + check(sum == 7); |
398 + | + |
399 + | + sum = 0; |
400 + | + j = 0; |
401 + | + for (; j < 5; ++j) { |
402 + | + if (j == 3) continue; |
403 + | + sum += j; |
404 + | + } |
405 + | + check(sum == 7); |
406 + | + |
407 + | + sum = 0; |
408 + | + j = 0; |
409 + | + for (; j < 5;) { |
410 + | + if (j == 3) { |
411 + | + j++; |
412 + | + continue; |
413 + | + } |
414 + | + sum += j; |
415 + | + j++; |
416 + | + } |
417 + | + check(sum == 7); |
418 + | + |
419 + | + sum = 0; |
420 + | + for (let i: Smi = 0;; ++i) { |
421 + | + if (i == 3) continue; |
422 + | + if (i == 5) break; |
423 + | + sum += i; |
424 + | + } |
425 + | + check(sum == 7); |
426 + | + |
427 + | + sum = 0; |
428 + | + j = 0; |
429 + | + for (;;) { |
430 + | + if (j == 3) { |
431 + | + j++; |
432 + | + continue; |
433 + | + } |
434 + | + |
435 + | + if (j == 5) break; |
436 + | + sum += j; |
437 + | + j++; |
438 + | + } |
439 + | + check(sum == 7); |
440 + | + |
441 + | + j = 0; |
442 + | + try { |
443 + | + for (;;) { |
444 + | + if (++j == 10) goto Exit; |
445 + | + } |
446 + | + } |
447 + | + label Exit { |
448 + | + check(j == 10); |
449 + | + } |
450 + | + |
451 + | + // Test if we can handle uninitialized values on the stack. |
452 + | + let _i: Smi; |
453 + | + for (let j: Smi = 0; j < 10; ++j) { |
454 + | + } |
455 + | + } |
456 + | + |
457 + | + @export |
458 + | + macro TestSubtyping(x: Smi) { |
459 + | + const _foo: Object = x; |
460 + | + } |
461 + | + |
462 + | + macro IncrementIfSmi<A: type>(x: A): A { |
463 + | + typeswitch (x) { |
464 + | + case (x: Smi): { |
465 + | + return x + 1; |
466 + | + } |
467 + | + case (o: A): { |
468 + | + return o; |
469 + | + } |
470 + | + } |
471 + | + } |
472 + | + |
473 + | + type NumberOrFixedArray = Number | FixedArray; |
474 + | + macro TypeswitchExample(implicit context: Context)(x: NumberOrFixedArray): |
475 + | + int32 { |
476 + | + let result: int32 = 0; |
477 + | + typeswitch (IncrementIfSmi(x)) { |
478 + | + case (_x: FixedArray): { |
479 + | + result = result + 1; |
480 + | + } |
481 + | + case (Number): { |
482 + | + result = result + 2; |
483 + | + } |
484 + | + } |
485 + | + |
486 + | + result = result * 10; |
487 + | + |
488 + | + typeswitch (IncrementIfSmi(x)) { |
489 + | + case (x: Smi): { |
490 + | + result = result + Convert<int32>(x); |
491 + | + } |
492 + | + case (a: FixedArray): { |
493 + | + result = result + Convert<int32>(a.length); |
494 + | + } |
495 + | + case (_x: HeapNumber): { |
496 + | + result = result + 7; |
497 + | + } |
498 + | + } |
499 + | + |
500 + | + return result; |
501 + | + } |
502 + | + |
503 + | + @export |
504 + | + macro TestTypeswitch(implicit context: Context)() { |
505 + | + check(TypeswitchExample(FromConstexpr<Smi>(5)) == 26); |
506 + | + const a: FixedArray = AllocateZeroedFixedArray(3); |
507 + | + check(TypeswitchExample(a) == 13); |
508 + | + check(TypeswitchExample(FromConstexpr<Number>(0.5)) == 27); |
509 + | + } |
510 + | + |
511 + | + @export |
512 + | + macro TestTypeswitchAsanLsanFailure(implicit context: Context)(obj: Object) { |
513 + | + typeswitch (obj) { |
514 + | + case (_o: Smi): { |
515 + | + } |
516 + | + case (_o: JSTypedArray): { |
517 + | + } |
518 + | + case (_o: JSReceiver): { |
519 + | + } |
520 + | + case (_o: HeapObject): { |
521 + | + } |
522 + | + } |
523 + | + } |
524 + | + |
525 + | + macro ExampleGenericOverload<A: type>(o: Object): A { |
526 + | + return o; |
527 + | + } |
528 + | + macro ExampleGenericOverload<A: type>(o: Smi): A { |
529 + | + return o + 1; |
530 + | + } |
531 + | + |
532 + | + @export |
533 + | + macro TestGenericOverload(implicit context: Context)() { |
534 + | + const xSmi: Smi = 5; |
535 + | + const xObject: Object = xSmi; |
536 + | + check(ExampleGenericOverload<Smi>(xSmi) == 6); |
537 + | + check(UnsafeCast<Smi>(ExampleGenericOverload<Object>(xObject)) == 5); |
538 + | + } |
539 + | + |
540 + | + @export |
541 + | + macro TestEquality(implicit context: Context)() { |
542 + | + const notEqual: bool = |
543 + | + AllocateHeapNumberWithValue(0.5) != AllocateHeapNumberWithValue(0.5); |
544 + | + check(!notEqual); |
545 + | + const equal: bool = |
546 + | + AllocateHeapNumberWithValue(0.5) == AllocateHeapNumberWithValue(0.5); |
547 + | + check(equal); |
548 + | + } |
549 + | + |
550 + | + macro BoolToBranch(x: bool): never |
551 + | + labels Taken, NotTaken { |
552 + | + if (x) { |
553 + | + goto Taken; |
554 + | + } else { |
555 + | + goto NotTaken; |
556 + | + } |
557 + | + } |
558 + | + |
559 + | + @export |
560 + | + macro TestOrAnd1(x: bool, y: bool, z: bool): bool { |
561 + | + return BoolToBranch(x) || y && z ? true : false; |
562 + | + } |
563 + | + |
564 + | + @export |
565 + | + macro TestOrAnd2(x: bool, y: bool, z: bool): bool { |
566 + | + return x || BoolToBranch(y) && z ? true : false; |
567 + | + } |
568 + | + |
569 + | + @export |
570 + | + macro TestOrAnd3(x: bool, y: bool, z: bool): bool { |
571 + | + return x || y && BoolToBranch(z) ? true : false; |
572 + | + } |
573 + | + |
574 + | + @export |
575 + | + macro TestAndOr1(x: bool, y: bool, z: bool): bool { |
576 + | + return BoolToBranch(x) && y || z ? true : false; |
577 + | + } |
578 + | + |
579 + | + @export |
580 + | + macro TestAndOr2(x: bool, y: bool, z: bool): bool { |
581 + | + return x && BoolToBranch(y) || z ? true : false; |
582 + | + } |
583 + | + |
584 + | + @export |
585 + | + macro TestAndOr3(x: bool, y: bool, z: bool): bool { |
586 + | + return x && y || BoolToBranch(z) ? true : false; |
587 + | + } |
588 + | + |
589 + | + @export |
590 + | + macro TestLogicalOperators() { |
591 + | + check(TestAndOr1(true, true, true)); |
592 + | + check(TestAndOr2(true, true, true)); |
593 + | + check(TestAndOr3(true, true, true)); |
594 + | + check(TestAndOr1(true, true, false)); |
595 + | + check(TestAndOr2(true, true, false)); |
596 + | + check(TestAndOr3(true, true, false)); |
597 + | + check(TestAndOr1(true, false, true)); |
598 + | + check(TestAndOr2(true, false, true)); |
599 + | + check(TestAndOr3(true, false, true)); |
600 + | + check(!TestAndOr1(true, false, false)); |
601 + | + check(!TestAndOr2(true, false, false)); |
602 + | + check(!TestAndOr3(true, false, false)); |
603 + | + check(TestAndOr1(false, true, true)); |
604 + | + check(TestAndOr2(false, true, true)); |
605 + | + check(TestAndOr3(false, true, true)); |
606 + | + check(!TestAndOr1(false, true, false)); |
607 + | + check(!TestAndOr2(false, true, false)); |
608 + | + check(!TestAndOr3(false, true, false)); |
609 + | + check(TestAndOr1(false, false, true)); |
610 + | + check(TestAndOr2(false, false, true)); |
611 + | + check(TestAndOr3(false, false, true)); |
612 + | + check(!TestAndOr1(false, false, false)); |
613 + | + check(!TestAndOr2(false, false, false)); |
614 + | + check(!TestAndOr3(false, false, false)); |
615 + | + check(TestOrAnd1(true, true, true)); |
616 + | + check(TestOrAnd2(true, true, true)); |
617 + | + check(TestOrAnd3(true, true, true)); |
618 + | + check(TestOrAnd1(true, true, false)); |
619 + | + check(TestOrAnd2(true, true, false)); |
620 + | + check(TestOrAnd3(true, true, false)); |
621 + | + check(TestOrAnd1(true, false, true)); |
622 + | + check(TestOrAnd2(true, false, true)); |
623 + | + check(TestOrAnd3(true, false, true)); |
624 + | + check(TestOrAnd1(true, false, false)); |
625 + | + check(TestOrAnd2(true, false, false)); |
626 + | + check(TestOrAnd3(true, false, false)); |
627 + | + check(TestOrAnd1(false, true, true)); |
628 + | + check(TestOrAnd2(false, true, true)); |
629 + | + check(TestOrAnd3(false, true, true)); |
630 + | + check(!TestOrAnd1(false, true, false)); |
631 + | + check(!TestOrAnd2(false, true, false)); |
632 + | + check(!TestOrAnd3(false, true, false)); |
633 + | + check(!TestOrAnd1(false, false, true)); |
634 + | + check(!TestOrAnd2(false, false, true)); |
635 + | + check(!TestOrAnd3(false, false, true)); |
636 + | + check(!TestOrAnd1(false, false, false)); |
637 + | + check(!TestOrAnd2(false, false, false)); |
638 + | + check(!TestOrAnd3(false, false, false)); |
639 + | + } |
640 + | + |
641 + | + @export |
642 + | + macro TestCall(i: Smi): Smi labels A { |
643 + | + if (i < 5) return i; |
644 + | + goto A; |
645 + | + } |
646 + | + |
647 + | + @export |
648 + | + macro TestOtherwiseWithCode1() { |
649 + | + let v: Smi = 0; |
650 + | + let s: Smi = 1; |
651 + | + try { |
652 + | + TestCall(10) otherwise goto B(++s); |
653 + | + } |
654 + | + label B(v1: Smi) { |
655 + | + v = v1; |
656 + | + } |
657 + | + assert(v == 2); |
658 + | + } |
659 + | + |
660 + | + @export |
661 + | + macro TestOtherwiseWithCode2() { |
662 + | + let s: Smi = 0; |
663 + | + for (let i: Smi = 0; i < 10; ++i) { |
664 + | + TestCall(i) otherwise break; |
665 + | + ++s; |
666 + | + } |
667 + | + assert(s == 5); |
668 + | + } |
669 + | + |
670 + | + @export |
671 + | + macro TestOtherwiseWithCode3() { |
672 + | + let s: Smi = 0; |
673 + | + for (let i: Smi = 0; i < 10; ++i) { |
674 + | + s += TestCall(i) otherwise break; |
675 + | + } |
676 + | + assert(s == 10); |
677 + | + } |
678 + | + |
679 + | + @export |
680 + | + macro TestForwardLabel() { |
681 + | + try { |
682 + | + goto A; |
683 + | + } |
684 + | + label A { |
685 + | + goto B(5); |
686 + | + } |
687 + | + label B(b: Smi) { |
688 + | + assert(b == 5); |
689 + | + } |
690 + | + } |
691 + | + |
692 + | + @export |
693 + | + macro TestQualifiedAccess(implicit context: Context)() { |
694 + | + const s: Smi = 0; |
695 + | + check(!array::IsJSArray(s)); |
696 + | + } |
697 + | + |
698 + | + @export |
699 + | + macro TestCatch1(implicit context: Context)(): Smi { |
700 + | + let r: Smi = 0; |
701 + | + try { |
702 + | + ThrowTypeError(kInvalidArrayLength); |
703 + | + } catch (_e) { |
704 + | + r = 1; |
705 + | + return r; |
706 + | + } |
707 + | + } |
708 + | + |
709 + | + @export |
710 + | + macro TestCatch2Wrapper(implicit context: Context)(): never { |
711 + | + ThrowTypeError(kInvalidArrayLength); |
712 + | + } |
713 + | + |
714 + | + @export |
715 + | + macro TestCatch2(implicit context: Context)(): Smi { |
716 + | + let r: Smi = 0; |
717 + | + try { |
718 + | + TestCatch2Wrapper(); |
719 + | + } catch (_e) { |
720 + | + r = 2; |
721 + | + return r; |
722 + | + } |
723 + | + } |
724 + | + |
725 + | + @export |
726 + | + macro TestCatch3WrapperWithLabel(implicit context: Context)(): |
727 + | + never labels _Abort { |
728 + | + ThrowTypeError(kInvalidArrayLength); |
729 + | + } |
730 + | + |
731 + | + @export |
732 + | + macro TestCatch3(implicit context: Context)(): Smi { |
733 + | + let r: Smi = 0; |
734 + | + try { |
735 + | + TestCatch3WrapperWithLabel() otherwise Abort; |
736 + | + } |
737 + | + label Abort { |
738 + | + return -1; |
739 + | + } |
740 + | + catch (_e) { |
741 + | + r = 2; |
742 + | + return r; |
743 + | + } |
744 + | + } |
745 + | + |
746 + | + // This test doesn't actually test the functionality of iterators, |
747 + | + // it's only purpose is to make sure tha the CSA macros in the |
748 + | + // IteratorBuiltinsAssembler match the signatures provided in |
749 + | + // iterator.tq. |
750 + | + @export |
751 + | + macro TestIterator(implicit context: Context)(o: JSReceiver, map: Map) { |
752 + | + try { |
753 + | + const t1: Object = iterator::GetIteratorMethod(o); |
754 + | + const t2: iterator::IteratorRecord = iterator::GetIterator(o); |
755 + | + |
756 + | + const _t3: Object = iterator::IteratorStep(t2) otherwise Fail; |
757 + | + const _t4: Object = iterator::IteratorStep(t2, map) otherwise Fail; |
758 + | + |
759 + | + const t5: Object = iterator::IteratorValue(o); |
760 + | + const _t6: Object = iterator::IteratorValue(o, map); |
761 + | + |
762 + | + const _t7: JSArray = iterator::IterableToList(t1, t1); |
763 + | + |
764 + | + iterator::IteratorCloseOnException(t2, t5); |
765 + | + } |
766 + | + label Fail {} |
767 + | + } |
768 + | + |
769 + | + @export |
770 + | + macro TestFrame1(implicit context: Context)() { |
771 + | + const f: Frame = LoadFramePointer(); |
772 + | + const frameType: FrameType = |
773 + | + Cast<FrameType>(f.context_or_frame_type) otherwise unreachable; |
774 + | + assert(frameType == STUB_FRAME); |
775 + | + assert(f.caller == LoadParentFramePointer()); |
776 + | + typeswitch (f) { |
777 + | + case (_f: StandardFrame): { |
778 + | + unreachable; |
779 + | + } |
780 + | + case (_f: ArgumentsAdaptorFrame): { |
781 + | + unreachable; |
782 + | + } |
783 + | + case (_f: StubFrame): { |
784 + | + } |
785 + | + } |
786 + | + } |
787 + | + |
788 + | + @export |
789 + | + macro TestNew(implicit context: Context)() { |
790 + | + const f: JSArray = NewJSArray(); |
791 + | + check(f.IsEmpty()); |
792 + | + f.length = 0; |
793 + | + } |
794 + | + |
795 + | + struct TestInner { |
796 + | + SetX(newValue: int32) { |
797 + | + this.x = newValue; |
798 + | + } |
799 + | + GetX(): int32 { |
800 + | + return this.x; |
801 + | + } |
802 + | + x: int32; |
803 + | + y: int32; |
804 + | + } |
805 + | + |
806 + | + struct TestOuter { |
807 + | + a: int32; |
808 + | + b: TestInner; |
809 + | + c: int32; |
810 + | + } |
811 + | + |
812 + | + @export |
813 + | + macro TestStructConstructor(implicit context: Context)() { |
814 + | + // Test default constructor |
815 + | + let a: TestOuter = TestOuter{a: 5, b: TestInner{x: 6, y: 7}, c: 8}; |
816 + | + check(a.a == 5); |
817 + | + check(a.b.x == 6); |
818 + | + check(a.b.y == 7); |
819 + | + check(a.c == 8); |
820 + | + a.b.x = 1; |
821 + | + check(a.b.x == 1); |
822 + | + a.b.SetX(2); |
823 + | + check(a.b.x == 2); |
824 + | + check(a.b.GetX() == 2); |
825 + | + } |
826 + | + |
827 + | + class InternalClass extends Struct { |
828 + | + Flip() labels NotASmi { |
829 + | + const tmp = Cast<Smi>(this.b) otherwise NotASmi; |
830 + | + this.b = this.a; |
831 + | + this.a = tmp; |
832 + | + } |
833 + | + a: Smi; |
834 + | + b: Number; |
835 + | + } |
836 + | + |
837 + | + macro NewInternalClass(x: Smi): InternalClass { |
838 + | + return new InternalClass{a: x, b: x + 1}; |
839 + | + } |
840 + | + |
841 + | + @export |
842 + | + macro TestInternalClass(implicit context: Context)() { |
843 + | + const o = NewInternalClass(5); |
844 + | + o.Flip() otherwise unreachable; |
845 + | + check(o.a == 6); |
846 + | + check(o.b == 5); |
847 + | + } |
848 + | + |
849 + | + struct StructWithConst { |
850 + | + TestMethod1(): int32 { |
851 + | + return this.b; |
852 + | + } |
853 + | + TestMethod2(): Object { |
854 + | + return this.a; |
855 + | + } |
856 + | + a: Object; |
857 + | + const b: int32; |
858 + | + } |
859 + | + |
860 + | + @export |
861 + | + macro TestConstInStructs() { |
862 + | + const x = StructWithConst{a: Null, b: 1}; |
863 + | + let y = StructWithConst{a: Null, b: 1}; |
864 + | + y.a = Undefined; |
865 + | + const _copy = x; |
866 + | + |
867 + | + check(x.TestMethod1() == 1); |
868 + | + check(x.TestMethod2() == Null); |
869 + | + } |
870 + | + |
871 + | + struct TestIterator { |
872 + | + Next(): Object labels NoMore { |
873 + | + if (this.count-- == 0) goto NoMore; |
874 + | + return TheHole; |
875 + | + } |
876 + | + count: Smi; |
877 + | + } |
878 + | + |
879 + | + @export |
880 + | + macro TestNewFixedArrayFromSpread(implicit context: Context)(): Object { |
881 + | + let i = TestIterator{count: 5}; |
882 + | + return new FixedArray{map: kFixedArrayMap, length: 5, objects: ...i}; |
883 + | + } |
884 + | + |
885 + | + class SmiPair extends Struct { |
886 + | + GetA():&Smi { |
887 + | + return & this.a; |
888 + | + } |
889 + | + a: Smi; |
890 + | + b: Smi; |
891 + | + } |
892 + | + |
893 + | + macro Swap<T: type>(a:&T, b:&T) { |
894 + | + const tmp = * a; |
895 + | + * a = * b; |
896 + | + * b = tmp; |
897 + | + } |
898 + | + |
899 + | + @export |
900 + | + macro TestReferences() { |
901 + | + const array = new SmiPair{a: 7, b: 2}; |
902 + | + const ref:&Smi = & array.a; |
903 + | + * ref = 3 + * ref; |
904 + | + -- * ref; |
905 + | + Swap(& array.b, array.GetA()); |
906 + | + check(array.a == 2); |
907 + | + check(array.b == 9); |
908 + | + } |
909 + | + |
910 + | + @export |
911 + | + macro TestStaticAssert() { |
912 + | + StaticAssert(1 + 2 == 3); |
913 + | + } |
914 + | + |
915 + | + class SmiBox extends Struct { |
916 + | + value: Smi; |
917 + | + unrelated: Smi; |
918 + | + } |
919 + | + |
920 + | + builtin NewSmiBox(implicit context: Context)(value: Smi): SmiBox { |
921 + | + return new SmiBox{value, unrelated: 0}; |
922 + | + } |
923 + | + |
924 + | + @export |
925 + | + macro TestLoadEliminationFixed(implicit context: Context)() { |
926 + | + const box = NewSmiBox(123); |
927 + | + const v1 = box.value; |
928 + | + box.unrelated = 999; |
929 + | + const v2 = (box.unrelated == 0) ? box.value : box.value; |
930 + | + StaticAssert(WordEqual(v1, v2)); |
931 + | + |
932 + | + box.value = 11; |
933 + | + const v3 = box.value; |
934 + | + const eleven: Smi = 11; |
935 + | + StaticAssert(WordEqual(v3, eleven)); |
936 + | + } |
937 + | + |
938 + | + @export |
939 + | + macro TestLoadEliminationVariable(implicit context: Context)() { |
940 + | + const a = UnsafeCast<FixedArray>(kEmptyFixedArray); |
941 + | + const box = NewSmiBox(1); |
942 + | + const v1 = a.objects[box.value]; |
943 + | + const u1 = a.objects[box.value + 2]; |
944 + | + const v2 = a.objects[box.value]; |
945 + | + const u2 = a.objects[box.value + 2]; |
946 + | + StaticAssert(WordEqual(v1, v2)); |
947 + | + StaticAssert(WordEqual(u1, u2)); |
948 + | + } |
949 + | + |
950 + | + @export |
951 + | + macro TestRedundantArrayElementCheck(implicit context: Context)(): Smi { |
952 + | + const a = kEmptyFixedArray; |
953 + | + for (let i: Smi = 0; i < a.length; i++) { |
954 + | + if (a.objects[i] == TheHole) { |
955 + | + if (a.objects[i] == TheHole) { |
956 + | + return -1; |
957 + | + } else { |
958 + | + StaticAssert(false); |
959 + | + } |
960 + | + } |
961 + | + } |
962 + | + return 1; |
963 + | + } |
964 + | + |
965 + | + @export |
966 + | + macro TestRedundantSmiCheck(implicit context: Context)(): Smi { |
967 + | + const a = kEmptyFixedArray; |
968 + | + const x = a.objects[1]; |
969 + | + typeswitch (x) { |
970 + | + case (Smi): { |
971 + | + Cast<Smi>(x) otherwise VerifiedUnreachable(); |
972 + | + return -1; |
973 + | + } |
974 + | + case (Object): { |
975 + | + } |
976 + | + } |
977 + | + return 1; |
978 + | + } |
979 + | + |
980 + | + struct SBox<T: type> { |
981 + | + value: T; |
982 + | + } |
983 + | + |
984 + | + @export |
985 + | + macro TestGenericStruct1(): intptr { |
986 + | + const i: intptr = 123; |
987 + | + let box = SBox<intptr>{value: i}; |
988 + | + let boxbox = SBox<SBox<intptr>>{value: box}; |
989 + | + check(box.value == 123); |
990 + | + boxbox.value.value *= 2; |
991 + | + check(boxbox.value.value == 246); |
992 + | + return boxbox.value.value; |
993 + | + } |
994 + | + |
995 + | + struct TestTuple<T1: type, T2: type> { |
996 + | + const fst: T1; |
997 + | + const snd: T2; |
998 + | + } |
999 + | + |
1000 + | + macro Swap<T1: type, T2: type>(tuple: TestTuple<T1, T2>): |
1001 + | + TestTuple<T2, T1> { |
1002 + | + return TestTuple<T2, T1>{fst: tuple.snd, snd: tuple.fst}; |
1003 + | + } |
1004 + | + |
1005 + | + @export |
1006 + | + macro TestGenericStruct2(): TestTuple<Smi, intptr> { |
1007 + | + const intptrAndSmi = TestTuple<intptr, Smi>{fst: 1, snd: 2}; |
1008 + | + const smiAndIntptr = Swap<intptr, Smi>(intptrAndSmi); |
1009 + | + check(intptrAndSmi.fst == smiAndIntptr.snd); |
1010 + | + check(intptrAndSmi.snd == smiAndIntptr.fst); |
1011 + | + return smiAndIntptr; |
1012 + | + } |
1013 + | + |
1014 + | +} |