Hook functions now directly callable instead of w/ "hook" statements.

The return value of the call is an implicit boolean value of T if all
hook handlers ran, or F if one hook handler exited as a result of a
break statement and potentially prevented other handlers from running.

Scripts don't need to declare hooks with an explicit return type of bool
(internally, that's assumed), and any values given to (optional) return
statements in handler definitions are just ignored.

Addresses #918.
This commit is contained in:
Jon Siwek 2012-11-26 16:54:36 -06:00
parent e2fdf16e0c
commit 378ee699ff
15 changed files with 108 additions and 145 deletions

View file

@ -349,16 +349,31 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
break;
}
if ( flow == FLOW_BREAK && Flavor() == FUNC_FLAVOR_HOOK )
if ( Flavor() == FUNC_FLAVOR_HOOK )
{
// short-circuit execution of remaining hook handler bodies
break;
// Ignore any return values of hook bodies, final return value
// depends on whether a body returns as a result of break statement
Unref(result);
result = 0;
if ( flow == FLOW_BREAK )
{
// short-circuit execution of remaining hook handler bodies
result = new Val(false, TYPE_BOOL);
break;
}
}
}
if ( Flavor() == FUNC_FLAVOR_HOOK )
{
if ( ! result )
result = new Val(true, TYPE_BOOL);
}
// Warn if the function returns something, but we returned from
// the function without an explicit return, or without a value.
if ( FType()->YieldType() && FType()->YieldType()->Tag() != TYPE_VOID &&
else if ( FType()->YieldType() && FType()->YieldType()->Tag() != TYPE_VOID &&
(flow != FLOW_RETURN /* we fell off the end */ ||
! result /* explicit return with no result */) &&
! f->HasDelayed() )