Side effects on record fields when triggering events


is the following correct: when I trigger an event in the policy layer
via the event() statement and pass a record value as an event argument,
then at the time the triggered event is processed, the value is taken
from the same location in memory that was passed to the event()

For example, this ...

  type foo: record {

  event e1(f: foo) {
        print fmt("e1: %d", f$a);

  event bro_init() {
        local f: foo;
        print fmt("bro_init: %d", f$a);
        event e1(f);

... yields:

  bro_init: 0
  e1: 1

So it seems that what is passed to the event handler is the value in its
state before it goes out of scope (end of bro_init()). Any modifications
of the record value that happen between the time of triggering the event
and its processing will be visible to the event handler.

Isn't that rather dangerous? My intuition was that an event() statement
passes copies of all parameters to the event handlers to guarantee they
all get the same values. I now do this manually where it is a problem in
my policies.

It gets more interesting -- why does the following work?

  type foo: record {

  global bar: table[count] of foo;

  event e1(f: foo)
        print fmt("e1: %d", f$a);

  function f1(): foo
        local f: foo;
        return f;

  event bro_init()
        bar[1] = f1();
        print fmt("bro_init: %d", bar[1]$a);
        event e1(bar[1]);

        delete bar[1];

It yields:

  bro_init: 0
  e1: 0

After event e1 is triggered, the value passed to the e1 handler is
erased from the global table. So why does this not give a run-time
error? I'm confused at this point about the assumptions I can make about
record values received by event handlers.

If I missed the explanations of the call semantics in the manual then
please point me to them, otherwise I think they should really be

Thanks in advance!

Okay Chema and I tracked it down to the reference counting that is going
on in the core -- upon triggering, the reference count is bumped up by 1
per matching event handler and the value eventually dies after those
handlers have been execuded. Until then any changes to the value are
visible wherever a reference to the value still exists.

I'm amazed this hasn't caused me problems earlier.