diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | parse.cxx | 23 | ||||
-rw-r--r-- | stap.1.in | 14 | ||||
-rw-r--r-- | tapset/context.stp | 51 | ||||
-rw-r--r-- | tapset/conversions.stp | 10 | ||||
-rw-r--r-- | tapset/logging.stp | 28 | ||||
-rw-r--r-- | tapset/timestamp.stp | 4 | ||||
-rwxr-xr-x | testsuite/parseok/twelve.stp | 2 | ||||
-rwxr-xr-x | testsuite/semko/nineteen.stp | 2 | ||||
-rwxr-xr-x | testsuite/semko/twenty.stp | 7 | ||||
-rwxr-xr-x | testsuite/semok/seven.stp | 4 |
11 files changed, 85 insertions, 70 deletions
@@ -1,3 +1,13 @@ +2005-09-03 Frank Ch. Eigler <fche@elastic.org> + + PR 1292, by popular request. + * parse.cxx (parse_functiondecl): Allow optional value/param type + declarations. + * stap.1.in: Document this. + * tapset/*.stp: Convert most functions accordingly. + * testsuite/parseok/twelve.stp, semok/seven.stp, + semko/twenty.stp: Test this. + 2005-09-02 Frank Ch. Eigler <fche@redhat.com> * translate.cxx (varlock): Use trylock only for write locks. @@ -774,6 +774,18 @@ parser::parse_functiondecl (std::vector<functiondecl*>& functions) fd->tok = t; t = next (); + if (t->type == tok_operator && t->content == ":") + { + t = next (); + if (t->type == tok_identifier && t->content == "string") + fd->type = pe_string; + else if (t->type == tok_identifier && t->content == "long") + fd->type = pe_long; + else throw parse_error ("expected 'string' or 'long'"); + + t = next (); + } + if (! (t->type == tok_operator && t->content == "(")) throw parse_error ("expected '('"); @@ -792,6 +804,17 @@ parser::parse_functiondecl (std::vector<functiondecl*>& functions) fd->formal_args.push_back (vd); t = next (); + if (t->type == tok_operator && t->content == ":") + { + t = next (); + if (t->type == tok_identifier && t->content == "string") + vd->type = pe_string; + else if (t->type == tok_identifier && t->content == "long") + vd->type = pe_long; + else throw parse_error ("expected 'string' or 'long'"); + + t = next (); + } if (t->type == tok_operator && t->content == ")") break; if (t->type == tok_operator && t->content == ",") @@ -315,8 +315,18 @@ function thisfn (arg1, arg2) { return arg1 + arg2 } .ESAMPLE -Note the usual absence of type declarations, which are instead -inferred by the translator. Functions may call others or themselves +Note the general absence of type declarations, which are instead +inferred by the translator. However, if desired, a function +definition may include explicit type declarations for its return value +and/or its arguments. This is especially helpful for embedded-C +functions. In the following example, the type inference engine need +only infer type type of arg2 (a string). +.SAMPLE +function thatfn:string (arg1:long, arg2) { + return string(arg1) . arg2 +} +.ESAMPLE +Functions may call others or themselves recursively, up to a fixed nesting limit. This limit is defined by a macro in the translated C code and is in the neighbourhood of 30. diff --git a/tapset/context.stp b/tapset/context.stp index 7ed693b8..32b009bf 100644 --- a/tapset/context.stp +++ b/tapset/context.stp @@ -1,94 +1,82 @@ -function _print_regs () %{ - if (CONTEXT && CONTEXT->regs) { +function print_regs () %{ + if (CONTEXT->regs) { _stp_print_regs (CONTEXT->regs); } %} -function print_regs(){_print_regs()} -function _print_backtrace () %{ - if (CONTEXT && CONTEXT->regs) { +function print_backtrace () %{ + if (CONTEXT->regs) { _stp_stack_print(CONTEXT->regs); } %} -function print_backtrace(){_print_backtrace()} - -function _backtrace () %{ - if (CONTEXT && CONTEXT->regs) { +function backtrace () %{ + if (CONTEXT->regs) { String str = _stp_string_init (0); _stp_stack_sprint (str, CONTEXT->regs, 0); strlcpy (THIS->__retvalue, _stp_string_ptr(str), MAXSTRINGLEN); } else strlcpy (THIS->__retvalue, "", MAXSTRINGLEN); %} -function backtrace(){return "" . _backtrace()} -function _execname () %{ - if(unlikely(in_interrupt())) +function execname:string () %{ + if (unlikely(in_interrupt())) strlcpy (THIS->__retvalue, "<unknown>", MAXSTRINGLEN); else - strlcpy (THIS->__retvalue, current->comm, MAXSTRINGLEN); + strlcpy (THIS->__retvalue, current->comm, MAXSTRINGLEN); %} -function execname(){return ""._execname()} -function _pid() %{ - if(unlikely(in_interrupt())) +function pid:long () %{ + if (unlikely(in_interrupt())) THIS->__retvalue = 0; else THIS->__retvalue = current->pid; %} -function pid(){return 0+_pid()} -function _ppid() %{ - if(unlikely(in_interrupt() || !current->parent)) +function ppid:long () %{ + if (unlikely(in_interrupt() || !current->parent)) THIS->__retvalue = 0; else THIS->__retvalue = current->parent->pid; %} -function ppid(){return 0+_ppid()} -function _pexecname() %{ +function pexecname:string () %{ if(unlikely(in_interrupt() || !current->parent || !current->parent->comm)) strlcpy (THIS->__retvalue, "<unknown>", MAXSTRINGLEN); else strlcpy (THIS->__retvalue, current->parent->comm, MAXSTRINGLEN); %} -function pexecname(){return ""._pexecname()} -function _gid() %{ +function gid:long () %{ if(unlikely(in_interrupt())) THIS->__retvalue = 0; else THIS->__retvalue = current->gid; %} -function gid(){return 0+_gid()} -function _egid() %{ +function egid:long () %{ if(unlikely(in_interrupt())) THIS->__retvalue = 0; else THIS->__retvalue = current->egid; %} -function egid(){return 0+_egid()} -function _uid() %{ +function uid:long () %{ if(unlikely(in_interrupt())) THIS->__retvalue = 0; else THIS->__retvalue = current->uid; %} -function uid(){return 0+_uid()} -function _euid() %{ +function euid:long () %{ if(unlikely(in_interrupt())) THIS->__retvalue = 0; else THIS->__retvalue = current->euid; %} -function euid(){return 0+_euid()} -function _print_stack(stk) %{ +function print_stack(stk:string) %{ char *ptr = THIS->stk; char *tok = strsep(&ptr, " "); _stp_printf ("trace for %d (%s)\n", current->pid, current->comm); @@ -99,4 +87,3 @@ function _print_stack(stk) %{ tok = strsep(&ptr, " "); } %} -function print_stack (stk) {_print_stack("".stk)} diff --git a/tapset/conversions.stp b/tapset/conversions.stp index 5c0230d4..901f26a4 100644 --- a/tapset/conversions.stp +++ b/tapset/conversions.stp @@ -1,14 +1,8 @@ -function _hexstring (num) %{ +function hexstring:string (num:long) %{ sprintf (THIS->__retvalue, "0x%llx", (long long) THIS->num); %} -function hexstring (num) { - return "" . _hexstring (num + 0) -} -function _string (num) %{ +function string:string (num:long) %{ sprintf (THIS->__retvalue, "%lld", (long long) THIS->num); %} -function string (num) { - return "" . _string (num + 0) -} diff --git a/tapset/logging.stp b/tapset/logging.stp index a2abf922..eff7b555 100644 --- a/tapset/logging.stp +++ b/tapset/logging.stp @@ -1,44 +1,28 @@ # This file contains simple bridging functions to the runtime -function _print (msg) %{ +function print (msg:string) %{ _stp_print (THIS->msg); %} -function print (msg) { - _print (msg . "\n") -} - -// same as print +// almost the same as print function log (msg) { - _print (msg . "\n") + print (msg . "\n") } -function _printk (msg) %{ +function printk (msg:string) %{ printk (KERN_INFO "%s\n", THIS->msg); %} -function printk (msg) { - _printk (msg . "") -} - -function _warn (msg) %{ +function warn (msg:string) %{ _stp_warn ("%s", THIS->msg); %} -function warn (msg) { - _warn (msg . "") -} - // NB: exit() does *not* cause immediate return from current function/probe function exit () %{ _stp_exit (); %} -function _error (msg) %{ +function error (msg:string) %{ CONTEXT->last_error = "called error()"; /* kill current probe */ _stp_error ("%s", THIS->msg); /* implies _stp_exit */ %} - -function error (msg) { - _error (msg . "") -} diff --git a/tapset/timestamp.stp b/tapset/timestamp.stp index f8e1ea4e..b71841d4 100644 --- a/tapset/timestamp.stp +++ b/tapset/timestamp.stp @@ -3,14 +3,14 @@ %} // return in milliseconds since epoch -function gettimeofday_ms () %{ +function gettimeofday_ms:long () %{ struct timeval tm; do_gettimeofday (& tm); THIS->__retvalue = (tm.tv_sec * 1000) + (tm.tv_usec / 1000); %} // return in seconds since epoch -function gettimeofday_s () %{ +function gettimeofday_s:long () %{ struct timeval tm; do_gettimeofday (& tm); THIS->__retvalue = tm.tv_sec; diff --git a/testsuite/parseok/twelve.stp b/testsuite/parseok/twelve.stp index d5029d1a..2e20da18 100755 --- a/testsuite/parseok/twelve.stp +++ b/testsuite/parseok/twelve.stp @@ -6,7 +6,7 @@ /* hello world */ %} -function foo (p1, p2) %{ +function foo:long (p1:string, p2:long, p3) %{ /* goodbye world */ %} diff --git a/testsuite/semko/nineteen.stp b/testsuite/semko/nineteen.stp index 04a9af20..bd8a4129 100755 --- a/testsuite/semko/nineteen.stp +++ b/testsuite/semko/nineteen.stp @@ -1,4 +1,4 @@ -#! stap -p4 +#! stap -p2 # PR 1155: should start working when we can resolve the parameters of # the inlines. diff --git a/testsuite/semko/twenty.stp b/testsuite/semko/twenty.stp new file mode 100755 index 00000000..899efdc1 --- /dev/null +++ b/testsuite/semko/twenty.stp @@ -0,0 +1,7 @@ +#! stap -p2 + +function a:string () { } + +probe begin { + a() + 1 +} diff --git a/testsuite/semok/seven.stp b/testsuite/semok/seven.stp index 73264923..f0b248bd 100755 --- a/testsuite/semok/seven.stp +++ b/testsuite/semok/seven.stp @@ -2,8 +2,8 @@ global ar1, ar2 -function string (v) { num=v+0; return "stringify me" } # to become a built-in -function printk (s) { str=s.""; return 0 } # to become a built-in +function string:string (v:long) { } # to become a built-in +function printk (s:string) { return 0 } # to become a built-in function search (key) { |