| 1 | OK, this is the third iteration, it has to be done right this time! :)
|
|---|
| 2 |
|
|---|
| 3 | There are multiple tasks involved:
|
|---|
| 4 | . Generating the header files (solved)
|
|---|
| 5 | . Generating the memory allocators and typecodes (solved)
|
|---|
| 6 | . Generating the POA tie-ins (solved)
|
|---|
| 7 | . Generating the stubs and exception demarshallers (not so solved)
|
|---|
| 8 | . Generating the skeletons and exception marshallers (not so solved)
|
|---|
| 9 |
|
|---|
| 10 | So it is mostly doing the marshalling/demarshalling that is the hard part. The reason it is hard is because:
|
|---|
| 11 | . We need to allow choosing between multiple mechanisms, e.g.:
|
|---|
| 12 | Inlined code
|
|---|
| 13 | Call to a separate function (possibly shared between multiple stubs/skels).
|
|---|
| 14 | Use the CORBA_any routine.
|
|---|
| 15 |
|
|---|
| 16 | It will not be an all-or-nothing decision between the mechanisms - we
|
|---|
| 17 | will try to mix the different mechanisms according to heuristics. The
|
|---|
| 18 | granularity of the decision will be on the level of a 'marshallable
|
|---|
| 19 | entity' (big long words to denote something that can be marshalled,
|
|---|
| 20 | hereafter abbreviated as 'ME').
|
|---|
| 21 |
|
|---|
| 22 | So, with an ME:
|
|---|
| 23 |
|
|---|
| 24 | def atomically_marshallable():
|
|---|
| 25 | # The results of this function depend on more than just the data type, but also:
|
|---|
| 26 | # Whether we have to do endian swapping (only applies to demarshalling)
|
|---|
| 27 | # Whether the data arrangement in memory matches the data arrangement on the wire
|
|---|
| 28 | if is_complex:
|
|---|
| 29 | return FALSE
|
|---|
| 30 | if is_struct or is_union or is_sequence or is_array:
|
|---|
| 31 | return probably-FALSE
|
|---|
| 32 | return TRUE
|
|---|
| 33 |
|
|---|
| 34 | if atomically_marshallable():
|
|---|
| 35 | marshal_inline()
|
|---|
| 36 | else if not is_recursive() and data_type_use_count == 1:
|
|---|
| 37 | marshal_inline()
|
|---|
| 38 | else:
|
|---|
| 39 | if use_any_marshaller():
|
|---|
| 40 | marshal_via_any_marshaller()
|
|---|
| 41 | else:
|
|---|
| 42 | generate_marshalling_function()
|
|---|
| 43 | call_marshalling_function()
|
|---|
| 44 |
|
|---|
| 45 | The decision is made on a per-data-type basis and NOT on a per-stub
|
|---|
| 46 | basis, because we want to be consistent (i.e. no inlining the
|
|---|
| 47 | marshalling in one function and then calling the any_marshaller in
|
|---|
| 48 | another function, for the same data type).
|
|---|
| 49 |
|
|---|
| 50 | Generating the call-to-separate-function and ORBit_*marshal_any calls
|
|---|
| 51 | should be easy once it is determined that this is desired. Generating
|
|---|
| 52 | the inline code (and generating the separate-function, which will use
|
|---|
| 53 | the 'inlined code' engine), is a difficult thing, because of the
|
|---|
| 54 | optimizations involved and the different situations that the code
|
|---|
| 55 | might be used in.
|
|---|
| 56 |
|
|---|
| 57 | ----------------
|
|---|
| 58 | OK the above blah is either implemented or total crap.
|
|---|
| 59 |
|
|---|
| 60 | Biggest issue that seems to be looming is memory management during
|
|---|
| 61 | demarshalling. It's not at all clear whether caller or called
|
|---|
| 62 | allocates, how we get rid of things if there is an error or we don't
|
|---|
| 63 | need them, etc.
|
|---|
| 64 |
|
|---|
| 65 | Problems to solve:
|
|---|
| 66 | Currently the marshal/demarshal code is stupid about
|
|---|
| 67 | allocating, esp. for toplevels.
|
|---|
| 68 |
|
|---|
| 69 | We need to handle all cases of OIDL_Marshal_Where properly.
|
|---|
| 70 |
|
|---|
| 71 | OIDL_Marshal_Where is a function of context rather than data
|
|---|
| 72 | type. It will always be MW_Heap or MW_Null for
|
|---|
| 73 | stubs. We need the concept of 'allocation contexts' -
|
|---|
| 74 | i.e. where a variable is 'auto' in or alloca'd in. No we
|
|---|
| 75 | don't, we just need to have a mask of allowed marshalling
|
|---|
| 76 | methods passed down.
|
|---|
| 77 |
|
|---|
| 78 | Possible solutions:
|
|---|
| 79 | We need to know how to allocate a variable for each potential
|
|---|
| 80 | OIDL_Marshal_Where and generate the valuestr for it.
|
|---|
| 81 |
|
|---|
| 82 | 'Caller allocates' allows some optimizations in
|
|---|
| 83 | skeletons. So, if we are going to ask someone to demarshal
|
|---|
| 84 | something, we need to make sure it is allocated first.
|
|---|