Skip to content

Commit

Permalink
patch
Browse files Browse the repository at this point in the history
  • Loading branch information
oligamiq committed Oct 6, 2024
1 parent 3ea98e9 commit fe82c31
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 2,426 deletions.
2,387 changes: 70 additions & 2,317 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ cargo-test-support = { version = "0.4.0", path = "crates/cargo-test-support" }
cargo-util = { version = "0.2.14", path = "crates/cargo-util" }
cargo-util-schemas = { version = "0.6.0", path = "crates/cargo-util-schemas" }
cargo_metadata = "0.18.1"
clap = { git = "https://github.com/oligamiq/clap" }
clap_complete = { git = "https://github.com/oligamiq/clap", features = ["unstable-dynamic"] }
clap = "=4.5.17"
clap_complete = { version = "=4.5.28", features = ["unstable-dynamic"] }
color-print = "0.3.6"
completest-pty = "0.5.3"
core-foundation = { version = "0.10.0", features = ["mac_os_10_7_support"] }
Expand Down Expand Up @@ -250,10 +250,11 @@ git2-curl.workspace = true

[target.'cfg(all(target_os = "wasi", target_env = "p1"))'.dependencies]
fetch.workspace = true
rustc_driver.workspace = true
rustc_driver_impl.workspace = true
# rustc_driver.workspace = true
# rustc_driver_impl.workspace = true
capture_io.workspace = true
libc.workspace = true
rustc_runner.workspace = true

[dev-dependencies]
annotate-snippets = { workspace = true, features = ["testing-colors"] }
Expand All @@ -280,3 +281,6 @@ all-static = ['vendored-openssl', 'curl/static-curl', 'curl/force-system-lib-on-

[lints]
workspace = true

[profile.release]
panic = 'unwind'
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn main() {
let target = std::env::var("TARGET").unwrap();
println!("cargo:rustc-env=RUST_HOST_TARGET={target}");

if (target == "wasm32-wasip1-threads") {
if target == "wasm32-wasip1-threads" {
let wasi_sysroot = std::env::var("WASI_SYSROOT").unwrap();
println!("cargo:rustc-flags=-L {}/../../lib/clang/18/lib/wasip1 -lstatic=clang_rt.builtins-wasm32", Path::new(&wasi_sysroot).display());
}
Expand Down
6 changes: 5 additions & 1 deletion crates/capture_io/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{io::{Read as _, Write as _}, os::fd::AsRawFd as _};
use std::{io::{Read as _, Seek, Write as _}, os::fd::AsRawFd as _};

/// This is a simple implementation of capturing stdout/stderr/stdin.
/// If used incorrectly, memory leaks can occur.
Expand Down Expand Up @@ -181,6 +181,10 @@ impl StdinCapturer {
pub fn set_stdin(&mut self, input: &[u8]) -> Result<(), std::io::Error> {
self.capture_file.write_all(input)?;

self.capture_file.flush()?;

self.capture_file.seek(std::io::SeekFrom::Start(0))?;

let fd = self.capture_file.as_raw_fd();

exchange_local_fd(0, fd)?;
Expand Down
6 changes: 4 additions & 2 deletions crates/rustc_runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ path = "lib.rs"
[dependencies]

[target.'cfg(all(target_os = "wasi", target_env = "p1"))'.dependencies]
rustc_driver.workspace = true
rustc_driver_impl.workspace = true
# rustc_driver.workspace = true
# rustc_driver_impl.workspace = true
capture_io.workspace = true
anyhow.workspace = true
log = "0.4"
serde_json.workspace = true

[lints]
workspace = true
160 changes: 69 additions & 91 deletions crates/rustc_runner/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::{process::{Command, ExitStatus, Output}, sync::{Arc, LazyLock, Mutex}, thread};

use capture_io::{StdinCapturer, StdoutCapturer};
use rustc_driver::{Callbacks, RunCompiler};
use log::LevelFilter;
// use rustc_driver::{Callbacks, RunCompiler};

pub struct Task {
input: Option<Vec<u8>>,
Expand All @@ -14,8 +15,8 @@ pub struct TaskResult {
pub stderr: Vec<u8>,
}

struct NoneCallbacks;
impl Callbacks for NoneCallbacks {}
// struct NoneCallbacks;
// impl Callbacks for NoneCallbacks {}

fn default_panic_callback(
stdout: Vec<u8>,
Expand All @@ -30,6 +31,30 @@ fn default_panic_callback(
Ok(())
}

pub fn wasm_run(
args: Vec<String>,
env: Vec<(String, String)>,
target: String,
) -> bool {
#[link(wasm_import_module = "extend_imports")]
extern "C" {
fn wasm_run(json_ptr: *const u8, json_len: usize) -> i32;
}

let value = serde_json::json!({
"args": args,
"env": [],
"target": target,
});
let json = serde_json::to_string(&value).unwrap();
let json_ptr = json.as_ptr();
let json_len = json.len();

let is_error = unsafe { wasm_run(json_ptr, json_len) } != 0;

is_error
}

pub fn rustc_run(
cmd: &Command,
input: Option<Vec<u8>>,
Expand Down Expand Up @@ -115,91 +140,40 @@ pub fn rustc_run(
}
}

let task = Task {
input,
args,
};
println!("Running rustc with args: {:?}", &args);

println!("Running rustc with args: {:?}", task.args);
let out = StdoutCapturer::new_stdout()?;
let err = StdoutCapturer::new_stderr()?;
let mut r#in = StdinCapturer::new()?;

let out = Arc::new(StdoutCapturer::new_stdout()?);
let err = Arc::new(StdoutCapturer::new_stderr()?);
let mut r#in = Arc::new(Mutex::new(StdinCapturer::new()?));

let ex_env_clone = ex_env.clone();
let default_env_clone = default_env.clone();
let out_weak_clone = Arc::downgrade(&out);
let err_weak_clone = Arc::downgrade(&err);
let in_weak_clone = Arc::downgrade(&r#in);
let stdin = if let Some(stdin) = input.clone() {
[stdin, vec![]].concat()
} else {
// return EOF
vec![]
};

let thread: thread::JoinHandle<anyhow::Result<(bool, Vec<u8>, Vec<u8>)>> = thread::spawn(move || {
for (key, value) in &ex_env_clone {
if let Some(value) = value {
std::env::set_var(key, value);
} else {
std::env::remove_var(key);
}
}
// println!("&&&& Running rustc, envs: {:?}", std::env::vars().collect::<Vec<_>>());

let Task { input, args } = task;
out.start_capture()?;
err.start_capture()?;
r#in.set_stdin(&stdin)?;

let mut callbacks = NoneCallbacks;
let thread: thread::JoinHandle<anyhow::Result<bool>> = thread::spawn(move || {

let rustc = RunCompiler::new(&args, &mut callbacks);
// println!("&&&& Rustc finished");
let is_error = wasm_run(args, vec![], "wasm32-wasip1-threads".to_string());

let stdin = if let Some(stdin) = input.clone() {
[stdin, vec![0x1A]].concat()
} else {
// return EOF
vec![0x1A]
};

out.start_capture()?;
err.start_capture()?;
r#in.lock().unwrap().set_stdin(&stdin)?;

// run rustc
let is_error = match rustc.run() {
Ok(_) => false,
Err(_) => true,
};

for (key, value) in &ex_env_clone {
if let Some(value) = value {
std::env::remove_var(key);
}
}
for (key, value) in default_env_clone {
std::env::set_var(key, value);
}

let stdout = Arc::into_inner(out).unwrap().stop_capture()?;
let stderr = Arc::into_inner(err).unwrap().stop_capture()?;
Arc::into_inner(r#in).unwrap().into_inner().unwrap().stop_capture()?;

println!("Rustc finished");

Ok((is_error, stdout, stderr))
Ok(is_error)
});

Ok(match thread.join() {
Err(e) => {
for (key, value) in &ex_env {
if let Some(value) = value {
std::env::remove_var(key);
}
}
for (key, value) in default_env {
std::env::set_var(key, value);
}

let stdout = Arc::into_inner(out_weak_clone.upgrade().unwrap()).unwrap().get_stoped_capture()?;
let stderr = Arc::into_inner(err_weak_clone.upgrade().unwrap()).unwrap().get_stoped_capture()?;
let r#in = Arc::into_inner(in_weak_clone.upgrade().unwrap()).unwrap();
r#in.clear_poison();
r#in.into_inner().unwrap().drop_stoped_capture()?;
let stdout = out.stop_capture()?;
let stderr = err.stop_capture()?;
r#in.stop_capture()?;

println!("Thread failed");
println!("&&&& Thread failed");

// This is memory leak, but we can't do anything
// If drop is called, it will panic
Expand All @@ -213,21 +187,21 @@ pub fn rustc_run(
}
}
Ok(result) => {
println!("Thread finished");
println!("result: {:?}", result);

std::mem::drop(out_weak_clone);
println!("out_weak_clone dropped");
std::mem::drop(err_weak_clone);
println!("err_weak_clone dropped");
std::mem::drop(in_weak_clone);
println!("in_weak_clone dropped");

result.map(|(is_error, stdout, stderr)| TaskResult {
is_error,
// println!("result: {:?}", result);

let stdout = out.stop_capture()?;
let stderr = err.stop_capture()?;
r#in.stop_capture()?;

println!("&&&& Thread finished");

let result = result?;

TaskResult {
is_error: result,
stdout,
stderr,
})?
}
},
})
}
Expand All @@ -250,11 +224,15 @@ pub fn rustc_run_with_streaming(
println!("stdout: {}", stdout);

for line in stdout.lines() {
on_stdout_line(line)?;
if line.starts_with("{") {
on_stdout_line(line)?;
}
}

for line in stderr.lines() {
on_stderr_line(line)?;
if line.starts_with("{") {
on_stderr_line(line)?;
}
}

println!("Rustc finished");
Expand Down
17 changes: 14 additions & 3 deletions src/bin/cargo/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,20 @@ fn main() {

let nightly_features_allowed = matches!(&*features::channel(), "nightly" | "dev");
if nightly_features_allowed {
clap_complete::CompleteEnv::with_factory(|| cli::cli(&mut gctx))
.var("CARGO_COMPLETE")
.complete();
let _span = tracing::span!(tracing::Level::TRACE, "completions").entered();
let args = std::env::args_os();
let current_dir = std::env::current_dir().ok();
let completer =
clap_complete::CompleteEnv::with_factory(|| cli::cli(&mut gctx)).var("CARGO_COMPLETE");
if completer
.try_complete(args, current_dir.as_deref())
.unwrap_or_else(|e| {
let mut shell = Shell::new();
cargo::exit_with_error(e.into(), &mut shell)
})
{
return;
}
}

let result = if let Some(lock_addr) = cargo::ops::fix_get_proxy_lock_addr() {
Expand Down
29 changes: 28 additions & 1 deletion src/cargo/ops/cargo_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,32 @@ pub fn run(

gctx.shell().status("Running", process.to_string())?;

process.exec_replace()
#[cfg(not(all(target_os = "wasi", target_env = "p1")))] {
process.exec_replace()
}
#[cfg(all(target_os = "wasi", target_env = "p1"))] {
let args = vec![process.get_program().to_string_lossy().to_string()]
.into_iter()
.chain(process.get_args().map(|arg| arg.to_string_lossy().to_string()))
.collect::<Vec<_>>();

// stdin is not captured because I tired.

// wasm32-wasip1, wasm32-wasip1-threads
use crate::core::compiler::CompileKind;

let target = match options.build_config.requested_kinds.iter().filter(|&k| match k {
CompileKind::Host => true,
CompileKind::Target(t) => {
t.short_name() == "wasm32-wasip1" || t.short_name() == "wasm32-wasip1-threads"
},
}).next() {
Some(CompileKind::Target(t)) => t.short_name(),
_ => "wasm32-wasip1",
};
if rustc_runner::wasm_run(args, vec![], target.to_owned()) {
anyhow::bail!("Error running the program");
}
Ok(())
}
}
18 changes: 12 additions & 6 deletions src/cargo/util/flock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,31 +436,37 @@ mod sys {
use std::io::{Error, Result};

pub(super) fn lock_shared(file: &File) -> Result<()> {
Err(Error::from_raw_os_error(libc::ENOSYS))
// Err(Error::from_raw_os_error(libc::ENOSYS))
Ok(())
}

pub(super) fn lock_exclusive(file: &File) -> Result<()> {
Err(Error::from_raw_os_error(libc::ENOSYS))
// Err(Error::from_raw_os_error(libc::ENOSYS))
Ok(())
}

pub(super) fn try_lock_shared(file: &File) -> Result<()> {
Err(Error::from_raw_os_error(libc::ENOSYS))
// Err(Error::from_raw_os_error(libc::ENOSYS))
Ok(())
}

pub(super) fn try_lock_exclusive(file: &File) -> Result<()> {
Err(Error::from_raw_os_error(libc::ENOSYS))
// Err(Error::from_raw_os_error(libc::ENOSYS))
Ok(())
}

pub(super) fn unlock(file: &File) -> Result<()> {
Err(Error::from_raw_os_error(libc::ENOSYS))
// Err(Error::from_raw_os_error(libc::ENOSYS))
Ok(())
}

pub(super) fn error_contended(err: &Error) -> bool {
false
}

pub(super) fn error_unsupported(err: &Error) -> bool {
true
// true
false
}
}

Expand Down

0 comments on commit fe82c31

Please sign in to comment.