unplugin-typegpu 0.11.6 → 0.12.1
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/{babel-B7h6V8Bs.js → babel-C62qx26_.js} +16 -5
- package/{babel-ZVrKmopN.d.cts → babel-CYu2-eXe.d.cts} +1 -1
- package/{babel--cjzbyRs.d.ts → babel-DOOIkQDL.d.ts} +1 -1
- package/{babel-C7MhY2Q5.cjs → babel-DpCnkpmi.cjs} +16 -5
- package/babel.cjs +2 -2
- package/babel.d.cts +2 -2
- package/babel.d.ts +2 -2
- package/babel.js +2 -2
- package/{bun-D_FFJG6e.cjs → bun-Bijjhb7w.cjs} +3 -3
- package/{bun-f_IcPQ-M.js → bun-CJralo3D.js} +3 -3
- package/{bun-CF67VgNO.d.ts → bun-DKuUuTVo.d.ts} +1 -1
- package/{bun-iEmr0VLQ.d.cts → bun-YVuHXBJq.d.cts} +1 -1
- package/bun.cjs +3 -3
- package/bun.d.cts +2 -2
- package/bun.d.ts +2 -2
- package/bun.js +3 -3
- package/{common-CmJ77T6N.d.cts → common-BriEOmpZ.d.cts} +10 -4
- package/{common-BZrmpQ_X.d.ts → common-CWaD5wkm.d.ts} +10 -4
- package/common-Dilxou2I.js +710 -0
- package/common-hMfUmUk0.cjs +790 -0
- package/esbuild.cjs +6 -6
- package/esbuild.d.cts +5 -5
- package/esbuild.d.ts +5 -5
- package/esbuild.js +6 -6
- package/{factory-W6dKP7m4.js → factory-BSXzHM_n.js} +10 -70
- package/{factory-BgweY_8-.cjs → factory-CXjNN-uX.cjs} +11 -71
- package/farm.cjs +6 -6
- package/farm.d.cts +5 -5
- package/farm.d.ts +5 -5
- package/farm.js +6 -6
- package/{index-zDnadEd0.d.cts → index-COouFDDA.d.cts} +7 -7
- package/{index-BkLJ1amC.d.ts → index-DaJ1nxWt.d.ts} +1 -1
- package/index.cjs +6 -6
- package/index.d.cts +5 -5
- package/index.d.ts +5 -5
- package/index.js +6 -6
- package/package.json +5 -5
- package/{rolldown-browser-DQtD9pV1.cjs → rolldown-browser-0UeIgV94.cjs} +1 -1
- package/{rolldown-browser-D3BM6oXF.d.ts → rolldown-browser-1an_WnxF.d.ts} +13 -9
- package/rolldown-browser-Da9eNbZo.d.cts +44 -0
- package/{rolldown-browser-NmW1NQnD.js → rolldown-browser-XH90sRcH.js} +1 -1
- package/rolldown-browser.cjs +3 -3
- package/rolldown-browser.d.cts +2 -2
- package/rolldown-browser.d.ts +2 -2
- package/rolldown-browser.js +3 -3
- package/rolldown.cjs +6 -6
- package/rolldown.d.cts +5 -5
- package/rolldown.d.ts +5 -5
- package/rolldown.js +6 -6
- package/rollup.cjs +6 -6
- package/rollup.d.cts +5 -5
- package/rollup.d.ts +5 -5
- package/rollup.js +6 -6
- package/rspack.cjs +6 -6
- package/rspack.d.cts +5 -5
- package/rspack.d.ts +5 -5
- package/rspack.js +6 -6
- package/{src-YdrXaMF1.js → src-BPzkBd5O.js} +1 -1
- package/{src-NN6mroxq.cjs → src-CYnpqmx5.cjs} +2 -2
- package/vite.cjs +6 -6
- package/vite.d.cts +5 -5
- package/vite.d.ts +5 -5
- package/vite.js +6 -6
- package/webpack.cjs +6 -6
- package/webpack.d.cts +5 -5
- package/webpack.d.ts +5 -5
- package/webpack.js +6 -6
- package/common-CK7zOjbK.js +0 -279
- package/common-ddv56_tk.cjs +0 -346
- package/rolldown-browser-CvOoUvEH.d.cts +0 -40
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
import { transpileFn } from "tinyest-for-wgsl";
|
|
2
|
+
import * as t from "@babel/types";
|
|
3
|
+
import MagicString from "magic-string";
|
|
4
|
+
import * as tinyest from "tinyest";
|
|
5
|
+
|
|
6
|
+
//#region src/core/embeddedMetadata.ts
|
|
7
|
+
const embeddedTypegpuMetadataCache = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
/**
|
|
9
|
+
* Returns the node after unwrapping any parenthesized expressions.
|
|
10
|
+
*/
|
|
11
|
+
function unwrapParentheses(node) {
|
|
12
|
+
let current = node;
|
|
13
|
+
while (t.isParenthesizedExpression(current)) current = current.expression;
|
|
14
|
+
return current;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Returns the property name of a member expression.
|
|
18
|
+
*/
|
|
19
|
+
function memberPropertyName(node) {
|
|
20
|
+
if (!node.computed && t.isIdentifier(node.property)) return node.property.name;
|
|
21
|
+
if (node.computed && t.isStringLiteral(node.property)) return node.property.value;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns whether the node is a global TypeGPU metadata expression (`globalThis.__TYPEGPU_META__`).
|
|
25
|
+
*/
|
|
26
|
+
function isGlobalTypegpuMetadata(node) {
|
|
27
|
+
const unwrapped = unwrapParentheses(node);
|
|
28
|
+
return t.isMemberExpression(unwrapped) && t.isIdentifier(unwrapped.object, { name: "globalThis" }) && memberPropertyName(unwrapped) === "__TYPEGPU_META__";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns whether the node is a TypeGPU metadata set call (`(globalThis.__TYPEGPU_META__ ??= new WeakMap()).set`)
|
|
32
|
+
*/
|
|
33
|
+
function isTypegpuMetadataSetCall(node) {
|
|
34
|
+
const callee = unwrapParentheses(node.callee);
|
|
35
|
+
if (!t.isMemberExpression(callee) || memberPropertyName(callee) !== "set") return false;
|
|
36
|
+
const receiver = unwrapParentheses(callee.object);
|
|
37
|
+
return t.isAssignmentExpression(receiver, { operator: "??=" }) && isGlobalTypegpuMetadata(receiver.left);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns the node of the property with the given name in the object, if it exists.
|
|
41
|
+
*/
|
|
42
|
+
function objectPropertyValue(object, expectedName) {
|
|
43
|
+
for (const property of object.properties) {
|
|
44
|
+
if (!t.isObjectProperty(property) || property.computed) continue;
|
|
45
|
+
if ((t.isIdentifier(property.key) ? property.key.name : t.isStringLiteral(property.key) ? property.key.value : void 0) === expectedName) return property.value;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Returns metadata embedded by unplugin-typegpu for this exact function.
|
|
50
|
+
* Externals are required as part of the emitted shape, but are intentionally not evaluated.
|
|
51
|
+
*
|
|
52
|
+
* Consider:
|
|
53
|
+
* ```ts
|
|
54
|
+
* const f = ($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = () => {
|
|
55
|
+
* 'use gpu';
|
|
56
|
+
* }, {
|
|
57
|
+
* v: 2,
|
|
58
|
+
* name: "f",
|
|
59
|
+
* ast: {
|
|
60
|
+
* params: [],
|
|
61
|
+
* body: [0, []]
|
|
62
|
+
* },
|
|
63
|
+
* externals: {}
|
|
64
|
+
* }) && $.f)({});
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
function getEmbeddedTypegpuMetadata(path) {
|
|
68
|
+
var _expressionPath$paren, _assignedPath$parentP;
|
|
69
|
+
const cached = embeddedTypegpuMetadataCache.get(path);
|
|
70
|
+
if (cached !== void 0) return cached;
|
|
71
|
+
let expressionPath = path;
|
|
72
|
+
while ((_expressionPath$paren = expressionPath.parentPath) === null || _expressionPath$paren === void 0 ? void 0 : _expressionPath$paren.isParenthesizedExpression()) expressionPath = expressionPath.parentPath;
|
|
73
|
+
const assignmentPath = expressionPath.parentPath;
|
|
74
|
+
if (!(assignmentPath === null || assignmentPath === void 0 ? void 0 : assignmentPath.isAssignmentExpression({ operator: "=" }))) return;
|
|
75
|
+
let assignedPath = assignmentPath;
|
|
76
|
+
while ((_assignedPath$parentP = assignedPath.parentPath) === null || _assignedPath$parentP === void 0 ? void 0 : _assignedPath$parentP.isParenthesizedExpression()) assignedPath = assignedPath.parentPath;
|
|
77
|
+
const callPath = assignedPath.parentPath;
|
|
78
|
+
if (!((callPath === null || callPath === void 0 ? void 0 : callPath.isCallExpression()) && isTypegpuMetadataSetCall(callPath.node))) return;
|
|
79
|
+
const metadataNode = callPath.node.arguments[1];
|
|
80
|
+
if (!t.isObjectExpression(metadataNode)) return;
|
|
81
|
+
const versionNode = objectPropertyValue(metadataNode, "v");
|
|
82
|
+
const nameNode = objectPropertyValue(metadataNode, "name");
|
|
83
|
+
const astNode = objectPropertyValue(metadataNode, "ast");
|
|
84
|
+
const externalsNode = objectPropertyValue(metadataNode, "externals");
|
|
85
|
+
if (!t.isNumericLiteral(versionNode) || nameNode === void 0 || astNode === void 0 || externalsNode === void 0) return;
|
|
86
|
+
const name = t.isStringLiteral(nameNode) ? nameNode.value : void 0;
|
|
87
|
+
const embeddedTypegpuMetadata = {
|
|
88
|
+
v: versionNode.value,
|
|
89
|
+
name
|
|
90
|
+
};
|
|
91
|
+
embeddedTypegpuMetadataCache.set(path, embeddedTypegpuMetadata);
|
|
92
|
+
return embeddedTypegpuMetadata;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/checkPrivateRedeclaration.js
|
|
97
|
+
function _checkPrivateRedeclaration(e, t$1) {
|
|
98
|
+
if (t$1.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/classPrivateMethodInitSpec.js
|
|
103
|
+
function _classPrivateMethodInitSpec(e, a) {
|
|
104
|
+
_checkPrivateRedeclaration(e, a), a.add(e);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/classPrivateFieldInitSpec.js
|
|
109
|
+
function _classPrivateFieldInitSpec(e, t$1, a) {
|
|
110
|
+
_checkPrivateRedeclaration(e, t$1), t$1.set(e, a);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/assertClassBrand.js
|
|
115
|
+
function _assertClassBrand(e, t$1, n) {
|
|
116
|
+
if ("function" == typeof e ? e === t$1 : e.has(t$1)) return arguments.length < 3 ? t$1 : n;
|
|
117
|
+
throw new TypeError("Private element is not present on this object");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/classPrivateFieldGet2.js
|
|
122
|
+
function _classPrivateFieldGet2(s, a) {
|
|
123
|
+
return s.get(_assertClassBrand(s, a));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/typeof.js
|
|
128
|
+
function _typeof(o) {
|
|
129
|
+
"@babel/helpers - typeof";
|
|
130
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
|
|
131
|
+
return typeof o$1;
|
|
132
|
+
} : function(o$1) {
|
|
133
|
+
return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
|
|
134
|
+
}, _typeof(o);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/toPrimitive.js
|
|
139
|
+
function toPrimitive(t$1, r) {
|
|
140
|
+
if ("object" != _typeof(t$1) || !t$1) return t$1;
|
|
141
|
+
var e = t$1[Symbol.toPrimitive];
|
|
142
|
+
if (void 0 !== e) {
|
|
143
|
+
var i = e.call(t$1, r || "default");
|
|
144
|
+
if ("object" != _typeof(i)) return i;
|
|
145
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
146
|
+
}
|
|
147
|
+
return ("string" === r ? String : Number)(t$1);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/toPropertyKey.js
|
|
152
|
+
function toPropertyKey(t$1) {
|
|
153
|
+
var i = toPrimitive(t$1, "string");
|
|
154
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/defineProperty.js
|
|
159
|
+
function _defineProperty(e, r, t$1) {
|
|
160
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
161
|
+
value: t$1,
|
|
162
|
+
enumerable: !0,
|
|
163
|
+
configurable: !0,
|
|
164
|
+
writable: !0
|
|
165
|
+
}) : e[r] = t$1, e;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/objectSpread2.js
|
|
170
|
+
function ownKeys(e, r) {
|
|
171
|
+
var t$1 = Object.keys(e);
|
|
172
|
+
if (Object.getOwnPropertySymbols) {
|
|
173
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
174
|
+
r && (o = o.filter(function(r$1) {
|
|
175
|
+
return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
|
|
176
|
+
})), t$1.push.apply(t$1, o);
|
|
177
|
+
}
|
|
178
|
+
return t$1;
|
|
179
|
+
}
|
|
180
|
+
function _objectSpread2(e) {
|
|
181
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
182
|
+
var t$1 = null != arguments[r] ? arguments[r] : {};
|
|
183
|
+
r % 2 ? ownKeys(Object(t$1), !0).forEach(function(r$1) {
|
|
184
|
+
_defineProperty(e, r$1, t$1[r$1]);
|
|
185
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t$1)) : ownKeys(Object(t$1)).forEach(function(r$1) {
|
|
186
|
+
Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t$1, r$1));
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return e;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/core/obfuscate.ts
|
|
194
|
+
const { NodeTypeCatalog: NODE } = tinyest;
|
|
195
|
+
/**
|
|
196
|
+
* Generates all strings consisting of lowercase letters of the given length.
|
|
197
|
+
*/
|
|
198
|
+
function* fixedLengthNameGenerator(length) {
|
|
199
|
+
if (length === 0) {
|
|
200
|
+
yield "";
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
for (let i = 97; i <= 122; i++) for (const name of fixedLengthNameGenerator(length - 1)) yield `${String.fromCharCode(i)}${name}`;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Generates all strings consisting of lowercase letters.
|
|
207
|
+
*/
|
|
208
|
+
function* nameGenerator() {
|
|
209
|
+
for (let i = 1;; i++) for (const name of fixedLengthNameGenerator(i)) yield name;
|
|
210
|
+
}
|
|
211
|
+
var _nameMap = /* @__PURE__ */ new WeakMap();
|
|
212
|
+
var _nameGenerator = /* @__PURE__ */ new WeakMap();
|
|
213
|
+
var _Obfuscator_brand = /* @__PURE__ */ new WeakSet();
|
|
214
|
+
var Obfuscator = class {
|
|
215
|
+
constructor() {
|
|
216
|
+
_classPrivateMethodInitSpec(this, _Obfuscator_brand);
|
|
217
|
+
_classPrivateFieldInitSpec(this, _nameMap, /* @__PURE__ */ new Map());
|
|
218
|
+
_classPrivateFieldInitSpec(this, _nameGenerator, nameGenerator());
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* If `name` wasn't obfuscated before, give it a new obfuscated name.
|
|
222
|
+
* Then, returns the obfuscated version of `name`.
|
|
223
|
+
*/
|
|
224
|
+
obfuscate(name) {
|
|
225
|
+
let obfuscatedName = _classPrivateFieldGet2(_nameMap, this).get(name);
|
|
226
|
+
if (!obfuscatedName) {
|
|
227
|
+
obfuscatedName = _assertClassBrand(_Obfuscator_brand, this, _generateFreshName).call(this);
|
|
228
|
+
_classPrivateFieldGet2(_nameMap, this).set(name, obfuscatedName);
|
|
229
|
+
}
|
|
230
|
+
return obfuscatedName;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
function _generateFreshName() {
|
|
234
|
+
return _classPrivateFieldGet2(_nameGenerator, this).next().value;
|
|
235
|
+
}
|
|
236
|
+
var Context = class {
|
|
237
|
+
constructor() {
|
|
238
|
+
_defineProperty(this, "obfuscator", void 0);
|
|
239
|
+
this.obfuscator = new Obfuscator();
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
function obfuscate(fn) {
|
|
243
|
+
const ctx = new Context();
|
|
244
|
+
const params = fn.params.map((param) => {
|
|
245
|
+
if (param.type === "i") return _objectSpread2(_objectSpread2({}, param), {}, { name: ctx.obfuscator.obfuscate(param.name) });
|
|
246
|
+
return _objectSpread2(_objectSpread2({}, param), {}, { props: param.props.map((prop) => _objectSpread2(_objectSpread2({}, prop), {}, { alias: ctx.obfuscator.obfuscate(prop.alias) })) });
|
|
247
|
+
});
|
|
248
|
+
const body = obf(ctx, fn.body);
|
|
249
|
+
const externalNames = /* @__PURE__ */ new Map();
|
|
250
|
+
fn.externalNames.forEach((value, key) => externalNames.set(ctx.obfuscator.obfuscate(key), value));
|
|
251
|
+
return {
|
|
252
|
+
params,
|
|
253
|
+
body,
|
|
254
|
+
externalNames
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const visitors = {
|
|
258
|
+
block(ctx, node) {
|
|
259
|
+
return [NODE.block, node[1].map((node$1) => obf(ctx, node$1))];
|
|
260
|
+
},
|
|
261
|
+
binaryExpr(ctx, node) {
|
|
262
|
+
return [
|
|
263
|
+
NODE.binaryExpr,
|
|
264
|
+
obf(ctx, node[1]),
|
|
265
|
+
node[2],
|
|
266
|
+
obf(ctx, node[3])
|
|
267
|
+
];
|
|
268
|
+
},
|
|
269
|
+
assignmentExpr(ctx, node) {
|
|
270
|
+
return [
|
|
271
|
+
NODE.assignmentExpr,
|
|
272
|
+
obf(ctx, node[1]),
|
|
273
|
+
node[2],
|
|
274
|
+
obf(ctx, node[3])
|
|
275
|
+
];
|
|
276
|
+
},
|
|
277
|
+
logicalExpr(ctx, node) {
|
|
278
|
+
return [
|
|
279
|
+
NODE.logicalExpr,
|
|
280
|
+
obf(ctx, node[1]),
|
|
281
|
+
node[2],
|
|
282
|
+
obf(ctx, node[3])
|
|
283
|
+
];
|
|
284
|
+
},
|
|
285
|
+
unaryExpr(ctx, node) {
|
|
286
|
+
return [
|
|
287
|
+
NODE.unaryExpr,
|
|
288
|
+
node[1],
|
|
289
|
+
obf(ctx, node[2])
|
|
290
|
+
];
|
|
291
|
+
},
|
|
292
|
+
numericLiteral(_ctx, node) {
|
|
293
|
+
return [NODE.numericLiteral, node[1]];
|
|
294
|
+
},
|
|
295
|
+
call(ctx, node) {
|
|
296
|
+
return [
|
|
297
|
+
NODE.call,
|
|
298
|
+
obf(ctx, node[1]),
|
|
299
|
+
node[2].map((node$1) => obf(ctx, node$1))
|
|
300
|
+
];
|
|
301
|
+
},
|
|
302
|
+
memberAccess(ctx, node) {
|
|
303
|
+
return [
|
|
304
|
+
NODE.memberAccess,
|
|
305
|
+
obf(ctx, node[1]),
|
|
306
|
+
node[2]
|
|
307
|
+
];
|
|
308
|
+
},
|
|
309
|
+
indexAccess(ctx, node) {
|
|
310
|
+
return [
|
|
311
|
+
NODE.indexAccess,
|
|
312
|
+
obf(ctx, node[1]),
|
|
313
|
+
obf(ctx, node[2])
|
|
314
|
+
];
|
|
315
|
+
},
|
|
316
|
+
return(ctx, node) {
|
|
317
|
+
return node.length === 1 ? [NODE.return] : [NODE.return, obf(ctx, node[1])];
|
|
318
|
+
},
|
|
319
|
+
if(ctx, node) {
|
|
320
|
+
return node.length === 3 ? [
|
|
321
|
+
NODE.if,
|
|
322
|
+
obf(ctx, node[1]),
|
|
323
|
+
obf(ctx, node[2])
|
|
324
|
+
] : [
|
|
325
|
+
NODE.if,
|
|
326
|
+
obf(ctx, node[1]),
|
|
327
|
+
obf(ctx, node[2]),
|
|
328
|
+
obf(ctx, node[3])
|
|
329
|
+
];
|
|
330
|
+
},
|
|
331
|
+
let(ctx, node) {
|
|
332
|
+
return node.length === 2 ? [NODE.let, obf(ctx, node[1])] : [
|
|
333
|
+
NODE.let,
|
|
334
|
+
obf(ctx, node[1]),
|
|
335
|
+
obf(ctx, node[2])
|
|
336
|
+
];
|
|
337
|
+
},
|
|
338
|
+
const(ctx, node) {
|
|
339
|
+
return node.length === 2 ? [NODE.const, obf(ctx, node[1])] : [
|
|
340
|
+
NODE.const,
|
|
341
|
+
obf(ctx, node[1]),
|
|
342
|
+
obf(ctx, node[2])
|
|
343
|
+
];
|
|
344
|
+
},
|
|
345
|
+
for(ctx, node) {
|
|
346
|
+
return [
|
|
347
|
+
NODE.for,
|
|
348
|
+
obf(ctx, node[1]),
|
|
349
|
+
obf(ctx, node[2]),
|
|
350
|
+
obf(ctx, node[3]),
|
|
351
|
+
obf(ctx, node[4])
|
|
352
|
+
];
|
|
353
|
+
},
|
|
354
|
+
while(ctx, node) {
|
|
355
|
+
return [
|
|
356
|
+
NODE.while,
|
|
357
|
+
obf(ctx, node[1]),
|
|
358
|
+
obf(ctx, node[2])
|
|
359
|
+
];
|
|
360
|
+
},
|
|
361
|
+
continue(_ctx, _node) {
|
|
362
|
+
return [NODE.continue];
|
|
363
|
+
},
|
|
364
|
+
break(_ctx, _node) {
|
|
365
|
+
return [NODE.break];
|
|
366
|
+
},
|
|
367
|
+
forOf(ctx, node) {
|
|
368
|
+
return [
|
|
369
|
+
NODE.forOf,
|
|
370
|
+
obf(ctx, node[1]),
|
|
371
|
+
obf(ctx, node[2]),
|
|
372
|
+
obf(ctx, node[3])
|
|
373
|
+
];
|
|
374
|
+
},
|
|
375
|
+
arrayExpr(ctx, node) {
|
|
376
|
+
return [NODE.arrayExpr, node[1].map((node$1) => obf(ctx, node$1))];
|
|
377
|
+
},
|
|
378
|
+
preUpdate(ctx, node) {
|
|
379
|
+
return [
|
|
380
|
+
NODE.preUpdate,
|
|
381
|
+
node[1],
|
|
382
|
+
obf(ctx, node[2])
|
|
383
|
+
];
|
|
384
|
+
},
|
|
385
|
+
postUpdate(ctx, node) {
|
|
386
|
+
return [
|
|
387
|
+
NODE.postUpdate,
|
|
388
|
+
node[1],
|
|
389
|
+
obf(ctx, node[2])
|
|
390
|
+
];
|
|
391
|
+
},
|
|
392
|
+
stringLiteral(_ctx, node) {
|
|
393
|
+
return [NODE.stringLiteral, node[1]];
|
|
394
|
+
},
|
|
395
|
+
objectExpr(ctx, node) {
|
|
396
|
+
return [NODE.objectExpr, Object.fromEntries(Object.entries(node[1]).map(([key, value]) => [key, obf(ctx, value)]))];
|
|
397
|
+
},
|
|
398
|
+
conditionalExpr(ctx, node) {
|
|
399
|
+
return [
|
|
400
|
+
NODE.conditionalExpr,
|
|
401
|
+
obf(ctx, node[1]),
|
|
402
|
+
obf(ctx, node[2]),
|
|
403
|
+
obf(ctx, node[3])
|
|
404
|
+
];
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
const nodeIdToName = new Map(Object.entries(NODE).map(([key, value]) => [value, key]));
|
|
408
|
+
/**
|
|
409
|
+
* Traverses the AST and generates a new one that is obfuscated.
|
|
410
|
+
* Copies old AST when identifiers cannot appear in a subtree,
|
|
411
|
+
* e.g. in a member access property, or for operator nodes ('=', '<', ...).
|
|
412
|
+
*/
|
|
413
|
+
function obf(ctx, node) {
|
|
414
|
+
if (node === null) return node;
|
|
415
|
+
if (typeof node === "string") return ctx.obfuscator.obfuscate(node);
|
|
416
|
+
if (typeof node === "boolean") return node;
|
|
417
|
+
const nodeName = nodeIdToName.get(node[0]);
|
|
418
|
+
if (nodeName === void 0) throw new Error(`Internal error, no name for node type ${node[0]}.`);
|
|
419
|
+
const visitor = visitors[nodeName];
|
|
420
|
+
if (!visitor) throw new Error(`Internal error, no visitor for node '${nodeName}'.`);
|
|
421
|
+
return visitor(ctx, node);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
//#endregion
|
|
425
|
+
//#region src/core/common.ts
|
|
426
|
+
/**
|
|
427
|
+
* Each breaking change to the metadata format requires a bump to this number.
|
|
428
|
+
* It's used at runtime by `typegpu` to determine how to interpret a function's metadata.
|
|
429
|
+
*/
|
|
430
|
+
const METADATA_FORMAT_VERSION = 2;
|
|
431
|
+
function checkOpts(opts) {
|
|
432
|
+
if (opts.unstable_obfuscate && opts.autoNamingEnabled) throw new Error(`Options 'unstable_obfuscate' and 'autoNamingEnabled' cannot be enabled at the same time.`);
|
|
433
|
+
return opts;
|
|
434
|
+
}
|
|
435
|
+
function initPluginState(state, methods) {
|
|
436
|
+
var _state$opts$autoNamin;
|
|
437
|
+
state.tgpuAliases = new Set(state.opts.forceTgpuAlias ? [state.opts.forceTgpuAlias] : []);
|
|
438
|
+
state.autoNamingEnabled = (_state$opts$autoNamin = state.opts.autoNamingEnabled) !== null && _state$opts$autoNamin !== void 0 ? _state$opts$autoNamin : true;
|
|
439
|
+
state.inUseGpuScope = false;
|
|
440
|
+
Object.assign(state, methods);
|
|
441
|
+
}
|
|
442
|
+
/** Regular expressions used for early pruning (to avoid unnecessary parsing, which is expensive) */
|
|
443
|
+
const earlyPruneRegex = [/["']use gpu["']/, /t(ype)?gpu/];
|
|
444
|
+
const defaultOptions = {
|
|
445
|
+
include: /\.m?[jt]sx?(?:\?.*)?$/,
|
|
446
|
+
autoNamingEnabled: true,
|
|
447
|
+
earlyPruning: true,
|
|
448
|
+
unstable_obfuscate: false
|
|
449
|
+
};
|
|
450
|
+
/**
|
|
451
|
+
* Returns the block scope of a function declaration, if one exists.
|
|
452
|
+
* Used to hoist a function declaration to the top of the scope it's visible in.
|
|
453
|
+
*/
|
|
454
|
+
function getBlockScope(path) {
|
|
455
|
+
if (!path.node.id) return;
|
|
456
|
+
const binding = path.scope.getBinding(path.node.id.name);
|
|
457
|
+
if (!binding) return;
|
|
458
|
+
let scopePath = binding.scope.path;
|
|
459
|
+
if (t.isNode(scopePath.node.body)) scopePath = scopePath.get("body");
|
|
460
|
+
if (t.isBlockStatement(scopePath.node) || t.isProgram(scopePath.node)) return scopePath;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Checks if `node` is an alias for the 'tgpu' object, traditionally
|
|
464
|
+
* available via `import { tgpu } from 'typegpu'`.
|
|
465
|
+
*/
|
|
466
|
+
function isTgpu(state, node) {
|
|
467
|
+
let path = "";
|
|
468
|
+
let tail = node;
|
|
469
|
+
while (true) if (tail.type === "MemberExpression") {
|
|
470
|
+
if (tail.property.type === "StringLiteral" && tail.property.value === "~unstable") {
|
|
471
|
+
tail = tail.object;
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
if (tail.property.type !== "Identifier") break;
|
|
475
|
+
path = path ? `${tail.property.name}.${path}` : tail.property.name;
|
|
476
|
+
tail = tail.object;
|
|
477
|
+
} else if (tail.type === "Identifier") {
|
|
478
|
+
path = path ? `${tail.name}.${path}` : tail.name;
|
|
479
|
+
break;
|
|
480
|
+
} else break;
|
|
481
|
+
return state.tgpuAliases.has(path);
|
|
482
|
+
}
|
|
483
|
+
function gatherTgpuAliases(state, node) {
|
|
484
|
+
if (node.source.value !== "typegpu") return;
|
|
485
|
+
for (const spec of node.specifiers) if (spec.type === "ImportDefaultSpecifier" || spec.type === "ImportSpecifier" && spec.imported.type === "Identifier" && spec.imported.name === "tgpu") state.tgpuAliases.add(spec.local.name);
|
|
486
|
+
else if (spec.type === "ImportNamespaceSpecifier") state.tgpuAliases.add(`${spec.local.name}.tgpu`);
|
|
487
|
+
}
|
|
488
|
+
const fnShellFunctionNames = [
|
|
489
|
+
"fn",
|
|
490
|
+
"vertexFn",
|
|
491
|
+
"fragmentFn",
|
|
492
|
+
"computeFn"
|
|
493
|
+
];
|
|
494
|
+
function isShellImplementationCall(node, state) {
|
|
495
|
+
return node.callee.type === "CallExpression" && node.callee.callee.type === "MemberExpression" && node.callee.callee.property.type === "Identifier" && fnShellFunctionNames.includes(node.callee.callee.property.name) && node.arguments.length === 1 && isTgpu(state, node.callee.callee.object);
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Extracts a name and expression from nodes that contain a label and an expression,
|
|
499
|
+
* such as VariableDeclarator or PropertyDefinition.
|
|
500
|
+
* Returns a tuple of [name, expression] if found, otherwise undefined.
|
|
501
|
+
*
|
|
502
|
+
* @example
|
|
503
|
+
* extractLabelledExpression(node`let name = tgpu.bindGroupLayout({});`)
|
|
504
|
+
* // ["name", node`tgpu.bindGroupLayout({})`]
|
|
505
|
+
*/
|
|
506
|
+
function extractLabelledExpression(path) {
|
|
507
|
+
if (path.node.type === "VariableDeclarator" && path.node.id.type === "Identifier" && path.node.init) return [path.node.id.name, path.get("init")];
|
|
508
|
+
else if (path.node.type === "AssignmentExpression") {
|
|
509
|
+
const maybeName = tryFindIdentifier(path.node.left);
|
|
510
|
+
if (maybeName) return [maybeName, path.get("right")];
|
|
511
|
+
} else if (path.node.type === "ObjectProperty" && path.node.key.type === "Identifier") return [path.node.key.name, path.get("value")];
|
|
512
|
+
else if (path.node.type === "ClassProperty" && path.node.value && path.node.key.type === "Identifier") return [path.node.key.name, path.get("value")];
|
|
513
|
+
else if (path.node.type === "ClassPrivateProperty" && path.node.value && path.node.key.type === "PrivateName") return [path.node.key.id.name, path.get("value")];
|
|
514
|
+
}
|
|
515
|
+
function getFunctionName(path) {
|
|
516
|
+
var _extractLabelledExpre, _path$node$id;
|
|
517
|
+
const maybeName = path.parentPath ? (_extractLabelledExpre = extractLabelledExpression(path.parentPath)) === null || _extractLabelledExpre === void 0 ? void 0 : _extractLabelledExpre[0] : void 0;
|
|
518
|
+
return maybeName !== null && maybeName !== void 0 ? maybeName : path.node.type === "FunctionDeclaration" || path.node.type === "FunctionExpression" ? (_path$node$id = path.node.id) === null || _path$node$id === void 0 ? void 0 : _path$node$id.name : void 0;
|
|
519
|
+
}
|
|
520
|
+
const resourceConstructors = [
|
|
521
|
+
"bindGroupLayout",
|
|
522
|
+
"vertexLayout",
|
|
523
|
+
"privateVar",
|
|
524
|
+
"workgroupVar",
|
|
525
|
+
"const",
|
|
526
|
+
"slot",
|
|
527
|
+
"accessor",
|
|
528
|
+
"mutableAccessor",
|
|
529
|
+
"comptime",
|
|
530
|
+
...fnShellFunctionNames,
|
|
531
|
+
"createBuffer",
|
|
532
|
+
"createMutable",
|
|
533
|
+
"createReadonly",
|
|
534
|
+
"createUniform",
|
|
535
|
+
"createQuerySet",
|
|
536
|
+
"createPipeline",
|
|
537
|
+
"createComputePipeline",
|
|
538
|
+
"createGuardedComputePipeline",
|
|
539
|
+
"createRenderPipeline",
|
|
540
|
+
"createTexture",
|
|
541
|
+
"createSampler",
|
|
542
|
+
"createComparisonSampler",
|
|
543
|
+
"struct",
|
|
544
|
+
"unstruct",
|
|
545
|
+
"createView"
|
|
546
|
+
];
|
|
547
|
+
/**
|
|
548
|
+
* Checks if `node` should be wrapped in an autoname function.
|
|
549
|
+
* Since it is mostly for debugging and clean WGSL generation,
|
|
550
|
+
* some false positives and false negatives are admissible.
|
|
551
|
+
*/
|
|
552
|
+
function containsResourceConstructorCall(node, state) {
|
|
553
|
+
if (node.type === "CallExpression") {
|
|
554
|
+
if (isShellImplementationCall(node, state)) return true;
|
|
555
|
+
if (node.callee.type === "Identifier" && resourceConstructors.includes(node.callee.name)) return true;
|
|
556
|
+
if (node.callee.type === "MemberExpression") {
|
|
557
|
+
if (node.callee.property.type === "Identifier") {
|
|
558
|
+
if (resourceConstructors.includes(node.callee.property.name)) return true;
|
|
559
|
+
if (node.callee.property.name === "$name") return false;
|
|
560
|
+
}
|
|
561
|
+
return containsResourceConstructorCall(node.callee.object, state);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (node.type === "TaggedTemplateExpression") return containsResourceConstructorCall(node.tag, state);
|
|
565
|
+
return false;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Tries to find an identifier in a node.
|
|
569
|
+
*
|
|
570
|
+
* @example
|
|
571
|
+
* // syntax is simplified, imagine the arguments are appropriate nodes instead
|
|
572
|
+
* tryFindIdentifier('myBuffer'); // 'myBuffer'
|
|
573
|
+
* tryFindIdentifier('buffers.myBuffer'); // 'myBuffer'
|
|
574
|
+
* tryFindIdentifier('this.myBuffer'); // 'myBuffer'
|
|
575
|
+
* tryFindIdentifier('[a, b]'); // undefined
|
|
576
|
+
*/
|
|
577
|
+
function tryFindIdentifier(node) {
|
|
578
|
+
if (node.type === "Identifier") return node.name;
|
|
579
|
+
if (node.type === "PrivateName") return tryFindIdentifier(node.id);
|
|
580
|
+
if (node.type === "MemberExpression") return tryFindIdentifier(node.property);
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Checks if `node` contains a label and a tgpu expression that could be named.
|
|
584
|
+
* If so, it calls the provided callback. Nodes selected for naming include (but are not limited to):
|
|
585
|
+
*
|
|
586
|
+
* `let name = tgpu.bindGroupLayout({});` (VariableDeclarator)
|
|
587
|
+
*
|
|
588
|
+
* `name = tgpu.bindGroupLayout({});` (AssignmentExpression)
|
|
589
|
+
*
|
|
590
|
+
* `property: tgpu.bindGroupLayout({})` (Property/ObjectProperty)
|
|
591
|
+
*
|
|
592
|
+
* Since it is mostly for debugging and clean WGSL generation,
|
|
593
|
+
* some false positives and false negatives are admissible.
|
|
594
|
+
*
|
|
595
|
+
* This function is NOT used for auto-naming shell-less functions.
|
|
596
|
+
* Those are handled separately.
|
|
597
|
+
*
|
|
598
|
+
* @privateRemarks
|
|
599
|
+
* When adding new checks, you need to call this method in the corresponding node in Babel.
|
|
600
|
+
*/
|
|
601
|
+
function performExpressionNaming(state, path, namingCallback) {
|
|
602
|
+
if (!state.autoNamingEnabled) return;
|
|
603
|
+
const labelledExpression = extractLabelledExpression(path);
|
|
604
|
+
if (labelledExpression) {
|
|
605
|
+
const [label, expressionPath] = labelledExpression;
|
|
606
|
+
if (containsResourceConstructorCall(expressionPath.node, state)) namingCallback(expressionPath, label);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
const operators = {
|
|
610
|
+
"+": "__tsover_add",
|
|
611
|
+
"-": "__tsover_sub",
|
|
612
|
+
"*": "__tsover_mul",
|
|
613
|
+
"/": "__tsover_div",
|
|
614
|
+
"%": "__tsover_mod",
|
|
615
|
+
"+=": "__tsover_add",
|
|
616
|
+
"-=": "__tsover_sub",
|
|
617
|
+
"*=": "__tsover_mul",
|
|
618
|
+
"/=": "__tsover_div",
|
|
619
|
+
"%=": "__tsover_mod"
|
|
620
|
+
};
|
|
621
|
+
function containsUseGpuDirective(node) {
|
|
622
|
+
var _node$body$directives, _node$body;
|
|
623
|
+
return ("directives" in node.body ? (_node$body$directives = (_node$body = node.body) === null || _node$body === void 0 ? void 0 : _node$body.directives) !== null && _node$body$directives !== void 0 ? _node$body$directives : [] : []).map((directive) => directive.value.value).includes("use gpu");
|
|
624
|
+
}
|
|
625
|
+
const fnNodeToTranspiledMap = /* @__PURE__ */ new WeakMap();
|
|
626
|
+
function functionOnExit(path, state) {
|
|
627
|
+
const node = path.node;
|
|
628
|
+
if (!containsUseGpuDirective(node) || getEmbeddedTypegpuMetadata(path) !== void 0) return;
|
|
629
|
+
state.inUseGpuScope = false;
|
|
630
|
+
const ast = fnNodeToTranspiledMap.get(path.node);
|
|
631
|
+
const maybeName = getFunctionName(path);
|
|
632
|
+
if (!ast) throw new Error(`No metadata found for function ${maybeName !== null && maybeName !== void 0 ? maybeName : "<unnamed>"}`);
|
|
633
|
+
state.assignMetadata(path, maybeName, ast);
|
|
634
|
+
path.skip();
|
|
635
|
+
}
|
|
636
|
+
function transpile(rootNode, obf$1) {
|
|
637
|
+
const result = transpileFn(rootNode);
|
|
638
|
+
if (obf$1) return obfuscate(result);
|
|
639
|
+
return result;
|
|
640
|
+
}
|
|
641
|
+
const functionVisitor = {
|
|
642
|
+
ImportDeclaration(path, state) {
|
|
643
|
+
gatherTgpuAliases(state, path.node);
|
|
644
|
+
},
|
|
645
|
+
VariableDeclarator(path, state) {
|
|
646
|
+
performExpressionNaming(state, path, (pathToName, name) => {
|
|
647
|
+
state.wrapInAutoName(pathToName, name);
|
|
648
|
+
});
|
|
649
|
+
},
|
|
650
|
+
ObjectProperty(path, state) {
|
|
651
|
+
performExpressionNaming(state, path, (pathToName, name) => state.wrapInAutoName(pathToName, name));
|
|
652
|
+
},
|
|
653
|
+
ClassProperty(path, state) {
|
|
654
|
+
performExpressionNaming(state, path, (pathToName, name) => state.wrapInAutoName(pathToName, name));
|
|
655
|
+
},
|
|
656
|
+
ClassPrivateProperty(path, state) {
|
|
657
|
+
performExpressionNaming(state, path, (pathToName, name) => state.wrapInAutoName(pathToName, name));
|
|
658
|
+
},
|
|
659
|
+
AssignmentExpression: { exit(path, state) {
|
|
660
|
+
const runtimeFn = operators[path.node.operator];
|
|
661
|
+
if (state.inUseGpuScope && runtimeFn) state.replaceWithAssignmentOverload(path, runtimeFn);
|
|
662
|
+
performExpressionNaming(state, path, (pathToName, name) => state.wrapInAutoName(pathToName, name));
|
|
663
|
+
path.skip();
|
|
664
|
+
} },
|
|
665
|
+
BinaryExpression: { exit(path, state) {
|
|
666
|
+
const runtimeFn = operators[path.node.operator];
|
|
667
|
+
if (state.inUseGpuScope && runtimeFn) state.replaceWithBinaryOverload(path, runtimeFn);
|
|
668
|
+
path.skip();
|
|
669
|
+
} },
|
|
670
|
+
ArrowFunctionExpression: {
|
|
671
|
+
enter(path, state) {
|
|
672
|
+
if (containsUseGpuDirective(path.node) && getEmbeddedTypegpuMetadata(path) === void 0) {
|
|
673
|
+
fnNodeToTranspiledMap.set(path.node, transpile(path.node, this.opts.unstable_obfuscate));
|
|
674
|
+
if (state.inUseGpuScope) throw new Error(`Nesting 'use gpu' functions is not allowed`);
|
|
675
|
+
state.inUseGpuScope = true;
|
|
676
|
+
}
|
|
677
|
+
},
|
|
678
|
+
exit: functionOnExit
|
|
679
|
+
},
|
|
680
|
+
FunctionExpression: {
|
|
681
|
+
enter(path, state) {
|
|
682
|
+
if (containsUseGpuDirective(path.node) && getEmbeddedTypegpuMetadata(path) === void 0) {
|
|
683
|
+
fnNodeToTranspiledMap.set(path.node, transpile(path.node, this.opts.unstable_obfuscate));
|
|
684
|
+
if (state.inUseGpuScope) throw new Error(`Nesting 'use gpu' functions is not allowed`);
|
|
685
|
+
state.inUseGpuScope = true;
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
exit: functionOnExit
|
|
689
|
+
},
|
|
690
|
+
FunctionDeclaration: {
|
|
691
|
+
enter(path, state) {
|
|
692
|
+
if (containsUseGpuDirective(path.node) && getEmbeddedTypegpuMetadata(path) === void 0) {
|
|
693
|
+
fnNodeToTranspiledMap.set(path.node, transpile(path.node, this.opts.unstable_obfuscate));
|
|
694
|
+
if (state.inUseGpuScope) throw new Error(`Nesting 'use gpu' functions is not allowed`);
|
|
695
|
+
state.inUseGpuScope = true;
|
|
696
|
+
}
|
|
697
|
+
},
|
|
698
|
+
exit: functionOnExit
|
|
699
|
+
},
|
|
700
|
+
CallExpression: { exit(path, state) {
|
|
701
|
+
const node = path.node;
|
|
702
|
+
if (isShellImplementationCall(node, state)) {
|
|
703
|
+
const implementation = node.arguments[0];
|
|
704
|
+
if (implementation && (implementation.type === "FunctionExpression" || implementation.type === "ArrowFunctionExpression") && !containsUseGpuDirective(implementation)) state.assignMetadata(path.get("arguments.0"), getFunctionName(path.get("arguments.0")), transpile(implementation, this.opts.unstable_obfuscate));
|
|
705
|
+
}
|
|
706
|
+
} }
|
|
707
|
+
};
|
|
708
|
+
|
|
709
|
+
//#endregion
|
|
710
|
+
export { functionVisitor as a, _objectSpread2 as c, earlyPruneRegex as i, checkOpts as n, getBlockScope as o, defaultOptions as r, initPluginState as s, METADATA_FORMAT_VERSION as t };
|