August 23, 2004
"antiAlias" <fu@bar.com> wrote in message news:cgd6r6$2jn8$1@digitaldaemon.com...
> The flag approach has merit, but needs to be appropriately exception-checked; worse, it's not thread safe. You'd potentially need to use thread locals instead.
>
> A different approach would be for the function-calling protocol to be modified slightly in debug mode: a flag gets pushed onto the stack by the caller, indicating whether or not invariants should execute. Those methods within the class itself push a 'false' for their own methods, while all external calls push a 'true' instead.
>
> No exception issues; no thread-safety issues.

But then you cannot mix and match debug builds with non-debug builds, significantly reducing their utility.


August 23, 2004
"Bent Rasmussen" <exo@bent-rasmussen.info> wrote in message news:cgcfrh$28bh$1@digitaldaemon.com...
> > Yes, but it wouldn't solve the problem. The invariant could still call
> > some
> > external function, which could then call a member function, which would
> > then
> > invoke the invariant agian.
>
> I thought about that too, but isn't that acceptable?

It'll result in infinite recursion.


August 23, 2004
Yeah; I can see how that would be desirable. Another approach is for the invariant to check the return address; if it's within the range of the current module then don't execute. That way, all the effort is contained and performed by the invariant itself. You might even expose that as an optional invariant-type ...


"Walter" <newshound@digitalmars.com> wrote in message news:cgdbvt$2nht$2@digitaldaemon.com...
>
> "antiAlias" <fu@bar.com> wrote in message news:cgd6r6$2jn8$1@digitaldaemon.com...
> > The flag approach has merit, but needs to be appropriately exception-checked; worse, it's not thread safe. You'd potentially need
to
> > use thread locals instead.
> >
> > A different approach would be for the function-calling protocol to be modified slightly in debug mode: a flag gets pushed onto the stack by
the
> > caller, indicating whether or not invariants should execute. Those
methods
> > within the class itself push a 'false' for their own methods, while all external calls push a 'true' instead.
> >
> > No exception issues; no thread-safety issues.
>
> But then you cannot mix and match debug builds with non-debug builds, significantly reducing their utility.
>
>


August 23, 2004
"antiAlias" <fu@bar.com> wrote in message news:cgdhln$2que$1@digitaldaemon.com...
> Yeah; I can see how that would be desirable. Another approach is for the invariant to check the return address; if it's within the range of the current module then don't execute. That way, all the effort is contained
and
> performed by the invariant itself. You might even expose that as an
optional
> invariant-type ...

I don't see how any calls to the invariant can work, then <g>.


August 23, 2004
"Walter" <newshound@digitalmars.com> wrote in message news:cgdm0d$2ub8$1@digitaldaemon.com...
> I don't see how any calls to the invariant can work, then <g>.

Don't follow you ... if the invariant knows the range of executable addresses within the containing module, it can accept calls from without the range whilst ignoring those from within.

The compiler would have to setup begin & end labels for the code generated within the containing module (or something like that), the linker/loader would patch them in the usual manner to represent real addresses, and the invariant would check the address of said labels against the provided return-address (from the stack) to see if it's being called from within the same (containing) module.

Calls from a different module will have a return-address that is outside the range of the called module and, therefore, the invariant would execute.

Am I missing something here?


August 23, 2004
I am, of course, using the term 'module' to loosely mean D source-file.

"antiAlias" <fu@bar.com> wrote in message news:cgdmnf$2v2t$1@digitaldaemon.com...
> "Walter" <newshound@digitalmars.com> wrote in message news:cgdm0d$2ub8$1@digitaldaemon.com...
> > I don't see how any calls to the invariant can work, then <g>.
>
> Don't follow you ... if the invariant knows the range of executable addresses within the containing module, it can accept calls from without
the
> range whilst ignoring those from within.
>
> The compiler would have to setup begin & end labels for the code generated within the containing module (or something like that), the linker/loader would patch them in the usual manner to represent real addresses, and the invariant would check the address of said labels against the provided return-address (from the stack) to see if it's being called from within
the
> same (containing) module.
>
> Calls from a different module will have a return-address that is outside
the
> range of the called module and, therefore, the invariant would execute.
>
> Am I missing something here?
>
>


August 23, 2004
Ahhh ... right. I am missing something. The invariant is invoked by the callee, not the caller ... whoops. Is there a known stack-frame you can peek at? You'd only be looking one frame removed (the call immediately prior to the invariant call) ... I think it's fair to say that circuitous routes /will/ invoke the invariant.


"antiAlias" <fu@bar.com> wrote in message news:cgdmnf$2v2t$1@digitaldaemon.com...
> "Walter" <newshound@digitalmars.com> wrote in message news:cgdm0d$2ub8$1@digitaldaemon.com...
> > I don't see how any calls to the invariant can work, then <g>.
>
> Don't follow you ... if the invariant knows the range of executable addresses within the containing module, it can accept calls from without
the
> range whilst ignoring those from within.
>
> The compiler would have to setup begin & end labels for the code generated within the containing module (or something like that), the linker/loader would patch them in the usual manner to represent real addresses, and the invariant would check the address of said labels against the provided return-address (from the stack) to see if it's being called from within
the
> same (containing) module.
>
> Calls from a different module will have a return-address that is outside
the
> range of the called module and, therefore, the invariant would execute.
>
> Am I missing something here?
>
>


August 23, 2004
"antiAlias" <fu@bar.com> wrote in message news:cgdnbq$2vhn$1@digitaldaemon.com...
> Ahhh ... right. I am missing something. The invariant is invoked by the callee, not the caller ... whoops. Is there a known stack-frame you can
peek
> at? You'd only be looking one frame removed (the call immediately prior to the invariant call) ... I think it's fair to say that circuitous routes /will/ invoke the invariant.

It starts getting fairly complicated handling all the special cases when one starts doing that.


August 24, 2004
"Walter" <newshound@digitalmars.com> wrote in message news:cgdvem$351$1@digitaldaemon.com...
>
> "antiAlias" <fu@bar.com> wrote in message news:cgdnbq$2vhn$1@digitaldaemon.com...
> > Ahhh ... right. I am missing something. The invariant is invoked by the callee, not the caller ... whoops. Is there a known stack-frame you can
> peek
> > at? You'd only be looking one frame removed (the call immediately prior
to
> > the invariant call) ... I think it's fair to say that circuitous routes /will/ invoke the invariant.
>
> It starts getting fairly complicated handling all the special cases when
one
> starts doing that.

That sounds intriguing. I can imagine special-cases via support for other languages, but from within D itself, I'm at a loss to speculate. Care to elaborate a little?

Special-cases aside; would this not be a viable solution, given that it avoids exception and thread-safety issues?



August 24, 2004
"antiAlias" <fu@bar.com> wrote in message news:cgeoip$fcn$1@digitaldaemon.com...
> "Walter" <newshound@digitalmars.com> wrote in message news:cgdvem$351$1@digitaldaemon.com...
> >
> > "antiAlias" <fu@bar.com> wrote in message news:cgdnbq$2vhn$1@digitaldaemon.com...
> > > Ahhh ... right. I am missing something. The invariant is invoked by
the
> > > callee, not the caller ... whoops. Is there a known stack-frame you
can
> > peek
> > > at? You'd only be looking one frame removed (the call immediately
prior
> to
> > > the invariant call) ... I think it's fair to say that circuitous
routes
> > > /will/ invoke the invariant.
> >
> > It starts getting fairly complicated handling all the special cases when
> one
> > starts doing that.
>
> That sounds intriguing. I can imagine special-cases via support for other languages, but from within D itself, I'm at a loss to speculate. Care to elaborate a little?
>
> Special-cases aside; would this not be a viable solution, given that it avoids exception and thread-safety issues?

The compiler generates different stack frames based on things like optimization settings, debugging, exception handling, etc. Then there are the multiple calling conventions, each with their own way of doing things.