about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-07-31 13:30:44 +0200
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-08-01 09:56:21 +0200
commit23d351d6d496d61f859da9676a4c72c0be9643ea (patch)
treee1165c6b908d48e02b545b38effb59f1d3cbe385
parentadfea61665385428b9c9aced9442dba65464c3c8 (diff)
downloadrust-23d351d6d496d61f859da9676a4c72c0be9643ea.tar.gz
rust-23d351d6d496d61f859da9676a4c72c0be9643ea.zip
Move tls code to its own file
-rw-r--r--miri/fn_call.rs3
-rw-r--r--miri/lib.rs91
-rw-r--r--miri/tls.rs94
3 files changed, 101 insertions, 87 deletions
diff --git a/miri/fn_call.rs b/miri/fn_call.rs
index cf3464ce3af..bef37c57981 100644
--- a/miri/fn_call.rs
+++ b/miri/fn_call.rs
@@ -12,9 +12,10 @@ use rustc_miri::interpret::*;
 use super::{
     TlsKey,
     EvalContext,
-    MemoryExt,
 };
 
+use tls::MemoryExt;
+
 use super::memory::Kind;
 
 pub trait EvalContextExt<'tcx> {
diff --git a/miri/lib.rs b/miri/lib.rs
index 89985593bc7..ab63ff7f29e 100644
--- a/miri/lib.rs
+++ b/miri/lib.rs
@@ -33,10 +33,12 @@ mod operator;
 mod intrinsic;
 mod helpers;
 mod memory;
+mod tls;
 
 use fn_call::EvalContextExt as MissingFnsEvalContextExt;
 use operator::EvalContextExt as OperatorEvalContextExt;
 use intrinsic::EvalContextExt as IntrinsicEvalContextExt;
+use tls::MemoryExt as TlsMemoryExt;
 
 pub fn eval_main<'a, 'tcx: 'a>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -165,7 +167,8 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, Evaluator> {
         // FIXME: replace loop by some structure that works with stepping
         while let Some((instance, ptr, key)) = dtor {
             trace!("Running TLS dtor {:?} on {:?}", instance, ptr);
-            // TODO: Potentially, this has to support all the other possible instances? See eval_fn_call in terminator/mod.rs
+            // TODO: Potentially, this has to support all the other possible instances?
+            // See eval_fn_call in interpret/terminator/mod.rs
             let mir = self.load_mir(instance.def)?;
             self.push_stack_frame(
                 instance,
@@ -191,91 +194,6 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, Evaluator> {
     }
 }
 
-trait MemoryExt<'tcx> {
-    fn create_tls_key(&mut self, dtor: Option<ty::Instance<'tcx>>) -> TlsKey;
-    fn delete_tls_key(&mut self, key: TlsKey) -> EvalResult<'tcx>;
-    fn load_tls(&mut self, key: TlsKey) -> EvalResult<'tcx, Pointer>;
-    fn store_tls(&mut self, key: TlsKey, new_data: Pointer) -> EvalResult<'tcx>;
-    fn fetch_tls_dtor(&mut self, key: Option<TlsKey>) -> EvalResult<'tcx, Option<(ty::Instance<'tcx>, Pointer, TlsKey)>>;
-}
-
-impl<'a, 'tcx: 'a> MemoryExt<'tcx> for Memory<'a, 'tcx, Evaluator> {
-    fn create_tls_key(&mut self, dtor: Option<ty::Instance<'tcx>>) -> TlsKey {
-        let new_key = self.data.next_thread_local;
-        self.data.next_thread_local += 1;
-        self.data.thread_local.insert(new_key, TlsEntry { data: Pointer::null(), dtor });
-        trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor);
-        return new_key;
-    }
-
-    fn delete_tls_key(&mut self, key: TlsKey) -> EvalResult<'tcx> {
-        return match self.data.thread_local.remove(&key) {
-            Some(_) => {
-                trace!("TLS key {} removed", key);
-                Ok(())
-            },
-            None => Err(EvalError::TlsOutOfBounds)
-        }
-    }
-
-    fn load_tls(&mut self, key: TlsKey) -> EvalResult<'tcx, Pointer> {
-        return match self.data.thread_local.get(&key) {
-            Some(&TlsEntry { data, .. }) => {
-                trace!("TLS key {} loaded: {:?}", key, data);
-                Ok(data)
-            },
-            None => Err(EvalError::TlsOutOfBounds)
-        }
-    }
-
-    fn store_tls(&mut self, key: TlsKey, new_data: Pointer) -> EvalResult<'tcx> {
-        return match self.data.thread_local.get_mut(&key) {
-            Some(&mut TlsEntry { ref mut data, .. }) => {
-                trace!("TLS key {} stored: {:?}", key, new_data);
-                *data = new_data;
-                Ok(())
-            },
-            None => Err(EvalError::TlsOutOfBounds)
-        }
-    }
-    
-    /// Returns a dtor, its argument and its index, if one is supposed to run
-    ///
-    /// An optional destructor function may be associated with each key value.
-    /// At thread exit, if a key value has a non-NULL destructor pointer,
-    /// and the thread has a non-NULL value associated with that key,
-    /// the value of the key is set to NULL, and then the function pointed
-    /// to is called with the previously associated value as its sole argument.
-    /// The order of destructor calls is unspecified if more than one destructor
-    /// exists for a thread when it exits.
-    ///
-    /// If, after all the destructors have been called for all non-NULL values
-    /// with associated destructors, there are still some non-NULL values with
-    /// associated destructors, then the process is repeated.
-    /// If, after at least {PTHREAD_DESTRUCTOR_ITERATIONS} iterations of destructor
-    /// calls for outstanding non-NULL values, there are still some non-NULL values
-    /// with associated destructors, implementations may stop calling destructors,
-    /// or they may continue calling destructors until no non-NULL values with
-    /// associated destructors exist, even though this might result in an infinite loop.
-    fn fetch_tls_dtor(&mut self, key: Option<TlsKey>) -> EvalResult<'tcx, Option<(ty::Instance<'tcx>, Pointer, TlsKey)>> {
-        use std::collections::Bound::*;
-        let start = match key {
-            Some(key) => Excluded(key),
-            None => Unbounded,
-        };
-        for (&key, &mut TlsEntry { ref mut data, dtor }) in self.data.thread_local.range_mut((start, Unbounded)) {
-            if !data.is_null()? {
-                if let Some(dtor) = dtor {
-                    let ret = Some((dtor, *data, key));
-                    *data = Pointer::null();
-                    return Ok(ret);
-                }
-            }
-        }
-        return Ok(None);
-    }
-}
-
 impl<'tcx> Machine<'tcx> for Evaluator {
     type Data = EvaluatorData;
     type MemoryData = MemoryData<'tcx>;
@@ -329,6 +247,7 @@ impl<'tcx> Machine<'tcx> for Evaluator {
         ecx: &mut EvalContext<'a, 'tcx, Self>,
         ty: ty::Ty<'tcx>,
     ) -> EvalResult<'tcx, PrimVal> {
+        // FIXME: call the `exchange_malloc` lang item if available
         let size = ecx.type_size(ty)?.expect("box only works with sized types");
         let align = ecx.type_align(ty)?;
         if size == 0 {
diff --git a/miri/tls.rs b/miri/tls.rs
new file mode 100644
index 00000000000..035cd7f0aaf
--- /dev/null
+++ b/miri/tls.rs
@@ -0,0 +1,94 @@
+use rustc::ty;
+
+use super::{
+    TlsKey, TlsEntry,
+    EvalResult, EvalError,
+    Pointer,
+    Memory,
+    Evaluator,
+};
+
+pub trait MemoryExt<'tcx> {
+    fn create_tls_key(&mut self, dtor: Option<ty::Instance<'tcx>>) -> TlsKey;
+    fn delete_tls_key(&mut self, key: TlsKey) -> EvalResult<'tcx>;
+    fn load_tls(&mut self, key: TlsKey) -> EvalResult<'tcx, Pointer>;
+    fn store_tls(&mut self, key: TlsKey, new_data: Pointer) -> EvalResult<'tcx>;
+    fn fetch_tls_dtor(&mut self, key: Option<TlsKey>) -> EvalResult<'tcx, Option<(ty::Instance<'tcx>, Pointer, TlsKey)>>;
+}
+
+impl<'a, 'tcx: 'a> MemoryExt<'tcx> for Memory<'a, 'tcx, Evaluator> {
+    fn create_tls_key(&mut self, dtor: Option<ty::Instance<'tcx>>) -> TlsKey {
+        let new_key = self.data.next_thread_local;
+        self.data.next_thread_local += 1;
+        self.data.thread_local.insert(new_key, TlsEntry { data: Pointer::null(), dtor });
+        trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor);
+        return new_key;
+    }
+
+    fn delete_tls_key(&mut self, key: TlsKey) -> EvalResult<'tcx> {
+        return match self.data.thread_local.remove(&key) {
+            Some(_) => {
+                trace!("TLS key {} removed", key);
+                Ok(())
+            },
+            None => Err(EvalError::TlsOutOfBounds)
+        }
+    }
+
+    fn load_tls(&mut self, key: TlsKey) -> EvalResult<'tcx, Pointer> {
+        return match self.data.thread_local.get(&key) {
+            Some(&TlsEntry { data, .. }) => {
+                trace!("TLS key {} loaded: {:?}", key, data);
+                Ok(data)
+            },
+            None => Err(EvalError::TlsOutOfBounds)
+        }
+    }
+
+    fn store_tls(&mut self, key: TlsKey, new_data: Pointer) -> EvalResult<'tcx> {
+        return match self.data.thread_local.get_mut(&key) {
+            Some(&mut TlsEntry { ref mut data, .. }) => {
+                trace!("TLS key {} stored: {:?}", key, new_data);
+                *data = new_data;
+                Ok(())
+            },
+            None => Err(EvalError::TlsOutOfBounds)
+        }
+    }
+    
+    /// Returns a dtor, its argument and its index, if one is supposed to run
+    ///
+    /// An optional destructor function may be associated with each key value.
+    /// At thread exit, if a key value has a non-NULL destructor pointer,
+    /// and the thread has a non-NULL value associated with that key,
+    /// the value of the key is set to NULL, and then the function pointed
+    /// to is called with the previously associated value as its sole argument.
+    /// The order of destructor calls is unspecified if more than one destructor
+    /// exists for a thread when it exits.
+    ///
+    /// If, after all the destructors have been called for all non-NULL values
+    /// with associated destructors, there are still some non-NULL values with
+    /// associated destructors, then the process is repeated.
+    /// If, after at least {PTHREAD_DESTRUCTOR_ITERATIONS} iterations of destructor
+    /// calls for outstanding non-NULL values, there are still some non-NULL values
+    /// with associated destructors, implementations may stop calling destructors,
+    /// or they may continue calling destructors until no non-NULL values with
+    /// associated destructors exist, even though this might result in an infinite loop.
+    fn fetch_tls_dtor(&mut self, key: Option<TlsKey>) -> EvalResult<'tcx, Option<(ty::Instance<'tcx>, Pointer, TlsKey)>> {
+        use std::collections::Bound::*;
+        let start = match key {
+            Some(key) => Excluded(key),
+            None => Unbounded,
+        };
+        for (&key, &mut TlsEntry { ref mut data, dtor }) in self.data.thread_local.range_mut((start, Unbounded)) {
+            if !data.is_null()? {
+                if let Some(dtor) = dtor {
+                    let ret = Some((dtor, *data, key));
+                    *data = Pointer::null();
+                    return Ok(ret);
+                }
+            }
+        }
+        return Ok(None);
+    }
+}