mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
2
.gitignore
vendored
2
.gitignore
vendored
@@ -14,3 +14,5 @@ tests/snippets/resources
|
||||
flame-graph.html
|
||||
flame.txt
|
||||
flamescope.json
|
||||
/wapm.lock
|
||||
/wapm_packages
|
||||
|
||||
@@ -32,6 +32,7 @@ num-traits = "0.2.8"
|
||||
flame = { version = "0.2", optional = true }
|
||||
flamescope = { version = "0.1", optional = true }
|
||||
|
||||
[target.'cfg(not(target_os = "wasi"))'.dependencies]
|
||||
rustyline = "=5.0.1"
|
||||
|
||||
|
||||
|
||||
21
README.md
21
README.md
@@ -34,6 +34,27 @@ Or use the interactive shell:
|
||||
>>>>> 2+2
|
||||
4
|
||||
|
||||
### WASI
|
||||
|
||||
You can compile RustPython to a standalone WebAssembly WASI module so it can run anywhere.
|
||||
|
||||
```shell
|
||||
$ wapm install rustpython
|
||||
$ wapm run rustpython
|
||||
>>>>> 2+2
|
||||
4
|
||||
```
|
||||
|
||||
#### Building the WASI file
|
||||
|
||||
You can build the WebAssembly WASI file with:
|
||||
|
||||
```
|
||||
cargo build --release --target wasm32-wasi --features="freeze-stdlib"
|
||||
```
|
||||
|
||||
> Note: we use the `freeze-stdlib` to include the standard libarary inside the binary.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
RustPython is in a development phase and should not be used in production or a
|
||||
|
||||
80
src/main.rs
80
src/main.rs
@@ -321,7 +321,8 @@ fn write_profile(matches: &ArgMatches) -> Result<(), Box<dyn std::error::Error>>
|
||||
}
|
||||
|
||||
fn run_rustpython(vm: &VirtualMachine, matches: &ArgMatches) -> PyResult<()> {
|
||||
import::init_importlib(&vm, true)?;
|
||||
// We only include the standard library bytecode in WASI
|
||||
import::init_importlib(&vm, cfg!(not(target_os = "wasi")))?;
|
||||
|
||||
if let Some(paths) = option_env!("BUILDTIME_RUSTPYTHONPATH") {
|
||||
let sys_path = vm.get_attribute(vm.sys_module.clone(), "path")?;
|
||||
@@ -486,6 +487,7 @@ fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> ShellExecResul
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
|
||||
use rustyline::{error::ReadlineError, Editor};
|
||||
|
||||
@@ -596,3 +598,79 @@ fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "wasi")]
|
||||
fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
|
||||
use std::io::prelude::*;
|
||||
use std::io::{self, BufRead};
|
||||
|
||||
println!(
|
||||
"Welcome to the magnificent Rust Python {} interpreter \u{1f631} \u{1f596}",
|
||||
crate_version!()
|
||||
);
|
||||
|
||||
// Read a single line:
|
||||
let mut input = String::new();
|
||||
let mut continuing = false;
|
||||
|
||||
loop {
|
||||
let prompt_name = if continuing { "ps2" } else { "ps1" };
|
||||
let prompt = vm
|
||||
.get_attribute(vm.sys_module.clone(), prompt_name)
|
||||
.and_then(|prompt| vm.to_str(&prompt));
|
||||
let prompt = match prompt {
|
||||
Ok(ref s) => s.as_str(),
|
||||
Err(_) => "",
|
||||
};
|
||||
print!("{}", prompt);
|
||||
io::stdout().flush().ok().expect("Could not flush stdout");
|
||||
|
||||
let stdin = io::stdin();
|
||||
|
||||
let result = match stdin.lock().lines().next().unwrap() {
|
||||
Ok(line) => {
|
||||
debug!("You entered {:?}", line);
|
||||
let stop_continuing = line.is_empty();
|
||||
|
||||
if input.is_empty() {
|
||||
input = line;
|
||||
} else {
|
||||
input.push_str(&line);
|
||||
}
|
||||
input.push_str("\n");
|
||||
|
||||
if continuing {
|
||||
if stop_continuing {
|
||||
continuing = false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
match shell_exec(vm, &input, scope.clone()) {
|
||||
ShellExecResult::Ok => {
|
||||
input.clear();
|
||||
Ok(())
|
||||
}
|
||||
ShellExecResult::Continue => {
|
||||
continuing = true;
|
||||
Ok(())
|
||||
}
|
||||
ShellExecResult::PyErr(err) => {
|
||||
input.clear();
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Readline error: {:?}", err);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(exc) = result {
|
||||
print_exception(vm, &exc);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ fn duration_to_f64(d: Duration) -> f64 {
|
||||
(d.as_secs() as f64) + (f64::from(d.subsec_nanos()) / 1e9)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
|
||||
fn time_time(_vm: &VirtualMachine) -> f64 {
|
||||
match SystemTime::now().duration_since(UNIX_EPOCH) {
|
||||
Ok(v) => duration_to_f64(v),
|
||||
@@ -64,7 +64,7 @@ fn time_time(_vm: &VirtualMachine) -> f64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
|
||||
fn time_time(_vm: &VirtualMachine) -> f64 {
|
||||
use wasm_bindgen::prelude::*;
|
||||
#[wasm_bindgen]
|
||||
|
||||
20
wapm.toml
Normal file
20
wapm.toml
Normal file
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name="rustpython"
|
||||
version="0.0.4"
|
||||
description="A Python-3 (CPython >= 3.5.0) Interpreter written in Rust 🐍 😱 🤘"
|
||||
license-file="LICENSE"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/RustPython/RustPython"
|
||||
|
||||
[[module]]
|
||||
name="rustpython"
|
||||
source="target/wasm32-wasi/release/rustpython.wasm"
|
||||
abi = "wasi"
|
||||
interfaces = {wasi= "0.0.0-unstable"}
|
||||
|
||||
[[command]]
|
||||
name="rustpython"
|
||||
module="rustpython"
|
||||
|
||||
# [fs]
|
||||
# "Lib"="Lib"
|
||||
Reference in New Issue
Block a user