mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
skeleton for running pretty expects
This commit is contained in:
parent
2fb2ffc80c
commit
68c51782e6
5 changed files with 153 additions and 29 deletions
|
@ -5,15 +5,17 @@ use build::BuiltFile;
|
|||
use bumpalo::Bump;
|
||||
use clap::{Arg, ArgMatches, Command, ValueSource};
|
||||
use roc_build::link::{LinkType, LinkingStrategy};
|
||||
use roc_collections::VecMap;
|
||||
use roc_error_macros::{internal_error, user_error};
|
||||
use roc_load::{LoadingProblem, Threading};
|
||||
use roc_load::{Expectations, LoadingProblem, Threading};
|
||||
use roc_module::symbol::{Interns, ModuleId};
|
||||
use roc_mono::ir::OptLevel;
|
||||
use roc_repl_cli::expect_mono_module_to_dylib;
|
||||
use roc_target::TargetInfo;
|
||||
use std::env;
|
||||
use std::ffi::{CString, OsStr};
|
||||
use std::io;
|
||||
use std::os::raw::c_char;
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use target_lexicon::BinaryFormat;
|
||||
|
@ -281,6 +283,8 @@ pub enum FormatMode {
|
|||
CheckOnly,
|
||||
}
|
||||
|
||||
const SHM_SIZE: i64 = 1024;
|
||||
|
||||
pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
||||
let arena = Bump::new();
|
||||
let filename = matches.value_of_os(ROC_FILE).unwrap();
|
||||
|
@ -341,7 +345,7 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
|||
let shared_fd =
|
||||
libc::shm_open(cstring.as_ptr().cast(), libc::O_RDWR | libc::O_CREAT, 0o666);
|
||||
|
||||
libc::ftruncate(shared_fd, 1024);
|
||||
libc::ftruncate(shared_fd, SHM_SIZE);
|
||||
|
||||
let _shared_ptr = libc::mmap(
|
||||
std::ptr::null_mut(),
|
||||
|
@ -782,31 +786,13 @@ unsafe fn roc_run_native_fast(
|
|||
argv: &[*const c_char],
|
||||
envp: &[*const c_char],
|
||||
) {
|
||||
match executable {
|
||||
#[cfg(target_os = "linux")]
|
||||
ExecutableFile::MemFd(fd, path) => {
|
||||
if libc::fexecve(fd, argv.as_ptr(), envp.as_ptr()) != 0 {
|
||||
internal_error!(
|
||||
"libc::fexecve({:?}, ..., ...) failed: {:?}",
|
||||
path,
|
||||
errno::errno()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(target_family = "unix", not(target_os = "linux")))]
|
||||
ExecutableFile::OnDisk(_, path) => {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let path_cstring = CString::new(path.as_os_str().as_bytes()).unwrap();
|
||||
if libc::execve(path_cstring.as_ptr().cast(), argv.as_ptr(), envp.as_ptr()) != 0 {
|
||||
internal_error!(
|
||||
"libc::execve({:?}, ..., ...) failed: {:?}",
|
||||
path,
|
||||
errno::errno()
|
||||
);
|
||||
}
|
||||
}
|
||||
if executable.execve(argv, envp) != 0 {
|
||||
internal_error!(
|
||||
"libc::{}({:?}, ..., ...) failed: {:?}",
|
||||
ExecutableFile::SYSCALL,
|
||||
executable.as_path(),
|
||||
errno::errno()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -819,6 +805,12 @@ enum ExecutableFile {
|
|||
}
|
||||
|
||||
impl ExecutableFile {
|
||||
#[cfg(target_os = "linux")]
|
||||
const SYSCALL: &'static str = "fexecve";
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
const SYSCALL: &'static str = "execve";
|
||||
|
||||
fn as_path(&self) -> &Path {
|
||||
match self {
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -827,6 +819,109 @@ impl ExecutableFile {
|
|||
ExecutableFile::OnDisk(_, path_buf) => path_buf.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn execve(&self, argv: &[*const c_char], envp: &[*const c_char]) -> c_int {
|
||||
match self {
|
||||
#[cfg(target_os = "linux")]
|
||||
ExecutableFile::MemFd(fd, path) => libc::fexecve(*fd, argv.as_ptr(), envp.as_ptr()),
|
||||
|
||||
#[cfg(all(target_family = "unix", not(target_os = "linux")))]
|
||||
ExecutableFile::OnDisk(_, path) => {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let path_cstring = CString::new(path.as_os_str().as_bytes()).unwrap();
|
||||
libc::execve(path_cstring.as_ptr().cast(), argv.as_ptr(), envp.as_ptr())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// with Expect
|
||||
unsafe fn roc_run_native_debug(
|
||||
executable: ExecutableFile,
|
||||
argv: &[*const c_char],
|
||||
envp: &[*const c_char],
|
||||
mut expectations: VecMap<ModuleId, Expectations>,
|
||||
interns: Interns,
|
||||
) {
|
||||
use signal_hook::{consts::signal::SIGCHLD, consts::signal::SIGUSR1, iterator::Signals};
|
||||
|
||||
let mut signals = Signals::new(&[SIGCHLD, SIGUSR1]).unwrap();
|
||||
|
||||
match libc::fork() {
|
||||
0 => {
|
||||
// we are the child
|
||||
|
||||
if executable.execve(argv, envp) < 0 {
|
||||
// Get the current value of errno
|
||||
let e = errno::errno();
|
||||
|
||||
// Extract the error code as an i32
|
||||
let code = e.0;
|
||||
|
||||
// Display a human-friendly error message
|
||||
println!("💥 Error {}: {}", code, e);
|
||||
}
|
||||
}
|
||||
-1 => {
|
||||
// something failed
|
||||
|
||||
// Get the current value of errno
|
||||
let e = errno::errno();
|
||||
|
||||
// Extract the error code as an i32
|
||||
let code = e.0;
|
||||
|
||||
// Display a human-friendly error message
|
||||
println!("Error {}: {}", code, e);
|
||||
|
||||
process::exit(1)
|
||||
}
|
||||
1.. => {
|
||||
let name = "/roc_expect_buffer"; // IMPORTANT: shared memory object names must begin with / and contain no other slashes!
|
||||
let cstring = CString::new(name).unwrap();
|
||||
|
||||
let arena = &bumpalo::Bump::new();
|
||||
let interns = arena.alloc(interns);
|
||||
|
||||
for sig in &mut signals {
|
||||
match sig {
|
||||
SIGCHLD => {
|
||||
// clean up
|
||||
libc::shm_unlink(cstring.as_ptr().cast());
|
||||
|
||||
// dbg!(libc::unlink(app_path.as_ptr().cast()));
|
||||
|
||||
// done!
|
||||
process::exit(0);
|
||||
}
|
||||
SIGUSR1 => {
|
||||
// this is the signal we use for an expect failure. Let's see what the child told us
|
||||
let shared_fd =
|
||||
libc::shm_open(cstring.as_ptr().cast(), libc::O_RDONLY, 0o666);
|
||||
|
||||
libc::ftruncate(shared_fd, SHM_SIZE);
|
||||
|
||||
let shared_ptr = libc::mmap(
|
||||
std::ptr::null_mut(),
|
||||
SHM_SIZE as usize,
|
||||
libc::PROT_READ,
|
||||
libc::MAP_SHARED,
|
||||
shared_fd,
|
||||
0,
|
||||
);
|
||||
|
||||
let shared_memory_ptr: *const u8 = shared_ptr.cast();
|
||||
|
||||
// render_expect_failure(arena, &mut expectations, interns, shared_memory_ptr);
|
||||
todo!()
|
||||
}
|
||||
_ => println!("received signal {}", sig),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue