]> git.lizzy.rs Git - rust.git/commitdiff
remove support for not having libstd MIR
authorRalf Jung <post@ralfj.de>
Mon, 10 Dec 2018 11:26:20 +0000 (12:26 +0100)
committerRalf Jung <post@ralfj.de>
Mon, 10 Dec 2018 11:26:20 +0000 (12:26 +0100)
src/fn_call.rs
src/lib.rs

index 701dc8ca92ca26a7e3b75a3785326dd90f56b815..e28497aa256fcce817052ae23fd52e6e6964d473 100644 (file)
@@ -17,18 +17,6 @@ fn emulate_foreign_item(
         ret: mir::BasicBlock,
     ) -> EvalResult<'tcx>;
 
-    /// Emulate a function that should have MIR but does not.
-    /// This is solely to support execution without full MIR.
-    /// Fail if emulating this function is not supported.
-    /// This function will handle `goto_block` if needed.
-    fn emulate_missing_fn(
-        &mut self,
-        path: String,
-        args: &[OpTy<'tcx, Borrow>],
-        dest: Option<PlaceTy<'tcx, Borrow>>,
-        ret: Option<mir::BasicBlock>,
-    ) -> EvalResult<'tcx>;
-
     fn find_fn(
         &mut self,
         instance: ty::Instance<'tcx>,
@@ -81,24 +69,8 @@ fn find_fn(
             return Ok(None);
         }
 
-        // Otherwise we really want to see the MIR -- but if we do not have it, maybe we can
-        // emulate something. This is a HACK to support running without a full-MIR libstd.
-        let mir = match self.load_mir(instance.def) {
-            Ok(mir) => mir,
-            Err(EvalError { kind: EvalErrorKind::NoMirFor(path), .. }) => {
-                self.emulate_missing_fn(
-                    path,
-                    args,
-                    dest,
-                    ret,
-                )?;
-                // `goto_block` already handled
-                return Ok(None);
-            }
-            Err(other) => return Err(other),
-        };
-
-        Ok(Some(mir))
+        // Otherwise, load the MIR
+        Ok(Some(self.load_mir(instance.def)?))
     }
 
     fn emulate_foreign_item(
@@ -657,58 +629,6 @@ fn emulate_foreign_item(
         Ok(())
     }
 
-    fn emulate_missing_fn(
-        &mut self,
-        path: String,
-        _args: &[OpTy<'tcx, Borrow>],
-        dest: Option<PlaceTy<'tcx, Borrow>>,
-        ret: Option<mir::BasicBlock>,
-    ) -> EvalResult<'tcx> {
-        // In some cases in non-MIR libstd-mode, not having a destination is legit.  Handle these early.
-        match &path[..] {
-            "std::panicking::rust_panic_with_hook" |
-            "core::panicking::panic_fmt::::panic_impl" |
-            "std::rt::begin_panic_fmt" =>
-                return err!(MachineError("the evaluated program panicked".to_string())),
-            _ => {}
-        }
-
-        let dest = dest.ok_or_else(
-            // Must be some function we do not support
-            || EvalErrorKind::NoMirFor(path.clone()),
-        )?;
-
-        match &path[..] {
-            // A Rust function is missing, which means we are running with MIR missing for libstd (or other dependencies).
-            // Still, we can make many things mostly work by "emulating" or ignoring some functions.
-            "std::io::_print" |
-            "std::io::_eprint" => {
-                warn!(
-                    "Ignoring output.  To run programs that prints, make sure you have a libstd with full MIR."
-                );
-            }
-            "std::thread::Builder::new" => {
-                return err!(Unimplemented("miri does not support threading".to_owned()))
-            }
-            "std::env::args" => {
-                return err!(Unimplemented(
-                    "miri does not support program arguments".to_owned(),
-                ))
-            }
-            "std::panicking::panicking" |
-            "std::rt::panicking" => {
-                // we abort on panic -> `std::rt::panicking` always returns false
-                self.write_scalar(Scalar::from_bool(false), dest)?;
-            }
-
-            _ => return err!(NoMirFor(path)),
-        }
-
-        self.goto_block(ret)?;
-        self.dump_place(*dest);
-        Ok(())
-    }
-
     fn write_null(&mut self, dest: PlaceTy<'tcx, Borrow>) -> EvalResult<'tcx> {
         self.write_scalar(Scalar::from_int(0, dest.layout.size), dest)
     }
index 71abff2675e3cd856af4166ae7394cc79741ff2d..9641670a2edfb384cc86faa273ef4bfb142ad45d 100644 (file)
@@ -80,82 +80,62 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
         ));
     }
 
-    let libstd_has_mir = {
-        let rustc_panic = ecx.resolve_path(&["std", "panicking", "rust_panic"])?;
-        ecx.load_mir(rustc_panic.def).is_ok()
-    };
-
-    if libstd_has_mir {
-        let start_id = tcx.lang_items().start_fn().unwrap();
-        let main_ret_ty = tcx.fn_sig(main_id).output();
-        let main_ret_ty = main_ret_ty.no_bound_vars().unwrap();
-        let start_instance = ty::Instance::resolve(
-            ecx.tcx.tcx,
-            ty::ParamEnv::reveal_all(),
-            start_id,
-            ecx.tcx.mk_substs(
-                ::std::iter::once(ty::subst::Kind::from(main_ret_ty)))
-            ).unwrap();
-        let start_mir = ecx.load_mir(start_instance.def)?;
-
-        if start_mir.arg_count != 3 {
-            return err!(AbiViolation(format!(
-                "'start' lang item should have three arguments, but has {}",
-                start_mir.arg_count
-            )));
-        }
-
-        // Return value (in static memory so that it does not count as leak)
-        let ret = ecx.layout_of(start_mir.return_ty())?;
-        let ret_ptr = ecx.allocate(ret, MiriMemoryKind::MutStatic.into())?;
-
-        // Push our stack frame
-        ecx.push_stack_frame(
-            start_instance,
-            DUMMY_SP, // there is no call site, we want no span
-            start_mir,
-            Some(ret_ptr.into()),
-            StackPopCleanup::None { cleanup: true },
-        )?;
-
-        let mut args = ecx.frame().mir.args_iter();
-
-        // First argument: pointer to main()
-        let main_ptr = ecx.memory_mut().create_fn_alloc(main_instance).with_default_tag();
-        let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
-        ecx.write_scalar(Scalar::Ptr(main_ptr), dest)?;
-
-        // Second argument (argc): 1
-        let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
-        ecx.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
-
-        // FIXME: extract main source file path
-        // Third argument (argv): &[b"foo"]
-        let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
-        let foo = ecx.memory_mut().allocate_static_bytes(b"foo\0").with_default_tag();
-        let foo_ty = ecx.tcx.mk_imm_ptr(ecx.tcx.types.u8);
-        let foo_layout = ecx.layout_of(foo_ty)?;
-        let foo_place = ecx.allocate(foo_layout, MiriMemoryKind::Env.into())?;
-        ecx.write_scalar(Scalar::Ptr(foo), foo_place.into())?;
-        ecx.memory_mut().mark_immutable(foo_place.to_ptr()?.alloc_id)?;
-        ecx.write_scalar(foo_place.ptr, dest)?;
-
-        assert!(args.next().is_none(), "start lang item has more arguments than expected");
-    } else {
-        let ret_place = MPlaceTy::dangling(ecx.layout_of(tcx.mk_unit())?, &ecx).into();
-        ecx.push_stack_frame(
-            main_instance,
-            DUMMY_SP, // there is no call site, we want no span
-            main_mir,
-            Some(ret_place),
-            StackPopCleanup::None { cleanup: true },
-        )?;
-
-        // No arguments
-        let mut args = ecx.frame().mir.args_iter();
-        assert!(args.next().is_none(), "main function must not have arguments");
+    let start_id = tcx.lang_items().start_fn().unwrap();
+    let main_ret_ty = tcx.fn_sig(main_id).output();
+    let main_ret_ty = main_ret_ty.no_bound_vars().unwrap();
+    let start_instance = ty::Instance::resolve(
+        ecx.tcx.tcx,
+        ty::ParamEnv::reveal_all(),
+        start_id,
+        ecx.tcx.mk_substs(
+            ::std::iter::once(ty::subst::Kind::from(main_ret_ty)))
+        ).unwrap();
+    let start_mir = ecx.load_mir(start_instance.def)?;
+
+    if start_mir.arg_count != 3 {
+        return err!(AbiViolation(format!(
+            "'start' lang item should have three arguments, but has {}",
+            start_mir.arg_count
+        )));
     }
 
+    // Return value (in static memory so that it does not count as leak)
+    let ret = ecx.layout_of(start_mir.return_ty())?;
+    let ret_ptr = ecx.allocate(ret, MiriMemoryKind::MutStatic.into())?;
+
+    // Push our stack frame
+    ecx.push_stack_frame(
+        start_instance,
+        DUMMY_SP, // there is no call site, we want no span
+        start_mir,
+        Some(ret_ptr.into()),
+        StackPopCleanup::None { cleanup: true },
+    )?;
+
+    let mut args = ecx.frame().mir.args_iter();
+
+    // First argument: pointer to main()
+    let main_ptr = ecx.memory_mut().create_fn_alloc(main_instance).with_default_tag();
+    let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
+    ecx.write_scalar(Scalar::Ptr(main_ptr), dest)?;
+
+    // Second argument (argc): 1
+    let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
+    ecx.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
+
+    // FIXME: extract main source file path
+    // Third argument (argv): &[b"foo"]
+    let dest = ecx.eval_place(&mir::Place::Local(args.next().unwrap()))?;
+    let foo = ecx.memory_mut().allocate_static_bytes(b"foo\0").with_default_tag();
+    let foo_ty = ecx.tcx.mk_imm_ptr(ecx.tcx.types.u8);
+    let foo_layout = ecx.layout_of(foo_ty)?;
+    let foo_place = ecx.allocate(foo_layout, MiriMemoryKind::Env.into())?;
+    ecx.write_scalar(Scalar::Ptr(foo), foo_place.into())?;
+    ecx.memory_mut().mark_immutable(foo_place.to_ptr()?.alloc_id)?;
+    ecx.write_scalar(foo_place.ptr, dest)?;
+
+    assert!(args.next().is_none(), "start lang item has more arguments than expected");
+
     Ok(ecx)
 }