@@ -2,6 +2,7 @@ use std::mem::variant_count;
22
33use rustc_abi:: HasDataLayout ;
44
5+ use crate :: concurrency:: thread:: ThreadNotFound ;
56use crate :: * ;
67
78#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
@@ -14,7 +15,7 @@ pub enum PseudoHandle {
1415pub enum Handle {
1516 Null ,
1617 Pseudo ( PseudoHandle ) ,
17- Thread ( u32 ) ,
18+ Thread ( ThreadId ) ,
1819}
1920
2021impl PseudoHandle {
@@ -34,6 +35,14 @@ impl PseudoHandle {
3435 }
3536}
3637
38+ /// Errors that can occur when constructing a [`Handle`] from a Scalar.
39+ pub enum HandleError {
40+ /// There is no thread with the given ID.
41+ ThreadNotFound ( ThreadNotFound ) ,
42+ /// Can't convert scalar to handle because it is structurally invalid.
43+ InvalidHandle ,
44+ }
45+
3746impl Handle {
3847 const NULL_DISCRIMINANT : u32 = 0 ;
3948 const PSEUDO_DISCRIMINANT : u32 = 1 ;
@@ -51,7 +60,7 @@ impl Handle {
5160 match self {
5261 Self :: Null => 0 ,
5362 Self :: Pseudo ( pseudo_handle) => pseudo_handle. value ( ) ,
54- Self :: Thread ( thread) => thread,
63+ Self :: Thread ( thread) => thread. to_u32 ( ) ,
5564 }
5665 }
5766
@@ -95,7 +104,7 @@ impl Handle {
95104 match discriminant {
96105 Self :: NULL_DISCRIMINANT if data == 0 => Some ( Self :: Null ) ,
97106 Self :: PSEUDO_DISCRIMINANT => Some ( Self :: Pseudo ( PseudoHandle :: from_value ( data) ?) ) ,
98- Self :: THREAD_DISCRIMINANT => Some ( Self :: Thread ( data) ) ,
107+ Self :: THREAD_DISCRIMINANT => Some ( Self :: Thread ( ThreadId :: new_unchecked ( data) ) ) ,
99108 _ => None ,
100109 }
101110 }
@@ -126,21 +135,35 @@ impl Handle {
126135 Scalar :: from_target_isize ( signed_handle. into ( ) , cx)
127136 }
128137
129- pub fn from_scalar < ' tcx > (
138+ /// Convert a scalar into a structured `Handle`.
139+ /// Structurally invalid handles return [`HandleError::InvalidHandle`].
140+ /// If the handle is structurally valid but semantically invalid, e.g. a for non-existent thread
141+ /// ID, returns [`HandleError::ThreadNotFound`].
142+ pub fn try_from_scalar < ' tcx > (
130143 handle : Scalar ,
131- cx : & impl HasDataLayout ,
132- ) -> InterpResult < ' tcx , Option < Self > > {
144+ cx : & MiriInterpCx < ' tcx > ,
145+ ) -> InterpResult < ' tcx , Result < Self , HandleError > > {
133146 let sign_extended_handle = handle. to_target_isize ( cx) ?;
134147
135148 #[ expect( clippy:: cast_sign_loss) ] // we want to lose the sign
136149 let handle = if let Ok ( signed_handle) = i32:: try_from ( sign_extended_handle) {
137150 signed_handle as u32
138151 } else {
139152 // if a handle doesn't fit in an i32, it isn't valid.
140- return interp_ok ( None ) ;
153+ return interp_ok ( Err ( HandleError :: InvalidHandle ) ) ;
141154 } ;
142155
143- interp_ok ( Self :: from_packed ( handle) )
156+ match Self :: from_packed ( handle) {
157+ Some ( Self :: Thread ( thread) ) => {
158+ // validate the thread id
159+ match cx. machine . threads . thread_id_try_from ( thread. to_u32 ( ) ) {
160+ Ok ( id) => interp_ok ( Ok ( Self :: Thread ( id) ) ) ,
161+ Err ( e) => interp_ok ( Err ( HandleError :: ThreadNotFound ( e) ) ) ,
162+ }
163+ }
164+ Some ( handle) => interp_ok ( Ok ( handle) ) ,
165+ None => interp_ok ( Err ( HandleError :: InvalidHandle ) ) ,
166+ }
144167 }
145168}
146169
@@ -158,14 +181,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
158181 let this = self . eval_context_mut ( ) ;
159182
160183 let handle = this. read_scalar ( handle_op) ?;
161- let ret = match Handle :: from_scalar ( handle, this) ? {
162- Some ( Handle :: Thread ( thread) ) => {
163- if let Ok ( thread) = this. thread_id_try_from ( thread) {
164- this. detach_thread ( thread, /*allow_terminated_joined*/ true ) ?;
165- this. eval_windows ( "c" , "TRUE" )
166- } else {
167- this. invalid_handle ( "CloseHandle" ) ?
168- }
184+ let ret = match Handle :: try_from_scalar ( handle, this) ? {
185+ Ok ( Handle :: Thread ( thread) ) => {
186+ this. detach_thread ( thread, /*allow_terminated_joined*/ true ) ?;
187+ this. eval_windows ( "c" , "TRUE" )
169188 }
170189 _ => this. invalid_handle ( "CloseHandle" ) ?,
171190 } ;
0 commit comments