Skip to content
This repository has been archived by the owner on Jan 3, 2020. It is now read-only.

Commit

Permalink
Implement Clone for Value and use it in Value::itself
Browse files Browse the repository at this point in the history
Avoid calling itself via funcall to work around a stack split that is
documented in GH-145.

The Clone implementation panics if attempting to clone a Value with ruby
type == ruby::Data. We cannot safely increase the ref count on the Rc
smart pointer that backs the void *.

Fixes GH-3.
  • Loading branch information
lopopolo committed Jul 4, 2019
1 parent 9f4d937 commit c77e8e0
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion mruby/src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ impl Value {
where
T: TryFromMrb<Self, From = types::Ruby, To = types::Rust>,
{
self.funcall::<T, _, _>("itself", &[])
self.clone().try_into::<T>()
}

/// Call `#freeze` on this [`Value`] and consume `self`.
Expand Down Expand Up @@ -401,6 +401,18 @@ impl fmt::Debug for Value {
}
}

impl Clone for Value {
fn clone(&self) -> Self {
if self.ruby_type() == types::Ruby::Data {
panic!("Cannot safely clone a Value with type tag Ruby::Data.");
}
Self {
interp: self.interp.clone(),
value: self.value.clone(),
}
}
}

#[cfg(test)]
mod tests {
use crate::convert::FromMrb;
Expand Down

0 comments on commit c77e8e0

Please sign in to comment.