diff --git a/Cargo.toml b/Cargo.toml index b842acf..053e106 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ keywords = ["mruby", "ruby", "bindings", "repl"] license = "MPL-2.0" [build-dependencies] -gcc = "0.3.22" +cc = "1.0" tar = "0.4.4" walkdir = "0.1.5" diff --git a/build.rs b/build.rs index 627f834..6109cd1 100644 --- a/build.rs +++ b/build.rs @@ -5,7 +5,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -extern crate gcc; +extern crate cc; extern crate tar; extern crate walkdir; @@ -25,7 +25,7 @@ fn main() { let mut archive = Archive::new(File::open("src/mruby/mruby-out.tar").unwrap()); archive.unpack("target").unwrap(); - let mut config = gcc::Config::new(); + let mut config = cc::Build::new(); for entry in WalkDir::new("target/mruby-out/src").into_iter().filter_entry(|e| e.file_type().is_dir() || is_c(e)) { let entry = entry.unwrap(); @@ -35,7 +35,7 @@ fn main() { config.include("target/mruby-out/include").compile("libmruby.a"); - let mut config = gcc::Config::new(); + let mut config = cc::Build::new(); config.file("src/mrb_ext.c").include("target/mruby-out/include").compile("libmrbe.a"); } diff --git a/examples/container.rs b/examples/container.rs index 94ad503..2dd3e66 100644 --- a/examples/container.rs +++ b/examples/container.rs @@ -3,6 +3,7 @@ extern crate mrusty; use mrusty::{Mruby, MrubyImpl}; +use mrusty::{MrInt}; fn main() { let mruby = Mruby::new(); diff --git a/src/lib.rs b/src/lib.rs index e78aced..96bdba5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,10 +27,12 @@ mod spec; /// Not meant to be called directly. #[doc(hidden)] -pub use mruby_ffi::MrValue; +pub use mruby_ffi::{MrValue, MrDataType, MrInt, MrFloat}; /// Not meant to be called directly. #[doc(hidden)] pub use mruby_ffi::mrb_get_args; +#[doc(hidden)] +pub use mruby_ffi::{mrb_ext_value_sizeof, mrb_ext_data_type_sizeof, mrb_ext_int_sizeof, mrb_ext_float_sizeof}; pub use mruby::Class; pub use mruby::ClassLike; diff --git a/src/macros.rs b/src/macros.rs index a2870af..7e5693a 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -27,6 +27,7 @@ /// ``` /// # #[macro_use] extern crate mrusty; /// use mrusty::{Mruby, MrubyImpl}; +/// use mrusty::MrInt; /// /// # fn main() { /// let mruby = Mruby::new(); @@ -108,7 +109,7 @@ /// /// ``` /// # #[macro_use] extern crate mrusty; -/// use mrusty::{Mruby, MrubyImpl}; +/// use mrusty::{Mruby, MrubyImpl, MrInt}; /// /// # fn main() { /// let mruby = Mruby::new(); @@ -158,20 +159,16 @@ macro_rules! mrfn { // init ( @init ) => (); - ( @init $name:ident, bool ) => (let $name = ::std::mem::uninitialized::();); - ( @init $name:ident, i32 ) => (let $name = ::std::mem::uninitialized::();); - ( @init $name:ident, f64 ) => (let $name = ::std::mem::uninitialized::();); - ( @init $name:ident, (&str) ) => (let $name = ::std::mem::uninitialized::<*const ::std::os::raw::c_char>();); - ( @init $name:ident, (Vec) ) => (let $name = ::std::mem::uninitialized::<$crate::MrValue>();); - ( @init $name:ident, Class ) => (let $name = ::std::mem::uninitialized::<$crate::MrValue>();); - ( @init $name:ident, Value ) => (let $name = ::std::mem::uninitialized::<$crate::MrValue>();); - ( @init $name:ident, (&mut $_t:ty) ) => (let $name = ::std::mem::uninitialized::<$crate::MrValue>();); - ( @init $name:ident, (&$_t:ty) ) => (let $name = ::std::mem::uninitialized::<$crate::MrValue>();); - ( @init $name:ident : $t:tt ) => (mrfn!(@init $name, $t)); - ( @init $name:ident : $t:tt, $($names:ident : $ts:tt),+ ) => { - mrfn!(@init $name, $t); - mrfn!(@init $( $names : $ts ),*); - }; + ( @init $name:ident, bool ) => (let $name = ::std::mem::MaybeUninit::::zeroed().assume_init();); + ( @init $name:ident, i32 ) => (let $name = ::std::mem::MaybeUninit::::uninit().assume_init();); + ( @init $name:ident, f64 ) => (let $name = ::std::mem::MaybeUninit::::uninit().assume_init();); + ( @init $name:ident, (&str) ) => (let $name = ::std::mem::MaybeUninit::<*const ::std::os::raw::c_char>::uninit().assume_init();); + ( @init $name:ident, (Vec) ) => (let $name = ::std::mem::MaybeUninit::<$crate::MrValue>::uninit().assume_init();); + ( @init $name:ident, Class ) => (let $name = ::std::mem::MaybeUninit::<$crate::MrValue>::uninit().assume_init();); + ( @init $name:ident, Value ) => (let $name = ::std::mem::MaybeUninit::<$crate::MrValue>::uninit().assume_init();); + ( @init $name:ident, (&mut $_t:ty) ) => (let $name = ::std::mem::MaybeUninit::<$crate::MrValue>::uninit().assume_init();); + ( @init $name:ident, (&$_t:ty) ) => (let $name = ::std::mem::MaybeUninit::<$crate::MrValue>::uninit().assume_init();); + ( @init $($names:ident : $ts:tt),+ ) => ($( mrfn!(@init $names, $ts); )*); // sig ( @sig ) => (""); @@ -184,13 +181,13 @@ macro_rules! mrfn { ( @sig Value ) => ("o"); ( @sig (&mut $_t:ty) ) => ("o"); ( @sig (&$_t:ty) ) => ("o"); - ( @sig $t:tt, $( $ts:tt ),+ ) => (concat!(mrfn!(@sig $t), mrfn!(@sig $( $ts ),*))); + ( @sig $($ts:tt),+ ) => (concat!( $( mrfn!(@sig $ts) ),* )); // args ( @args ) => (); ( @args $name:ident, bool ) => (&$name as *const bool); - ( @args $name:ident, i32 ) => (&$name as *const i32); - ( @args $name:ident, f64 ) => (&$name as *const f64); + ( @args $name:ident, i32 ) => (&$name as *const MrInt); + ( @args $name:ident, f64 ) => (&$name as *const MrFloat); ( @args $name:ident, (&str) ) => (&$name as *const *const ::std::os::raw::c_char); ( @args $name:ident, (Vec) ) => (&$name as *const $crate::MrValue); ( @args $name:ident, Class ) => (&$name as *const $crate::MrValue); @@ -198,37 +195,21 @@ macro_rules! mrfn { ( @args $name:ident, (&mut $_t:ty) ) => (&$name as *const $crate::MrValue); ( @args $name:ident, (&$_t:ty) ) => (&$name as *const $crate::MrValue); ( @args $name:ident : $t:tt ) => (mrfn!(@args $name, $t)); - ( @args $mrb:expr, $sig:expr, $name:ident : $t:tt) => { - $crate::mrb_get_args($mrb, $sig, mrfn!(@args $name, $t)); - }; - ( @args $mrb:expr, $sig:expr, $name:ident : $t:tt, $($names:ident : $ts:tt),+ ) => { - $crate::mrb_get_args($mrb, $sig, mrfn!(@args $name, $t), $( mrfn!(@args $names : $ts) ),*); + ( @args $mrb:expr, $sig:expr) => (); + ( @args $mrb:expr, $sig:expr, $( $names:ident : $ts:tt ),+ ) => { + $crate::mrb_get_args($mrb, $sig $( , mrfn!(@args $names : $ts) )*); }; // args_rest - ( @args_rest $mruby:expr, $sig:expr, $name:ident : $t:tt) => { + ( @args_rest $mruby:expr, $sig:expr $( , $names:ident : $ts:tt )* ) => { { let mrb = $mruby.borrow().mrb; - let args = ::std::mem::uninitialized::<*mut $crate::MrValue>(); - let count = ::std::mem::uninitialized::(); + let args = ::std::mem::MaybeUninit::<*mut $crate::MrValue>::uninit().assume_init(); + let count = ::std::mem::MaybeUninit::::uninit().assume_init(); - $crate::mrb_get_args(mrb, $sig, mrfn!(@args $name, $t), &args as *const *mut $crate::MrValue, - &count as *const i32); - - let args = ::std::slice::from_raw_parts(args, count as usize); - args.iter().map(|arg| { $crate::Value::new($mruby.clone(), arg.clone()) }).collect::>() - } - }; - ( @args_rest $mruby:expr, $sig:expr, $name:ident : $t:tt, $($names:ident : $ts:tt),+ ) => { - { - let mrb = $mruby.borrow().mrb; - - let args = ::std::mem::uninitialized::<*mut $crate::MrValue>(); - let count = ::std::mem::uninitialized::(); - - $crate::mrb_get_args(mrb, $sig, mrfn!(@args $name, $t), $( mrfn!(@args $names : $ts) ),* , - &args as *const *mut $crate::MrValue, &count as *const i32); + $crate::mrb_get_args(mrb, $sig, $( mrfn!(@args $names, $ts), )* + &args as *const *mut $crate::MrValue, &count as *const MrInt); let args = ::std::slice::from_raw_parts(args, count as usize); args.iter().map(|arg| { $crate::Value::new($mruby.clone(), arg.clone()) }).collect::>() @@ -236,34 +217,16 @@ macro_rules! mrfn { }; // args_rest_blk - ( @args_rest_blk $mruby:expr, $sig:expr, $name:ident : $t:tt) => { - { - let mrb = $mruby.borrow().mrb; - - let args = ::std::mem::uninitialized::<*mut $crate::MrValue>(); - let count = ::std::mem::uninitialized::(); - let blk = ::std::mem::uninitialized::<$crate::MrValue>(); - - $crate::mrb_get_args(mrb, $sig, mrfn!(@args $name, $t), &args as *const *mut $crate::MrValue, - &count as *const i32, &blk as *const $crate::MrValue); - - let args = ::std::slice::from_raw_parts(args, count as usize); - let args = args.iter().map(|arg| { $crate::Value::new($mruby.clone(), arg.clone()) }).collect::>(); - let blk = $crate::Value::new($mruby.clone(), blk); - - (args, blk) - } - }; - ( @args_rest_blk $mruby:expr, $sig:expr, $name:ident : $t:tt, $($names:ident : $ts:tt),+ ) => { + ( @args_rest_blk $mruby:expr, $sig:expr $( , $names:ident : $ts:tt)* ) => { { let mrb = $mruby.borrow().mrb; - let args = ::std::mem::uninitialized::<*mut $crate::MrValue>(); - let count = ::std::mem::uninitialized::(); - let blk = ::std::mem::uninitialized::<$crate::MrValue>(); + let args = ::std::mem::MaybeUninit::<*mut $crate::MrValue>::uninit().assume_init(); + let count = ::std::mem::MaybeUninit::::uninit().assume_init(); + let blk = ::std::mem::MaybeUninit::<$crate::MrValue>::uninit().assume_init(); - $crate::mrb_get_args(mrb, $sig, mrfn!(@args $name, $t), $( mrfn!(@args $names : $ts) ),* , - &args as *const *mut $crate::MrValue, &count as *const i32, &blk as *const $crate::MrValue); + $crate::mrb_get_args(mrb, $sig, $(mrfn!(@args $names, $ts), )* + &args as *const *mut $crate::MrValue, &count as *const MrInt, &blk as *const $crate::MrValue); let args = ::std::slice::from_raw_parts(args, count as usize); let args = args.iter().map(|arg| { $crate::Value::new($mruby.clone(), arg.clone()) }).collect::>(); @@ -276,8 +239,12 @@ macro_rules! mrfn { // conv ( @conv $mruby:expr ) => (); ( @conv $mruby:expr, $name:ident, bool ) => (); - ( @conv $mruby:expr, $name:ident, i32 ) => (); - ( @conv $mruby:expr, $name:ident, f64 ) => (); + ( @conv $mruby:expr, $name:ident, i32 ) => { + let $name = $name as i32; + }; + ( @conv $mruby:expr, $name:ident, f64 ) => { + let $name = $name as f64; + }; ( @conv $mruby:expr, $name:ident, (&str) ) => { let $name = ::std::ffi::CStr::from_ptr($name).to_str().unwrap(); }; @@ -298,11 +265,7 @@ macro_rules! mrfn { let $name = $crate::Value::new($mruby.clone(), $name).to_obj::<$t>().unwrap(); let $name = $name.borrow(); }; - ( @conv $mruby:expr, $name:ident : $t:tt ) => (mrfn!(@conv $mruby, $name, $t)); - ( @conv $mruby:expr, $name:ident : $t:tt, $($names:ident : $ts:tt),+ ) => { - mrfn!(@conv $mruby, $name, $t); - mrfn!(@conv $mruby, $( $names : $ts ),*); - }; + ( @conv $mruby:expr, $($names:ident : $ts:tt),+ )=> ($( mrfn!(@conv $mruby, $names, $ts); )*); // slf ( @slf $slf:ident, bool ) => (let $slf = $slf.to_bool().unwrap();); @@ -329,76 +292,7 @@ macro_rules! mrfn { $block } }; - ( |$mruby:ident, $slf:ident : $st:tt; &$blk:ident| $block:expr ) => { - |$mruby, $slf| { - mrfn!(@slf $slf, $st); - - unsafe { - let mrb = $mruby.borrow().mrb; - - mrfn!(@init $blk : Value); - - let sig_str = ::std::ffi::CString::new("&").unwrap(); - - mrfn!(@args mrb, sig_str.as_ptr(), $blk : Value); - mrfn!(@conv $mruby, $blk : Value); - - $block - } - } - }; - ( |$mruby:ident, $slf:ident : $st:tt; $args:ident| $block:expr ) => { - |$mruby, $slf| { - mrfn!(@slf $slf, $st); - - unsafe { - let mrb = $mruby.borrow().mrb; - - let $args = ::std::mem::uninitialized::<*mut $crate::MrValue>(); - let count = ::std::mem::uninitialized::(); - - let sig_str = ::std::ffi::CString::new("*").unwrap(); - - $crate::mrb_get_args(mrb, sig_str.as_ptr(), &$args as *const *mut $crate::MrValue, - &count as *const i32); - - let $args = ::std::slice::from_raw_parts($args, count as usize); - let $args = $args.iter().map(|arg| { - $crate::Value::new($mruby.clone(), arg.clone()) - }).collect::>(); - - $block - } - } - }; - ( |$mruby:ident, $slf:ident : $st:tt; $args:ident, &$blk:ident| $block:expr ) => { - |$mruby, $slf| { - mrfn!(@slf $slf, $st); - - unsafe { - let mrb = $mruby.borrow().mrb; - - let $args = ::std::mem::uninitialized::<*mut $crate::MrValue>(); - let count = ::std::mem::uninitialized::(); - let $blk = ::std::mem::uninitialized::<$crate::MrValue>(); - - let sig_str = ::std::ffi::CString::new("*&").unwrap(); - - $crate::mrb_get_args(mrb, sig_str.as_ptr(), - &$args as *const *mut $crate::MrValue, &count as *const i32, - &$blk as *const $crate::MrValue); - - let $args = ::std::slice::from_raw_parts($args, count as usize); - let $args = $args.iter().map(|arg| { - $crate::Value::new($mruby.clone(), arg.clone()) - }).collect::>(); - let $blk = $crate::Value::new($mruby.clone(), $blk); - - $block - } - } - }; - ( |$mruby:ident, $slf:ident : $st:tt, $( $name:ident : $t:tt ),*| $block:expr ) => { + ( |$mruby:ident, $slf:ident : $st:tt $( , $name:ident : $t:tt )*| $block:expr ) => { |$mruby, $slf| { unsafe { mrfn!(@slf $slf, $st); @@ -408,31 +302,31 @@ macro_rules! mrfn { let mrb = $mruby.borrow().mrb; let sig_str = ::std::ffi::CString::new(mrfn!(@sig $( $t ),*)).unwrap(); - mrfn!(@args mrb, sig_str.as_ptr(), $( $name : $t ),*); - mrfn!(@conv $mruby, $( $name : $t ),*); + mrfn!(@args mrb, sig_str.as_ptr() $( , $name : $t )*); + mrfn!(@conv $mruby $( , $name : $t )*); $block } } }; - ( |$mruby:ident, $slf:ident : $st:tt, $( $name:ident : $t:tt ),* ; &$blk:ident| $block:expr ) => { + ( |$mruby:ident, $slf:ident : $st:tt $( , $name:ident : $t:tt )* ; &$blk:ident| $block:expr ) => { |$mruby, $slf| { unsafe { mrfn!(@slf $slf, $st); - mrfn!(@init $( $name : $t ),*, $blk : Value); + mrfn!(@init $( $name : $t, )* $blk : Value); let mrb = $mruby.borrow().mrb; let sig_str = ::std::ffi::CString::new(concat!(mrfn!(@sig $( $t ),*), "&")).unwrap(); - mrfn!(@args mrb, sig_str.as_ptr(), $( $name : $t ),*, $blk : Value); - mrfn!(@conv $mruby, $( $name : $t ),*, $blk : Value); + mrfn!(@args mrb, sig_str.as_ptr() $( , $name : $t )*, $blk : Value); + mrfn!(@conv $mruby $( , $name : $t )*, $blk : Value); $block } } }; - ( |$mruby:ident, $slf:ident : $st:tt, $( $name:ident : $t:tt ),* ; $args:ident| $block:expr ) => { + ( |$mruby:ident, $slf:ident : $st:tt $( , $name:ident : $t:tt )* ; $args:ident| $block:expr ) => { |$mruby, $slf| { unsafe { mrfn!(@slf $slf, $st); @@ -441,14 +335,14 @@ macro_rules! mrfn { let sig_str = ::std::ffi::CString::new(concat!(mrfn!(@sig $( $t ),*), "*")).unwrap(); - let $args = mrfn!(@args_rest $mruby, sig_str.as_ptr(), $( $name : $t ),*); - mrfn!(@conv $mruby, $( $name : $t ),*); + let $args = mrfn!(@args_rest $mruby, sig_str.as_ptr() $( , $name : $t )*); + mrfn!(@conv $mruby $( , $name : $t )*); $block } } }; - ( |$mruby:ident, $slf:ident : $st:tt, $( $name:ident : $t:tt ),* ; $args:ident, &$blk:ident| $block:expr ) => { + ( |$mruby:ident, $slf:ident : $st:tt $( , $name:ident : $t:tt )* ; $args:ident, &$blk:ident| $block:expr ) => { |$mruby, $slf| { unsafe { mrfn!(@slf $slf, $st); @@ -457,8 +351,8 @@ macro_rules! mrfn { let sig_str = ::std::ffi::CString::new(concat!(mrfn!(@sig $( $t ),*), "*&")).unwrap(); - let ($args, $blk) = mrfn!(@args_rest_blk $mruby, sig_str.as_ptr(), $( $name : $t ),*); - mrfn!(@conv $mruby, $( $name : $t ),*); + let ($args, $blk) = mrfn!(@args_rest_blk $mruby, sig_str.as_ptr() $( , $name : $t )*); + mrfn!(@conv $mruby $( , $name : $t )*); $block } @@ -1084,6 +978,7 @@ macro_rules! mruby_defines { /// ``` /// # #[macro_use] extern crate mrusty; /// use mrusty::{Mruby, MrubyFile, MrubyImpl}; +/// use mrusty::MrInt; /// /// # fn main() { /// let mruby = Mruby::new(); @@ -1194,6 +1089,7 @@ macro_rules! mrusty_class { /// ``` /// # #[macro_use] extern crate mrusty; /// use mrusty::{Mruby, MrubyImpl}; +/// use mrusty::MrInt; /// /// # fn main() { /// let mruby = Mruby::new(); diff --git a/src/mrb_ext.c b/src/mrb_ext.c index 93aa3d9..31ae4ae 100644 --- a/src/mrb_ext.c +++ b/src/mrb_ext.c @@ -6,6 +6,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include +#include #include #include @@ -15,6 +16,8 @@ #include #include #include +#include +#include void* mrb_ext_get_ud(struct mrb_state* mrb) { return mrb->ud; @@ -24,14 +27,96 @@ void mrb_ext_set_ud(struct mrb_state* mrb, void* ud) { mrb->ud = ud; } -int mrb_ext_fixnum_to_cint(mrb_value value) { +mrb_value mrb_ext_load_nstring_cxt_nothrow(mrb_state *mrb, const char *s, size_t len, mrbc_context *cxt) { + mrb_value value; + + struct mrb_jmpbuf c_jmp; + struct mrb_jmpbuf *pc_jmp_bak; + pc_jmp_bak = mrb->jmp; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + value = mrb_load_nstring_cxt(mrb, s, len, cxt); + } + MRB_CATCH(&c_jmp) { + value = mrb_nil_value(); + } + MRB_END_EXC(&c_jmp); + + mrb->jmp = pc_jmp_bak; + + return value; +} + +// from) load.c:read_binary_header() +static int +read_binary_size(const uint8_t *bin, size_t *bin_size) +{ + const struct rite_binary_header *header = (const struct rite_binary_header *)bin; + + if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) { + // no-op + } else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) { + // no-op + } else { + return MRB_DUMP_INVALID_FILE_HEADER; + } + + if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) { + return MRB_DUMP_INVALID_FILE_HEADER; + } + + *bin_size = (size_t)bin_to_uint32(header->binary_size); + + return MRB_DUMP_OK; +} +// from) load.c:irep_error() +static void +irep_error(mrb_state *mrb) +{ + mrb_exc_set(mrb, mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error")); +} + +mrb_value mrb_ext_load_irep_cxt_suppress_alignment(mrb_state *mrb, const uint8_t *bin, mrbc_context *c) { + size_t bin_size = 0; + const size_t header_size = sizeof(struct rite_binary_header); + + int result = read_binary_size(bin, &bin_size); + if (result != MRB_DUMP_OK || bin_size <= header_size) { + irep_error(mrb); + return mrb_nil_value(); + } + + // suppress alignment at run + const uint8_t *cpy_bin = (const uint8_t *)mrb_malloc(mrb, bin_size); + + memcpy(cpy_bin, bin, bin_size); + mrb_value value = mrb_load_irep_cxt(mrb, cpy_bin, c); + mrb_free(mrb, cpy_bin); + + return value; +} + +mrb_int mrb_ext_fixnum_to_cint(mrb_value value) { return mrb_fixnum(value); } -double mrb_ext_float_to_cdouble(mrb_value value) { +mrb_float mrb_ext_float_to_cdouble(mrb_value value) { return mrb_float(value); } +void* mrb_ext_ptr_to_ptr(mrb_value value) { + return mrb_ptr(value); +} + +mrb_sym mrb_ext_symbol_to_cuint(mrb_value value) { + return mrb_symbol(value); +} + +enum mrb_vtype mrb_ext_type(mrb_value value) { + return mrb_type(value); +} + void* mrb_ext_data_ptr(mrb_value value) { return DATA_PTR(value); } @@ -48,22 +133,14 @@ mrb_value mrb_ext_true() { return mrb_true_value(); } -mrb_value mrb_ext_cint_to_fixnum(int value) { +mrb_value mrb_ext_cint_to_fixnum(mrb_int value) { return mrb_fixnum_value(value); } -mrb_value mrb_ext_cdouble_to_float(struct mrb_state* mrb, double value) { +mrb_value mrb_ext_cdouble_to_float(struct mrb_state* mrb, mrb_float value) { return mrb_float_value(mrb, value); } -mrb_value mrb_ext_proc_to_value(struct mrb_state* mrb, struct RProc* proc) { - mrb_value value = mrb_cptr_value(mrb, proc); - - value.tt = MRB_TT_PROC; - - return value; -} - const char* mrb_ext_sym2name(struct mrb_state* mrb, mrb_value value) { return mrb_sym2name(mrb, mrb_symbol(value)); } @@ -72,9 +149,7 @@ mrb_value mrb_ext_sym_new(struct mrb_state* mrb, const char* string, size_t len) { mrb_value value; - mrb_symbol(value) = mrb_intern(mrb, string, len); - - value.tt = MRB_TT_SYMBOL; + SET_SYM_VALUE(value, mrb_intern(mrb, string, len)); return value; } @@ -91,6 +166,15 @@ mrb_value mrb_ext_set_ptr(struct mrb_state* mrb, void* ptr) { return value; } +mrb_data_type mrb_ext_data_type(const char* name, void (*dfree)(mrb_state *mrb, void*)) { + mrb_data_type data_type = { + .struct_name = name, + .dfree = dfree + }; + + return data_type; +} + void mrb_ext_data_init(mrb_value* value, void* ptr, const mrb_data_type* type) { mrb_data_init(*value, ptr, type); } @@ -98,8 +182,8 @@ void mrb_ext_data_init(mrb_value* value, void* ptr, const mrb_data_type* type) { mrb_value mrb_ext_class_value(struct RClass* klass) { mrb_value value; - value.value.p = klass; - value.tt = MRB_TT_CLASS; + mrb_ptr(value) = klass; + mrb_type(value) = MRB_TT_CLASS; return value; } @@ -107,8 +191,8 @@ mrb_value mrb_ext_class_value(struct RClass* klass) { mrb_value mrb_ext_module_value(struct RClass* module) { mrb_value value; - value.value.p = module; - value.tt = MRB_TT_MODULE; + mrb_ptr(value) = module; + mrb_type(value) = MRB_TT_MODULE; return value; } @@ -116,8 +200,8 @@ mrb_value mrb_ext_module_value(struct RClass* module) { mrb_value mrb_ext_data_value(struct RData* data) { mrb_value value; - value.value.p = data; - value.tt = MRB_TT_DATA; + mrb_ptr(value) = data; + mrb_type(value) = MRB_TT_DATA; return value; } @@ -126,12 +210,17 @@ void mrb_ext_set_instance_tt(struct RClass* class, enum mrb_vtype type) { MRB_SET_INSTANCE_TT(class, type); } -int mrb_ext_ary_len(struct mrb_state* mrb, mrb_value array) { - return mrb_ary_len(mrb, array); +mrb_int mrb_ext_ary_len(struct mrb_state* mrb, mrb_value array) { + return RARRAY_LEN(array); } -unsigned int mrb_ext_get_mid(struct mrb_state* mrb) { - return mrb_get_mid(mrb); +mrb_sym mrb_ext_get_mid(struct mrb_state* mrb) { + mrb_sym mid = mrb_get_mid(mrb); + if (mid == mrb_intern_lit(mrb, "new")) { + mid = mrb_intern_lit(mrb, "initialize"); + } + + return mid; } mrb_value mrb_ext_get_exc(struct mrb_state* mrb) { @@ -159,9 +248,21 @@ mrb_value mrb_ext_exc_str(struct mrb_state* mrb, mrb_value exc) { return mrb_funcall(mrb, exc, "inspect", 0); } -mrb_noreturn void mrb_ext_raise(struct mrb_state* mrb, const char* eclass, +mrb_noreturn void mrb_ext_raise_nothrow(struct mrb_state* mrb, const char* eclass, const char* msg) { - mrb_raise(mrb, mrb_class_get(mrb, eclass), msg); + + struct mrb_jmpbuf c_jmp; + struct mrb_jmpbuf *pc_jmp_bak; + pc_jmp_bak = mrb->jmp; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + mrb_raise(mrb, mrb_class_get(mrb, eclass), msg); + } + MRB_CATCH(&c_jmp) {} + MRB_END_EXC(&c_jmp); + + mrb->jmp = pc_jmp_bak; } mrb_bool mrb_ext_class_defined_under(struct mrb_state* mrb, @@ -173,10 +274,26 @@ mrb_bool mrb_ext_class_defined_under(struct mrb_state* mrb, return mrb_const_defined(mrb, mrb_obj_value(outer), mrb_symbol(sym)); } -struct RClass* mrb_ext_get_class(mrb_value value) { - return (struct RClass*) value.value.p; +struct RClass* mrb_ext_class_ptr(mrb_value value) { + return mrb_class_ptr(value); } struct RClass* mrb_ext_class(struct mrb_state* mrb, mrb_value value) { return mrb_class(mrb, value); } + +size_t mrb_ext_value_sizeof() { + return sizeof(mrb_value); +} + +size_t mrb_ext_data_type_sizeof() { + return sizeof(mrb_data_type); +} + +size_t mrb_ext_int_sizeof() { + return sizeof(mrb_int); +} + +size_t mrb_ext_float_sizeof() { + return sizeof(mrb_float); +} diff --git a/src/mruby.rs b/src/mruby.rs index 3fd50d4..5f64c4a 100644 --- a/src/mruby.rs +++ b/src/mruby.rs @@ -41,11 +41,11 @@ pub struct Mruby { pub mrb: *const MrState, ctx: *const MrContext, filename: Option, - classes: HashMap, - methods: HashMap Value>>>, - class_methods: HashMap Value>>>, - mruby_methods: HashMap Value>>>, - mruby_class_methods: HashMap Value>>>, + classes: HashMap, String, CString)>, + methods: HashMap Value>>>, + class_methods: HashMap Value>>>, + mruby_methods: HashMap Value>>>, + mruby_class_methods: HashMap Value>>>, files: HashMap>, required: HashSet } @@ -63,7 +63,7 @@ impl Mruby { unsafe { let mrb = mrb_open(); - let mruby = Rc::new(RefCell::new( + let mruby: MrubyType = Rc::new(RefCell::new( Mruby { mrb: mrb, ctx: mrbc_context_new(mrb), @@ -86,7 +86,7 @@ impl Mruby { let ptr = mrb_ext_get_ud(mrb); let mruby: MrubyType = mem::transmute(ptr); - let name = mem::uninitialized::<*const c_char>(); + let name = mem::MaybeUninit::<*const c_char>::uninit().assume_init(); let sig_str = CString::new("z").unwrap(); @@ -184,7 +184,7 @@ impl Mruby { let mruby: MrubyType = mem::transmute(ptr); mruby.run_unchecked(" - class RustPanic < Exception + class RustPanic < StandardError def initialize(message) super message end @@ -201,7 +201,7 @@ impl Mruby { let eclass_str = CString::new(eclass).unwrap(); let message_str = CString::new(message).unwrap(); - mrb_ext_raise(mrb, eclass_str.as_ptr(), message_str.as_ptr()); + mrb_ext_raise_nothrow(mrb, eclass_str.as_ptr(), message_str.as_ptr()); MrValue::nil() } @@ -312,12 +312,11 @@ pub trait MrubyImpl { /// /// match result { /// Err(MrubyError::Runtime(err)) => { - /// assert_eq!(err, "script.rb:1: undefined method \'nope\' for 1 (NoMethodError)"); + /// assert_eq!(err, "script.rb:1: undefined method \'nope\' (NoMethodError)"); /// }, /// _ => assert!(false) /// } /// ``` - #[inline] fn filename(&self, filename: &str); /// Runs mruby `script` on a state and context and returns a `Value` in an `Ok` @@ -343,12 +342,11 @@ pub trait MrubyImpl { /// /// match result { /// Err(MrubyError::Runtime(err)) => { - /// assert_eq!(err, "TypeError: expected String"); + /// assert_eq!(err, "TypeError: Fixnum cannot be converted to String"); /// }, /// _ => assert!(false) /// } /// ``` - #[inline] fn run(&self, script: &str) -> Result; /// Runs mruby `script` on a state and context and returns a `Value`. If an mruby Exception is @@ -394,7 +392,6 @@ pub trait MrubyImpl { /// assert_eq!(result.to_str().unwrap(), "surprize"); /// # } /// ``` - #[inline] unsafe fn run_unchecked(&self, script: &str) -> Value; /// Runs mruby compiled (.mrb) `script` on a state and context and returns a `Value` in an `Ok` @@ -406,7 +403,6 @@ pub trait MrubyImpl { /// let mruby = Mruby::new(); /// let result = mruby.runb(include_bytes!("script.mrb")).unwrap(); /// ``` - #[inline] fn runb(&self, script: &[u8]) -> Result; /// Runs mruby (compiled (.mrb) or not (.rb)) `script` on a state and context and returns a @@ -421,7 +417,6 @@ pub trait MrubyImpl { /// let mruby = Mruby::new(); /// let result = mruby.execute(&Path::new("script.rb")).unwrap(); /// ``` - #[inline] fn execute(&self, script: &Path) -> Result; /// Returns whether the mruby `Class` or `Module` named `name` is defined. @@ -438,7 +433,6 @@ pub trait MrubyImpl { /// assert!(object); /// assert!(!objekt); /// ``` - #[inline] fn is_defined(&self, name: &str) -> bool; /// Returns whether the mruby `Class` or `Module` named `name` is defined under `outer` `Class` @@ -456,7 +450,6 @@ pub trait MrubyImpl { /// /// assert!(mruby.is_defined_under("Mine", &module)); /// ``` - #[inline] fn is_defined_under(&self, name: &str, outer: &T) -> bool; /// Returns the mruby `Class` named `name` in a `Some` or `None` if it is not defined. @@ -473,7 +466,6 @@ pub trait MrubyImpl { /// assert_eq!(object.unwrap().to_str(), "Object"); /// assert!(objekt.is_err()); /// ``` - #[inline] fn get_class(&self, name: &str) -> Result; /// Returns the mruby `Class` named `name` under `outer` `Class` or `Module` in a `Some` or @@ -495,7 +487,6 @@ pub trait MrubyImpl { /// /// assert_eq!(result.to_str(), "Mine::Container"); /// ``` - #[inline] fn get_class_under(&self, name: &str, outer: &T) -> Result; /// Returns the mruby `Module` named `name` in a `Some` or `None` if it is not defined. @@ -512,7 +503,6 @@ pub trait MrubyImpl { /// assert_eq!(kernel.unwrap().to_str(), "Kernel"); /// assert!(kernet.is_err()); /// ``` - #[inline] fn get_module(&self, name: &str) -> Result; /// Returns the mruby `Module` named `name` under `outer` `Class` or `Module` in a `Some` or @@ -532,7 +522,6 @@ pub trait MrubyImpl { /// /// assert_eq!(result.to_str(), "Just::Mine"); /// ``` - #[inline] fn get_module_under(&self, name: &str, outer: &T) -> Result; /// Defines a dynamic file that can be `require`d containing the Rust type `T` and runs its @@ -543,6 +532,7 @@ pub trait MrubyImpl { /// ``` /// # #[macro_use] extern crate mrusty; /// use mrusty::{Mruby, MrubyFile, MrubyImpl, MrubyType}; + /// use mrusty::MrInt; /// /// # fn main() { /// let mruby = Mruby::new(); @@ -576,7 +566,6 @@ pub trait MrubyImpl { /// assert_eq!(result.to_i32().unwrap(), 3); /// # } /// ``` - #[inline] fn def_file(&self, name: &str); /// Defines an mruby `Class` named `name`. @@ -711,6 +700,7 @@ pub trait MrubyImpl { /// ``` /// # #[macro_use] extern crate mrusty; /// use mrusty::{Mruby, MrubyImpl}; + /// use mrusty::MrInt; /// /// # fn main() { /// let mruby = Mruby::new(); @@ -736,6 +726,7 @@ pub trait MrubyImpl { /// ``` /// # #[macro_use] extern crate mrusty; /// use mrusty::{Mruby, MrubyImpl}; + /// use mrusty::MrInt; /// /// # fn main() { /// let mruby = Mruby::new(); @@ -771,6 +762,7 @@ pub trait MrubyImpl { /// ``` /// # #[macro_use] extern crate mrusty; /// use mrusty::{Mruby, MrubyImpl}; + /// use mrusty::MrInt; /// /// # fn main() { /// let mruby = Mruby::new(); @@ -825,7 +817,6 @@ pub trait MrubyImpl { /// /// assert_eq!(result.to_bool().unwrap(), true); /// ``` - #[inline] fn nil(&self) -> Value; /// Creates mruby `Value` containing `true` or `false`. @@ -840,7 +831,6 @@ pub trait MrubyImpl { /// /// assert_eq!(b.to_bool().unwrap(), true); /// ``` - #[inline] fn bool(&self, value: bool) -> Value; /// Creates mruby `Value` of `Class` `Fixnum`. @@ -856,7 +846,6 @@ pub trait MrubyImpl { /// /// assert_eq!(fixn.to_i32().unwrap(), 2); /// ``` - #[inline] fn fixnum(&self, value: i32) -> Value; /// Creates mruby `Value` of `Class` `Float`. @@ -871,7 +860,6 @@ pub trait MrubyImpl { /// /// assert_eq!(fl.to_f64().unwrap(), 2.3); /// ``` - #[inline] fn float(&self, value: f64) -> Value; /// Creates mruby `Value` of `Class` `String`. @@ -886,7 +874,6 @@ pub trait MrubyImpl { /// /// assert_eq!(s.to_str().unwrap(), "hi"); /// ``` - #[inline] fn string(&self, value: &str) -> Value; /// Creates mruby `Value` of `Class` `Symbol`. @@ -901,7 +888,6 @@ pub trait MrubyImpl { /// /// assert_eq!(s.to_str().unwrap(), "hi"); /// ``` - #[inline] fn symbol(&self, value: &str) -> Value; /// Creates mruby `Value` of `Class` `name` containing a Rust object of type `T`. @@ -913,6 +899,7 @@ pub trait MrubyImpl { /// ``` /// # use mrusty::Mruby; /// # use mrusty::MrubyImpl; + /// # use mrusty::MrInt; /// let mruby = Mruby::new(); /// /// struct Cont { @@ -923,7 +910,6 @@ pub trait MrubyImpl { /// /// let value = mruby.obj(Cont { value: 3 }); /// ``` - #[inline] fn obj(&self, obj: T) -> Value; /// Creates mruby `Value` of `Class` `name` containing a Rust `Option` of type `T`. @@ -952,7 +938,6 @@ pub trait MrubyImpl { /// assert_eq!(none.call("nil?", vec![]).unwrap().to_bool().unwrap(), true); /// assert_eq!(some.value, 3); /// ``` - #[inline] fn option(&self, obj: Option) -> Value; /// Creates mruby `Value` of `Class` `Array`. @@ -975,7 +960,6 @@ pub trait MrubyImpl { /// mruby.fixnum(3) /// ]); /// ``` - #[inline] fn array(&self, value: Vec) -> Value; } @@ -1027,9 +1011,9 @@ fn get_class_for(mruby: &MrubyType, name: &str, get: F) -> Class } } - let data_type = MrDataType { name: c_name.as_ptr(), free: free:: }; + let data_type = mrb_ext_data_type(c_name.as_ptr(), free::); - mruby.borrow_mut().classes.insert(TypeId::of::(), (class, data_type, name)); + mruby.borrow_mut().classes.insert(TypeId::of::(), (class, Rc::new(data_type), name, c_name)); mruby.borrow_mut().methods.insert(TypeId::of::(), HashMap::new()); mruby.borrow_mut().class_methods.insert(TypeId::of::(), HashMap::new()); @@ -1183,10 +1167,10 @@ impl MrubyImpl for MrubyType { let ptr = data.to_ptr().unwrap(); let args = *mem::transmute::<*const u8, *const [*const u8; 3]>(ptr); - let script_len: &i32 = mem::transmute(args[1]); + let script_len: &usize = mem::transmute(args[1]); let ctx: *const MrContext = mem::transmute(args[2]); - let result = mrb_load_nstring_cxt(mrb, args[0], *script_len, ctx); + let result = mrb_ext_load_nstring_cxt_nothrow(mrb, args[0], *script_len, ctx); mrb_ext_raise_current(mrb); @@ -1210,7 +1194,7 @@ impl MrubyImpl for MrubyType { let args_ptr: *const u8 = mem::transmute(&args); let data = MrValue::ptr(mrb, args_ptr); - let state = mem::uninitialized::(); + let state = mem::MaybeUninit::::zeroed().assume_init(); let value = mrb_protect(mrb, run_protected, data, &state as *const bool); @@ -1232,7 +1216,7 @@ impl MrubyImpl for MrubyType { (borrow.mrb, borrow.ctx) }; - let value = mrb_load_nstring_cxt(mrb, script.as_ptr(), script.len() as i32, ctx); + let value = mrb_ext_load_nstring_cxt_nothrow(mrb, script.as_ptr(), script.len(), ctx); Value::new(self.clone(), value) } @@ -1246,7 +1230,7 @@ impl MrubyImpl for MrubyType { let ctx: *const MrContext = mem::transmute(args[1]); - let result = mrb_load_irep_cxt(mrb, args[0], ctx); + let result = mrb_ext_load_irep_cxt_suppress_alignment(mrb, args[0], ctx); mrb_ext_raise_current(mrb); @@ -1268,7 +1252,7 @@ impl MrubyImpl for MrubyType { let args_ptr: *const u8 = mem::transmute(&args); let data = MrValue::ptr(mrb, args_ptr); - let state = mem::uninitialized::(); + let state = mem::MaybeUninit::::zeroed().assume_init(); let value = mrb_protect(mrb, runb_protected, data, &state as *const bool); @@ -1288,18 +1272,18 @@ impl MrubyImpl for MrubyType { Some(ext) => { self.filename(script.file_name().unwrap().to_str().unwrap()); - let mut file = try!(File::open(script)); + let mut file = File::open(script)?; match ext.to_str().unwrap() { "rb" => { let mut script = String::new(); - try!(file.read_to_string(&mut script)); + file.read_to_string(&mut script)?; self.run(&script) }, "mrb" => { let mut script = Vec::new(); - try!(file.read_to_end(&mut script)); + file.read_to_end(&mut script)?; self.runb(&script) }, @@ -1396,7 +1380,7 @@ impl MrubyImpl for MrubyType { let mut borrow = self.borrow_mut(); if borrow.files.contains_key(name) { - let mut file = borrow.files.get_mut(name).unwrap(); + let file = borrow.files.get_mut(name).unwrap(); file.push(T::require); } else { @@ -1668,6 +1652,7 @@ impl Value { /// ``` /// # #[macro_use] extern crate mrusty; /// use mrusty::{Mruby, MrubyImpl}; + /// use mrusty::MrInt; /// /// # fn main() { /// let mruby = Mruby::new(); @@ -1702,7 +1687,7 @@ impl Value { None => panic!("Class not found.") }; - let data_type = &class.1; + let data_type = &*class.1; mrb_ext_data_init(&self.value as *const MrValue, ptr, data_type as *const MrDataType); } @@ -1730,12 +1715,12 @@ impl Value { let ptr = data.to_ptr().unwrap(); let args = *mem::transmute::<*const u8, *const [*const u8; 4]>(ptr); - let value: MrValue = mem::transmute_copy(&*args[0]); + let value: &MrValue = mem::transmute(args[0]); let sym: &u32 = mem::transmute(args[1]); - let argc: &i32 = mem::transmute(args[2]); + let argc: &MrInt = mem::transmute(args[2]); let argv: *const MrValue = mem::transmute(args[3]); - let result = mrb_funcall_argv(mrb, value, *sym, *argc, argv); + let result = mrb_funcall_argv(mrb, *value, *sym, *argc, argv); mrb_ext_raise_current(mrb); @@ -1753,15 +1738,15 @@ impl Value { let value_ptr: *const u8 = mem::transmute(&self.value); let sym_ptr: *const u8 = mem::transmute(&sym); - let argc = args.len(); - let argc_ptr: * const u8 = mem::transmute(&argc); + let argc = args.len() as MrInt; + let argc_ptr: *const u8 = mem::transmute(&argc); let argv_ptr: *const u8 = mem::transmute(args.as_ptr()); let args = [value_ptr, sym_ptr, argc_ptr, argv_ptr]; let args_ptr: *const u8 = mem::transmute(&args); let data = MrValue::ptr(mrb, args_ptr); - let state = mem::uninitialized::(); + let state = mem::MaybeUninit::::zeroed().assume_init(); let value = mrb_protect(mrb, call_protected, data, &state as *const bool); @@ -1801,7 +1786,7 @@ impl Value { let args: Vec = args.iter().map(|value| value.value).collect(); let result = mrb_funcall_argv(self.mruby.borrow().mrb, self.value, sym, - args.len() as i32, args.as_ptr()); + args.len() as MrInt, args.as_ptr()); Value::new(self.mruby.clone(), result) } @@ -1900,7 +1885,7 @@ impl Value { /// ``` #[inline] pub fn set_var(&self, name: &str, value: Value) { - match self.value.typ { + match self.value.typ() { MrType::MRB_TT_OBJECT | MrType::MRB_TT_CLASS | MrType::MRB_TT_MODULE | @@ -2111,7 +2096,7 @@ impl Value { /// ``` #[inline] pub fn to_option(&self) -> Result>>, MrubyError> { - if self.value.typ == MrType::MRB_TT_DATA { + if self.value.typ() == MrType::MRB_TT_DATA { self.to_obj::().map(|obj| Some(obj)) } else { Ok(None) @@ -2162,7 +2147,7 @@ impl Value { #[inline] pub fn to_class(&self) -> Result { unsafe { - let class = try!(self.value.to_class()); + let class = self.value.to_class()?; Ok(Class::new(self.mruby.clone(), class)) } @@ -2183,7 +2168,7 @@ impl Value { #[inline] pub fn to_module(&self) -> Result { unsafe { - let module = try!(self.value.to_module()); + let module = self.value.to_module()?; Ok(Module::new(self.mruby.clone(), module)) } @@ -2194,13 +2179,11 @@ use std::fmt; impl Clone for Value { fn clone(&self) -> Value { - if self.value.typ == MrType::MRB_TT_DATA { + if self.value.typ() == MrType::MRB_TT_DATA { unsafe { let ptr = mrb_ext_data_ptr(self.value); let rc: Rc = mem::transmute(ptr); - rc.clone(); - mem::forget(rc); } } diff --git a/src/mruby/get_mruby.sh b/src/mruby/get_mruby.sh index 43b35c1..980e983 100755 --- a/src/mruby/get_mruby.sh +++ b/src/mruby/get_mruby.sh @@ -14,7 +14,7 @@ # * compile, linker & archiver # * unzip -VERSION=1.2.0 +VERSION=2.1.0 CURRENT=$PWD # Checks is /tmp/mruby needs cleaning or creation. @@ -46,14 +46,14 @@ cp -R include ../mruby-out # Adds src and C-compiled mrblib. cp src/*.c ../mruby-out/src -cp src/*.h ../mruby-out/src +cp src/*.h ../mruby-out/include cp build/host/mrblib/mrblib.c ../mruby-out/src/mrblib/mrblib.c # Removes incompatible files. -find mrbgems -type f ! -name "*.c" -and ! -name "*.h" -and ! -name "*.def" -delete +find mrbgems -type f ! -name "*.c" -and ! -name "*.h" -and ! -name "*.def" -and ! -name "*.cstub" -delete find mrbgems -type d -empty -delete -find build/host/mrbgems -type f ! -name "*.c" -and ! -name "*.h" -delete +find build/host/mrbgems -type f ! -name "*.c" -and ! -name "*.h" -and ! -name "*.cstub" -delete find build/host/mrbgems -type d -empty -delete # Removes incompatible gems. @@ -69,6 +69,12 @@ rm -rf build/host/mrbgems/mruby-test cp -R mrbgems/* ../mruby-out/src/mrbgems cp -R build/host/mrbgems/* ../mruby-out/src/mrbgems +# Copies header files. + +mkdir -p ../mruby-out/include/mruby/ext +find mrbgems -path '*/include/mruby/ext/*' -name '*.h' -exec cp {} ../mruby-out/include/mruby/ext \; +find mrbgems -path '*/include/mruby/*' -name '*.h' -exec cp {} ../mruby-out/include/mruby \; + cd .. tar -cf $CURRENT/mruby-out.tar mruby-out diff --git a/src/mruby/mruby-out.tar b/src/mruby/mruby-out.tar index 032a0c9..19ca081 100644 Binary files a/src/mruby/mruby-out.tar and b/src/mruby/mruby-out.tar differ diff --git a/src/mruby_ffi.rs b/src/mruby_ffi.rs index 31fab80..a15e3e5 100644 --- a/src/mruby_ffi.rs +++ b/src/mruby_ffi.rs @@ -9,7 +9,7 @@ use std::any::Any; use std::cell::RefCell; use std::ffi::CStr; use std::mem; -use std::os::raw::c_char; +use std::os::raw::{c_char, c_uchar}; use std::rc::Rc; use super::MrubyError; @@ -21,20 +21,22 @@ pub enum MrClass {} pub enum MrData {} pub type MrFunc = extern "C" fn(*const MrState, MrValue) -> MrValue; +pub type MrDfree = extern "C" fn(*const MrState, *const u8); + +pub type MrFloat = f64; +pub type MrInt = i64; #[repr(C)] pub struct MrDataType { - pub name: *const c_char, - pub free: extern "C" fn(*const MrState, *const u8) + _buf: [u8; 16] } /// Not meant to be called directly. #[doc(hidden)] #[repr(C)] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Eq, PartialEq)] pub struct MrValue { - pub value: u64, - pub typ: MrType, + _buf: [u8; 16] } impl MrValue { @@ -54,12 +56,12 @@ impl MrValue { #[inline] pub unsafe fn fixnum(value: i32) -> MrValue { - mrb_ext_cint_to_fixnum(value) + mrb_ext_cint_to_fixnum(value as MrInt) } #[inline] pub unsafe fn float(mrb: *const MrState, value: f64) -> MrValue { - mrb_ext_cdouble_to_float(mrb, value) + mrb_ext_cdouble_to_float(mrb, value as MrFloat) } #[inline] @@ -84,10 +86,10 @@ impl MrValue { #[inline] pub unsafe fn array(mrb: *const MrState, value: Vec) -> MrValue { - let array = mrb_ary_new_capa(mrb, value.len() as i32); + let array = mrb_ary_new_capa(mrb, value.len() as MrInt); for (i, value) in value.iter().enumerate() { - mrb_ary_set(mrb, array, i as i32, *value); + mrb_ary_set(mrb, array, i as MrInt, *value); } array @@ -100,7 +102,7 @@ impl MrValue { #[inline] pub unsafe fn to_bool<'a>(&self) -> Result { - match self.typ { + match self.typ() { MrType::MRB_TT_FALSE => Ok(false), MrType::MRB_TT_TRUE => Ok(true), _ => Err(MrubyError::Cast("TrueClass or FalseClass".to_owned())) @@ -109,9 +111,9 @@ impl MrValue { #[inline] pub unsafe fn to_i32(&self) -> Result { - match self.typ { + match self.typ() { MrType::MRB_TT_FIXNUM => { - Ok(mrb_ext_fixnum_to_cint(*self)) + Ok(mrb_ext_fixnum_to_cint(*self) as i32) }, _ => Err(MrubyError::Cast("Fixnum".to_owned())) } @@ -119,9 +121,9 @@ impl MrValue { #[inline] pub unsafe fn to_f64(&self) -> Result { - match self.typ { + match self.typ() { MrType::MRB_TT_FLOAT => { - Ok(mrb_ext_float_to_cdouble(*self)) + Ok(mrb_ext_float_to_cdouble(*self) as f64) }, _ => Err(MrubyError::Cast("Float".to_owned())) } @@ -129,14 +131,14 @@ impl MrValue { #[inline] pub unsafe fn to_str<'a>(&self, mrb: *const MrState) -> Result<&'a str, MrubyError> { - match self.typ { + match self.typ() { MrType::MRB_TT_STRING => { - let s = mrb_str_to_cstr(mrb, *self) as *const i8; + let s = mrb_str_to_cstr(mrb, *self); Ok(CStr::from_ptr(s).to_str().unwrap().clone()) }, MrType::MRB_TT_SYMBOL => { - let s = mrb_ext_sym2name(mrb, *self) as *const i8; + let s = mrb_ext_sym2name(mrb, *self); Ok(CStr::from_ptr(s).to_str().unwrap().clone()) }, @@ -147,9 +149,9 @@ impl MrValue { #[inline] pub unsafe fn to_obj(&self, mrb: *const MrState, typ: &MrDataType) -> Result>, MrubyError> { - match self.typ { + match self.typ() { MrType::MRB_TT_DATA => { - let ptr = mrb_data_get_ptr(mrb, *self, typ as *const MrDataType) as *const u8; + let ptr = mrb_data_get_ptr(mrb, *self, typ as *const MrDataType); let rc: Rc> = mem::transmute(ptr); let result = Ok(rc.clone()); @@ -164,13 +166,13 @@ impl MrValue { #[inline] pub unsafe fn to_vec(&self, mrb: *const MrState) -> Result, MrubyError> { - match self.typ { + match self.typ() { MrType::MRB_TT_ARRAY => { - let len = mrb_ext_ary_len(mrb, *self) as usize; - let mut vec = Vec::with_capacity(len); + let len = mrb_ext_ary_len(mrb, *self); + let mut vec = Vec::with_capacity(len as usize); for i in 0..len { - vec.push(mrb_ary_ref(mrb, *self, i as i32)); + vec.push(mrb_ary_ref(mrb, *self, i as MrInt)); } Ok(vec) @@ -181,9 +183,9 @@ impl MrValue { #[inline] pub unsafe fn to_class(&self) -> Result<*const MrClass, MrubyError> { - match self.typ { + match self.typ() { MrType::MRB_TT_CLASS => { - Ok(mrb_ext_get_class(*self)) + Ok(mrb_ext_class_ptr(*self)) }, _ => Err(MrubyError::Cast("Class".to_owned())) } @@ -191,9 +193,9 @@ impl MrValue { #[inline] pub unsafe fn to_module(&self) -> Result<*const MrClass, MrubyError> { - match self.typ { + match self.typ() { MrType::MRB_TT_MODULE => { - Ok(mrb_ext_get_class(*self)) + Ok(mrb_ext_class_ptr(*self)) }, _ => Err(MrubyError::Cast("Module".to_owned())) } @@ -201,27 +203,48 @@ impl MrValue { #[inline] pub unsafe fn to_ptr(&self) -> Result<*const u8, MrubyError> { - match self.typ { + match self.typ() { MrType::MRB_TT_CPTR => { Ok(mrb_ext_get_ptr(*self)) }, _ => Err(MrubyError::Cast("Pointer".to_owned())) } } + + #[inline] + pub fn typ(&self) -> MrType { + unsafe { mrb_ext_type(*self) } + } +} + +use std::fmt; + +impl fmt::Debug for MrValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + unsafe { + write!(f, "p:{:?}, f:{}, i:{}, sym:{}, typ:{:?}", + mrb_ext_ptr_to_ptr(*self), + mrb_ext_float_to_cdouble(*self), + mrb_ext_fixnum_to_cint(*self), + mrb_ext_symbol_to_cuint(*self), + self.typ()) + } + } } #[allow(dead_code)] +#[allow(non_camel_case_types)] #[repr(C)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum MrType { MRB_TT_FALSE, - MRB_TT_FREE, MRB_TT_TRUE, + MRB_TT_FLOAT, MRB_TT_FIXNUM, MRB_TT_SYMBOL, MRB_TT_UNDEF, - MRB_TT_FLOAT, MRB_TT_CPTR, + MRB_TT_FREE, MRB_TT_OBJECT, MRB_TT_CLASS, MRB_TT_MODULE, @@ -237,6 +260,8 @@ pub enum MrType { MRB_TT_ENV, MRB_TT_DATA, MRB_TT_FIBER, + MRB_TT_ISTRUCT, + MRB_TT_BREAK, MRB_TT_MAXDEFINE } @@ -244,9 +269,7 @@ extern "C" { pub fn mrb_open() -> *const MrState; pub fn mrb_close(mrb: *const MrState); - #[inline] pub fn mrb_ext_get_ud(mrb: *const MrState) -> *const u8; - #[inline] pub fn mrb_ext_set_ud(mrb: *const MrState, ud: *const u8); pub fn mrbc_context_new(mrb: *const MrState) -> *const MrContext; @@ -255,9 +278,9 @@ extern "C" { pub fn mrbc_filename(mrb: *const MrState, context: *const MrContext, filename: *const c_char) -> *const c_char; - pub fn mrb_load_nstring_cxt(mrb: *const MrState, code: *const u8, len: i32, + pub fn mrb_ext_load_nstring_cxt_nothrow(mrb: *const MrState, code: *const c_uchar, len: usize, context: *const MrContext) -> MrValue; - pub fn mrb_load_irep_cxt(mrb: *const MrState, code: *const u8, + pub fn mrb_ext_load_irep_cxt_suppress_alignment(mrb: *const MrState, code: *const c_uchar, context: *const MrContext) -> MrValue; pub fn mrb_class_defined(mrb: *const MrState, name: *const c_char) -> bool; @@ -297,86 +320,67 @@ extern "C" { pub fn mrb_protect(mrb: *const MrState, fun: MrFunc, data: MrValue, state: *const bool) -> MrValue; - #[inline] pub fn mrb_ext_class(mrb: *const MrState, value: MrValue) -> *const MrClass; - pub fn mrb_get_args(mrb: *const MrState, format: *const c_char, ...); + pub fn mrb_get_args(mrb: *const MrState, format: *const c_char, ...) -> MrInt; pub fn mrb_ext_get_mid(mrb: *const MrState) -> u32; pub fn mrb_intern(mrb: *const MrState, string: *const c_char, len: usize) -> u32; - pub fn mrb_funcall_argv(mrb: *const MrState, object: MrValue, sym: u32, argc: i32, + // *const MrValue is MrValue array + pub fn mrb_funcall_argv(mrb: *const MrState, object: MrValue, sym: u32, argc: MrInt, argv: *const MrValue) -> MrValue; - #[inline] pub fn mrb_iv_defined(mrb: *const MrState, object: MrValue, sym: u32) -> bool; - #[inline] pub fn mrb_iv_get(mrb: *const MrState, object: MrValue, sym: u32) -> MrValue; - #[inline] pub fn mrb_iv_set(mrb: *const MrState, object: MrValue, sym: u32, value: MrValue); - #[inline] - pub fn mrb_ext_fixnum_to_cint(value: MrValue) -> i32; - #[inline] - pub fn mrb_ext_float_to_cdouble(value: MrValue) -> f64; + pub fn mrb_ext_fixnum_to_cint(value: MrValue) -> MrInt; + pub fn mrb_ext_float_to_cdouble(value: MrValue) -> MrFloat; + pub fn mrb_ext_ptr_to_ptr(value: MrValue) -> *const u8; + pub fn mrb_ext_symbol_to_cuint(value: MrValue) -> u32; + pub fn mrb_ext_type(value: MrValue) -> MrType; - #[inline] pub fn mrb_ext_nil() -> MrValue; - #[inline] pub fn mrb_ext_false() -> MrValue; - #[inline] pub fn mrb_ext_true() -> MrValue; - #[inline] - pub fn mrb_ext_cint_to_fixnum(value: i32) -> MrValue; - #[inline] - pub fn mrb_ext_cdouble_to_float(mrb: *const MrState, value: f64) -> MrValue; - #[inline] - pub fn mrb_str_new(mrb: *const MrState, value: *const u8, len: usize) -> MrValue; - #[inline] - pub fn mrb_ext_sym2name(mrb: *const MrState, value: MrValue) -> *const u8; - #[inline] - pub fn mrb_ext_sym_new(mrb: *const MrState, value: *const u8, len: usize) -> MrValue; - #[inline] + pub fn mrb_ext_cint_to_fixnum(value: MrInt) -> MrValue; + pub fn mrb_ext_cdouble_to_float(mrb: *const MrState, value: MrFloat) -> MrValue; + pub fn mrb_str_new(mrb: *const MrState, value: *const c_uchar, len: usize) -> MrValue; + pub fn mrb_ext_sym2name(mrb: *const MrState, value: MrValue) -> *const c_char; + pub fn mrb_ext_sym_new(mrb: *const MrState, value: *const c_uchar, len: usize) -> MrValue; pub fn mrb_ext_get_ptr(value: MrValue) -> *const u8; - #[inline] pub fn mrb_ext_set_ptr(mrb: *const MrState, ptr: *const u8) -> MrValue; - #[inline] + pub fn mrb_ext_data_type(name: *const c_char, dfree: MrDfree) -> MrDataType; + pub fn mrb_str_to_cstr(mrb: *const MrState, value: MrValue) -> *const c_char; - #[inline] pub fn mrb_data_object_alloc(mrb: *const MrState, class: *const MrClass, ptr: *const u8, typ: *const MrDataType) -> *const MrData; - #[inline] pub fn mrb_data_get_ptr(mrb: *const MrState, value: MrValue, typ: *const MrDataType) -> *const u8; - #[inline] pub fn mrb_ext_data_ptr(value: MrValue) -> *const u8; - #[inline] pub fn mrb_ext_data_init(value: *const MrValue, ptr: *const u8, typ: *const MrDataType); - #[inline] pub fn mrb_ext_set_instance_tt(class: *const MrClass, typ: MrType); - #[inline] pub fn mrb_ext_data_value(data: *const MrData) -> MrValue; - pub fn mrb_ary_new_capa(mrb: *const MrState, size: i32) -> MrValue; - #[inline] - pub fn mrb_ary_ref(mrb: *const MrState, array: MrValue, i: i32) -> MrValue; - #[inline] - pub fn mrb_ary_set(mrb: *const MrState, array: MrValue, i: i32, value: MrValue); - #[inline] - pub fn mrb_ext_ary_len(mrb: *const MrState, array: MrValue) -> i32; + pub fn mrb_ary_new_capa(mrb: *const MrState, size: MrInt) -> MrValue; + pub fn mrb_ary_ref(mrb: *const MrState, array: MrValue, i: MrInt) -> MrValue; + pub fn mrb_ary_set(mrb: *const MrState, array: MrValue, i: MrInt, value: MrValue); + pub fn mrb_ext_ary_len(mrb: *const MrState, array: MrValue) -> MrInt; - #[inline] - pub fn mrb_ext_raise(mrb: *const MrState, eclass: *const c_char, msg: *const c_char); - #[inline] + pub fn mrb_ext_raise_nothrow(mrb: *const MrState, eclass: *const c_char, msg: *const c_char); pub fn mrb_ext_raise_current(mrb: *const MrState); - #[inline] pub fn mrb_ext_exc_str(mrb: *const MrState, exc: MrValue) -> MrValue; - #[inline] - pub fn mrb_ext_get_class(class: MrValue) -> *const MrClass; + pub fn mrb_ext_class_ptr(class: MrValue) -> *const MrClass; + + pub fn mrb_ext_value_sizeof() -> usize; + pub fn mrb_ext_data_type_sizeof() -> usize; + pub fn mrb_ext_int_sizeof() -> usize; + pub fn mrb_ext_float_sizeof() -> usize; } diff --git a/src/repl.rs b/src/repl.rs index fee169f..0bbafd9 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -75,7 +75,7 @@ impl Repl { /// /// repl.start(&GnuReadLine); /// ``` - pub fn start(&self, read_line: &ReadLine) { + pub fn start(&self, read_line: &dyn ReadLine) { let mut command = String::new(); let single = self.name.clone() + "> "; @@ -101,7 +101,7 @@ impl Repl { }; if input.ends_with("\\") { - let trimmed = input.trim_right_matches("\\"); + let trimmed = input.trim_end_matches("\\"); command = command + trimmed + "\n"; read_line.add(&trimmed); diff --git a/src/spec.rs b/src/spec.rs index df5ce3a..207956b 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -308,8 +308,8 @@ mod tests { end it 'does not concatenate with String' do - expect { '' + 1 }.to raise_error TypeError, \"expected String\" - expect { 1 + '' }.not_to raise_error Exception + expect { '' + 1 }.to raise_error TypeError, \"Fixnum cannot be converted to String\" + expect { 1 + '' }.to raise_error TypeError, \"non float value\" end it { is_expected.to respond_to :to_s } diff --git a/src/tests/mruby_ffi.rs b/src/tests/mruby_ffi.rs index 20291e0..980ca97 100644 --- a/src/tests/mruby_ffi.rs +++ b/src/tests/mruby_ffi.rs @@ -42,14 +42,41 @@ fn exec_bin_context() { let mrb = mrb_open(); let context = mrbc_context_new(mrb); - let bin = [82u8, 73u8, 84u8, 69u8, 48u8, 48u8, 48u8, 51u8, 107u8, 70u8, 0u8, 0u8, 0u8, - 72u8, 77u8, 65u8, 84u8, 90u8, 48u8, 48u8, 48u8, 48u8, 73u8, 82u8, 69u8, 80u8, - 0u8, 0u8, 0u8, 42u8, 48u8, 48u8, 48u8, 48u8, 0u8, 0u8, 0u8, 34u8, 0u8, 1u8, 0u8, - 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 192u8, 0u8, 131u8, 0u8, 0u8, 0u8, 74u8, - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 69u8, 78u8, 68u8, 0u8, 0u8, 0u8, 0u8, - 8u8]; - - let result = mrb_load_irep_cxt(mrb, bin.as_ptr(), context); + let bin = [ + // struct rite_binary_header + 69u8, 84u8, 73u8, 82u8, // Binary identifier "RITE" + 48u8, 48u8, 48u8, 54u8, // Binary format version "0006" + 204u8, 148u8, // Binary CRC + 0u8, 0u8, 0u8, 69u8, // Binary size + 77u8, 65u8, 84u8, 90u8, // Compiler name "MATZ" + 48u8, 48u8, 48u8, 48u8, // Compiler version "0000" + + // struct rite_section_irep_header + 73u8, 82u8, 69u8, 80u8, // section_ident "IREP" + 0u8, 0u8, 0u8, 39u8, // section_size + 48u8, 48u8, 48u8, 50u8, // rite_version "0002" + + // irep record + 0u8, 0u8, 0u8, 46u8, // record size + 0u8, 1u8, // number of local variable + 0u8, 2u8, // number of register variable + 0u8, 0u8, // number of child irep + + // ISEQ BLOCK + 0u8, 0u8, 0u8, 5u8, // number of iseq + // skip_padding target(nothing) + 8u8, 1u8, 55u8, 1u8, 103u8, // mrb_code * number of iseq + + // POOL BLOCK + 0u8, 0u8, 0u8, 0u8, // number of pool + + // SYMS BLOCK + 0u8, 0u8, 0u8, 0u8, // syms length + + 69u8, 78u8, 68u8, 0u8, // RITE_BINARY_EOF "END\0" + 0u8, 0u8, 0u8, 8u8]; + + let result = mrb_ext_load_irep_cxt_suppress_alignment(mrb, bin.as_ptr(), context); assert_eq!(result.to_i32().unwrap(), 2); @@ -94,7 +121,7 @@ fn define_method() { let code = "Mine.new.job"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context).to_i32().unwrap(), 2); + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context).to_i32().unwrap(), 2); mrbc_context_free(mrb, context); mrb_close(mrb); @@ -276,7 +303,7 @@ fn include_module() { let code = "module Increment; def inc; self + 1; end; end"; - mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context); + mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context); let fixnum_str = CString::new("Fixnum").unwrap(); let fixnum = mrb_class_get(mrb, fixnum_str.as_ptr()); @@ -287,7 +314,7 @@ fn include_module() { let code = "1.inc"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_i32().unwrap(), 2); mrbc_context_free(mrb, context); @@ -318,7 +345,7 @@ fn define_class_method() { let code = "Mine.job"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_i32().unwrap(), 2); mrbc_context_free(mrb, context); @@ -345,12 +372,12 @@ fn define_constant() { let code = "Object::ONE"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_i32().unwrap(), 1); let code = "Kernel::ONE"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_i32().unwrap(), 1); mrbc_context_free(mrb, context); @@ -379,7 +406,7 @@ fn define_module_function() { let code = "hi"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_str(mrb).unwrap(), "hi"); mrbc_context_free(mrb, context); @@ -389,25 +416,42 @@ fn define_module_function() { #[test] fn protect() { - use std::mem::uninitialized; + use std::mem::MaybeUninit; unsafe { let mrb = mrb_open(); + let ctx = mrbc_context_new(mrb); - extern "C" fn job(mrb: *const MrState, _data: MrValue) -> MrValue { + extern "C" fn run_protected(mrb: *const MrState, data: MrValue) -> MrValue { unsafe { - let runtime_str = CString::new("RuntimeError").unwrap(); - let excepting_str = CString::new("excepting").unwrap(); + let ptr = data.to_ptr().unwrap(); + let args = *mem::transmute::<*const u8, *const [*const u8; 3]>(ptr); + + let script = args[0]; + let script_len: &usize = mem::transmute(args[1]); + let ctx: *const MrContext = mem::transmute(args[2]); + + let result = mrb_ext_load_nstring_cxt_nothrow(mrb, script, *script_len, ctx); - mrb_ext_raise(mrb, runtime_str.as_ptr(), excepting_str.as_ptr()); + mrb_ext_raise_current(mrb); - MrValue::nil() + result } } - let state = uninitialized::(); + let script = "false 'surprize'"; + let script_ptr = script.as_ptr(); + let script_len = script.len(); + let script_len_ptr: *const u8 = mem::transmute(&script_len); + let ctx_ptr: *const u8 = mem::transmute(ctx); + + let args = [script_ptr, script_len_ptr, ctx_ptr]; + let args_ptr: *const u8 = mem::transmute(&args); + let data = MrValue::ptr(mrb, args_ptr); + + let state = MaybeUninit::::zeroed().assume_init(); - let exc = mrb_protect(mrb, job, MrValue::nil(), &state as *const bool); + let exc = mrb_protect(mrb, run_protected, data, &state as *const bool); assert_eq!(state, true); @@ -421,15 +465,16 @@ fn protect() { let class = mrb_funcall_argv(mrb, exc, class_sym, 0, args.as_ptr()); let result = mrb_funcall_argv(mrb, class, to_s_sym, 0, args.as_ptr()); - assert_eq!(result.to_str(mrb).unwrap(), "RuntimeError"); + assert_eq!(result.to_str(mrb).unwrap(), "SyntaxError"); + mrbc_context_free(mrb, ctx); mrb_close(mrb); } } #[test] pub fn args() { - use std::mem::uninitialized; + use std::mem::MaybeUninit; unsafe { let mrb = mrb_open(); @@ -437,8 +482,8 @@ pub fn args() { extern "C" fn add(mrb: *const MrState, _slf: MrValue) -> MrValue { unsafe { - let a = uninitialized::(); - let b = uninitialized::(); + let a = MaybeUninit::::uninit().assume_init(); + let b = MaybeUninit::::uninit().assume_init(); let sig_str = CString::new("oo").unwrap(); @@ -467,7 +512,7 @@ pub fn args() { let code = "Mine.new.add 1, 1"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_i32().unwrap(), 2); mrbc_context_free(mrb, context); @@ -478,7 +523,7 @@ pub fn args() { #[test] pub fn str_args() { use std::ffi::CStr; - use std::mem::uninitialized; + use std::mem::MaybeUninit; use std::os::raw::c_char; unsafe { @@ -487,8 +532,8 @@ pub fn str_args() { extern "C" fn add(mrb: *const MrState, _slf: MrValue) -> MrValue { unsafe { - let a = uninitialized::<*const c_char>(); - let b = uninitialized::<*const c_char>(); + let a = MaybeUninit::<*const c_char>::uninit().assume_init(); + let b = MaybeUninit::<*const c_char>::uninit().assume_init(); let sig_str = CString::new("zz").unwrap(); @@ -520,7 +565,7 @@ pub fn str_args() { let code = "Mine.new.add 'a', 'b'"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_str(mrb).unwrap(), "ab"); mrbc_context_free(mrb, context); @@ -530,7 +575,7 @@ pub fn str_args() { #[test] pub fn array_args() { - use std::mem::uninitialized; + use std::mem::MaybeUninit; unsafe { let mrb = mrb_open(); @@ -538,7 +583,7 @@ pub fn array_args() { extern "C" fn add(mrb: *const MrState, _slf: MrValue) -> MrValue { unsafe { - let array = uninitialized::(); + let array = MaybeUninit::::uninit().assume_init(); let a_str = CString::new("A").unwrap(); @@ -568,7 +613,7 @@ pub fn array_args() { let code = "Mine.new.add [1, 1]"; - assert_eq!(mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + assert_eq!(mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_i32().unwrap(), 2); mrbc_context_free(mrb, context); @@ -611,7 +656,7 @@ fn iv() { let one = MrValue::fixnum(1); let code = "Mine.new"; - let obj = mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context); + let obj = mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context); let value_str = CString::new("value").unwrap(); @@ -724,7 +769,7 @@ fn obj() { } } - let data_type = MrDataType { name: cont_str.as_ptr(), free: free }; + let data_type = mrb_ext_data_type(cont_str.as_ptr(), free); let obj = Cont { value: 3 }; let obj = MrValue::obj(mrb, cont_class, obj, &data_type); @@ -789,7 +834,7 @@ fn obj_init() { } } - let data_type = &MrDataType { name: cont_str.as_ptr(), free: free }; + let data_type = &mrb_ext_data_type(cont_str.as_ptr(), free); mrb_ext_set_ud(mrb, mem::transmute::<&MrDataType, *const u8>(data_type)); @@ -802,7 +847,7 @@ fn obj_init() { 1 << 12); let code = "Cont.new.value"; - let val = mrb_load_nstring_cxt(mrb, code.as_ptr(), code.len() as i32, context) + let val = mrb_ext_load_nstring_cxt_nothrow(mrb, code.as_ptr(), code.len(), context) .to_i32().unwrap(); assert_eq!(val, 3); @@ -848,7 +893,7 @@ fn obj_scoping() { } } - let data_type = MrDataType { name: cont_str.as_ptr(), free: free }; + let data_type = mrb_ext_data_type(cont_str.as_ptr(), free); { let orig = Cont { value: 3 }; diff --git a/tests/api.rs b/tests/api.rs index 5610778..f9d38d0 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -11,6 +11,8 @@ extern crate mrusty; use std::path::Path; use mrusty::{Mruby, MrubyFile, MrubyImpl}; +use mrusty::{MrValue, MrDataType, MrInt, MrFloat}; +use mrusty::{mrb_ext_value_sizeof, mrb_ext_data_type_sizeof, mrb_ext_int_sizeof, mrb_ext_float_sizeof}; mod example; @@ -206,6 +208,57 @@ fn api_mruby_class() { assert_eq!(result.to_f64().unwrap(), 3.0); } +#[test] +fn api_mruby_panic() { + let mruby = Mruby::new(); + + Scalar::require(mruby.clone()); + + let result = mruby.run(r#" + s = Scalar.new 0.0 + str = 'start' + begin + str = 'begin' + s.panic + str = 'Oh, not throwed' + rescue => e + str = 'rescued' + end + + str + "#).unwrap(); + + assert_eq!(result.to_str().unwrap(), "rescued"); +} + +#[test] +fn api_mrb_sizeof() { + { + let csize = unsafe { mrb_ext_value_sizeof() }; + let rsize = std::mem::size_of::(); + + assert_eq!(csize, rsize); + } + { + let csize = unsafe { mrb_ext_data_type_sizeof() }; + let rsize = std::mem::size_of::(); + + assert_eq!(csize, rsize); + } + { + let csize = unsafe { mrb_ext_float_sizeof() }; + let rsize = std::mem::size_of::(); + + assert_eq!(csize, rsize); + } + { + let csize = unsafe { mrb_ext_int_sizeof() }; + let rsize = std::mem::size_of::(); + + assert_eq!(csize, rsize); + } +} + describe!(Scalar, " context 'when zero' do let(:zero) { Scalar.new 0 } diff --git a/tests/compiled.mrb b/tests/compiled.mrb index 86bacd2..091bdb7 100644 Binary files a/tests/compiled.mrb and b/tests/compiled.mrb differ diff --git a/tests/example/scalar.rs b/tests/example/scalar.rs index 95c2ffb..5ac4811 100644 --- a/tests/example/scalar.rs +++ b/tests/example/scalar.rs @@ -6,6 +6,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use mrusty::MrubyImpl; +use mrusty::MrFloat; use super::Vector; diff --git a/tests/example/vector.rs b/tests/example/vector.rs index 8700304..4d45b69 100644 --- a/tests/example/vector.rs +++ b/tests/example/vector.rs @@ -6,6 +6,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use mrusty::MrubyImpl; +use mrusty::MrFloat; use super::Scalar;