A backend for the p≡p Engine built on Sequoia.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.6 KiB

12 months ago
  1. // Wraps an ffi function.
  2. //
  3. // This wrapper allows the function to return a Result. The Ok
  4. // variant should be (). It may be something else. In that case, the
  5. // value is simply discarded. The Error variant must be convertable
  6. // to a `crate::ErrorCode` using `Into`.
  7. macro_rules! ffi {
  8. (fn $f:ident( $( $v:ident: $t:ty ),* ) -> $rt:ty $body:block ) => {
  9. // The wrapper. It calls $f and turns the result into an
  10. // error code.
  11. #[no_mangle] pub extern "C"
  12. fn $f($($v: $t,)*) -> crate::ErrorCode {
  13. tracer!(*crate::TRACE, stringify!($f));
  14. // The actual function.
  15. fn inner($($v: $t,)*) -> $rt { $body };
  16. t!("entered");
  17. // We use AssertUnwindSafe. This is safe, because if we
  18. // catch a panic, we abort. If we turn the panic into an
  19. // error, then we need to reexamine this assumption.
  20. let r = std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
  21. match inner($($v,)*) {
  22. Ok(_) => {
  23. t!("-> success");
  24. ErrorCode::from(crate::Error::StatusOk)
  25. }
  26. Err(err) => {
  27. t!("-> error: {}{}",
  28. err,
  29. {
  30. use std::error::Error;
  31. let mut causes = String::new();
  32. let mut cause = err.source();
  33. while let Some(e) = cause {
  34. causes.push_str("\n because: ");
  35. causes.push_str(&e.to_string());
  36. cause = e.source();
  37. }
  38. causes
  39. });
  40. ErrorCode::from(err)
  41. }
  42. }
  43. }));
  44. match r {
  45. Ok(code) => code,
  46. Err(_) => {
  47. t!("-> panic!");
  48. unsafe { ::libc::abort() };
  49. }
  50. }
  51. }
  52. }
  53. }
  54. // Creates a stub for a ffi, which returns an error.
  55. #[allow(unused_macros)]
  56. macro_rules! stub {
  57. ($f:ident) => {
  58. #[no_mangle] pub extern "C"
  59. fn $f() -> crate::ErrorCode {
  60. tracer!(*crate::TRACE, stringify!($f));
  61. t!("{} is a stub\n", stringify!($f));
  62. crate::Error::UnknownError(
  63. anyhow::anyhow!("Function not implemented"),
  64. stringify!($f).into()).into()
  65. }
  66. };
  67. }