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) -> i32 { (*p)++; ${f.expect_order(2)} return 0; } fn c(p : ptr) -> i32 { if (*p == 1) { ${f.expect_order(3)} } else { ${f.expect_order(1)} } return 0; }`, })); });