Handling undefined in shader functions is a whole set of problems. Because undefined as a value doesn't exist on the GPU, yet undefined behavior does, users can wrongly depend on checks against an empty array item under the assumption that it will fail, yet the GPU will happily read from outside of the bounds of the array and give a truthy value.
Let's say we have a function like this:
function foo() {
'use gpu';
const arr = [1, 2, 3];
while (true) {
if (!arr[i]) {
break;
}
// ...
}
}
Currently, we will generate the following WGSL:
fn foo() {
var arr = array<i32>(1, 2, 3);
while (true) {
if (!arr[i]) { // WILL read outside of the array, potentially infinite loop
break;
}
// ...
}
}
It's very hard to exhaustively track whether something can or can't be undefined by tracing through the program, and then again we'd have to verify that devs don't depend on the value being undefined or not.
Solution
My current solution to this problem, is to recognize that coercing non-bool primitives to bool in WGSL is equivalent to comparing them to 0.
let a = bool(1);
// same thing
let b = 1 != 0;
When coercing numbers to bool in JavaScript, there are many more cases where the result can be false:
!!(0) -> false
!!(NaN) -> false
!!(undefined) -> false
- (a few more...)
We can use that fact to nudge users in the right direction, to state their intent. I think we should throw a descriptive error each time a runtime-known value is coerced/cast into a boolean, and require devs to change it to a more explicit form.
What about comptime
Comptime-known values are fine to coerce to bools 👍
Handling
undefinedin shader functions is a whole set of problems. Becauseundefinedas a value doesn't exist on the GPU, yetundefined behaviordoes, users can wrongly depend on checks against an empty array item under the assumption that it will fail, yet the GPU will happily read from outside of the bounds of the array and give a truthy value.Let's say we have a function like this:
Currently, we will generate the following WGSL:
It's very hard to exhaustively track whether something can or can't be
undefinedby tracing through the program, and then again we'd have to verify that devs don't depend on the value being undefined or not.Solution
My current solution to this problem, is to recognize that coercing non-bool primitives to
boolin WGSL is equivalent to comparing them to0.When coercing numbers to
boolin JavaScript, there are many more cases where the result can befalse:!!(0)->false!!(NaN)->false!!(undefined)->falseWe can use that fact to nudge users in the right direction, to state their intent. I think we should throw a descriptive error each time a runtime-known value is coerced/cast into a boolean, and require devs to change it to a more explicit form.
What about comptime
Comptime-known values are fine to coerce to bools 👍