| export const description = ` |
| Flow control tests for function calls. |
| `; |
| |
| import { makeTestGroup } from '../../../../common/framework/test_group.js'; |
| import { AllFeaturesMaxLimitsGPUTest } from '../../../gpu_test.js'; |
| |
| import { runFlowControlTest } from './harness.js'; |
| |
| export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest); |
| |
| g.test('call_basic') |
| .desc('Test that flow control enters a called function') |
| .params(u => u.combine('preventValueOptimizations', [true, false])) |
| .fn(t => { |
| runFlowControlTest(t, f => ({ |
| entrypoint: ` |
| ${f.expect_order(0)} |
| f(); |
| ${f.expect_order(2)} |
| `, |
| extra: ` |
| fn f() { |
| ${f.expect_order(1)} |
| }`, |
| })); |
| }); |
| |
| g.test('call_nested') |
| .desc('Test that flow control enters a nested function calls') |
| .params(u => u.combine('preventValueOptimizations', [true, false])) |
| .fn(t => { |
| runFlowControlTest(t, f => ({ |
| entrypoint: ` |
| ${f.expect_order(0)} |
| a(); |
| ${f.expect_order(6)} |
| `, |
| extra: ` |
| fn a() { |
| ${f.expect_order(1)} |
| b(); |
| ${f.expect_order(5)} |
| } |
| fn b() { |
| ${f.expect_order(2)} |
| c(); |
| ${f.expect_order(4)} |
| } |
| fn c() { |
| ${f.expect_order(3)} |
| }`, |
| })); |
| }); |
| |
| g.test('call_repeated') |
| .desc('Test that flow control enters a nested function calls') |
| .params(u => u.combine('preventValueOptimizations', [true, false])) |
| .fn(t => { |
| runFlowControlTest(t, f => ({ |
| entrypoint: ` |
| ${f.expect_order(0)} |
| a(); |
| ${f.expect_order(10)} |
| `, |
| extra: ` |
| fn a() { |
| ${f.expect_order(1)} |
| b(); |
| ${f.expect_order(5)} |
| b(); |
| ${f.expect_order(9)} |
| } |
| fn b() { |
| ${f.expect_order(2, 6)} |
| c(); |
| ${f.expect_order(4, 8)} |
| } |
| fn c() { |
| ${f.expect_order(3, 7)} |
| }`, |
| })); |
| }); |
| |
| g.test('arg_eval') |
| .desc('Test that arguments are evaluated left to right') |
| .params(u => u.combine('preventValueOptimizations', [true, false])) |
| .fn(t => { |
| runFlowControlTest(t, f => ({ |
| entrypoint: ` |
| ${f.expect_order(0)} |
| a(b(), c(), d()); |
| ${f.expect_order(5)} |
| `, |
| extra: ` |
| fn a(p1 : u32, p2 : u32, p3 : u32) { |
| ${f.expect_order(4)} |
| } |
| fn b() -> u32 { |
| ${f.expect_order(1)} |
| return 0; |
| } |
| fn c() -> u32 { |
| ${f.expect_order(2)} |
| return 0; |
| } |
| fn d() -> u32 { |
| ${f.expect_order(3)} |
| return 0; |
| }`, |
| })); |
| }); |
| |
| g.test('arg_eval_logical_and') |
| .desc('Test that arguments are evaluated left to right') |
| .params(u => u.combine('preventValueOptimizations', [true, false])) |
| .fn(t => { |
| runFlowControlTest(t, f => ({ |
| entrypoint: ` |
| ${f.expect_order(0)} |
| a(b(${f.value(1)}) && c()); |
| a(b(${f.value(0)}) && c()); |
| ${f.expect_order(6)} |
| `, |
| extra: ` |
| fn a(p : bool) { |
| ${f.expect_order(3, 5)} |
| } |
| fn b(x : i32) -> bool { |
| ${f.expect_order(1, 4)} |
| return x == 1; |
| } |
| fn c() -> bool { |
| ${f.expect_order(2)} |
| return true; |
| }`, |
| })); |
| }); |
| |
| g.test('arg_eval_logical_or') |
| .desc('Test that arguments are evaluated left to right') |
| .params(u => u.combine('preventValueOptimizations', [true, false])) |
| .fn(t => { |
| runFlowControlTest(t, f => ({ |
| entrypoint: ` |
| ${f.expect_order(0)} |
| a(b(${f.value(1)}) || c()); |
| a(b(${f.value(0)}) || c()); |
| ${f.expect_order(6)} |
| `, |
| extra: ` |
| fn a(p : bool) { |
| ${f.expect_order(3, 5)} |
| } |
| fn b(x : i32) -> bool { |
| ${f.expect_order(1, 4)} |
| return x == 0; |
| } |
| fn c() -> bool { |
| ${f.expect_order(2)} |
| return true; |
| }`, |
| })); |
| }); |
| |
| g.test('arg_eval_pointers') |
| .desc('Test that arguments are evaluated left to right') |
| .params(u => u.combine('preventValueOptimizations', [true, false])) |
| .fn(t => { |
| runFlowControlTest(t, f => ({ |
| entrypoint: ` |
| var x : i32 = ${f.value(0)}; |
| ${f.expect_order(0)} |
| _ = c(&x); |
| a(b(&x), c(&x)); |
| ${f.expect_order(5)} |
| `, |
| extra: ` |
| fn a(p1 : i32, p2 : i32) { |
| ${f.expect_order(4)} |
| } |
| fn b(p : ptr<function, i32>) -> i32 { |
| (*p)++; |
| ${f.expect_order(2)} |
| return 0; |
| } |
| fn c(p : ptr<function, i32>) -> i32 { |
| if (*p == 1) { |
| ${f.expect_order(3)} |
| } else { |
| ${f.expect_order(1)} |
| } |
| return 0; |
| }`, |
| })); |
| }); |