@@ -107,8 +107,8 @@ function makeCheckStatement(varName, line) {
107107 } ;
108108}
109109
110- function protectLoops ( ast , shaderNames ) {
111- let loopCount = 0 ;
110+ function collectLoopsToProtect ( ast , shaderNames ) {
111+ const loops = [ ] ;
112112
113113 function visitNode ( node , ancestors ) {
114114 const isInsideShader = ancestors . some ( ( ancestor , idx ) => {
@@ -142,30 +142,19 @@ function protectLoops(ast, shaderNames) {
142142
143143 if ( isInsideShader ) return ;
144144
145- const varName = `_LP${ loopCount ++ } ` ;
146- const { line } = node . loc . start ;
147- const check = makeCheckStatement ( varName , line ) ;
148-
149- if ( node . body . type === 'BlockStatement' ) {
150- node . body . body . unshift ( check ) ;
151- } else {
152- node . body = { type : 'BlockStatement' , body : [ check , node . body ] } ;
153- }
154-
155- const varDecl = makeVarDecl ( varName ) ;
145+ let parentBlock = null ;
156146 for ( let i = ancestors . length - 1 ; i >= 0 ; i -- ) {
157147 const ancestor = ancestors [ i ] ;
158148 if (
159149 ancestor !== node &&
160150 ( ancestor . type === 'BlockStatement' || ancestor . type === 'Program' )
161151 ) {
162- const nodeIdx = ancestor . body . indexOf ( node ) ;
163- if ( nodeIdx !== - 1 ) {
164- ancestor . body . splice ( nodeIdx , 0 , varDecl ) ;
165- break ;
166- }
152+ parentBlock = ancestor ;
153+ break ;
167154 }
168155 }
156+
157+ loops . push ( { loop : node , parentBlock } ) ;
169158 }
170159
171160 walk . ancestor ( ast , {
@@ -174,7 +163,29 @@ function protectLoops(ast, shaderNames) {
174163 DoWhileStatement : visitNode
175164 } ) ;
176165
177- return loopCount ;
166+ return loops ;
167+ }
168+
169+ function injectProtection ( loops ) {
170+ loops . forEach ( ( { loop, parentBlock } , idx ) => {
171+ const varName = `_LP${ idx } ` ;
172+ const { line } = loop . loc . start ;
173+ const check = makeCheckStatement ( varName , line ) ;
174+
175+ if ( loop . body . type === 'BlockStatement' ) {
176+ loop . body . body . unshift ( check ) ;
177+ } else {
178+ loop . body = { type : 'BlockStatement' , body : [ check , loop . body ] } ;
179+ }
180+
181+ if ( parentBlock ) {
182+ const varDecl = makeVarDecl ( varName ) ;
183+ const nodeIdx = parentBlock . body . indexOf ( loop ) ;
184+ if ( nodeIdx !== - 1 ) {
185+ parentBlock . body . splice ( nodeIdx , 0 , varDecl ) ;
186+ }
187+ }
188+ } ) ;
178189}
179190
180191function parseJs ( jsText ) {
@@ -199,9 +210,11 @@ export function jsPreprocess(jsText) {
199210 if ( ! ast ) return jsText ;
200211
201212 const shaderNames = collectShaderFunctionNames ( ast ) ;
202- const loopCount = protectLoops ( ast , shaderNames ) ;
213+ const loops = collectLoopsToProtect ( ast , shaderNames ) ;
214+
215+ if ( loops . length === 0 ) return jsText ;
203216
204- if ( loopCount === 0 ) return jsText ;
217+ injectProtection ( loops ) ;
205218
206219 return escodegen . generate ( ast ) ;
207220}
0 commit comments