I'm currently writing a wrapper for mruby and things went pretty well until now.
Basically all Rust objects (structs or enums) are sent to mruby and wrapped in mruby objects. The way I'm doing this is I'm sendingRcs to mruby by transmuting them to void pointers. What I'm trying to do is just keep a reference to how many strong rerefences I have to that Rust object, and Rc seems to be great for the task. mruby has a free callback where I'm getting back the objects. In that callback I'm reclaiming the Rc back to Rust with transmute.
The problem arises when I initialize one of these objects from mruby and call a method on it.
let mruby = MRuby::new();
struct Cont {
value: i32
}
mruby.def_class::<Cont>("Container");
mruby.def_method("Container", "initialize", mrfn!(|mruby, slf, v: i32| {
let cont = Cont { value: v };
slf.init("Container", cont)
}));
mruby.def_method("Container", "value", mrfn!(|mruby, slf| {
let cont = slf.to_obj::<Cont>("Container").unwrap();
mruby.fixnum(cont.value)
}));
let obj = mruby.run("Container.new(3)").unwrap();
let val = obj.call("value", vec![]);
This gets panicked at 'arithmetic operation overflowed', src/liballoc/rc.rs:866 because the number of strong references (which is 0; I don't really see why) gets decremented.
I can't really see what I'm doing wrong. Can anyone see what I'm doing wrong? Is there any better way of doing this?
[quote="dragostis, post:3, topic:4723"]
By using def_class<T>, you can only define free<T> for that particular mruby class.
[/quote]I don't see anything tying T to name there.
Not to name, but to T. Of course, if you mix name up with a wrong T, it will wreak havoc. I don't think you can link them somehow. I need to use name in order to get the closures from MRuby's HashMap and I can't use T as a key to it.
[quote="dragostis, post:5, topic:4723"]
Of course, if you mix name up with a wrong T, it will wreak havoc.
[/quote]An API with such properties must be marked unsafe.
I don't really see how I could use Any here. I could build some pattern matchers with all the Rust types that I want to use and then use Anys but that seems overly complicated. But then again, I probably can't see what you're aiming at.
I don't see why the Rust types that I'm sending to mruby should be 'static either.
[quote="dragostis, post:9, topic:4723"]
I don't really see how I could use Any here. I could build some pattern matchers with all the Rust types that I want to use and then use Anys but that seems overly complicated. But then again, I probably can't see what you're aiming at.
[/quote]An immediate application is you can get rid of name and index the classes map by TypeId.
[quote="dragostis, post:9, topic:4723"]
I don't see why the Rust types that I'm sending to mruby should be 'static either.
[/quote]Shared ownership (e.g. Rc) often implies you don't know in any one place how long the value is going to live. But you can't allow the Rc to outlive any references T could have borrowed. A conservative solution is requiring T: 'static i.e. not hold any non-static references.
@pnkfelix has been doing a lot of work on how Rust can integrate with external garbage collectors, regardless of what's done in the meantime, this should help a LOT in the future.
Well, I've fixed the issue in the meantime. I forgot to mem::forget a transmuted Rc. I'm implementing the Any design right now.
I'm not yet done with some of the basics. I still have a few important things to solve and I'll update the README.md on how to build mruby. I'm not sure we can do an automatic build though, since mruby requires Ruby to compile (it relies on cross-compilation for embedded functionality). It's probably not so complicated to do a build script for mruby using gcc, though.