-
Notifications
You must be signed in to change notification settings - Fork 15
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
Fix segfault in variables tests #641
Conversation
crates/ark/src/variables/variable.rs
Outdated
env.bind("x".into(), harp::parse_eval_base(code).unwrap()); | ||
let value = harp::parse_eval_base(code).unwrap(); | ||
env.bind("x".into(), value.sexp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what was happening is that with:
env.bind("x".into(), harp::parse_eval_base(code).unwrap());
harp::parse_eval_base(code).unwrap()
creates aRObject
which does protectionenv.bind()
consumesvalue: impl Into<SEXP>
, and callsvalue.into()
onvalue
. This consumes theRObject
(dropping and unprotecting it) and returns the unprotectedSEXP
- The unprotected
SEXP
is then used inRf_defineVar()
In theory it seems like Rf_defineVar()
shouldn't do anything to trigger a reallocation, but in practice we see this crash.
More broadly I think this suggests a typing issue with RObject
. I feel like its probably quite bad that we allow the underlying SEXP
to escape the lifetime of RObject
so easily. It's like we need to tie the lifetime of RObject
to the lifetime of underlying SEXP
unless you call something super explicit like unsafe into_sexp()
which has a SAFETY
note that you are taking protection ownership over the SEXP
from here on out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the impl Into<SEXP>
wouldn't work because we could just write temporary().sexp
right? hmm....
I wonder if .sexp
should return a 'SEXP
instead of a SEXP
.
I was also thinking that view()
should do the same to tie the lifetimes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing impl Into<SEXP>
seems to fix the problem as it seems temporary()
is only deleted after the function execution. At least that what I can tell from something like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also remove the impl Into<SEXP>
to reduce the footgun factor please?
crates/ark/src/variables/variable.rs
Outdated
env.bind("x".into(), harp::parse_eval_base(code).unwrap()); | ||
let value = harp::parse_eval_base(code).unwrap(); | ||
env.bind("x".into(), value.sexp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the impl Into<SEXP>
wouldn't work because we could just write temporary().sexp
right? hmm....
I wonder if .sexp
should return a 'SEXP
instead of a SEXP
.
I was also thinking that view()
should do the same to tie the lifetimes.
crates/harp/src/environment.rs
Outdated
@@ -91,13 +91,13 @@ impl Environment { | |||
std::iter::successors(Some(self.clone()), |p| p.parent()) | |||
} | |||
|
|||
pub fn bind(&self, name: RSymbol, value: impl Into<SEXP>) { | |||
pub fn bind(&self, name: RSymbol, value: SEXP) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm or maybe make it take an &RObject
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 94eba52
With current main, running:
Will eventually fail with:
While I'm not entirely sure what's happenning, I believe this is a protection issue, and this PR seems to fix the problem.