WESL Logo

Advanced Concepts

Mangling

Also see the Name Mangling section of the spec

Name mangling is a common compiler practice of renaming declarations to avoid conflicts when two declarations have the same name. Don’t be surprised if you see functions and structs be renamed in the WGSL output! WESL renames all declarations, except those in the root module (because they are exposed in the host code, as function entry-points, bindings and overrides).

Consider this WESL example:

// file util.rs:
fn foo() { ... }

// file main.rs:
fn foo() { ... }

@compute @workgroup_size(1)
fn main() {
    super::util::foo();
    foo();
}

With name mangling, it generates this:

fn package_util_foo() { ... } // the `foo` funtion from util.rs gets renamed with its mangled absolute path (package::util::foo)

fn foo() { ... } // the `foo` function in the root module is not renamed

@compute @workgroup_size(1)
fn main() {
    package_util_foo(); // references to package::util::foo also get renamed.
    foo();
}

Stripping (Dead Code Elimination)

related discussion: #68

When your WESL linker bundles your shader files into one final WGSL output, it may remove unused declarations. Unused declarations are those not accessed by any entrypoint function or const_asserts (recursively).

In general, code stripping has no observable effect. But in rare cases, it can be the indirect cause of nasty bugs. Here are the things to keep in mind:

Virtual modules and the constant module

related discussion: #74

In many cases shader authors want to write generic shaders that can be specialized for different purposes and constraints. Sometimes, the specialization needs to happen at runtime (e.g., if it depends on the hardware/platform where the shader is executed). WGSL has a mechanism for such specialization: override declarations. But overrides do not cover all use-cases (#74).

WESL has a mechanism called “Virtual Modules”, which creates an importable module that does not exist on the filesystem but contains declarations defined during linker invokation. For convenience, the WESL linkers have a special API to generate a virtual module named constant and push const-declarations to it.

Incremental Conditional Translation

Similarly, there are situations where you want to run the conditional compilation at runtime because the feature flags depend on the hardware/platform. Linkers can help with that by running the translation in two phases:

Behavior of const_asserts and directives

Module-scope const_asserts and directives are only included in the output WGSL if they are declared in the root module or in any module for which one declaration is included. Identical directives accross modules are de-duplicated.

There are additional rules (#71) for directives: