1- use crate :: { Context , JsError , JsNativeError , JsResult , vm:: opcode:: Operation } ;
1+ use crate :: {
2+ Context , JsError , JsNativeError , JsResult ,
3+ vm:: opcode:: { IndexOperand , Operation } ,
4+ } ;
25
36/// `DisposeResources` implements the DisposeResources operation.
47///
5- /// This opcode disposes all resources in the current disposal stack.
8+ /// This opcode disposes the last `count` resources from the disposal stack.
9+ /// The count is statically determined by the bytecompiler.
610///
711/// Operation:
812/// - Stack: **=>**
913pub ( crate ) struct DisposeResources ;
1014
1115impl DisposeResources {
12- pub ( crate ) fn operation ( ( ) : ( ) , context : & mut Context ) -> JsResult < ( ) > {
16+ pub ( crate ) fn operation ( count : IndexOperand , context : & mut Context ) -> JsResult < ( ) > {
17+ let count = u32:: from ( count) as usize ;
1318 let mut suppressed_error: Option < JsError > = None ;
1419
15- // Get the scope depth to know how many resources to dispose
16- let scope_depth = context. vm . current_disposal_scope_depth ( ) ;
17-
18- // Dispose resources in reverse order (LIFO) until we reach the scope depth
19- while context. vm . disposal_stack . len ( ) > scope_depth {
20+ // Dispose exactly `count` resources in reverse order (LIFO)
21+ for _ in 0 ..count {
2022 if let Some ( ( value, method) ) = context. vm . pop_disposable_resource ( ) {
21- // Call the dispose method
2223 let result = method. call ( & value, & [ ] , context) ;
2324
24- // If an error occurs, aggregate it
2525 if let Err ( err) = result {
2626 suppressed_error = Some ( match suppressed_error {
2727 None => err,
28- Some ( previous) => {
29- // Create a SuppressedError
30- create_suppressed_error ( err, & previous, context)
31- }
28+ Some ( previous) => create_suppressed_error ( err, & previous, context) ,
3229 } ) ;
3330 }
3431 }
3532 }
3633
37- // Pop the disposal scope depth marker
38- context. vm . pop_disposal_scope ( ) ;
39-
40- // If there were any errors, throw the aggregated error
4134 if let Some ( err) = suppressed_error {
4235 return Err ( err) ;
4336 }
@@ -62,7 +55,6 @@ fn create_suppressed_error(
6255 // TODO: Implement proper SuppressedError builtin in Phase 2
6356 let message = format ! ( "An error was suppressed during disposal: {suppressed}" ) ;
6457
65- // Attach the original error as a property
6658 // This is a temporary solution until SuppressedError is implemented
6759 JsNativeError :: error ( ) . with_message ( message) . into ( )
6860}
0 commit comments