RE: Implicit casting issues when binding to C++

  • From: "Janis Britals" <jbritals@xxxxxxxxx>
  • To: <luajit@xxxxxxxxxxxxx>
  • Date: Tue, 10 Jul 2012 15:25:31 +0200

Mike Pall wrote:

> > However there's one more situation requiring "forward" type 
> conversion (i.e.
> > based on the source type), and it is 
> static_cast<BaseType*>. This is 
> > really indispensable for C++.
> 
> Well, but that can be done in the conversion metamethod for 
> the base type (i.e. the destination type) as well, no?
> [I know that violates separation of concerns. But I don't 
> want to hardcode a behavior right now that may need to be 
> reworked for the 'real' C++ support in the future.]
> 
> Hardcoding a table lookup in C isn't that much more efficient vs.
> doing it in Lua. The internal number of the source type may 
> be retrieved with tonumber(ffi.typeof(source)) and used as an index.
> 
> You can manage such a conversion matrix as part of each base 
> type and fill it in when creating the derived types.

It could be done the way you describe here, of course. Reason why I would
like to do it in "C" is to avoid the extra metacall to VM and associated
"trace_abort". The downcasting to base type happens way more often than
conversions via implicit constructor calls, and it's practically
unavoidable, whereas you always can call the implicit constructor explicitly
to avoid the breaking of trace recording. And since the static_cast is
really nothing more than a small delta added to the resulting pointer I
think this warrants a special treatment in the conversion algorithm.

Now about enums:

> Well, the problem goes deeper than that. There are many 
> places where enums are automatically converted from or to 
> numbers or that need to deal with the corresponding number 
> type and not the enum type. Not so easy to untangle.

I suspected as much. Too bad.

> That's the first thing I'd have suggested. If you want to 
> preserve the ctype information, you'll need to box the 
> integer. Whether you box it in an enum objectg or a struct 
> doesn't really matter. Do you have an example where this 
> creates too much runtime overhead?

The thing that set me doubting was argument and result passing conventions.
Enums are always passed by value. If I box them in structs I need to pass
these structs also by value, which will cause some confusion, especially in
returning them. Currently I convert returned structs to extra arguments to
comply with the C++ "calling convention", because they always represent C++
classes, but I guess I could fiddle it a bit more to box the returned int
value in struct. I take my words about "too much runtime overhead" back.
It's just a bit more binding work, but it's not runtime.

I think I could live with this one. Thanks for making me think again :)

-- Janis



Other related posts: