mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 02:39:20 +00:00
fix: #443
This commit is contained in:
parent
ada421cd5c
commit
3fc42f65e8
4 changed files with 59 additions and 19 deletions
|
@ -3,9 +3,10 @@
|
|||
//! CPythonを呼び出すためのユーティリティー
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::process::{Command, ExitStatus, Stdio};
|
||||
|
||||
use crate::fn_name_full;
|
||||
use crate::io::Output;
|
||||
use crate::pathutil::remove_verbatim;
|
||||
use crate::serialize::get_magic_num_from_bytes;
|
||||
|
||||
|
@ -849,3 +850,23 @@ pub fn spawn_py(py_command: Option<&str>, code: &str) {
|
|||
.expect("cannot execute python");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exec_py_code(code: &str, output: Output) -> std::io::Result<ExitStatus> {
|
||||
let mut out = if cfg!(windows) {
|
||||
Command::new(which_python())
|
||||
.arg("-c")
|
||||
.arg(code)
|
||||
.stdout(output)
|
||||
.spawn()
|
||||
.expect("cannot execute python")
|
||||
} else {
|
||||
let exec_command = format!("{} -c \"{code}\"", which_python());
|
||||
Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(exec_command)
|
||||
.stdout(output)
|
||||
.spawn()
|
||||
.expect("cannot execute python")
|
||||
};
|
||||
out.wait()
|
||||
}
|
||||
|
|
|
@ -226,6 +226,20 @@ impl Compiler {
|
|||
Ok(CompleteArtifact::new(last, arti.warns))
|
||||
}
|
||||
|
||||
pub fn exec_compile(
|
||||
&mut self,
|
||||
src: String,
|
||||
mode: &str,
|
||||
) -> Result<CompleteArtifact<ExitStatus>, ErrorArtifact> {
|
||||
let arti = self.compile(src, mode)?;
|
||||
let stat = arti
|
||||
.object
|
||||
.exec(self.cfg.py_magic_num, self.cfg.output.clone())
|
||||
.expect("failed to dump a .pyc file (maybe permission denied)");
|
||||
let stat = ExitStatus::new(stat.code().unwrap_or(0), arti.warns.len(), 0);
|
||||
Ok(CompleteArtifact::new(stat, arti.warns))
|
||||
}
|
||||
|
||||
pub fn compile(
|
||||
&mut self,
|
||||
src: String,
|
||||
|
|
|
@ -3,8 +3,10 @@ use std::fmt::Write as _;
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, Read, Write as _};
|
||||
use std::path::Path;
|
||||
use std::process::ExitStatus;
|
||||
|
||||
use erg_common::impl_display_from_debug;
|
||||
use erg_common::io::Output;
|
||||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::opcode::CommonOpcode;
|
||||
|
@ -12,7 +14,7 @@ use erg_common::opcode308::Opcode308;
|
|||
use erg_common::opcode309::Opcode309;
|
||||
use erg_common::opcode310::Opcode310;
|
||||
use erg_common::opcode311::{BinOpCode, Opcode311};
|
||||
use erg_common::python_util::{env_magic_number, PythonVersion};
|
||||
use erg_common::python_util::{env_magic_number, exec_py_code, PythonVersion};
|
||||
use erg_common::serialize::*;
|
||||
use erg_common::Str;
|
||||
|
||||
|
@ -439,6 +441,19 @@ impl CodeObj {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn exec(self, py_magic_num: Option<u32>, output: Output) -> std::io::Result<ExitStatus> {
|
||||
let mut bytes = Vec::with_capacity(16);
|
||||
let py_magic_num = py_magic_num.unwrap_or_else(env_magic_number);
|
||||
let python_ver = get_ver_from_magic_num(py_magic_num);
|
||||
bytes.append(&mut self.into_bytes(python_ver));
|
||||
let mut bytecode = "".to_string();
|
||||
for b in bytes {
|
||||
write!(bytecode, "\\x{b:0>2x}").unwrap();
|
||||
}
|
||||
let code = format!("import marshal; exec(marshal.loads(b'{bytecode}'))");
|
||||
exec_py_code(&code, output)
|
||||
}
|
||||
|
||||
fn tables_info(&self) -> String {
|
||||
let mut tables = "".to_string();
|
||||
if !self.consts.is_empty() {
|
||||
|
|
24
src/dummy.rs
24
src/dummy.rs
|
@ -281,24 +281,14 @@ impl Runnable for DummyVM {
|
|||
|
||||
fn exec(&mut self) -> Result<ExitStatus, Self::Errs> {
|
||||
// Parallel execution is not possible without dumping with a unique file name.
|
||||
let filename = self.cfg().dump_pyc_filename();
|
||||
// let filename = self.cfg().dump_pyc_filename();
|
||||
let src = self.cfg_mut().input.read();
|
||||
let warns = self
|
||||
.compiler
|
||||
.compile_and_dump_as_pyc(&filename, src, "exec")
|
||||
.map_err(|eart| {
|
||||
eart.warns.write_all_to(&mut self.cfg_mut().output);
|
||||
eart.errors
|
||||
})?;
|
||||
warns.write_all_to(&mut self.cfg_mut().output);
|
||||
let code = exec_pyc(
|
||||
&filename,
|
||||
self.cfg().py_command,
|
||||
&self.cfg().runtime_args,
|
||||
self.cfg().output.clone(),
|
||||
);
|
||||
remove_file(&filename).unwrap();
|
||||
Ok(ExitStatus::new(code.unwrap_or(1), warns.len(), 0))
|
||||
let art = self.compiler.exec_compile(src, "exec").map_err(|eart| {
|
||||
eart.warns.write_all_to(&mut self.cfg_mut().output);
|
||||
eart.errors
|
||||
})?;
|
||||
art.warns.write_all_to(&mut self.cfg_mut().output);
|
||||
Ok(art.object)
|
||||
}
|
||||
|
||||
fn eval(&mut self, src: String) -> Result<String, EvalErrors> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue