Skip to content

Commit

Permalink
fix(minifier): harden storage selector
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyJasonBennett committed Apr 4, 2023
1 parent 6fe9beb commit 12bcb5d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 19 deletions.
20 changes: 12 additions & 8 deletions src/minifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface MinifyOptions {
const isWord = RegExp.prototype.test.bind(/^\w/)
const isSymbol = RegExp.prototype.test.bind(/[^\w\\]/)
const isName = RegExp.prototype.test.bind(/^[_A-Za-z]/)
const isStorage = RegExp.prototype.test.bind(/^(uniform|in|out|attribute|varying)$/)
const isStorage = RegExp.prototype.test.bind(/^(@|layout|uniform|in|out|attribute|varying)$/)

/**
* Minifies a string of GLSL or WGSL code.
Expand All @@ -28,18 +28,22 @@ export function minify(

const tokens: Token[] = tokenize(code).filter((token) => token.type !== 'whitespace' && token.type !== 'comment')

let mangleIndex: number = 0
let blockIndex: number | null = null
let mangleIndex: number = -1
let lineIndex: number = -1
let blockIndex: number = -1
let minified: string = ''
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i]

// Pad alphanumeric tokens
if (isWord(token.value) && isWord(tokens[i - 1]?.value)) minified += ' '
// Track newlines' offsets
if (/[;{}\\]|^fn$/.test(token.value)) lineIndex = i + 1

// Mark enter/leave block-scope
if (token.value === '{' && isName(tokens[i - 1]?.value)) blockIndex = i - 1
else if (token.value === '}') blockIndex = null
else if (token.value === '}') blockIndex = -1

// Pad alphanumeric tokens
if (isWord(token.value) && isWord(tokens[i - 1]?.value)) minified += ' '

// Pad symbols around #define and three.js #include (white-space sensitive)
if (
Expand All @@ -53,11 +57,11 @@ export function minify(
if (
token.type === 'identifier' &&
// Skip shader externals when disabled
(mangleExternals || (!isStorage(tokens[i - 1]?.value) && !isStorage(tokens[i - 2]?.value))) &&
(mangleExternals || !isStorage(tokens[lineIndex]?.value) || isWord(tokens[i + 1]?.value)) &&
// Is reference, declaration, namespace, or comma-separated list
(mangleMap.has(token.value) ||
// Skip struct properties
(blockIndex == null &&
(blockIndex === -1 &&
(isName(tokens[i - 1]?.value) ||
// uniform Type { ... } name;
(tokens[i - 1]?.value === '}' && tokens[i + 1]?.value === ';') ||
Expand Down
21 changes: 10 additions & 11 deletions tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,21 @@ Map {
}
`;
exports[`minify > can mangle WGSL 1`] = `"struct a{intensity:f32,position:vec3<f32>,one:f32,two:f32,};struct b{projectionMatrix:mat4x4<f32>,modelViewMatrix:mat4x4<f32>,normalMatrix:mat3x3<f32>,one:f32,two:f32,lights:array<a,4>,};@binding(0)@group(0)var<uniform>uniforms:b;@binding(1)@group(0)var sample:sampler;@binding(2)@group(0)var c:texture_2d<f32>;struct d{@location(0)position:vec4<f32>,@location(1)uv:vec2<f32>,};struct e{@builtin(position)position:vec4<f32>,@location(0)uv:vec2<f32>,};@vertex fn f(g:d)->e{var output:e;output.position=g.position;output.uv=g.uv;return output;}@fragment fn h(i:vec2<f32>)->vec4<f32>{var j=vec4<f32>(uniforms.lights[0].position*uniforms.lights[0].intensity,0.0);var k=uniforms.projectionMatrix*uniforms.modelViewMatrix*vec4<f32>(0.0,0.0,0.0,1.0);var l=textureSample(c,sample,i);l.a+=1.0;return l;}"`;
exports[`minify > can mangle WGSL 1`] = `"struct a{intensity:f32,position:vec3<f32>,one:f32,two:f32,};struct b{projectionMatrix:mat4x4<f32>,modelViewMatrix:mat4x4<f32>,normalMatrix:mat3x3<f32>,one:f32,two:f32,lights:array<a,4>,};@binding(0)@group(0)var<uniform>uniforms:Uniforms;@binding(1)@group(0)var sample:sampler;@binding(2)@group(0)var map:texture_2d<f32>;struct c{@location(0)position:vec4<f32>,@location(1)uv:vec2<f32>,};struct d{@builtin(position)position:vec4<f32>,@location(0)uv:vec2<f32>,};@vertex fn e(f:c)->d{var output:d;output.position=f.position;output.uv=f.uv;return output;}@fragment fn g(h:vec2<f32>)->vec4<f32>{var i=vec4<f32>(uniforms.lights[0].position*uniforms.lights[0].intensity,0.0);var j=uniforms.projectionMatrix*uniforms.modelViewMatrix*vec4<f32>(0.0,0.0,0.0,1.0);var k=textureSample(map,sample,h);k.a+=1.0;return k;}"`;
exports[`minify > can mangle WGSL 2`] = `
Map {
"LightData" => "a",
"Uniforms" => "b",
"map" => "c",
"VertexIn" => "d",
"VertexOut" => "e",
"vert_main" => "f",
"input" => "g",
"frag_main" => "h",
"uv" => "i",
"lightNormal" => "j",
"clipPosition" => "k",
"color" => "l",
"VertexIn" => "c",
"VertexOut" => "d",
"vert_main" => "e",
"input" => "f",
"frag_main" => "g",
"uv" => "h",
"lightNormal" => "i",
"clipPosition" => "j",
"color" => "k",
}
`;
Expand Down

0 comments on commit 12bcb5d

Please sign in to comment.