diff options
author | jistone <jistone> | 2006-12-22 02:34:05 +0000 |
---|---|---|
committer | jistone <jistone> | 2006-12-22 02:34:05 +0000 |
commit | ef474d24145b85f933d06a1648b0d9cbf6695fe5 (patch) | |
tree | 4025671f55ad05735ad61d94cca720aa33c4d65e | |
parent | 9c66f4e068e743727dfec5acec6547cd18a4030c (diff) | |
download | systemtap-steved-ef474d24145b85f933d06a1648b0d9cbf6695fe5.tar.gz systemtap-steved-ef474d24145b85f933d06a1648b0d9cbf6695fe5.tar.xz systemtap-steved-ef474d24145b85f933d06a1648b0d9cbf6695fe5.zip |
2006-12-21 Josh Stone <joshua.i.stone@intel.com>
PR 3671
* parse.cxx (parser::parse_global): Allow a maxsize on global arrays.
* staptree.h (struct vardecl): Add the maxsize field.
* staptree.cxx (vardecl::vardecl): Init. maxsize.
(vardecl::set_arity): Don't allow arity 0 when there's a maxsize.
(vardecl::compatible_arity): Ditto.
(vardecl::print): Include maxsize in output.
(target_symbol::print): Ditto.
* translate.cxx (struct mapvar, mapvar::mapvar): Add maxsize.
(mapvar::init): Init maps with the given maxsize if specified, else
keep using MAXMAPENTRIES.
(mapvar::set): Make the error message give the maxsize.
(mapvar::add): Ditto, and check for overflow on pmap add.
(c_unparser::getmap): Pass the maxsize from the vardecl to mapvar.
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | parse.cxx | 29 | ||||
-rw-r--r-- | staptree.cxx | 13 | ||||
-rw-r--r-- | staptree.h | 1 | ||||
-rw-r--r-- | translate.cxx | 29 |
5 files changed, 73 insertions, 16 deletions
@@ -1,3 +1,20 @@ +2006-12-21 Josh Stone <joshua.i.stone@intel.com> + + PR 3671 + * parse.cxx (parser::parse_global): Allow a maxsize on global arrays. + * staptree.h (struct vardecl): Add the maxsize field. + * staptree.cxx (vardecl::vardecl): Init. maxsize. + (vardecl::set_arity): Don't allow arity 0 when there's a maxsize. + (vardecl::compatible_arity): Ditto. + (vardecl::print): Include maxsize in output. + (target_symbol::print): Ditto. + * translate.cxx (struct mapvar, mapvar::mapvar): Add maxsize. + (mapvar::init): Init maps with the given maxsize if specified, else + keep using MAXMAPENTRIES. + (mapvar::set): Make the error message give the maxsize. + (mapvar::add): Ditto, and check for overflow on pmap add. + (c_unparser::getmap): Pass the maxsize from the vardecl to mapvar. + 2006-12-21 David Smith <dsmith@redhat.com> * hash.cxx (find_hash): Added two more options into the hash that @@ -1043,14 +1043,29 @@ parser::parse_global (vector <vardecl*>& globals, vector<probe*>& probes) globals.push_back (d); t = peek (); + + if (t && t->type == tok_operator && t->content == "[") // array size + { + int64_t size; + next (); + expect_number(size); + if (size <= 0 || size > 1000000) // arbitrary max + throw parse_error("array size out of range"); + d->maxsize = (int)size; + expect_known(tok_operator, "]"); + t = peek (); + } + if (t && t->type == tok_operator && t->content == "=") // initialization - { - next (); - d->init = parse_literal (); - d->set_arity(0); - d->type = d->init->type; - t = peek (); - } + { + if (!d->compatible_arity(0)) + throw parse_error("only scalar globals can be initialized"); + d->set_arity(0); + next (); + d->init = parse_literal (); + d->type = d->init->type; + t = peek (); + } if (t && t->type == tok_operator && t->content == ",") // next global { diff --git a/staptree.cxx b/staptree.cxx index aa464469..151d6863 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -104,7 +104,7 @@ probe_point::component::component (std::string const & f, literal * a): vardecl::vardecl (): - arity (-1), init(NULL) + arity (-1), maxsize(0), init(NULL) { } @@ -115,7 +115,7 @@ vardecl::set_arity (int a) if (a < 0) return; - if (arity != a && arity >= 0) + if ((arity != a && arity >= 0) || (a == 0 && maxsize > 0)) throw semantic_error ("inconsistent arity", tok); if (arity != a) @@ -130,6 +130,8 @@ vardecl::set_arity (int a) bool vardecl::compatible_arity (int a) { + if (a == 0 && maxsize > 0) + return false; if (arity == -1 || a == -1) return true; return arity == a; @@ -265,6 +267,8 @@ void target_symbol::print (std::ostream& o) const void vardecl::print (ostream& o) const { o << name; + if (maxsize > 0) + o << "[" << maxsize << "]"; if (arity > 0 || index_types.size() > 0) o << "[...]"; if (init) @@ -277,7 +281,10 @@ void vardecl::print (ostream& o) const void vardecl::printsig (ostream& o) const { - o << name << ":" << type; + o << name; + if (maxsize > 0) + o << "[" << maxsize << "]"; + o << ":" << type; if (index_types.size() > 0) { o << " ["; @@ -395,6 +395,7 @@ struct vardecl: public symboldecl void set_arity (int arity); bool compatible_arity (int a); int arity; // -1: unknown; 0: scalar; >0: array + int maxsize; // upperbound on size for arrays std::vector<exp_type> index_types; // for arrays only literal *init; // for global scalars only }; diff --git a/translate.cxx b/translate.cxx index d37600da..c20cde8d 100644 --- a/translate.cxx +++ b/translate.cxx @@ -435,12 +435,15 @@ struct mapvar : public var { vector<exp_type> index_types; + int maxsize; mapvar (bool local, exp_type ty, statistic_decl const & sd, string const & name, - vector<exp_type> const & index_types) + vector<exp_type> const & index_types, + int maxsize) : var (local, ty, sd, name), - index_types (index_types) + index_types (index_types), + maxsize (maxsize) {} static string shortname(exp_type e); @@ -547,11 +550,20 @@ struct mapvar string add (vector<tmpvar> const & indices, tmpvar const & val) const { + string res = "{ int rc = "; + // impedance matching: empty strings -> NULL if (type() == pe_stats) - return (call_prefix("add", indices) + ", " + val.qname() + ")"); + res += (call_prefix("add", indices) + ", " + val.qname() + ")"); else throw semantic_error("adding a value of an unsupported map type"); + + res += "; if (unlikely(rc)) c->last_error = \"Array overflow, check " + + stringify(maxsize > 0 ? + "size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES") + + "\"; }"; + + return res; } string set (vector<tmpvar> const & indices, tmpvar const & val) const @@ -567,7 +579,10 @@ struct mapvar else throw semantic_error("setting a value of an unsupported map type"); - res += "; if (unlikely(rc)) c->last_error = \"Array overflow, check MAXMAPENTRIES\"; }"; + res += "; if (unlikely(rc)) c->last_error = \"Array overflow, check " + + stringify(maxsize > 0 ? + "size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES") + + "\"; }"; return res; } @@ -589,7 +604,8 @@ struct mapvar string init () const { string mtype = is_parallel() ? "pmap" : "map"; - string prefix = qname() + " = _stp_" + mtype + "_new_" + keysym() + " (MAXMAPENTRIES" ; + string prefix = qname() + " = _stp_" + mtype + "_new_" + keysym() + " (" + + (maxsize > 0 ? stringify(maxsize) : "MAXMAPENTRIES") ; // Check for errors during allocation. string suffix = "if (" + qname () + " == NULL) rc = -ENOMEM;"; @@ -1905,7 +1921,8 @@ c_unparser::getmap(vardecl *v, token const *tok) i = session->stat_decls.find(v->name); if (i != session->stat_decls.end()) sd = i->second; - return mapvar (is_local (v, tok), v->type, sd, v->name, v->index_types); + return mapvar (is_local (v, tok), v->type, sd, + v->name, v->index_types, v->maxsize); } |