Understand and clearly define layering of concerns in WebIDL bindings |
|||
Issue descriptionPer https://codereview.chromium.org/2707243006/, There's an interesting difference of view points that I would like to crystallize into a guidance doc, because I need consistency and clarity in our decision making. Problem statement: what is the proper layering of responsibilities between C++ code and bindings-generated code? View point 1: If the behavior is spec'd in WebIDL, the bindings layer should contain it. View point 2: Bindings layer should be as lean as possible, only containing compile-time checks, but most behavior should be in C++. Both points have merits and we should discuss them thoroughly, weigh, decide, and document our decision.
,
Mar 31 2017
Brad, Ben -- would love your thoughts on the "SAB safe" checks topic, specifically.
,
Mar 31 2017
If you don't mind me jumping in here... I lean closer to #1. To the extent reasonable (e.g. it can check [NewObject], but it can't reasonably make a new object for you), the bindings system (esp. the generator) should take care of the behavior that's spelled out in WebIDL, so that people writing features can by and large focus on writing the feature itself. I'm not sure what "compile-time checks" you're referring to. For calls coming from JavaScript, there's very little validation we can do of callback arguments at compile time. Where it gets more interesting is cases where we're concerned about incorrect uses outside of the JS bindings system (i.e. calls from C++ -- I don't know exactly where Web Agents fits in). For example, I can understand why we might not want C++ functions to accept shared array buffers by default, because their semantics are special and might be surprising to other users. So we might want compile-time enforcement of some kind there. In those cases, the bindings generator should generate a call that conforms to those restrictions if possible, and reject the call (by throwing an exception) if not.
,
Mar 31 2017
> For example, I can understand why we might not want C++ functions to accept shared array buffers by default, because their semantics are special and might be surprising to other users. So we might want compile-time enforcement of some kind there. I definitely agree with this. It was very satisfying and reassuring to have the compiler catch all the cases while I was working on this CL. > In those cases, the bindings generator should generate a call that conforms to those restrictions if possible, and reject the call (by throwing an exception) if not. Oh, I think I see. Perhaps I missed @esphren's original idea for this. So rather than having the C++ API take MaybeShared<DOMArrayBufferView> and do the check in C++, it would take NotShared<DOMArrayBufferView>. The the binding layer would do the check to convert from DOMArrayBufferView* to NotShared<DOMArrayBufferView>, which would only succeed if the DOMArrayBufferView was not backed by a SAB. Then the C++ code could always use NotShared<DOMArrayBufferView>, without having to throw exceptions in the C++ code.
,
Mar 31 2017
> Oh, I think I see. Perhaps I missed @esphren's original idea for this. So rather than having the C++ API take MaybeShared<DOMArrayBufferView> and do the check in C++, it would take NotShared<DOMArrayBufferView>. The the binding layer would do the check to convert from DOMArrayBufferView* to NotShared<DOMArrayBufferView>, which would only succeed if the DOMArrayBufferView was not backed by a SAB. Then the C++ code could always use NotShared<DOMArrayBufferView>, without having to throw exceptions in the C++ code. Something like that is how I understood esprehn's request (though he can speak to that better) and makes sense to me. And C++ callers could convert their pointers to NotShared, which would come with a DCHECK that it was indeed unshared. (The only bikeshed I might consider is whether we can/want to make it such that NotShared is a more obvious default so that it's opt-in rather than opt-out.)
,
Mar 31 2017
To clarify my ambiguous last sentence: "opt in [to supporting shared buffers] rather than opt out [of permitting them]".
,
Mar 31 2017
Yeah that's what I meant. I think we should make the C++ code reflect the correct semantics and the idl code generator should emit types based on it such that it fails to compile if the C++ code disagrees. I don't think the bindings generator should be the only thing enforcing the rules for correctness, that leads to bugs where the C++ code violates rules without realizing it and it's easy to accidentally leave some checks out and cause a security or correctness bug. ex imagine an idl attribute CheckRange(Min,Max) void setFoo([CheckRange(10, 20)] double value); the idl compiler can emit the range check in the code generator and throw an exception, but the C++ should look something like void foo(CheckRange<double, 10, 20> value) instead of a bare double. A DCHECK inside the type would make sure that the value is always in range, and a C++ author now sees right in the code that the value is actually having a range enforced on it. This also means if someone changes the idl to have CheckRange(0, 20) they're forced to change the C++ and hopefully make sure it accepts the new range of values. I was suggesting doing the same thing for SharedArrayBuffer.
,
Mar 31 2017
OK, at least for SAB, I've started working on this implementation. Sorry it took me so long to get the idea... :-}
,
Apr 3 2017
Elliott's idea on #8 sounds reasonable :)
,
Apr 10 2017
Updating status and owner per #9.
,
Nov 30
|
|||
►
Sign in to add a comment |
|||
Comment 1 by dglazkov@chromium.org
, Mar 31 2017