@centril moving the "FFI is not a sandbox" conversation here
Here's the way I formulated the "not supposed to change behavior or protect the caller" idea in my conversation earlier:
I agree these are still not really fully-fleshed-out opinions, let alone statements of fact.
Well they are statements, but without justification ^^
But I would say that they "sound right" to me.
Do you have specific objections to either claim, or do you just want to see a justification before deciding whether or not you agree?
I think those are too coarse statements and not sufficiently nuanced
splitting ABIs, adding shims, etc. is in my view perfectly legitimate in the interest of e.g. soundness, perf, etc.
So, "soundness" is covered in the second bullet point.
I'm not sure I see how shims could ever _improve_ performance.
Didn't feel that way to me but ok
But that's certainly an aspect of the question I hadn't even considered.
@Kyle Strand well the nounwind assumption would, but it wouldn't ostensibly cover "the whole ABI"
nounwind isn't really a "shim", though, is it?
Re: soundness, could you suggest an alternate phrasing of the second bullet point that does make it clear?
@Kyle Strand not sure why you are linking perf and shims
Protecting the user from undefined behavior (e.g. via an abort shim, in case you mess up) and maintaining soundness is part of Rust's core values, and FFI is not inherently an opt-out from that protection.
"Splitting ABIs, adding shims, etc ... perf, etc"
Was the performance consideration only meant to apply to "splitting ABIs", then?
sure; nounwind & friends
Okay. My first impulse is to say that that's not really subject to the "not a sandbox" objection.
Isn't "maintaining soundness" covered by "protecting the user from undefined behavior"?
or implied by, rather
depends on whether you are talking about the safe or unsafe fragment
I'm a bit lost. "unsafe fragment"?
the abort shim protects you from UB even in unsafe code; but it also maintains soundness
one could ostensibly not have that shim for unsafe code, or only for unsafe code
@Kyle Strand either case, the soundness/UB point does poke a hole in "not a sandbox" pretty well
Yeah, that's why I'm trying to reformulate the objection without using the word "sandbox"; it's far too vague.
It's a metaphor that I believe helped me understand Nick's concern, but I fully agree it's not adequate!
But I think the first point stands:
_If_ it is true that exceptions are a well-defined part of an ABI, then I would agree with Nick that it's not a good idea to change the semantics of functions that
throw by changing their ABI strings when calling them from Rust.
"in any language" makes the claim also extraordinarily strong -- maybe one of these languages can't even make full use of the ABI representable without a lot of cost
...then it shouldn't expose that ABI.
The negative way to phrase it would be: exposing an ABI but leaving out well-defined parts of that ABI is essentially failing to expose that ABI.
I don't see why "ABI with restrictions" is illegitimate
Well, partly I would say it fails the principle of least surprise, especially if the mechanism for specifying the ABI gives no indication that the ABI isn't fully supported.
that's one consideration
I.e. if the ABI string were
itanium, where exceptions are definitely well defined (per the spec), one would expect that ABI to support exceptions.
well in this case the ABI string is different
Another is the one that @gnzlbg has been expressing, i.e., there's an appropriate way to restrict behavior/effects, but doing so via "ABIs with restrictions" is in some way suboptimal. (I don't want to try to paraphrase the reasoning here.)
The main ABI string we're concerned about is
extern "C", though. The ABI string is not different.
I'm familiar with their concerns re. effects :slight_smile:
There's sort of a "strong objection" to "ABI with restrictions", which is that they shouldn't exist at all; it sounds to me like Nick (the originator of the "sandbox" quote) is in this camp.
Then, there's a "weak objection", which is that "ABI with restrictions" is valid but must be explicit.
I'm not sure how much my personal opinion on the issue matters, but just so you know where I stand at the moment: I definitely agree with the "weak objection" stance that FFI mechanisms shouldn't implicitly disable well-defined parts of an ABI; I am currently on the fence with regard to the "strong objection" that e.g.
extern "C nounwind" is illegitimate.
That much was clear ^^
Anyway, the third consideration is that any well-defined part of an ABI is a means of translating program semantics into program behavior. C++ uses exceptions in this way, and somewhere between "most" and "all" ABIs consider this mechanism well-defined.
So, suppressing that feature of the ABI potentially changes the semantics of functions called via FFI, in a way that is both silent (e.g. you wouldn't get a warning at compile time or anything like that) and non-enforceable (i.e. the ABI exposed by C++ has no way of indicating whether or not an exception might be thrown).
I'll head off to bed but please do continue your points
Fair enough. I think that's all I have.
So to summarize (mostly for future reference when I'm writing up a summary later), the objections to "protecting the user from well-defined parts of the ABI" are:
Thanks for the discussion!
Last updated: Jan 26 2022 at 08:34 UTC