Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement mrb_raise with Rust panic! #1904

Open
wants to merge 22 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0dffa06
Enable `c_unwind` feature
lopopolo Jun 10, 2022
f270ae6
Sync toolchain to nightly in CI
lopopolo Nov 8, 2022
f006cf1
Remove `mruby-error` mrbgem from `artichoke-backend`
lopopolo Jun 10, 2022
2804eff
Disable `exc_throw` in mruby when compiling for Artichoke
lopopolo Jun 12, 2022
a144267
Prototype `mrb_protect` in Rust using `std::panic`
lopopolo Jun 12, 2022
69344b3
Use `C-unwind` ABI in `sys::protect` internals
lopopolo Jun 24, 2022
e7b2280
Skip panic hook and `RUST_BACKTRACE` handling when unwinding
lopopolo Jun 11, 2022
03b3219
Generate `C-unwind` ABI functions and function pointers from bindgen
lopopolo Jun 11, 2022
2e0387a
Use `C-unwind` ABI in `def` mruby FFI glue
lopopolo Jun 11, 2022
59b9f8c
Use `C-unwind` ABI for all native method impls in `extn`
lopopolo Jun 10, 2022
952f45e
Compile mruby as C++ to prepare for unwinding support
lopopolo Jun 11, 2022
317096d
Implement `mrb_ensure`
lopopolo Jun 11, 2022
160e560
Clean up Rust implementations of `mrb_protect` and `mrb_ensure`
lopopolo Jun 12, 2022
7f03bf6
Add note about `mrb_protect_error`
lopopolo Jun 25, 2022
4809272
Avoid implementing a static function as `#[no_mangle]` in Rust
lopopolo Jul 24, 2022
c1b865b
Update docs to reference C-unwind ABI
lopopolo Oct 24, 2022
c358db4
Fix compilation errors in panic payload downcasting
lopopolo Nov 1, 2022
2414e9c
Force mruby to compile when treated as C++
lopopolo Nov 8, 2022
958bece
Improve documentation in `raise` module
lopopolo Nov 8, 2022
bc693e2
Migrate tests to C-unwind ABI
lopopolo Nov 9, 2022
d20fbb5
Handle stack frame munging in protect flows
lopopolo Nov 9, 2022
1171d9f
cargo fmt
lopopolo Nov 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ jobs:
shell: bash
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal
rustup toolchain install nightly --profile minimal
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down Expand Up @@ -70,11 +70,11 @@ jobs:
- name: Install Rust toolchain
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal --component clippy
rustup toolchain install nightly --profile minimal --component clippy
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down Expand Up @@ -140,11 +140,11 @@ jobs:
- name: Install Rust toolchain
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal
rustup toolchain install nightly --profile minimal
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down Expand Up @@ -177,11 +177,11 @@ jobs:
- name: Install Rust toolchain
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal --component clippy
rustup toolchain install nightly --profile minimal --component clippy
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down Expand Up @@ -247,11 +247,11 @@ jobs:
- name: Install Rust toolchain
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal --component clippy
rustup toolchain install nightly --profile minimal --component clippy
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down Expand Up @@ -328,11 +328,11 @@ jobs:
- name: Install Rust toolchain
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal
rustup toolchain install nightly --profile minimal
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down Expand Up @@ -515,11 +515,11 @@ jobs:
- name: Install Rust toolchain
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal
rustup toolchain install nightly --profile minimal
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/crash.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ jobs:
- name: Install Rust toolchain
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal
rustup toolchain install nightly --profile minimal
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/spec-state.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ jobs:
- name: Install Rust toolchain
run: |
echo "::group::rustup toolchain install"
rustup toolchain install 1.65.0 --profile minimal
rustup toolchain install nightly --profile minimal
echo "::endgroup::"
echo "::group::set default toolchain"
rm -rf rust-toolchain
rustup default 1.65.0
rustup default nightly
echo "::endgroup::"
echo "::group::rustup version"
rustup -Vv
Expand Down
6 changes: 3 additions & 3 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ variables][mruby-globals]. Previous project goals and execution localized mruby

As core APIs and data structures are implemented in _Spinoso_ crates,
`artichoke-backend` will disable mruby C functions, [reimplement them in
Rust][artichoke-strangler], and expose `unsafe extern "C" fn` replacements for
interoperability with the remaining mruby pieces. This process is an application
of the [Strangler Fig pattern].
Rust][artichoke-strangler], and expose `unsafe extern "C-unwind" fn`
replacements for interoperability with the remaining mruby pieces. This process
is an application of the [Strangler Fig pattern].

[artichoke-backend-docs]:
https://artichoke.github.io/artichoke/artichoke_backend/
Expand Down
2 changes: 1 addition & 1 deletion artichoke-backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
`artichoke-backend` crate provides a Ruby interpreter. It currently is
implemented with [mruby] ABI-compatible bindings, some of which are implemented
in the vendored mruby C and exported by the [`sys`](src/sys) module, others of
which are implemented in Rust as `#[no_mangle] unsafe extern "C" fn`.
which are implemented in Rust as `#[no_mangle] unsafe extern "C-unwind" fn`.

`artichoke-backend` is slowly [strangling] its embedded mruby interpreter by
reimplementing (oxidizing) the APIs in Rust with Artichoke-sourced components.
Expand Down
23 changes: 19 additions & 4 deletions artichoke-backend/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ mod paths {
}

pub fn bindgen_header() -> PathBuf {
crate_root().join("cext").join("bindgen.h")
crate_root().join("cext").join("bindgen.hpp")
}
}

mod libs {
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::str;
Expand Down Expand Up @@ -95,7 +96,6 @@ mod libs {
"mrbgems/mruby-class-ext/src/class.c", // NOTE(GH-32): Pending removal.
"mrbgems/mruby-compiler/core/codegen.c", // Ruby parser and bytecode generation
"mrbgems/mruby-compiler/core/y.tab.c", // Ruby parser and bytecode generation
"mrbgems/mruby-error/src/exception.c", // `mrb_raise`, `mrb_protect`
"mrbgems/mruby-eval/src/eval.c", // eval, instance_eval, and friends
"mrbgems/mruby-fiber/src/fiber.c", // Fiber class from core, required by `Enumerator`
"mrbgems/mruby-metaprog/src/metaprog.c", // APIs on Kernel and Module for accessing classes and variables
Expand All @@ -117,7 +117,6 @@ mod libs {
[
"mrbgems/mruby-class-ext/include", // NOTE(GH-32): Pending removal.
"mrbgems/mruby-compiler/core", // Ruby parser and bytecode generation
"mrbgems/mruby-error/include", // `mrb_raise`, `mrb_protect`
"mrbgems/mruby-eval/include", // eval, instance_eval, and friends
"mrbgems/mruby-fiber/include", // Fiber class from core, required by `Enumerator`
"mrbgems/mruby-metaprog/include", // APIs on Kernel and Module for accessing classes and variables
Expand Down Expand Up @@ -181,13 +180,18 @@ mod libs {
let mut build = cc::Build::new();
build
.warnings(false)
.cpp(true)
.flag("-std=c++17")
.flag("-x")
.flag("c++")
.define("ARTICHOKE", None)
.define("MRB_ARY_NO_EMBED", None)
.define("MRB_GC_TURN_OFF_GENERATIONAL", None)
.define("MRB_INT64", None)
.define("MRB_NO_BOXING", None)
.define("MRB_NO_PRESYM", None)
.define("MRB_NO_STDIO", None)
.define("MRB_USE_CXX_EXCEPTION", None)
.define("MRB_UTF8_STRING", None);

for source in sources {
Expand Down Expand Up @@ -299,16 +303,18 @@ mod libs {
.arg("--no-doc-comments")
.arg("--size_t-is-usize")
.arg("--output")
.arg(bindings_out_path)
.arg(&bindings_out_path)
.arg(paths::bindgen_header())
.arg("--")
.arg("-std=c++17")
.arg("-DARTICHOKE")
.arg("-DMRB_ARY_NO_EMBED")
.arg("-DMRB_GC_TURN_OFF_GENERATIONAL")
.arg("-DMRB_INT64")
.arg("-DMRB_NO_BOXING")
.arg("-DMRB_NO_PRESYM")
.arg("-DMRB_NO_STDIO")
.arg("-DMRB_USE_CXX_EXCEPTION")
.arg("-DMRB_UTF8_STRING");

for include_dir in mruby_include_dirs().chain(mrbsys_include_dirs()) {
Expand All @@ -324,6 +330,15 @@ mod libs {

let status = command.status().unwrap();
assert!(status.success(), "bindgen failed");

let bindings = fs::read_to_string(&bindings_out_path).unwrap();
fs::write(
bindings_out_path,
bindings
.replace(r#"unsafe extern "C" fn"#, r#"unsafe extern "C-unwind" fn"#)
.replace(r#"extern "C" {"#, r#"extern "C-unwind" {"#),
)
.unwrap();
}

pub fn build(wasm: Option<Wasm>, out_dir: &OsStr) {
Expand Down
File renamed without changes.
4 changes: 0 additions & 4 deletions artichoke-backend/cext/mrbgems/src/gem_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
extern "C" {
#endif

void artichoke_mrbgem_mruby_error_gem_init(mrb_state *);
void artichoke_mrbgem_mruby_error_gem_final(mrb_state *);
void artichoke_mrbgem_mruby_eval_gem_init(mrb_state *);
void artichoke_mrbgem_mruby_eval_gem_final(mrb_state *);
void artichoke_mrbgem_mruby_metaprog_gem_init(mrb_state *);
Expand Down Expand Up @@ -37,13 +35,11 @@ mrb_final_mrbgems(mrb_state *mrb)
artichoke_mrbgem_mruby_proc_ext_gem_final(mrb);
artichoke_mrbgem_mruby_metaprog_gem_final(mrb);
artichoke_mrbgem_mruby_eval_gem_final(mrb);
artichoke_mrbgem_mruby_error_gem_final(mrb);
}

void
mrb_init_mrbgems(mrb_state *mrb)
{
artichoke_mrbgem_mruby_error_gem_init(mrb);
artichoke_mrbgem_mruby_eval_gem_init(mrb);
artichoke_mrbgem_mruby_metaprog_gem_init(mrb);
artichoke_mrbgem_mruby_proc_ext_gem_init(mrb);
Expand Down
16 changes: 0 additions & 16 deletions artichoke-backend/cext/mrbgems/src/mrbgems.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ extern "C" {

void mrb_mruby_class_ext_gem_init(mrb_state *mrb);
void mrb_mruby_class_ext_gem_final(mrb_state *mrb);
void mrb_mruby_error_gem_init(mrb_state *mrb);
void mrb_mruby_error_gem_final(mrb_state *mrb);
void mrb_mruby_eval_gem_init(mrb_state *mrb);
void mrb_mruby_eval_gem_final(mrb_state *mrb);
void mrb_mruby_fiber_gem_init(mrb_state *mrb);
Expand Down Expand Up @@ -41,20 +39,6 @@ artichoke_mrbgem_mruby_class_ext_gem_final(mrb_state *mrb)
mrb_mruby_class_ext_gem_final(mrb);
}

void
artichoke_mrbgem_mruby_error_gem_init(mrb_state *mrb)
{
int ai = mrb_gc_arena_save(mrb);
mrb_mruby_error_gem_init(mrb);
mrb_gc_arena_restore(mrb, ai);
}

void
artichoke_mrbgem_mruby_error_gem_final(mrb_state *mrb)
{
mrb_mruby_error_gem_final(mrb);
}

void
artichoke_mrbgem_mruby_eval_gem_init(mrb_state *mrb)
{
Expand Down
2 changes: 1 addition & 1 deletion artichoke-backend/src/convert/boxing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ mod tests {
#[derive(Default, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
struct Container(String);

unsafe extern "C" fn container_value(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
unsafe extern "C-unwind" fn container_value(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
unwrap_interpreter!(mrb, to => guard);

let mut value = Value::from(slf);
Expand Down
8 changes: 4 additions & 4 deletions artichoke-backend/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::Artichoke;

/// Typedef for an mruby free function for an [`mrb_value`](sys::mrb_value) with
/// `tt` [`MRB_TT_DATA`](sys::mrb_vtype::MRB_TT_DATA).
pub type Free = unsafe extern "C" fn(mrb: *mut sys::mrb_state, data: *mut c_void);
pub type Free = unsafe extern "C-unwind" fn(mrb: *mut sys::mrb_state, data: *mut c_void);

/// A generic implementation of a [`Free`] function for [`mrb_value`]s that
/// store an owned copy of a [`Box`] smart pointer.
Expand All @@ -38,7 +38,7 @@ pub type Free = unsafe extern "C" fn(mrb: *mut sys::mrb_state, data: *mut c_void
///
/// [`mrb_value`]: sys::mrb_value
/// [`MRB_TT_DATA`]: sys::mrb_vtype::MRB_TT_DATA
pub unsafe extern "C" fn box_unbox_free<T>(_mrb: *mut sys::mrb_state, data: *mut c_void)
pub unsafe extern "C-unwind" fn box_unbox_free<T>(_mrb: *mut sys::mrb_state, data: *mut c_void)
where
T: 'static + BoxUnboxVmValue,
{
Expand Down Expand Up @@ -100,7 +100,7 @@ mod free_test {
///
/// To extract method arguments, use [`mrb_get_args!`] and the supplied
/// interpreter.
pub type Method = unsafe extern "C" fn(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value;
pub type Method = unsafe extern "C-unwind" fn(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value;

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct ClassScope {
Expand Down Expand Up @@ -543,7 +543,7 @@ mod tests {
#[derive(Debug)]
struct Module;

extern "C" fn value(_mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
extern "C-unwind" fn value(_mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
unsafe {
match slf.tt {
sys::mrb_vtype::MRB_TT_CLASS => sys::mrb_sys_fixnum_value(8),
Expand Down
5 changes: 4 additions & 1 deletion artichoke-backend/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ mod tests {
#[derive(Debug)]
struct NestedEval;

unsafe extern "C" fn nested_eval_file(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
unsafe extern "C-unwind" fn nested_eval_file(
mrb: *mut sys::mrb_state,
_slf: sys::mrb_value,
) -> sys::mrb_value {
unwrap_interpreter!(mrb, to => guard);
let result = if let Ok(value) = guard.eval(b"__FILE__") {
value
Expand Down
Loading