@@ -76,6 +76,7 @@ import type {
7676 ItemLayer ,
7777 ItemStateStack ,
7878 ResolutionCtx ,
79+ StackLayer ,
7980 TgpuShaderStage ,
8081 Wgsl ,
8182} from './types.ts' ;
@@ -103,23 +104,8 @@ export type ResolutionCtxImplOptions = {
103104 readonly namespace : Namespace ;
104105} ;
105106
106- type SlotBindingLayer = {
107- type : 'slotBinding' ;
108- bindingMap : WeakMap < TgpuSlot < unknown > , unknown > ;
109- } ;
110-
111- type BlockScopeLayer = {
112- type : 'blockScope' ;
113- declarations : Map < string , Snippet > ;
114- } ;
115-
116107class ItemStateStackImpl implements ItemStateStack {
117- private _stack : (
118- | ItemLayer
119- | SlotBindingLayer
120- | FunctionScopeLayer
121- | BlockScopeLayer
122- ) [ ] = [ ] ;
108+ private _stack : StackLayer [ ] = [ ] ;
123109 private _itemDepth = 0 ;
124110
125111 get itemDepth ( ) : number {
@@ -146,21 +132,13 @@ class ItemStateStackImpl implements ItemStateStack {
146132 } ) ;
147133 }
148134
149- popItem ( ) {
150- this . pop ( 'item' ) ;
151- }
152-
153135 pushSlotBindings ( pairs : SlotValuePair < unknown > [ ] ) {
154136 this . _stack . push ( {
155137 type : 'slotBinding' ,
156138 bindingMap : new WeakMap ( pairs ) ,
157139 } ) ;
158140 }
159141
160- popSlotBindings ( ) {
161- this . pop ( 'slotBinding' ) ;
162- }
163-
164142 pushFunctionScope (
165143 functionType : 'normal' | TgpuShaderStage ,
166144 args : Snippet [ ] ,
@@ -182,31 +160,26 @@ class ItemStateStackImpl implements ItemStateStack {
182160 return scope ;
183161 }
184162
185- popFunctionScope ( ) {
186- this . pop ( 'functionScope' ) ;
187- }
188-
189163 pushBlockScope ( ) {
190164 this . _stack . push ( {
191165 type : 'blockScope' ,
192166 declarations : new Map ( ) ,
193167 } ) ;
194168 }
195169
196- popBlockScope ( ) {
197- this . pop ( 'blockScope' ) ;
198- }
199-
200- pop ( type ?: ( typeof this . _stack ) [ number ] [ 'type' ] ) {
170+ pop < T extends StackLayer [ 'type' ] > ( type : T ) : Extract < StackLayer , { type : T } > ;
171+ pop ( ) : StackLayer | undefined ;
172+ pop ( type ?: StackLayer [ 'type' ] ) {
201173 const layer = this . _stack [ this . _stack . length - 1 ] ;
202174 if ( ! layer || ( type && layer . type !== type ) ) {
203175 throw new Error ( `Internal error, expected a ${ type } layer to be on top.` ) ;
204176 }
205177
206- this . _stack . pop ( ) ;
178+ const poppedValue = this . _stack . pop ( ) ;
207179 if ( type === 'item' ) {
208180 this . _itemDepth -- ;
209181 }
182+ return poppedValue ;
210183 }
211184
212185 readSlot < T > ( slot : TgpuSlot < T > ) : T | undefined {
@@ -452,7 +425,7 @@ export class ResolutionCtxImpl implements ResolutionCtx {
452425 }
453426
454427 popBlockScope ( ) {
455- this . _itemStateStack . popBlockScope ( ) ;
428+ this . _itemStateStack . pop ( 'blockScope' ) ;
456429 }
457430
458431 generateLog ( op : string , args : Snippet [ ] ) : Snippet {
@@ -560,7 +533,7 @@ export class ResolutionCtxImpl implements ResolutionCtx {
560533 } ;
561534 } finally {
562535 if ( fnScopePushed ) {
563- this . _itemStateStack . popFunctionScope ( ) ;
536+ this . _itemStateStack . pop ( 'functionScope' ) ;
564537 }
565538 this . #namespaceInternal. nameRegistry . popFunctionScope ( ) ;
566539 }
@@ -612,7 +585,7 @@ export class ResolutionCtxImpl implements ResolutionCtx {
612585 try {
613586 return callback ( ) ;
614587 } finally {
615- this . _itemStateStack . popSlotBindings ( ) ;
588+ this . _itemStateStack . pop ( 'slotBinding' ) ;
616589 }
617590 }
618591
@@ -700,7 +673,7 @@ export class ResolutionCtxImpl implements ResolutionCtx {
700673
701674 throw new ResolutionError ( err , [ derived ] ) ;
702675 } finally {
703- this . _itemStateStack . popItem ( ) ;
676+ this . _itemStateStack . pop ( 'item' ) ;
704677 }
705678 }
706679
@@ -772,7 +745,7 @@ export class ResolutionCtxImpl implements ResolutionCtx {
772745
773746 throw new ResolutionError ( err , [ item ] ) ;
774747 } finally {
775- this . _itemStateStack . popItem ( ) ;
748+ this . _itemStateStack . pop ( 'item' ) ;
776749 }
777750 }
778751
0 commit comments