Re: Vote on Kevin's proposal


Subject: Re: Vote on Kevin's proposal
From: Stickley, John (john_stickley@mentorg.com)
Date: Thu Jan 02 2003 - 13:44:13 PST


Kevin,

Kevin Cameron wrote:
>>From: "Stickley, John" <john_stickley@mentorg.com>
>>
>>I vote "no" on accepting 1.1b in its current form
>>mainly because,
>>
>>1. I don't think dynamic binding is needed in first version
>> of the C calling interface.
>
>
> Did you discuss that with the CVE/Seamless team?

johnS:
No I did not but I as I demonstrated below you can fairly
easily create "function trays" that support a dynamic binding
scheme even if the SV-C interface itself does not inherently
support it. This scheme should work fine virtually any
environment.

>
>
>>2. Even if it were, a significantly simpler dynamic binding
>> scheme can be realized than what Kevin proposes.
>
>
> Not really. If you make it simpler in one place it'll get more
> complicated somewhere else.
>
>
>>I would also like to say that I carefully went over Kevin's
>>detailed examples on how the interface would be used.
>>
>>These examples demonstrate a complex technique for dynamically
>>binding C++ functions where the code itself requires knowledge
>>of the name mangling schemes of specific C++ compiler
>>environments. This, in my view, is unacceptible.
>
>
> You can take that issue to the ANSI committees. The point of
> methodology in the proposal is it allows mixing libraries from
> different compilers. You only need to write the name mangling
> code once for any one compiler.
>

johnS:
Still I think forcing a requirement to reverse-engineer
every compiler that comes along is not a good idea.
Plus you run the risk that older code libraries will
break with new versions of compilers that have changed
their mangling schemes. That's why I think avoiding
name mangling knowledge altogether is an inherently
good idea.

>
>>Here are my other main objections to it:
>>
>>1. We don't need both a "call forward" "register locator"
>> *and* a "call back" binding function. All we would need is
>> a call forward binding function (i.e. svBind()).
>
>
> You do if you want to link arbitrary C++ compilers code
> dynamically.

johnS:
I think call forward from C would work quite nicely in
a simplified dynamic binding scheme.

>
>
>>2. The string parsing requirement for argument profiles
>> is overly complicated and buys you very little. Plus
>> it requires the code to have knowledge of C++ compiler
>> name mangling schemes and even with this, there's no
>> guarantee that the pointers to the functions being
>> bound match the profiles of the extern definitions in
>> the SV side. So really the type safety that it is
>> attempting to create, falls well short of its goal.
>
>
> There is a guarantee that if you have generated the type
> strings properly, and the mangling is performed properly
> the routine will match the profile. There is no other
> proposal that offers any checking in this area.
>

johnS:
"if you have generated the type strings properly"
There's no guarantee of this ! Another proposal that
offers checking in this area is compile time checking
of functions against optionally generated headers.
(see below).

>
>>A static linking scheme that makes use of optional
>>SV compiler generated headers provides superior type
>>safety checking than Kevin's scheme does. The same
>>overall goals of the example given by Kevin can
>>alternately be accomplished using the static linking
>>scheme.
>
>
> Are mandating header generation?

johnS:
No, I continue to feel that this should be implementation
optional. But I predict that most implementations will
want to make use of it since it is easy to do.

>
> That's not a link-time check, there is no guarantee that
> the the code in the library matches correctly unless you
> include all the code-generation rules.

johnS:
True. But this should be easy enough for users to do.
They do it all the time (i.e. include header files)
when using C functions from other libraries and APIs.

>
> Only C++ combines the argument types with the C name of
> the routine, so only C++ comes close to guaranteeing that
> your calls match.

johnS:
ANSI C compilers also will check arguments of C functions
against extern declarations in headers.

>
>
>>Here's how:
>>
>>1. In SV code declare extern functions to Kevin's
>>"foo" double and "foo" int functions:
>>
>>SV declarations:
>>----------------
>>
>> extern context "foo_double" integer foo( real arg );
>> extern context "foo_int" integer foo( integer arg );
>
>
> The "foo_double"/"foo_int" is extra over my proposal, the
> locator works it out.

johnS:
Yes, a differentiator is needed in the name since
the function names must have C linkage. In a sense we
are requiring the user to provide explicit manual name
mangling for this particular example.

But, what's nice about doing it this way is that there
are no pre-made assumptions about compiler name mangling
schemes. Manual mangling in this example creates clearly
defined names that must simply be matched on the C side.
It is a simple mechanism and very easy for users to
understand and use. No magic processing is needed by a
locator function.

>>In this case foo_double() and foo_int() are extern "C"
>>linkage wrappers for the real overloaded C++ variants
>>of these functions shown in Kevin's example.
>>
>>Now, on the C side, you can still use dlopen() and dlsym()
>>to look up the functions as Kevin shows. But what you
>>do is set pointers that the C wrappers call.
>>
>>Here you've created application level dynamic binding
>>capability from static capability with very little
>>added overhead and with no name mangling interpretation
>>required.
>>
>>A better designed, more compact object oriented scheme
>>could also be used but here I just used a rudimentry
>>scheme to follow with the flow of Kevin's example.
>>
>>Optional SV compiler generated header sv_decls.h:
>>-------------------------------------------------
>>
>> extern "C" {
>> extern int foo_double( svHandle context, double arg );
>> extern int foo_int ( svHandle context, int arg );
>> };
>>
>>test.c:
>>-------
>>
>> // Define pointers to the real C++ functions here:
>> static int (*real_foo_double)( svHandle context, double arg );
>> static int (*real_foo_int) ( svHandle context, int arg );
>>
>> // Define the wrappers here that will be directly called
>> // from SV, which then call the real C++ functions.
>> extern "C" {
>> int foo_double( svHandle context, double arg ){
>> return (*real_foo_double)( context, arg ); }
>>
>> int foo_int( svHandle context, int arg ){
>> return (*real_foo_int)( context, arg ); }
>>
>> void (*bindMyFoos)( void *, void *); // "Locator" function pointer.
>> };
>>
>> main(){
>> // Dynamically load code library containing real functions:
>> void *lib = dlopen("./liblib.so",RTLD_NOW); // Open dynamic library
>>
>> // Now look up and call "locator" function that, itself,
>> // is an extern "C" function.
>> bindMyFoos = dlsym(lib,"BindMyFoos");
>> (*bindMyFoos)( (void *)&real_foo_double, (void *)&real_foo_int );
>>
>> ...
>> }
>
>
> Where did you tell SV to call "bindMyFoos" ?

johnS:
Right from the user's main() or anywhere else on the C side
during the initialization phase as the example here shows.

>
>
>>Dynamically loaded lib.cc:
>>--------------------------
>>
>> // Here are the real C++ foo functions:
>> int foo( svHandle context, double arg ) {
>> fprintf(stderr,"Called (double)\n");
>> return arg * ((user_struct *)(svGetUserData(context))->dbl;
>> }
>>
>> int foo( svHandle context ,int arg ) {
>> fprintf(stderr,"Called (int)\n");
>> return arg * ((user_struct *)(svGetUserData(context))->data[0];
>> }
>>
>> typedef int (*foo_double_type)(svContext context, double arg );
>> typedef int (*foo_int_type) (svContext context, int arg );
>>
>> extern "C" {
>> void BindMyFoos( void *real_foo_double, void *real_foo_int ){
>> // This assignments will pick correct variants of foo
>> // according to Stroustrup $r.13.3
>
>
> Does that mean you didn't try it?

johnS:
Quite honestly I did not try it. However, since you raised the
issue I created the following small program and verified that
it indeed does work for at least GNU and Solaris SPRO compilers.
Until now, I did not realize C++ supported this. Pretty cool !
This can be a nice template for writing code to create function
trays of dynamically bound function pointers.

------------------------------ cut here ---------------------

#include <stdio.h>
#include <assert.h>

typedef void *svContext;

typedef int (*foo_double_type)(svContext context, double arg );
typedef int (*foo_int_type) (svContext context, int arg );

static foo_double_type real_foo_double;
static foo_int_type real_foo_int;

// Here are the real C++ foo functions:
int foo( svContext context, double arg ) {
     printf("Called (double)\n");
     return (int)arg;
}

int foo( svContext context ,int arg ) {
     printf("Called (int)\n");
     return arg;
}

int main(){

     real_foo_double = &foo;
     real_foo_int = &foo;

     assert( (*real_foo_double)(NULL, 1.0) == 1 );
     assert( (*real_foo_int)(NULL, 2) == 2 );

     return 0;
}

------------------------------ cut here ---------------------

>
>
>> *((foo_double_type *)real_foo_double) = &foo;
>> *( (foo_int_type *)real_foo_int) = &foo;
>> }
>> };
>
>
> You don't have the data setup phase.

johnS:
I'm not sure what you mean by this. Please elaborate.

>
>
>>Note that this is just as efficient as Kevin's example with
>>two added benefits:
>>
>>1. No need for knowledge of compiler specific mangling schemes
>
>
> But the user needs to add information in the "extern" declaration
> to compensate.

johnS:
Either the user or, more ideally, the SV compiler if it chooses
to implement the optional header feature.

>
>
>>2. No dynamic binding needed in DirectC API. Can be handled
>> completely at application layer if required.
>
>
> But that didn't buy you anything, you still have no real argument
> checking, and the same number of indirections. And as a downside
> you are using more of the C linker name space which will lead to
> more name clashes.

johnS:
I think in a typical application, name clashes can be kept to a
minimum if good coding practices are used such as 3 letter prefixes
for function names, etc. that we've all been using for years.

>
> I suggest you redo your example with the missing bits added (how
> myBindFoos gets declared to SV, and how the contexts get initialized),
> and give us a version that compiles and runs like mine did.
>

johnS:
bindMyFoos() doesn't need to get declared to SV. It is declared
in and called from C. SV does not need to get involved.

> Kev.
>

-- johnS

>
>>-- johnS
>>
>>Warmke, Doug wrote:
>> > Team,
>> >
>> > I believe today is the deadline for voting on Kevin's proposal.
>> > Kevin requested an extension this week but there was no reply
>> > from either Ghassan or Swapnajit.
>> >
>> > If there is no extension, my vote on the proposal is "no".
>> >
>> > I feel the complexity is too high and therefore it is not
>> > in the spirit of the original DirectC requirements,
>> > "convenience and performance". Also the proposal is making
>> > too many assumptions regarding the rest of SV 3.1 which
>> > may or may not come true.
>> >
>> > Thanks for all the work you did on it, Kevin.
>> > I'm sorry I couldn't go with you on this one.
>> >
>> > Regards,
>> > Doug Warmke
>>
>>--
>> __
>> ______ | \
>>______________________/ \__ / \
>> \ H Dome ___/ |
>>John Stickley E | a __ ___/ / \____
>>Principal Engineer l | l | \ /
>>Verification Solutions Group | f | \/ ____
>>Mentor Graphics Corp. - MED C \ -- / /
>>17 E. Cedar Place a \ __/ / /
>>Ramsey, NJ 07446 p | / ___/
>> | / /
>>mailto:John_Stickley@mentor.com \ /
>>Phone: (201)818-2585 \ /
>> ---------
>>
>
>

-- 

This email may contain material that is confidential, privileged and/or attorney work product for the sole use of the intended recipient. Any review, reliance or distribution by others or forwarding without express permission is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. __ ______ | \ ______________________/ \__ / \ \ H Dome ___/ | John Stickley E | a __ ___/ / \____ Principal Engineer l | l | \ / Verification Solutions Group | f | \/ ____ Mentor Graphics Corp. - MED C \ -- / / 17 E. Cedar Place a \ __/ / / Ramsey, NJ 07446 p | / ___/ | / / mailto:John_Stickley@mentor.com \ / Phone: (201)818-2585 \ / ---------



This archive was generated by hypermail 2b28 : Thu Jan 02 2003 - 13:48:33 PST