wesl 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +369 -276
- package/dist/index.js.map +1 -1
- package/dist/minified.js +1176 -1102
- package/dist/minified.js.map +1 -1
- package/dist/tools/packages/wesl/src/BindIdents.d.ts +3 -0
- package/dist/tools/packages/wesl/src/ClickableError.d.ts +22 -0
- package/dist/tools/packages/wesl/src/LinkedWesl.d.ts +1 -1
- package/dist/tools/packages/wesl/src/Linker.d.ts +1 -1
- package/dist/tools/packages/wesl/src/Util.d.ts +1 -1
- package/dist/tools/packages/wesl/src/WESLCollect.d.ts +2 -2
- package/dist/tools/packages/wesl/src/WeslDevice.d.ts +0 -8
- package/dist/tools/packages/wesl/src/index.d.ts +1 -0
- package/dist/tools/packages/wesl/src/parse/WeslStream.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/TestUtil.d.ts +1 -1
- package/package.json +6 -6
- package/src/AbstractElems.ts +2 -2
- package/src/BindIdents.ts +67 -42
- package/src/ClickableError.ts +128 -0
- package/src/Conditions.ts +6 -6
- package/src/FlattenTreeImport.ts +2 -2
- package/src/LinkedWesl.ts +11 -11
- package/src/Linker.ts +15 -14
- package/src/LinkerUtil.ts +2 -2
- package/src/LiveDeclarations.ts +1 -1
- package/src/LowerAndEmit.ts +42 -31
- package/src/Mangler.ts +3 -3
- package/src/ParseWESL.ts +12 -6
- package/src/ParsedRegistry.ts +6 -6
- package/src/PathUtil.ts +2 -2
- package/src/RawEmit.ts +5 -5
- package/src/Reflection.ts +12 -10
- package/src/Scope.ts +7 -3
- package/src/TransformBindingStructs.ts +17 -17
- package/src/Util.ts +3 -3
- package/src/WESLCollect.ts +33 -27
- package/src/WeslDevice.ts +6 -84
- package/src/debug/ASTtoString.ts +12 -11
- package/src/debug/ImportToString.ts +3 -3
- package/src/debug/ScopeToString.ts +2 -1
- package/src/index.ts +1 -0
- package/src/parse/ImportGrammar.ts +13 -7
- package/src/parse/WeslBaseGrammar.ts +5 -2
- package/src/parse/WeslExpression.ts +30 -30
- package/src/parse/WeslGrammar.ts +192 -159
- package/src/parse/WeslStream.ts +8 -7
- package/src/test/BindWESL.test.ts +2 -2
- package/src/test/ConditionalTranslationCases.test.ts +39 -39
- package/src/test/ErrorLogging.test.ts +3 -3
- package/src/test/Expression.test.ts +3 -3
- package/src/test/FlattenTreeImport.test.ts +1 -1
- package/src/test/ImportCases.test.ts +40 -39
- package/src/test/ImportSyntaxCases.test.ts +1 -1
- package/src/test/Linker.test.ts +1 -1
- package/src/test/ParseWESL.test.ts +40 -16
- package/src/test/Reflection.test.ts +8 -8
- package/src/test/ScopeWESL.test.ts +2 -2
- package/src/test/TestLink.ts +6 -6
- package/src/test/TestUtil.ts +9 -9
- package/src/test/Tokenizer.test.ts +1 -1
- package/src/test/TransformBindingStructs.test.ts +1 -1
- package/src/test/WeslDevice.test.ts +6 -6
- package/src/vlq/vlq.ts +4 -4
package/dist/index.js
CHANGED
|
@@ -57,12 +57,10 @@ function logInternalSrc(log2, src, pos, ...msgs) {
|
|
|
57
57
|
log2(caret);
|
|
58
58
|
}
|
|
59
59
|
function carets(linePos, linePos2) {
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
return firstCaret + secondCaret;
|
|
60
|
+
const indent = " ".repeat(linePos);
|
|
61
|
+
const numCarets = linePos2 ? linePos2 - linePos : 1;
|
|
62
|
+
const carets2 = "^".repeat(numCarets);
|
|
63
|
+
return indent + carets2;
|
|
66
64
|
}
|
|
67
65
|
const startCache = /* @__PURE__ */ new Map();
|
|
68
66
|
function srcLine(src, position) {
|
|
@@ -294,6 +292,18 @@ function opt(arg) {
|
|
|
294
292
|
}
|
|
295
293
|
);
|
|
296
294
|
}
|
|
295
|
+
function not(arg) {
|
|
296
|
+
const p = parserArg(arg);
|
|
297
|
+
return parser("not", function _not(state) {
|
|
298
|
+
const pos = state.stream.checkpoint();
|
|
299
|
+
const result = p._run(state);
|
|
300
|
+
if (result === null) {
|
|
301
|
+
state.stream.reset(pos);
|
|
302
|
+
return { value: true };
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
305
|
+
});
|
|
306
|
+
}
|
|
297
307
|
function repeat(arg) {
|
|
298
308
|
const p = parserArg(arg);
|
|
299
309
|
return parser("repeat", repeatWhileFilter(p));
|
|
@@ -1138,6 +1148,112 @@ function errorHighlight(source, span2) {
|
|
|
1138
1148
|
" ".repeat(linePos) + "^".repeat(caretCount)
|
|
1139
1149
|
];
|
|
1140
1150
|
}
|
|
1151
|
+
/*!
|
|
1152
|
+
Copyright (c) 2017-2021 [these people](https://github.com/Rich-Harris/vlq/graphs/contributors)
|
|
1153
|
+
|
|
1154
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
1155
|
+
|
|
1156
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
1157
|
+
|
|
1158
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1159
|
+
*/
|
|
1160
|
+
const integer_to_char = {};
|
|
1161
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split("").forEach((char, i) => {
|
|
1162
|
+
integer_to_char[i] = char;
|
|
1163
|
+
});
|
|
1164
|
+
function encodeVlq(value) {
|
|
1165
|
+
if (typeof value === "number") {
|
|
1166
|
+
return encode_integer(value);
|
|
1167
|
+
}
|
|
1168
|
+
let result = "";
|
|
1169
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
1170
|
+
result += encode_integer(value[i]);
|
|
1171
|
+
}
|
|
1172
|
+
return result;
|
|
1173
|
+
}
|
|
1174
|
+
function encode_integer(num) {
|
|
1175
|
+
let result = "";
|
|
1176
|
+
if (num < 0) {
|
|
1177
|
+
num = -num << 1 | 1;
|
|
1178
|
+
} else {
|
|
1179
|
+
num <<= 1;
|
|
1180
|
+
}
|
|
1181
|
+
do {
|
|
1182
|
+
let clamped = num & 31;
|
|
1183
|
+
num >>>= 5;
|
|
1184
|
+
if (num > 0) {
|
|
1185
|
+
clamped |= 32;
|
|
1186
|
+
}
|
|
1187
|
+
result += integer_to_char[clamped];
|
|
1188
|
+
} while (num > 0);
|
|
1189
|
+
return result;
|
|
1190
|
+
}
|
|
1191
|
+
function throwClickableError(params) {
|
|
1192
|
+
const { url, text: text2, lineNumber, lineColumn, length, error } = params;
|
|
1193
|
+
const mappings = encodeVlq([
|
|
1194
|
+
0,
|
|
1195
|
+
0,
|
|
1196
|
+
Math.max(0, lineNumber - 1),
|
|
1197
|
+
Math.max(0, lineColumn - 1)
|
|
1198
|
+
]) + "," + // Sadly no browser makes use of this info to map the error properly
|
|
1199
|
+
encodeVlq([
|
|
1200
|
+
18,
|
|
1201
|
+
// Arbitrary number that is high enough
|
|
1202
|
+
0,
|
|
1203
|
+
Math.max(0, lineNumber - 1),
|
|
1204
|
+
Math.max(0, lineColumn - 1) + length
|
|
1205
|
+
]);
|
|
1206
|
+
const sourceMap = {
|
|
1207
|
+
version: 3,
|
|
1208
|
+
file: null,
|
|
1209
|
+
sources: [url],
|
|
1210
|
+
sourcesContent: [text2 ?? null],
|
|
1211
|
+
names: [],
|
|
1212
|
+
mappings
|
|
1213
|
+
};
|
|
1214
|
+
let generatedCode = `throw new Error(${JSON.stringify(error.message + "")})`;
|
|
1215
|
+
generatedCode += "\n//# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
|
|
1216
|
+
generatedCode += "\n//# sourceURL=" + sourceMap.sources[0];
|
|
1217
|
+
let oldLimit = 0;
|
|
1218
|
+
if ("stackTraceLimit" in Error) {
|
|
1219
|
+
oldLimit = Error.stackTraceLimit;
|
|
1220
|
+
Error.stackTraceLimit = 1;
|
|
1221
|
+
}
|
|
1222
|
+
try {
|
|
1223
|
+
(0, eval)(generatedCode);
|
|
1224
|
+
} catch (e) {
|
|
1225
|
+
if ("stackTraceLimit" in Error) {
|
|
1226
|
+
Error.stackTraceLimit = oldLimit;
|
|
1227
|
+
}
|
|
1228
|
+
error.message = "";
|
|
1229
|
+
throw e;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
function failIdent(ident2, msg) {
|
|
1233
|
+
const { refIdentElem, originalName } = ident2;
|
|
1234
|
+
const baseMessage = msg ?? `'${originalName}'`;
|
|
1235
|
+
if (refIdentElem) {
|
|
1236
|
+
failIdentElem(refIdentElem, baseMessage);
|
|
1237
|
+
} else {
|
|
1238
|
+
throw new Error(baseMessage);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
function failIdentElem(identElem, msg = "") {
|
|
1242
|
+
const { srcModule, start, end } = identElem;
|
|
1243
|
+
const { debugFilePath, src } = srcModule;
|
|
1244
|
+
const detailedMessage = `${msg} in file: ${debugFilePath}`;
|
|
1245
|
+
srcLog(src, [start, end], detailedMessage);
|
|
1246
|
+
const [lineNumber, lineColumn] = offsetToLineNumber(start, src);
|
|
1247
|
+
const length = end - start;
|
|
1248
|
+
throwClickableError({
|
|
1249
|
+
url: debugFilePath,
|
|
1250
|
+
text: src,
|
|
1251
|
+
lineNumber,
|
|
1252
|
+
lineColumn,
|
|
1253
|
+
length,
|
|
1254
|
+
error: new Error(detailedMessage)
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1141
1257
|
function elementValid(elem, conditions) {
|
|
1142
1258
|
const attributes = elem.attributes;
|
|
1143
1259
|
if (!attributes) return true;
|
|
@@ -1159,10 +1275,10 @@ function evaluateIfAttribute(ifAttribute, conditions) {
|
|
|
1159
1275
|
}
|
|
1160
1276
|
function evaluateIfExpression(expression2, conditions) {
|
|
1161
1277
|
const { kind: kind2 } = expression2;
|
|
1162
|
-
if (kind2
|
|
1278
|
+
if (kind2 === "unary-expression") {
|
|
1163
1279
|
assertThatDebug(expression2.operator.value === "!");
|
|
1164
1280
|
return !evaluateIfExpression(expression2.expression, conditions);
|
|
1165
|
-
} else if (kind2
|
|
1281
|
+
} else if (kind2 === "binary-expression") {
|
|
1166
1282
|
const op = expression2.operator.value;
|
|
1167
1283
|
const leftResult = evaluateIfExpression(expression2.left, conditions);
|
|
1168
1284
|
if (op === "||") {
|
|
@@ -1172,10 +1288,10 @@ function evaluateIfExpression(expression2, conditions) {
|
|
|
1172
1288
|
} else {
|
|
1173
1289
|
assertUnreachable(op);
|
|
1174
1290
|
}
|
|
1175
|
-
} else if (kind2
|
|
1291
|
+
} else if (kind2 === "literal") {
|
|
1176
1292
|
const { value } = expression2;
|
|
1177
1293
|
return value === "true";
|
|
1178
|
-
} else if (kind2
|
|
1294
|
+
} else if (kind2 === "parenthesized-expression") {
|
|
1179
1295
|
return evaluateIfExpression(expression2.expression, conditions);
|
|
1180
1296
|
} else if (kind2 === "translate-time-feature") {
|
|
1181
1297
|
return conditions[expression2.name];
|
|
@@ -1452,7 +1568,7 @@ function importElem(cc) {
|
|
|
1452
1568
|
function addToOpenElem(cc, elem) {
|
|
1453
1569
|
const weslContext = cc.app.context;
|
|
1454
1570
|
const { openElems } = weslContext;
|
|
1455
|
-
if (openElems
|
|
1571
|
+
if (openElems == null ? void 0 : openElems.length) {
|
|
1456
1572
|
const open = openElems[openElems.length - 1];
|
|
1457
1573
|
open.contents.push(elem);
|
|
1458
1574
|
}
|
|
@@ -1616,7 +1732,7 @@ const fnCollect = collectElem(
|
|
|
1616
1732
|
mergeScope(mergedScope, bodyScope);
|
|
1617
1733
|
const filtered = [];
|
|
1618
1734
|
for (const e of fnScope.contents) {
|
|
1619
|
-
if (e === headerScope || e
|
|
1735
|
+
if (e === headerScope || e === returnScope) {
|
|
1620
1736
|
continue;
|
|
1621
1737
|
} else if (e === bodyScope) {
|
|
1622
1738
|
filtered.push(mergedScope);
|
|
@@ -1724,7 +1840,7 @@ const typeRefCollect = collectElem(
|
|
|
1724
1840
|
// @ts-ignore
|
|
1725
1841
|
(cc, openElem) => {
|
|
1726
1842
|
var _a, _b;
|
|
1727
|
-
|
|
1843
|
+
const templateParamsTemp = (_a = cc.tags.templateParam) == null ? void 0 : _a.flat(3);
|
|
1728
1844
|
const typeRef = (_b = cc.tags.typeRefName) == null ? void 0 : _b[0];
|
|
1729
1845
|
const name2 = typeof typeRef === "string" ? typeRef : typeRef.ident;
|
|
1730
1846
|
const partElem = {
|
|
@@ -1760,7 +1876,7 @@ const memberRefCollect = collectElem(
|
|
|
1760
1876
|
"memberRef",
|
|
1761
1877
|
(cc, openElem) => {
|
|
1762
1878
|
const { component, structRef, extra_components } = cc.tags;
|
|
1763
|
-
const member = component[0];
|
|
1879
|
+
const member = component == null ? void 0 : component[0];
|
|
1764
1880
|
const name2 = structRef == null ? void 0 : structRef.flat()[0];
|
|
1765
1881
|
const extraComponents = extra_components == null ? void 0 : extra_components.flat()[0];
|
|
1766
1882
|
const partElem = {
|
|
@@ -1854,8 +1970,11 @@ function coverWithText(cc, elem) {
|
|
|
1854
1970
|
}
|
|
1855
1971
|
}
|
|
1856
1972
|
const word = kind("word");
|
|
1857
|
-
kind("keyword");
|
|
1858
|
-
const qualified_ident = withSepPlus(
|
|
1973
|
+
const keyword = kind("keyword");
|
|
1974
|
+
const qualified_ident = withSepPlus(
|
|
1975
|
+
"::",
|
|
1976
|
+
or(word, keyword, "package", "super")
|
|
1977
|
+
);
|
|
1859
1978
|
const number = kind("number");
|
|
1860
1979
|
function makeStatement(segments, finalSegment) {
|
|
1861
1980
|
return { kind: "import-statement", segments, finalSegment };
|
|
@@ -1877,8 +1996,10 @@ function prependSegments(segments, statement2) {
|
|
|
1877
1996
|
return statement2;
|
|
1878
1997
|
}
|
|
1879
1998
|
let import_collection = null;
|
|
1999
|
+
const segment_blacklist = or("super", "package", "import", "as");
|
|
2000
|
+
const packageWord = preceded(not(segment_blacklist), or(word, keyword));
|
|
1880
2001
|
const import_path_or_item = seq(
|
|
1881
|
-
|
|
2002
|
+
packageWord,
|
|
1882
2003
|
or(
|
|
1883
2004
|
preceded(
|
|
1884
2005
|
"::",
|
|
@@ -2020,7 +2141,7 @@ class WeslStream {
|
|
|
2020
2141
|
this.stream.reset(this.skipBlockComment(token2.span[1]));
|
|
2021
2142
|
}
|
|
2022
2143
|
} else if (kind2 === "word") {
|
|
2023
|
-
|
|
2144
|
+
const returnToken = token2;
|
|
2024
2145
|
if (keywordOrReserved.has(token2.text)) {
|
|
2025
2146
|
returnToken.kind = "keyword";
|
|
2026
2147
|
}
|
|
@@ -2108,7 +2229,7 @@ class WeslStream {
|
|
|
2108
2229
|
if (nextToken.text === "<") {
|
|
2109
2230
|
pendingCounter += 1;
|
|
2110
2231
|
} else if (nextToken.text[0] === ">") {
|
|
2111
|
-
if (nextToken.text === ">" || nextToken.text
|
|
2232
|
+
if (nextToken.text === ">" || nextToken.text === ">=") {
|
|
2112
2233
|
pendingCounter -= 1;
|
|
2113
2234
|
} else if (nextToken.text === ">>=" || nextToken.text === ">>") {
|
|
2114
2235
|
pendingCounter -= 2;
|
|
@@ -2277,9 +2398,9 @@ const expressionParser = (inTemplate) => {
|
|
|
2277
2398
|
)
|
|
2278
2399
|
);
|
|
2279
2400
|
};
|
|
2280
|
-
|
|
2401
|
+
const maybe_template = false;
|
|
2281
2402
|
const expression = expressionParser(maybe_template);
|
|
2282
|
-
|
|
2403
|
+
const is_template = true;
|
|
2283
2404
|
const template_arg_expression = expressionParser(is_template);
|
|
2284
2405
|
const std_type_specifier = seq(
|
|
2285
2406
|
qualified_ident.collect(refIdent, "typeRefName"),
|
|
@@ -2317,11 +2438,25 @@ const special_attribute = tagScope(
|
|
|
2317
2438
|
"@",
|
|
2318
2439
|
or(
|
|
2319
2440
|
// These attributes have no arguments
|
|
2320
|
-
or("compute", "const", "fragment", "invariant", "must_use", "vertex").map(
|
|
2441
|
+
or("compute", "const", "fragment", "invariant", "must_use", "vertex").map(
|
|
2442
|
+
(name2) => makeStandardAttribute([name2, []])
|
|
2443
|
+
),
|
|
2321
2444
|
// These attributes have arguments, but the argument doesn't have any identifiers
|
|
2322
|
-
preceded(
|
|
2323
|
-
|
|
2324
|
-
|
|
2445
|
+
preceded(
|
|
2446
|
+
"interpolate",
|
|
2447
|
+
req(
|
|
2448
|
+
delimited("(", name_list, ")"),
|
|
2449
|
+
"invalid @interpolate, expected '('"
|
|
2450
|
+
)
|
|
2451
|
+
).map(makeInterpolateAttribute),
|
|
2452
|
+
preceded(
|
|
2453
|
+
"builtin",
|
|
2454
|
+
req(delimited("(", name, ")"), "invalid @builtin, expected '('")
|
|
2455
|
+
).map(makeBuiltinAttribute),
|
|
2456
|
+
preceded(
|
|
2457
|
+
"diagnostic",
|
|
2458
|
+
req(diagnostic_control, "invalid @diagnostic, expected '('")
|
|
2459
|
+
).map(makeDiagnosticAttribute)
|
|
2325
2460
|
).ptag("attr_variant")
|
|
2326
2461
|
).collect(specialAttribute)
|
|
2327
2462
|
);
|
|
@@ -2357,7 +2492,7 @@ const normal_attribute = tagScope(
|
|
|
2357
2492
|
),
|
|
2358
2493
|
// Everything else is also a normal attribute, optional expression list
|
|
2359
2494
|
seq(
|
|
2360
|
-
// we don't want this to interfere with if_attribute,
|
|
2495
|
+
// we don't want this to interfere with if_attribute,
|
|
2361
2496
|
// but not("if") isn't necessary for now, since 'if' is a keyword, not a word
|
|
2362
2497
|
word.ptag("name"),
|
|
2363
2498
|
opt(() => attribute_argument_list)
|
|
@@ -2374,10 +2509,9 @@ const attribute_argument_list = delimited(
|
|
|
2374
2509
|
),
|
|
2375
2510
|
req(")", "invalid attribute arguments, expected ')'")
|
|
2376
2511
|
);
|
|
2377
|
-
const attribute_no_if = or(
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
).ctag("attribute");
|
|
2512
|
+
const attribute_no_if = or(special_attribute, normal_attribute).ctag(
|
|
2513
|
+
"attribute"
|
|
2514
|
+
);
|
|
2381
2515
|
const attribute_incl_if = or(
|
|
2382
2516
|
if_attribute,
|
|
2383
2517
|
special_attribute,
|
|
@@ -2418,7 +2552,10 @@ const struct_member = tagScope(
|
|
|
2418
2552
|
).collect(collectStructMember)
|
|
2419
2553
|
).ctag("members");
|
|
2420
2554
|
const struct_decl = seq(
|
|
2421
|
-
weslExtension(opt_attributes).collect(
|
|
2555
|
+
weslExtension(opt_attributes).collect(
|
|
2556
|
+
(cc) => cc.tags.attribute,
|
|
2557
|
+
"attributes"
|
|
2558
|
+
),
|
|
2422
2559
|
"struct",
|
|
2423
2560
|
req(globalTypeNameDecl, "invalid struct, expected name"),
|
|
2424
2561
|
seq(
|
|
@@ -2436,7 +2573,12 @@ const fnParam = tagScope(
|
|
|
2436
2573
|
seq(
|
|
2437
2574
|
opt_attributes.collect((cc) => cc.tags.attribute, "attributes"),
|
|
2438
2575
|
word.collect(declCollect, "decl_elem"),
|
|
2439
|
-
opt(
|
|
2576
|
+
opt(
|
|
2577
|
+
seq(
|
|
2578
|
+
":",
|
|
2579
|
+
req(type_specifier, "invalid fn parameter, expected type specifier")
|
|
2580
|
+
)
|
|
2581
|
+
).collect(typedDecl, "param_name")
|
|
2440
2582
|
).collect(collectFnParam)
|
|
2441
2583
|
).ctag("fn_param");
|
|
2442
2584
|
const fnParamList = seq("(", withSep(",", fnParam), ")");
|
|
@@ -2628,16 +2770,10 @@ const regular_statement = or(
|
|
|
2628
2770
|
)
|
|
2629
2771
|
);
|
|
2630
2772
|
const conditional_statement = tagScope(
|
|
2631
|
-
seq(
|
|
2632
|
-
opt_attributes,
|
|
2633
|
-
regular_statement
|
|
2634
|
-
).collect(statementCollect).collect(partialScopeCollect)
|
|
2773
|
+
seq(opt_attributes, regular_statement).collect(statementCollect).collect(partialScopeCollect)
|
|
2635
2774
|
);
|
|
2636
2775
|
const unconditional_statement = tagScope(
|
|
2637
|
-
seq(
|
|
2638
|
-
opt_attributes_no_if,
|
|
2639
|
-
regular_statement
|
|
2640
|
-
)
|
|
2776
|
+
seq(opt_attributes_no_if, regular_statement)
|
|
2641
2777
|
);
|
|
2642
2778
|
const statement = or(
|
|
2643
2779
|
compound_statement,
|
|
@@ -2646,10 +2782,7 @@ const statement = or(
|
|
|
2646
2782
|
);
|
|
2647
2783
|
const lhs_expression = or(
|
|
2648
2784
|
simple_component_reference,
|
|
2649
|
-
seq(
|
|
2650
|
-
qualified_ident.collect(refIdent),
|
|
2651
|
-
opt(component_or_swizzle)
|
|
2652
|
-
),
|
|
2785
|
+
seq(qualified_ident.collect(refIdent), opt(component_or_swizzle)),
|
|
2653
2786
|
seq(
|
|
2654
2787
|
"(",
|
|
2655
2788
|
() => lhs_expression,
|
|
@@ -2665,7 +2798,12 @@ const variable_or_value_statement = tagScope(
|
|
|
2665
2798
|
or(
|
|
2666
2799
|
// Also covers the = expression case
|
|
2667
2800
|
local_variable_decl,
|
|
2668
|
-
seq(
|
|
2801
|
+
seq(
|
|
2802
|
+
"const",
|
|
2803
|
+
req_optionally_typed_ident,
|
|
2804
|
+
req("=", "invalid const declaration, expected '='"),
|
|
2805
|
+
expression
|
|
2806
|
+
),
|
|
2669
2807
|
seq(
|
|
2670
2808
|
"let",
|
|
2671
2809
|
req_optionally_typed_ident,
|
|
@@ -2684,22 +2822,24 @@ const variable_updating_statement = or(
|
|
|
2684
2822
|
seq("_", "=", expression)
|
|
2685
2823
|
);
|
|
2686
2824
|
const fn_decl = seq(
|
|
2687
|
-
tagScope(
|
|
2688
|
-
|
|
2689
|
-
)
|
|
2825
|
+
tagScope(opt_attributes.collect((cc) => cc.tags.attribute || [])).ctag(
|
|
2826
|
+
"fn_attributes"
|
|
2827
|
+
),
|
|
2690
2828
|
text("fn"),
|
|
2691
2829
|
req(fnNameDecl, "invalid fn, expected function name"),
|
|
2692
2830
|
seq(
|
|
2693
|
-
req(fnParamList, "invalid fn, expected function parameters").collect(
|
|
2694
|
-
|
|
2695
|
-
"
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2831
|
+
req(fnParamList, "invalid fn, expected function parameters").collect(
|
|
2832
|
+
scopeCollect,
|
|
2833
|
+
"header_scope"
|
|
2834
|
+
),
|
|
2835
|
+
opt(
|
|
2836
|
+
seq(
|
|
2837
|
+
"->",
|
|
2838
|
+
opt_attributes.collect((cc) => cc.tags.attribute, "return_attributes"),
|
|
2839
|
+
type_specifier.ctag("return_type").collect(scopeCollect, "return_scope")
|
|
2840
|
+
)
|
|
2841
|
+
),
|
|
2842
|
+
req(unscoped_compound_statement, "invalid fn, expected function body").ctag("body_statement").collect(scopeCollect, "body_scope")
|
|
2703
2843
|
)
|
|
2704
2844
|
).collect(partialScopeCollect, "fn_partial_scope").collect(fnCollect);
|
|
2705
2845
|
const global_value_decl = or(
|
|
@@ -2720,11 +2860,20 @@ const global_value_decl = or(
|
|
|
2720
2860
|
).collect(collectVarLike("const"))
|
|
2721
2861
|
).collect(partialScopeCollect);
|
|
2722
2862
|
const global_alias = seq(
|
|
2723
|
-
weslExtension(opt_attributes).collect(
|
|
2863
|
+
weslExtension(opt_attributes).collect(
|
|
2864
|
+
(cc) => cc.tags.attribute,
|
|
2865
|
+
"attributes"
|
|
2866
|
+
),
|
|
2724
2867
|
"alias",
|
|
2725
|
-
req(word, "invalid alias, expected name").collect(
|
|
2868
|
+
req(word, "invalid alias, expected name").collect(
|
|
2869
|
+
globalDeclCollect,
|
|
2870
|
+
"alias_name"
|
|
2871
|
+
),
|
|
2726
2872
|
req("=", "invalid alias, expected '='"),
|
|
2727
|
-
req(type_specifier, "invalid alias, expected type").collect(
|
|
2873
|
+
req(type_specifier, "invalid alias, expected type").collect(
|
|
2874
|
+
scopeCollect,
|
|
2875
|
+
"alias_scope"
|
|
2876
|
+
),
|
|
2728
2877
|
req(";", "invalid alias, expected ';'")
|
|
2729
2878
|
).collect(aliasCollect);
|
|
2730
2879
|
const const_assert = tagScope(
|
|
@@ -2875,176 +3024,6 @@ function makeBinaryExpression([left, operator, right]) {
|
|
|
2875
3024
|
right
|
|
2876
3025
|
};
|
|
2877
3026
|
}
|
|
2878
|
-
/*!
|
|
2879
|
-
Copyright (c) 2017-2021 [these people](https://github.com/Rich-Harris/vlq/graphs/contributors)
|
|
2880
|
-
|
|
2881
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
2882
|
-
|
|
2883
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
2884
|
-
|
|
2885
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
2886
|
-
*/
|
|
2887
|
-
let integer_to_char = {};
|
|
2888
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split("").forEach(function(char, i) {
|
|
2889
|
-
integer_to_char[i] = char;
|
|
2890
|
-
});
|
|
2891
|
-
function encodeVlq(value) {
|
|
2892
|
-
if (typeof value === "number") {
|
|
2893
|
-
return encode_integer(value);
|
|
2894
|
-
}
|
|
2895
|
-
let result = "";
|
|
2896
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
2897
|
-
result += encode_integer(value[i]);
|
|
2898
|
-
}
|
|
2899
|
-
return result;
|
|
2900
|
-
}
|
|
2901
|
-
function encode_integer(num) {
|
|
2902
|
-
let result = "";
|
|
2903
|
-
if (num < 0) {
|
|
2904
|
-
num = -num << 1 | 1;
|
|
2905
|
-
} else {
|
|
2906
|
-
num <<= 1;
|
|
2907
|
-
}
|
|
2908
|
-
do {
|
|
2909
|
-
let clamped = num & 31;
|
|
2910
|
-
num >>>= 5;
|
|
2911
|
-
if (num > 0) {
|
|
2912
|
-
clamped |= 32;
|
|
2913
|
-
}
|
|
2914
|
-
result += integer_to_char[clamped];
|
|
2915
|
-
} while (num > 0);
|
|
2916
|
-
return result;
|
|
2917
|
-
}
|
|
2918
|
-
async function requestWeslDevice(adapter, descriptor) {
|
|
2919
|
-
if (!adapter) {
|
|
2920
|
-
throw new Error("No GPU adapter");
|
|
2921
|
-
}
|
|
2922
|
-
return adapter.requestDevice(descriptor).then(makeWeslDevice);
|
|
2923
|
-
}
|
|
2924
|
-
function makeWeslDevice(device) {
|
|
2925
|
-
const errorScopeStack = [];
|
|
2926
|
-
device.injectError = (type, error) => {
|
|
2927
|
-
const errorScope = errorScopeStack.findLast((v) => v.filter === type);
|
|
2928
|
-
if (errorScope !== void 0) {
|
|
2929
|
-
errorScope.errors.push(error);
|
|
2930
|
-
} else {
|
|
2931
|
-
error.then((e) => {
|
|
2932
|
-
if (e !== null) {
|
|
2933
|
-
dispatchError(e);
|
|
2934
|
-
}
|
|
2935
|
-
});
|
|
2936
|
-
}
|
|
2937
|
-
};
|
|
2938
|
-
function dispatchError(e) {
|
|
2939
|
-
device.addEventListener(
|
|
2940
|
-
"uncapturederror",
|
|
2941
|
-
(ev) => {
|
|
2942
|
-
if (!ev.defaultPrevented) {
|
|
2943
|
-
if ("compilationInfo" in ev.error) {
|
|
2944
|
-
const error = ev.error;
|
|
2945
|
-
if (error.compilationInfo) {
|
|
2946
|
-
for (const message of error.compilationInfo.messages) {
|
|
2947
|
-
throwClickableError({
|
|
2948
|
-
url: message.module.url,
|
|
2949
|
-
text: message.module.text ?? null,
|
|
2950
|
-
lineNumber: message.lineNum,
|
|
2951
|
-
lineColumn: message.linePos,
|
|
2952
|
-
length: message.length,
|
|
2953
|
-
error: new Error(message.type + ": " + message.message)
|
|
2954
|
-
});
|
|
2955
|
-
}
|
|
2956
|
-
} else {
|
|
2957
|
-
console.error(ev.error.message);
|
|
2958
|
-
}
|
|
2959
|
-
} else {
|
|
2960
|
-
console.error(ev.error.message);
|
|
2961
|
-
}
|
|
2962
|
-
}
|
|
2963
|
-
},
|
|
2964
|
-
{
|
|
2965
|
-
// This event listener should only happen for this event!
|
|
2966
|
-
once: true
|
|
2967
|
-
}
|
|
2968
|
-
);
|
|
2969
|
-
device.dispatchEvent(
|
|
2970
|
-
new GPUUncapturedErrorEvent("uncapturederror", { error: e })
|
|
2971
|
-
);
|
|
2972
|
-
}
|
|
2973
|
-
device.pushErrorScope = /* @__PURE__ */ ((baseFn) => {
|
|
2974
|
-
return function(filter) {
|
|
2975
|
-
errorScopeStack.push({
|
|
2976
|
-
filter,
|
|
2977
|
-
errors: []
|
|
2978
|
-
});
|
|
2979
|
-
return baseFn.call(this, filter);
|
|
2980
|
-
};
|
|
2981
|
-
})(device.pushErrorScope);
|
|
2982
|
-
device.popErrorScope = /* @__PURE__ */ ((baseFn) => {
|
|
2983
|
-
return function() {
|
|
2984
|
-
const errorScope = errorScopeStack.pop();
|
|
2985
|
-
if (errorScope === void 0) {
|
|
2986
|
-
throw new DOMException(
|
|
2987
|
-
"popErrorScope called on empty error scope stack",
|
|
2988
|
-
"OperationError"
|
|
2989
|
-
);
|
|
2990
|
-
}
|
|
2991
|
-
errorScope.errors.push(baseFn.call(this));
|
|
2992
|
-
const errorPromise = Promise.all(errorScope.errors).then(
|
|
2993
|
-
(values) => values.find((v) => v !== null) ?? null
|
|
2994
|
-
);
|
|
2995
|
-
return errorPromise;
|
|
2996
|
-
};
|
|
2997
|
-
})(device.popErrorScope);
|
|
2998
|
-
return device;
|
|
2999
|
-
}
|
|
3000
|
-
function throwClickableError({
|
|
3001
|
-
url,
|
|
3002
|
-
text: text2,
|
|
3003
|
-
lineNumber,
|
|
3004
|
-
lineColumn,
|
|
3005
|
-
length,
|
|
3006
|
-
error
|
|
3007
|
-
}) {
|
|
3008
|
-
let mappings = encodeVlq([
|
|
3009
|
-
0,
|
|
3010
|
-
0,
|
|
3011
|
-
Math.max(0, lineNumber - 1),
|
|
3012
|
-
Math.max(0, lineColumn - 1)
|
|
3013
|
-
]) + "," + // Sadly no browser makes use of this info to map the error properly
|
|
3014
|
-
encodeVlq([
|
|
3015
|
-
18,
|
|
3016
|
-
// Arbitrary number that is high enough
|
|
3017
|
-
0,
|
|
3018
|
-
Math.max(0, lineNumber - 1),
|
|
3019
|
-
Math.max(0, lineColumn - 1) + length
|
|
3020
|
-
]);
|
|
3021
|
-
const sourceMap = {
|
|
3022
|
-
version: 3,
|
|
3023
|
-
file: null,
|
|
3024
|
-
sources: [url],
|
|
3025
|
-
sourcesContent: [text2 ?? null],
|
|
3026
|
-
names: [],
|
|
3027
|
-
mappings
|
|
3028
|
-
};
|
|
3029
|
-
let generatedCode = `throw new Error(${JSON.stringify(error.message + "")})`;
|
|
3030
|
-
generatedCode += "\n//# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
|
|
3031
|
-
generatedCode += "\n//# sourceURL=" + sourceMap.sources[0];
|
|
3032
|
-
let oldLimit = 0;
|
|
3033
|
-
if ("stackTraceLimit" in Error) {
|
|
3034
|
-
oldLimit = Error.stackTraceLimit;
|
|
3035
|
-
Error.stackTraceLimit = 1;
|
|
3036
|
-
}
|
|
3037
|
-
try {
|
|
3038
|
-
(0, eval)(generatedCode);
|
|
3039
|
-
} catch (e) {
|
|
3040
|
-
if ("stackTraceLimit" in Error) {
|
|
3041
|
-
Error.stackTraceLimit = oldLimit;
|
|
3042
|
-
}
|
|
3043
|
-
error.message = "";
|
|
3044
|
-
e.cause = error;
|
|
3045
|
-
throw e;
|
|
3046
|
-
}
|
|
3047
|
-
}
|
|
3048
3027
|
class WeslParseError extends Error {
|
|
3049
3028
|
constructor(opts) {
|
|
3050
3029
|
const source = opts.src.src;
|
|
@@ -3219,6 +3198,26 @@ function bindIdents(params) {
|
|
|
3219
3198
|
const newStatements = [...globalStatements.values()];
|
|
3220
3199
|
return { decls, globalNames, newStatements, unbound };
|
|
3221
3200
|
}
|
|
3201
|
+
function findUnboundIdents(registry) {
|
|
3202
|
+
const bindContext = {
|
|
3203
|
+
registry,
|
|
3204
|
+
conditions: {},
|
|
3205
|
+
knownDecls: /* @__PURE__ */ new Set(),
|
|
3206
|
+
foundScopes: /* @__PURE__ */ new Set(),
|
|
3207
|
+
globalNames: /* @__PURE__ */ new Set(),
|
|
3208
|
+
globalStatements: /* @__PURE__ */ new Map(),
|
|
3209
|
+
mangler: minimalMangle,
|
|
3210
|
+
unbound: [],
|
|
3211
|
+
dontFollowDecls: true
|
|
3212
|
+
};
|
|
3213
|
+
Object.entries(registry.modules).map(([module, ast]) => {
|
|
3214
|
+
const rootDecls = findValidRootDecls(ast.rootScope, {});
|
|
3215
|
+
const declEntries = rootDecls.map((d) => [d.originalName, d]);
|
|
3216
|
+
const liveDecls = { decls: new Map(declEntries), parent: null };
|
|
3217
|
+
bindIdentsRecursive(ast.rootScope, bindContext, liveDecls, true);
|
|
3218
|
+
});
|
|
3219
|
+
return bindContext.unbound;
|
|
3220
|
+
}
|
|
3222
3221
|
function findValidRootDecls(rootScope, conditions) {
|
|
3223
3222
|
const found = [];
|
|
3224
3223
|
for (const e of rootScope.contents) {
|
|
@@ -3234,7 +3233,7 @@ function findValidRootDecls(rootScope, conditions) {
|
|
|
3234
3233
|
return found;
|
|
3235
3234
|
}
|
|
3236
3235
|
function bindIdentsRecursive(scope, bindContext, liveDecls, isRoot = false) {
|
|
3237
|
-
const {
|
|
3236
|
+
const { dontFollowDecls, foundScopes } = bindContext;
|
|
3238
3237
|
if (foundScopes.has(scope)) return [];
|
|
3239
3238
|
foundScopes.add(scope);
|
|
3240
3239
|
const newGlobals = [];
|
|
@@ -3254,7 +3253,12 @@ function bindIdentsRecursive(scope, bindContext, liveDecls, isRoot = false) {
|
|
|
3254
3253
|
}
|
|
3255
3254
|
}
|
|
3256
3255
|
});
|
|
3257
|
-
const newFromRefs = newGlobals
|
|
3256
|
+
const newFromRefs = dontFollowDecls ? [] : handleDecls(newGlobals, bindContext);
|
|
3257
|
+
return [newGlobals, newFromChildren, newFromRefs].flat();
|
|
3258
|
+
}
|
|
3259
|
+
function handleDecls(newGlobals, bindContext) {
|
|
3260
|
+
const { conditions } = bindContext;
|
|
3261
|
+
return newGlobals.flatMap((decl) => {
|
|
3258
3262
|
const foundsScope = decl.dependentScope;
|
|
3259
3263
|
if (foundsScope) {
|
|
3260
3264
|
const rootDecls = globalDeclToRootLiveDecls(decl, conditions);
|
|
@@ -3265,7 +3269,6 @@ function bindIdentsRecursive(scope, bindContext, liveDecls, isRoot = false) {
|
|
|
3265
3269
|
}
|
|
3266
3270
|
return [];
|
|
3267
3271
|
});
|
|
3268
|
-
return [newGlobals, newFromChildren, newFromRefs].flat();
|
|
3269
3272
|
}
|
|
3270
3273
|
function handleRef(ident2, liveDecls, bindContext) {
|
|
3271
3274
|
const { registry, conditions, unbound } = bindContext;
|
|
@@ -3278,7 +3281,7 @@ function handleRef(ident2, liveDecls, bindContext) {
|
|
|
3278
3281
|
} else if (stdWgsl(ident2.originalName)) {
|
|
3279
3282
|
ident2.std = true;
|
|
3280
3283
|
} else if (!unbound) {
|
|
3281
|
-
|
|
3284
|
+
failIdent(ident2, `unresolved identifier '${ident2.originalName}'`);
|
|
3282
3285
|
}
|
|
3283
3286
|
}
|
|
3284
3287
|
}
|
|
@@ -3325,16 +3328,6 @@ function globalDeclToRootLiveDecls(decl, conditions) {
|
|
|
3325
3328
|
root._scopeDecls = liveDecls;
|
|
3326
3329
|
return liveDecls;
|
|
3327
3330
|
}
|
|
3328
|
-
function failMissingIdent(ident2) {
|
|
3329
|
-
const { refIdentElem } = ident2;
|
|
3330
|
-
if (refIdentElem) {
|
|
3331
|
-
const { srcModule, start, end } = refIdentElem;
|
|
3332
|
-
const { debugFilePath: filePath } = srcModule;
|
|
3333
|
-
const msg = `unresolved identifier '${ident2.originalName}' in file: ${filePath}`;
|
|
3334
|
-
srcLog(srcModule.src, [start, end], msg);
|
|
3335
|
-
throw new Error(msg);
|
|
3336
|
-
}
|
|
3337
|
-
}
|
|
3338
3331
|
function setMangledName(proposedName, decl, globalNames, srcModule, mangler) {
|
|
3339
3332
|
if (!decl.mangledName) {
|
|
3340
3333
|
let mangledName;
|
|
@@ -3380,8 +3373,8 @@ function findQualifiedImport(refIdent2, parsed, conditions, virtuals, unbound) {
|
|
|
3380
3373
|
if (unbound) {
|
|
3381
3374
|
unbound.push(modulePathParts);
|
|
3382
3375
|
} else {
|
|
3383
|
-
const msg = `
|
|
3384
|
-
|
|
3376
|
+
const msg = `module not found for '${modulePathParts.join("::")}'`;
|
|
3377
|
+
failIdent(refIdent2, msg);
|
|
3385
3378
|
}
|
|
3386
3379
|
}
|
|
3387
3380
|
return result;
|
|
@@ -3457,16 +3450,21 @@ function lowerAndEmitElem(e, ctx) {
|
|
|
3457
3450
|
return;
|
|
3458
3451
|
// terminal elements copy strings to the output
|
|
3459
3452
|
case "text":
|
|
3460
|
-
|
|
3453
|
+
emitText(e, ctx);
|
|
3454
|
+
return;
|
|
3461
3455
|
case "name":
|
|
3462
|
-
|
|
3456
|
+
emitName(e, ctx);
|
|
3457
|
+
return;
|
|
3463
3458
|
case "synthetic":
|
|
3464
|
-
|
|
3459
|
+
emitSynthetic(e, ctx);
|
|
3460
|
+
return;
|
|
3465
3461
|
// identifiers are copied to the output, but with potentially mangled names
|
|
3466
3462
|
case "ref":
|
|
3467
|
-
|
|
3463
|
+
emitRefIdent(e, ctx);
|
|
3464
|
+
return;
|
|
3468
3465
|
case "decl":
|
|
3469
|
-
|
|
3466
|
+
emitDeclIdent(e, ctx);
|
|
3467
|
+
return;
|
|
3470
3468
|
// container elements just emit their child elements
|
|
3471
3469
|
case "param":
|
|
3472
3470
|
case "var":
|
|
@@ -3480,7 +3478,8 @@ function lowerAndEmitElem(e, ctx) {
|
|
|
3480
3478
|
case "statement":
|
|
3481
3479
|
case "stuff":
|
|
3482
3480
|
case "switch-clause":
|
|
3483
|
-
|
|
3481
|
+
emitContents(e, ctx);
|
|
3482
|
+
return;
|
|
3484
3483
|
// root level container elements get some extra newlines to make the output prettier
|
|
3485
3484
|
case "override":
|
|
3486
3485
|
case "const":
|
|
@@ -3488,17 +3487,22 @@ function lowerAndEmitElem(e, ctx) {
|
|
|
3488
3487
|
case "alias":
|
|
3489
3488
|
case "gvar":
|
|
3490
3489
|
emitRootElemNl(ctx);
|
|
3491
|
-
|
|
3490
|
+
emitContents(e, ctx);
|
|
3491
|
+
return;
|
|
3492
3492
|
case "fn":
|
|
3493
3493
|
emitRootElemNl(ctx);
|
|
3494
|
-
|
|
3494
|
+
emitFn(e, ctx);
|
|
3495
|
+
return;
|
|
3495
3496
|
case "struct":
|
|
3496
3497
|
emitRootElemNl(ctx);
|
|
3497
|
-
|
|
3498
|
+
emitStruct(e, ctx);
|
|
3499
|
+
return;
|
|
3498
3500
|
case "attribute":
|
|
3499
|
-
|
|
3501
|
+
emitAttribute(e, ctx);
|
|
3502
|
+
return;
|
|
3500
3503
|
case "directive":
|
|
3501
|
-
|
|
3504
|
+
emitDirective(e, ctx);
|
|
3505
|
+
return;
|
|
3502
3506
|
default:
|
|
3503
3507
|
assertUnreachable(e);
|
|
3504
3508
|
}
|
|
@@ -3547,7 +3551,9 @@ function emitAttributes(attributes, ctx) {
|
|
|
3547
3551
|
function emitStruct(e, ctx) {
|
|
3548
3552
|
const { name: name2, members, start, end } = e;
|
|
3549
3553
|
const { srcBuilder } = ctx;
|
|
3550
|
-
const validMembers = members.filter(
|
|
3554
|
+
const validMembers = members.filter(
|
|
3555
|
+
(m) => conditionsValid(m, ctx.conditions)
|
|
3556
|
+
);
|
|
3551
3557
|
const validLength = validMembers.length;
|
|
3552
3558
|
if (validLength === 0) {
|
|
3553
3559
|
warnEmptyStruct(e);
|
|
@@ -3573,12 +3579,8 @@ function emitStruct(e, ctx) {
|
|
|
3573
3579
|
function warnEmptyStruct(e) {
|
|
3574
3580
|
const { name: name2, members } = e;
|
|
3575
3581
|
const condStr = members.length ? "(with current conditions)" : "";
|
|
3576
|
-
const
|
|
3577
|
-
|
|
3578
|
-
name2.srcModule.src,
|
|
3579
|
-
e.start,
|
|
3580
|
-
`struct ${name2.ident.originalName} in ${filePath} has no members ${condStr}`
|
|
3581
|
-
);
|
|
3582
|
+
const message = `struct '${name2.ident.originalName}' has no members ${condStr}`;
|
|
3583
|
+
failIdentElem(name2, message);
|
|
3582
3584
|
}
|
|
3583
3585
|
function emitSynthetic(e, ctx) {
|
|
3584
3586
|
const { text: text2 } = e;
|
|
@@ -4015,7 +4017,7 @@ class LinkedWesl {
|
|
|
4015
4017
|
code: this.dest
|
|
4016
4018
|
});
|
|
4017
4019
|
device.popErrorScope();
|
|
4018
|
-
|
|
4020
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
4019
4021
|
device.injectError("validation", promise);
|
|
4020
4022
|
module.getCompilationInfo().then((compilationInfo) => {
|
|
4021
4023
|
if (compilationInfo.messages.length === 0) {
|
|
@@ -4059,7 +4061,7 @@ class LinkedWesl {
|
|
|
4059
4061
|
const srcPosition = srcMap.destToSrc(message.offset);
|
|
4060
4062
|
const srcEndPosition = message.length > 0 ? srcMap.destToSrc(message.offset + message.length) : srcPosition;
|
|
4061
4063
|
const length = srcEndPosition.position - srcPosition.position;
|
|
4062
|
-
|
|
4064
|
+
const [lineNum, linePos] = offsetToLineNumber(
|
|
4063
4065
|
srcPosition.position,
|
|
4064
4066
|
srcPosition.src.text
|
|
4065
4067
|
);
|
|
@@ -4082,7 +4084,7 @@ function compilationInfoToErrorMessage(compilationInfo, shaderModule) {
|
|
|
4082
4084
|
if (compilationInfo.messages.length === 0) return null;
|
|
4083
4085
|
let result = `Compilation log for [Invalid ShaderModule (${shaderModule.label || "unlabled"})]:
|
|
4084
4086
|
`;
|
|
4085
|
-
|
|
4087
|
+
const errorCount = compilationInfo.messages.filter(
|
|
4086
4088
|
(v) => v.type === "error"
|
|
4087
4089
|
).length;
|
|
4088
4090
|
if (errorCount > 0) {
|
|
@@ -4190,7 +4192,8 @@ async function link(params) {
|
|
|
4190
4192
|
const registry = parsedRegistry();
|
|
4191
4193
|
parseIntoRegistry(weslSrc, registry, "package", debugWeslRoot);
|
|
4192
4194
|
parseLibsIntoRegistry(libs, registry);
|
|
4193
|
-
|
|
4195
|
+
const srcMap = linkRegistry({ registry, ...params });
|
|
4196
|
+
return new LinkedWesl(srcMap);
|
|
4194
4197
|
}
|
|
4195
4198
|
function linkRegistry(params) {
|
|
4196
4199
|
const bound = bindAndTransform(params);
|
|
@@ -4214,7 +4217,7 @@ function bindAndTransform(params) {
|
|
|
4214
4217
|
if (constants) {
|
|
4215
4218
|
virtualLibs = { ...virtualLibs, constants: constantsGenerator(constants) };
|
|
4216
4219
|
}
|
|
4217
|
-
|
|
4220
|
+
const virtuals = virtualLibs && mapValues(virtualLibs, (fn2) => ({ fn: fn2 }));
|
|
4218
4221
|
const bindParams = { rootAst, registry, conditions, virtuals, mangler };
|
|
4219
4222
|
const bindResults = bindIdents(bindParams);
|
|
4220
4223
|
const { globalNames, decls: newDecls, newStatements } = bindResults;
|
|
@@ -4358,7 +4361,9 @@ function lowerBindingStructs(ast) {
|
|
|
4358
4361
|
({ memberRef, struct }) => transformBindingReference(memberRef, struct)
|
|
4359
4362
|
);
|
|
4360
4363
|
bindingRefs.forEach(
|
|
4361
|
-
({ intermediates }) => intermediates.forEach((e) =>
|
|
4364
|
+
({ intermediates }) => intermediates.forEach((e) => {
|
|
4365
|
+
e.contents = [];
|
|
4366
|
+
})
|
|
4362
4367
|
);
|
|
4363
4368
|
const contents = removeBindingStructs(moduleElem);
|
|
4364
4369
|
moduleElem.contents = [...newVars, ...contents];
|
|
@@ -4395,7 +4400,9 @@ function removeBindingStructs(moduleElem) {
|
|
|
4395
4400
|
function markBindingStructs(moduleElem) {
|
|
4396
4401
|
const structs = moduleElem.contents.filter((elem) => elem.kind === "struct");
|
|
4397
4402
|
const bindingStructs = structs.filter(containsBinding);
|
|
4398
|
-
bindingStructs.forEach((struct) =>
|
|
4403
|
+
bindingStructs.forEach((struct) => {
|
|
4404
|
+
struct.bindingStruct = true;
|
|
4405
|
+
});
|
|
4399
4406
|
return bindingStructs;
|
|
4400
4407
|
}
|
|
4401
4408
|
function containsBinding(struct) {
|
|
@@ -4469,17 +4476,18 @@ function findRefsToBindingStructs(moduleElem) {
|
|
|
4469
4476
|
}
|
|
4470
4477
|
function refersToBindingStruct(memberRef) {
|
|
4471
4478
|
const found = traceToStruct(memberRef.name.ident);
|
|
4472
|
-
if (found
|
|
4479
|
+
if (found == null ? void 0 : found.struct.bindingStruct) {
|
|
4473
4480
|
return { memberRef, ...found };
|
|
4474
4481
|
}
|
|
4475
4482
|
}
|
|
4476
4483
|
function traceToStruct(ident2) {
|
|
4484
|
+
var _a;
|
|
4477
4485
|
const decl = findDecl(ident2);
|
|
4478
4486
|
const declElem = decl.declElem;
|
|
4479
4487
|
if (declElem && declElem.kind === "param") {
|
|
4480
|
-
const name2 = declElem.name.typeRef.name;
|
|
4488
|
+
const name2 = (_a = declElem.name.typeRef) == null ? void 0 : _a.name;
|
|
4481
4489
|
if (typeof name2 !== "string") {
|
|
4482
|
-
if (name2.std) {
|
|
4490
|
+
if (name2 == null ? void 0 : name2.std) {
|
|
4483
4491
|
return void 0;
|
|
4484
4492
|
}
|
|
4485
4493
|
const paramDecl = findDecl(name2);
|
|
@@ -4504,6 +4512,88 @@ function transformBindingReference(memberRef, struct) {
|
|
|
4504
4512
|
memberRef.contents = [synthElem];
|
|
4505
4513
|
return synthElem;
|
|
4506
4514
|
}
|
|
4515
|
+
async function requestWeslDevice(adapter, descriptor) {
|
|
4516
|
+
if (!adapter) {
|
|
4517
|
+
throw new Error("No GPU adapter");
|
|
4518
|
+
}
|
|
4519
|
+
return adapter.requestDevice(descriptor).then(makeWeslDevice);
|
|
4520
|
+
}
|
|
4521
|
+
function makeWeslDevice(device) {
|
|
4522
|
+
const errorScopeStack = [];
|
|
4523
|
+
device.injectError = (type, error) => {
|
|
4524
|
+
const errorScope = errorScopeStack.findLast((v) => v.filter === type);
|
|
4525
|
+
if (errorScope !== void 0) {
|
|
4526
|
+
errorScope.errors.push(error);
|
|
4527
|
+
} else {
|
|
4528
|
+
error.then((e) => {
|
|
4529
|
+
if (e !== null) {
|
|
4530
|
+
dispatchError(e);
|
|
4531
|
+
}
|
|
4532
|
+
});
|
|
4533
|
+
}
|
|
4534
|
+
};
|
|
4535
|
+
function dispatchError(e) {
|
|
4536
|
+
device.addEventListener(
|
|
4537
|
+
"uncapturederror",
|
|
4538
|
+
(ev) => {
|
|
4539
|
+
if (!ev.defaultPrevented) {
|
|
4540
|
+
if ("compilationInfo" in ev.error) {
|
|
4541
|
+
const error = ev.error;
|
|
4542
|
+
if (error.compilationInfo) {
|
|
4543
|
+
for (const message of error.compilationInfo.messages) {
|
|
4544
|
+
throwClickableError({
|
|
4545
|
+
url: message.module.url,
|
|
4546
|
+
text: message.module.text ?? null,
|
|
4547
|
+
lineNumber: message.lineNum,
|
|
4548
|
+
lineColumn: message.linePos,
|
|
4549
|
+
length: message.length,
|
|
4550
|
+
error: new Error(message.type + ": " + message.message)
|
|
4551
|
+
});
|
|
4552
|
+
}
|
|
4553
|
+
} else {
|
|
4554
|
+
console.error(ev.error.message);
|
|
4555
|
+
}
|
|
4556
|
+
} else {
|
|
4557
|
+
console.error(ev.error.message);
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4560
|
+
},
|
|
4561
|
+
{
|
|
4562
|
+
// This event listener should only happen for this event!
|
|
4563
|
+
once: true
|
|
4564
|
+
}
|
|
4565
|
+
);
|
|
4566
|
+
device.dispatchEvent(
|
|
4567
|
+
new GPUUncapturedErrorEvent("uncapturederror", { error: e })
|
|
4568
|
+
);
|
|
4569
|
+
}
|
|
4570
|
+
device.pushErrorScope = /* @__PURE__ */ ((baseFn) => {
|
|
4571
|
+
return function(filter) {
|
|
4572
|
+
errorScopeStack.push({
|
|
4573
|
+
filter,
|
|
4574
|
+
errors: []
|
|
4575
|
+
});
|
|
4576
|
+
return baseFn.call(this, filter);
|
|
4577
|
+
};
|
|
4578
|
+
})(device.pushErrorScope);
|
|
4579
|
+
device.popErrorScope = /* @__PURE__ */ ((baseFn) => {
|
|
4580
|
+
return function() {
|
|
4581
|
+
const errorScope = errorScopeStack.pop();
|
|
4582
|
+
if (errorScope === void 0) {
|
|
4583
|
+
throw new DOMException(
|
|
4584
|
+
"popErrorScope called on empty error scope stack",
|
|
4585
|
+
"OperationError"
|
|
4586
|
+
);
|
|
4587
|
+
}
|
|
4588
|
+
errorScope.errors.push(baseFn.call(this));
|
|
4589
|
+
const errorPromise = Promise.all(errorScope.errors).then(
|
|
4590
|
+
(values) => values.find((v) => v !== null) ?? null
|
|
4591
|
+
);
|
|
4592
|
+
return errorPromise;
|
|
4593
|
+
};
|
|
4594
|
+
})(device.popErrorScope);
|
|
4595
|
+
return device;
|
|
4596
|
+
}
|
|
4507
4597
|
export {
|
|
4508
4598
|
LinkedWesl,
|
|
4509
4599
|
WeslParseError,
|
|
@@ -4511,6 +4601,7 @@ export {
|
|
|
4511
4601
|
astToString,
|
|
4512
4602
|
attributeToString$1 as attributeToString,
|
|
4513
4603
|
bindAndTransform,
|
|
4604
|
+
bindIdents,
|
|
4514
4605
|
bindingStructsPlugin,
|
|
4515
4606
|
blankWeslParseState,
|
|
4516
4607
|
childIdent,
|
|
@@ -4522,10 +4613,13 @@ export {
|
|
|
4522
4613
|
filterMap,
|
|
4523
4614
|
findMap,
|
|
4524
4615
|
findRefsToBindingStructs,
|
|
4616
|
+
findUnboundIdents,
|
|
4617
|
+
findValidRootDecls,
|
|
4525
4618
|
flatImports,
|
|
4526
4619
|
groupBy,
|
|
4527
4620
|
grouped,
|
|
4528
4621
|
identToString,
|
|
4622
|
+
isGlobal,
|
|
4529
4623
|
last,
|
|
4530
4624
|
lengthPrefixMangle,
|
|
4531
4625
|
link,
|
|
@@ -4560,7 +4654,6 @@ export {
|
|
|
4560
4654
|
scopeToStringLong,
|
|
4561
4655
|
selectModule,
|
|
4562
4656
|
syntheticWeslParseState,
|
|
4563
|
-
throwClickableError,
|
|
4564
4657
|
transformBindingReference,
|
|
4565
4658
|
transformBindingStruct,
|
|
4566
4659
|
underscoreMangle
|