@@ -294,9 +294,85 @@ pub enum cleantype {
294
294
normal_exit_and_unwind
295
295
}
296
296
297
+ // Cleanup functions
298
+
299
+ /// A cleanup function: a built-in destructor.
300
+ pub trait CleanupFunction {
301
+ fn clean ( & self , block : @mut Block ) -> @mut Block ;
302
+ }
303
+
304
+ /// A cleanup function that calls the "drop glue" (destructor function) on
305
+ /// a typed value.
306
+ pub struct TypeDroppingCleanupFunction {
307
+ val : ValueRef ,
308
+ t : ty:: t ,
309
+ }
310
+
311
+ impl CleanupFunction for TypeDroppingCleanupFunction {
312
+ fn clean ( & self , block : @mut Block ) -> @mut Block {
313
+ glue:: drop_ty ( block, self . val , self . t )
314
+ }
315
+ }
316
+
317
+ /// A cleanup function that calls the "drop glue" (destructor function) on
318
+ /// an immediate typed value.
319
+ pub struct ImmediateTypeDroppingCleanupFunction {
320
+ val : ValueRef ,
321
+ t : ty:: t ,
322
+ }
323
+
324
+ impl CleanupFunction for ImmediateTypeDroppingCleanupFunction {
325
+ fn clean ( & self , block : @mut Block ) -> @mut Block {
326
+ glue:: drop_ty_immediate ( block, self . val , self . t )
327
+ }
328
+ }
329
+
330
+ /// A cleanup function that releases a write guard, returning a value to
331
+ /// mutable status.
332
+ pub struct WriteGuardReleasingCleanupFunction {
333
+ root_key : root_map_key ,
334
+ frozen_val_ref : ValueRef ,
335
+ bits_val_ref : ValueRef ,
336
+ filename_val : ValueRef ,
337
+ line_val : ValueRef ,
338
+ }
339
+
340
+ impl CleanupFunction for WriteGuardReleasingCleanupFunction {
341
+ fn clean ( & self , bcx : @mut Block ) -> @mut Block {
342
+ write_guard:: return_to_mut ( bcx,
343
+ self . root_key ,
344
+ self . frozen_val_ref ,
345
+ self . bits_val_ref ,
346
+ self . filename_val ,
347
+ self . line_val )
348
+ }
349
+ }
350
+
351
+ /// A cleanup function that frees some memory in the garbage-collected heap.
352
+ pub struct GCHeapFreeingCleanupFunction {
353
+ ptr : ValueRef ,
354
+ }
355
+
356
+ impl CleanupFunction for GCHeapFreeingCleanupFunction {
357
+ fn clean ( & self , bcx : @mut Block ) -> @mut Block {
358
+ glue:: trans_free ( bcx, self . ptr )
359
+ }
360
+ }
361
+
362
+ /// A cleanup function that frees some memory in the exchange heap.
363
+ pub struct ExchangeHeapFreeingCleanupFunction {
364
+ ptr : ValueRef ,
365
+ }
366
+
367
+ impl CleanupFunction for ExchangeHeapFreeingCleanupFunction {
368
+ fn clean ( & self , bcx : @mut Block ) -> @mut Block {
369
+ glue:: trans_exchange_free ( bcx, self . ptr )
370
+ }
371
+ }
372
+
297
373
pub enum cleanup {
298
- clean( @fn ( @ mut Block ) -> @ mut Block , cleantype ) ,
299
- clean_temp( ValueRef , @fn ( @ mut Block ) -> @ mut Block , cleantype ) ,
374
+ clean( @CleanupFunction , cleantype ) ,
375
+ clean_temp( ValueRef , @CleanupFunction , cleantype ) ,
300
376
}
301
377
302
378
// Can't use deriving(Clone) because of the managed closure.
@@ -337,13 +413,19 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype {
337
413
}
338
414
339
415
pub fn add_clean ( bcx : @mut Block , val : ValueRef , t : ty:: t ) {
340
- if !ty:: type_needs_drop ( bcx. tcx ( ) , t) { return ; }
416
+ if !ty:: type_needs_drop ( bcx. tcx ( ) , t) {
417
+ return
418
+ }
341
419
342
420
debug ! ( "add_clean(%s, %s, %s)" , bcx. to_str( ) , bcx. val_to_str( val) , t. repr( bcx. tcx( ) ) ) ;
343
421
344
422
let cleanup_type = cleanup_type ( bcx. tcx ( ) , t) ;
345
423
do in_scope_cx ( bcx, None ) |scope_info| {
346
- scope_info. cleanups . push ( clean ( |a| glue:: drop_ty ( a, val, t) , cleanup_type) ) ;
424
+ scope_info. cleanups . push ( clean ( @TypeDroppingCleanupFunction {
425
+ val : val,
426
+ t : t,
427
+ } as @CleanupFunction ,
428
+ cleanup_type) ) ;
347
429
grow_scope_clean ( scope_info) ;
348
430
}
349
431
}
@@ -355,9 +437,12 @@ pub fn add_clean_temp_immediate(cx: @mut Block, val: ValueRef, ty: ty::t) {
355
437
ty. repr( cx. tcx( ) ) ) ;
356
438
let cleanup_type = cleanup_type ( cx. tcx ( ) , ty) ;
357
439
do in_scope_cx ( cx, None ) |scope_info| {
358
- scope_info. cleanups . push (
359
- clean_temp ( val, |a| glue:: drop_ty_immediate ( a, val, ty) ,
360
- cleanup_type) ) ;
440
+ scope_info. cleanups . push ( clean_temp ( val,
441
+ @ImmediateTypeDroppingCleanupFunction {
442
+ val : val,
443
+ t : ty,
444
+ } as @CleanupFunction ,
445
+ cleanup_type) ) ;
361
446
grow_scope_clean ( scope_info) ;
362
447
}
363
448
}
@@ -381,7 +466,12 @@ pub fn add_clean_temp_mem_in_scope_(bcx: @mut Block, scope_id: Option<ast::NodeI
381
466
t. repr( bcx. tcx( ) ) ) ;
382
467
let cleanup_type = cleanup_type ( bcx. tcx ( ) , t) ;
383
468
do in_scope_cx ( bcx, scope_id) |scope_info| {
384
- scope_info. cleanups . push ( clean_temp ( val, |a| glue:: drop_ty ( a, val, t) , cleanup_type) ) ;
469
+ scope_info. cleanups . push ( clean_temp ( val,
470
+ @TypeDroppingCleanupFunction {
471
+ val : val,
472
+ t : t,
473
+ } as @CleanupFunction ,
474
+ cleanup_type) ) ;
385
475
grow_scope_clean ( scope_info) ;
386
476
}
387
477
}
@@ -405,29 +495,36 @@ pub fn add_clean_return_to_mut(bcx: @mut Block,
405
495
bcx. val_to_str( frozen_val_ref) ,
406
496
bcx. val_to_str( bits_val_ref) ) ;
407
497
do in_scope_cx ( bcx, Some ( scope_id) ) |scope_info| {
408
- scope_info. cleanups . push (
409
- clean_temp (
498
+ scope_info. cleanups . push ( clean_temp (
410
499
frozen_val_ref,
411
- |bcx| write_guard:: return_to_mut ( bcx, root_key, frozen_val_ref, bits_val_ref,
412
- filename_val, line_val) ,
500
+ @WriteGuardReleasingCleanupFunction {
501
+ root_key : root_key,
502
+ frozen_val_ref : frozen_val_ref,
503
+ bits_val_ref : bits_val_ref,
504
+ filename_val : filename_val,
505
+ line_val : line_val,
506
+ } as @CleanupFunction ,
413
507
normal_exit_only) ) ;
414
508
grow_scope_clean ( scope_info) ;
415
509
}
416
510
}
417
511
pub fn add_clean_free ( cx : @mut Block , ptr : ValueRef , heap : heap ) {
418
512
let free_fn = match heap {
419
- heap_managed | heap_managed_unique => {
420
- let f: @fn ( @mut Block ) -> @mut Block = |a| glue:: trans_free ( a, ptr) ;
421
- f
422
- }
423
- heap_exchange | heap_exchange_closure => {
424
- let f: @fn ( @mut Block ) -> @mut Block = |a| glue:: trans_exchange_free ( a, ptr) ;
425
- f
426
- }
513
+ heap_managed | heap_managed_unique => {
514
+ @GCHeapFreeingCleanupFunction {
515
+ ptr : ptr,
516
+ } as @CleanupFunction
517
+ }
518
+ heap_exchange | heap_exchange_closure => {
519
+ @ExchangeHeapFreeingCleanupFunction {
520
+ ptr : ptr,
521
+ } as @CleanupFunction
522
+ }
427
523
} ;
428
524
do in_scope_cx ( cx, None ) |scope_info| {
429
- scope_info. cleanups . push ( clean_temp ( ptr, free_fn,
430
- normal_exit_and_unwind) ) ;
525
+ scope_info. cleanups . push ( clean_temp ( ptr,
526
+ free_fn,
527
+ normal_exit_and_unwind) ) ;
431
528
grow_scope_clean ( scope_info) ;
432
529
}
433
530
}
0 commit comments