diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0e005b7352..56cd0ba70d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -107,6 +107,16 @@ jobs: command: check args: --target aarch64-linux-android + - uses: actions-rs/toolchain@v1 + with: + target: wasm32-unknown-unknown + + - name: Check compilation for wasm32 + uses: actions-rs/cargo@v1 + with: + command: check + args: --target wasm32-unknown-unknown --no-default-features + - uses: actions-rs/toolchain@v1 with: target: wasm32-wasi diff --git a/Cargo.toml b/Cargo.toml index 9bec9d9507..db7ac49602 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ libc = "0.2.123" flame = { version = "0.2.2", optional = true } flamescope = { version = "0.1.2", optional = true } -[target.'cfg(not(target_os = "wasi"))'.dependencies] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] rustyline = "9.1.2" [dev-dependencies] diff --git a/src/shell/helper.rs b/src/shell/helper.rs index 33b584a0df..4cb18e0bd7 100644 --- a/src/shell/helper.rs +++ b/src/shell/helper.rs @@ -1,7 +1,9 @@ -#![cfg_attr(target_os = "wasi", allow(dead_code))] -use rustpython_vm::builtins::{PyDictRef, PyStrRef}; -use rustpython_vm::VirtualMachine; -use rustpython_vm::{function::ArgIterable, PyResult, TryFromObject}; +#![cfg_attr(target_arch = "wasm32", allow(dead_code))] +use rustpython_vm::{ + builtins::{PyDictRef, PyStrRef}, + function::ArgIterable, + PyResult, TryFromObject, VirtualMachine, +}; pub struct ShellHelper<'vm> { vm: &'vm VirtualMachine, @@ -140,7 +142,7 @@ impl<'vm> ShellHelper<'vm> { } cfg_if::cfg_if! { - if #[cfg(not(target_os = "wasi"))] { + if #[cfg(not(target_arch = "wasm32"))] { use rustyline::{ completion::Completer, highlight::Highlighter, hint::Hinter, validate::Validator, Context, Helper, diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 5c4067a0d8..ae7faa7ab1 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -1023,9 +1023,14 @@ pub(crate) fn raw_os_error_to_exc_type(errno: i32, vm: &VirtualMachine) -> Optio } } +#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] +pub(crate) fn raw_os_error_to_exc_type(_errno: i32, _vm: &VirtualMachine) -> Option { + None +} + pub(super) mod types { use crate::common::lock::PyRwLock; - #[cfg_attr(target_os = "wasi", allow(unused_imports))] + #[cfg_attr(target_arch = "wasm32", allow(unused_imports))] use crate::{ builtins::{traceback::PyTracebackRef, PyInt, PyTupleRef, PyTypeRef}, convert::ToPyResult, @@ -1033,7 +1038,7 @@ pub(super) mod types { PyObjectRef, PyRef, PyResult, VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; - #[cfg_attr(target_os = "wasi", allow(unused_imports))] + #[cfg_attr(target_arch = "wasm32", allow(unused_imports))] use std::ops::Deref; // This module is designed to be used as `use builtins::*;`. diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index a11ccf9e42..92873bec6c 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -9,8 +9,34 @@ cfg_if::cfg_if! { } } -use crate::{PyObjectRef, PyResult, TryFromObject, VirtualMachine}; -pub(crate) use _io::io_open as open; +use crate::{ + builtins::PyBaseExceptionRef, + convert::{ToPyException, ToPyObject}, + PyObjectRef, PyResult, TryFromObject, VirtualMachine, +}; +pub use _io::io_open as open; + +impl ToPyException for &'_ std::io::Error { + fn to_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef { + use std::io::ErrorKind; + + let excs = &vm.ctx.exceptions; + #[allow(unreachable_patterns)] // some errors are just aliases of each other + let exc_type = match self.kind() { + ErrorKind::NotFound => excs.file_not_found_error.clone(), + ErrorKind::PermissionDenied => excs.permission_error.clone(), + ErrorKind::AlreadyExists => excs.file_exists_error.clone(), + ErrorKind::WouldBlock => excs.blocking_io_error.clone(), + _ => self + .raw_os_error() + .and_then(|errno| crate::exceptions::raw_os_error_to_exc_type(errno, vm)) + .unwrap_or_else(|| excs.os_error.clone()), + }; + let errno = self.raw_os_error().to_pyobject(vm); + let msg = vm.ctx.new_str(self.to_string()).into(); + vm.new_exception(exc_type, vec![errno, msg]) + } +} pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { let ctx = &vm.ctx; diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index fa17e4740b..acab029ccb 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -8,8 +8,7 @@ use crate::{ VirtualMachine, }; use std::{ - ffi, fs, - io::{self, ErrorKind}, + ffi, fs, io, path::{Path, PathBuf}, }; @@ -236,31 +235,6 @@ impl PathOrFd { } } -impl ToPyException for io::Error { - fn to_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef { - (&self).to_pyexception(vm) - } -} -impl ToPyException for &'_ io::Error { - fn to_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef { - let excs = &vm.ctx.exceptions; - #[allow(unreachable_patterns)] // some errors are just aliases of each other - let exc_type = match self.kind() { - ErrorKind::NotFound => excs.file_not_found_error.clone(), - ErrorKind::PermissionDenied => excs.permission_error.clone(), - ErrorKind::AlreadyExists => excs.file_exists_error.clone(), - ErrorKind::WouldBlock => excs.blocking_io_error.clone(), - _ => self - .raw_os_error() - .and_then(|errno| crate::exceptions::raw_os_error_to_exc_type(errno, vm)) - .unwrap_or_else(|| excs.os_error.clone()), - }; - let errno = self.raw_os_error().to_pyobject(vm); - let msg = vm.ctx.new_str(self.to_string()).into(); - vm.new_exception(exc_type, vec![errno, msg]) - } -} - #[cfg(unix)] impl ToPyException for nix::Error { fn to_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef { diff --git a/vm/src/stdlib/thread.rs b/vm/src/stdlib/thread.rs index a540d0ef3a..90af5479c6 100644 --- a/vm/src/stdlib/thread.rs +++ b/vm/src/stdlib/thread.rs @@ -1,5 +1,5 @@ //! Implementation of the _thread module -#[cfg_attr(target_os = "wasi", allow(unused_imports))] +#[cfg_attr(target_arch = "wasm32", allow(unused_imports))] pub(crate) use _thread::{make_module, RawRMutex}; #[pymodule]