@@ -1247,75 +1247,6 @@ const ASTCallbacks = {
12471247 delete node . update ;
12481248 } ,
12491249
1250- // Swizzle assignments on storage fields like data[i].velocity.y *= -1 don't work
1251- // as plain assignments because data.get(i).velocity returns a StrandsNode without
1252- // an onRebind callback, so setting .y on it has no effect on the buffer.
1253- //
1254- // We detect this case here (ancestor walk is post-order, so by the time this runs
1255- // data[i] has already been converted to data.get(i) by the MemberExpression visitor).
1256- // buildPropertyPath returns null when it hits a non-Identifier object (like a .get()
1257- // call), which distinguishes this from struct-field swizzles like inputs.position.x
1258- // where buildPropertyPath returns a non-null path and the phi-node mechanism handles it.
1259- //
1260- // We rewrite fieldExpr.swizzle = rhs into a read-modify-write:
1261- // let __tmp = fieldExpr
1262- // __tmp.swizzle = rhs swizzleTrap.set mutates __tmp.id
1263- // fieldExpr = __tmp proxy setter writes back to the buffer
1264- ExpressionStatement ( node , state , ancestors ) {
1265- if ( ancestors . some ( a => nodeIsUniform ( a ) || nodeIsUniformCallbackFn ( a , state . uniformCallbackNames ) ) ) {
1266- return ;
1267- }
1268- const assign = node . expression ;
1269- if ( assign ?. type !== 'AssignmentExpression' ) return ;
1270- const left = assign . left ;
1271- if ( left . type !== 'MemberExpression' || left . computed ) return ;
1272- const propName = left . property . name ;
1273- if ( ! propName || ! isSwizzle ( propName ) ) return ;
1274- const fieldExpr = left . object ;
1275- // A plain identifier (e.g. myVec.y = 5) is handled directly by swizzleTrap.set.
1276- if ( fieldExpr . type === 'Identifier' ) return ;
1277- // A simple dotted path (e.g. inputs.position.x) is handled by the phi-node mechanism.
1278- if ( buildPropertyPath ( fieldExpr ) !== null ) return ;
1279-
1280- const tmpName = `__swizzle_tmp_${ blockVarCounter ++ } ` ;
1281- node . type = 'BlockStatement' ;
1282- node . body = [
1283- {
1284- type : 'VariableDeclaration' ,
1285- declarations : [ {
1286- type : 'VariableDeclarator' ,
1287- id : { type : 'Identifier' , name : tmpName } ,
1288- init : JSON . parse ( JSON . stringify ( fieldExpr ) ) ,
1289- } ] ,
1290- kind : 'let' ,
1291- } ,
1292- {
1293- type : 'ExpressionStatement' ,
1294- expression : {
1295- type : 'AssignmentExpression' ,
1296- operator : '=' ,
1297- left : {
1298- type : 'MemberExpression' ,
1299- object : { type : 'Identifier' , name : tmpName } ,
1300- property : { type : 'Identifier' , name : propName } ,
1301- computed : false ,
1302- } ,
1303- right : assign . right ,
1304- } ,
1305- } ,
1306- {
1307- type : 'ExpressionStatement' ,
1308- expression : {
1309- type : 'AssignmentExpression' ,
1310- operator : '=' ,
1311- left : JSON . parse ( JSON . stringify ( fieldExpr ) ) ,
1312- right : { type : 'Identifier' , name : tmpName } ,
1313- } ,
1314- } ,
1315- ] ;
1316- delete node . expression ;
1317- } ,
1318-
13191250 // Helper method to replace identifier references in AST nodes
13201251 replaceIdentifierReferences ( node , oldName , newName ) {
13211252 if ( ! node || typeof node !== 'object' ) return node ;
0 commit comments