diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | runtime/ChangeLog | 5 | ||||
-rw-r--r-- | runtime/map-values.c | 9 | ||||
-rw-r--r-- | runtime/map.h | 2 | ||||
-rwxr-xr-x | testsuite/buildok/twelve.stp | 31 | ||||
-rw-r--r-- | translate.cxx | 44 |
6 files changed, 95 insertions, 2 deletions
@@ -1,3 +1,9 @@ +2005-08-12 Graydon Hoare <graydon@redhat.com> + + * translate.cxx (c_tmpcounter::visit_array_in): Implement. + (c_unparser::visit_array_in): Likewise. + (mapvar::exists): New method. + 2005-08-12 Frank Ch. Eigler <fche@elastic.org> PR systemtap/1122 et alii diff --git a/runtime/ChangeLog b/runtime/ChangeLog index c0e2ac65..69864f19 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,8 @@ +2005-08-12 Graydon Hoare <graydon@redhat.com> + + * map-values.c (_stp_map_entry_exists): New function. + * map.h (_stp_map_entry_exists): Declare it. + 2005-08-12 Frank Ch. Eigler <fche@elastic.org> * arith.c: New file to contain arithmetic helper functions. diff --git a/runtime/map-values.c b/runtime/map-values.c index f0df9563..32cfb59d 100644 --- a/runtime/map-values.c +++ b/runtime/map-values.c @@ -51,5 +51,14 @@ void _stp_map_add_int64 (MAP map, int64_t val) } #endif +unsigned _stp_map_entry_exists (MAP map) +{ + struct map_node *m; + if (map == NULL || map->create || map->key == NULL) + return 0; + return 1; +} + + #endif /* _MAP_VALUES_C_ */ diff --git a/runtime/map.h b/runtime/map.h index 2a31fa8e..857751d2 100644 --- a/runtime/map.h +++ b/runtime/map.h @@ -241,5 +241,7 @@ void _stp_list_add_string(MAP, String); void _stp_map_key_int64(MAP, int64_t); void _stp_map_set_int64(MAP, int64_t); int64_t _stp_map_get_int64(MAP); + +unsigned _stp_map_entry_exists(MAP); /** @endcond */ #endif /* _MAP_H_ */ diff --git a/testsuite/buildok/twelve.stp b/testsuite/buildok/twelve.stp new file mode 100755 index 00000000..f30e0813 --- /dev/null +++ b/testsuite/buildok/twelve.stp @@ -0,0 +1,31 @@ +#! stap -p4 + +# testing the "in" operator + +global foo, goo, moo + +probe begin +{ + foo[10] = "a" + goo["a",12,"c",14,"d"] = 10 + moo[1,2,3,4,5] = "hello" + + if (10 in foo) + { + foo[10] = "yes" + } + + if (["a",12,"c",14,"d"] in goo) + { + goo["p",1,"q",2,"r"] += (12 in foo) + } + + x = 1 + y = 2 + z = 3 + + if ([x,y,z,y,x] in moo) + { + foo[30] = moo[(x in foo), (y in foo), (z in foo), (y in foo), (x in foo)] + } +} diff --git a/translate.cxx b/translate.cxx index 6b3ee308..c2425b84 100644 --- a/translate.cxx +++ b/translate.cxx @@ -150,7 +150,7 @@ struct c_tmpcounter: void visit_post_crement (post_crement* e); // void visit_logical_or_expr (logical_or_expr* e); // void visit_logical_and_expr (logical_and_expr* e); - // void visit_array_in (array_in* e); + void visit_array_in (array_in* e); // void visit_comparison (comparison* e); void visit_concatenation (concatenation* e); // void visit_ternary_expression (ternary_expression* e); @@ -322,6 +322,11 @@ struct mapvar return "_stp_map_key_del (" + qname() + ")"; } + string exists () const + { + return "_stp_map_entry_exists (" + qname() + ")"; + } + string seek (vector<tmpvar> const & indices) const { string result = "_stp_map_key" + mangled_indices() + " ("; @@ -1600,10 +1605,45 @@ c_unparser::visit_logical_and_expr (logical_and_expr* e) } +void +c_tmpcounter::visit_array_in (array_in* e) +{ + vardecl* r = e->operand->referent; + + // One temporary per index dimension. + for (unsigned i=0; i<r->index_types.size(); i++) + { + tmpvar ix = parent->gensym (r->index_types[i]); + ix.declare (*parent); + e->operand->indexes[i]->visit(this); + } + + // A boolean result. + tmpvar res = parent->gensym (e->type); + res.declare (*parent); +} + + void c_unparser::visit_array_in (array_in* e) { - throw semantic_error ("array-in expression not yet implemented", e->tok); + stmt_expr block(*this); + + vector<tmpvar> idx; + load_map_indices (e->operand, idx); + + tmpvar res = gensym (pe_long); + + o->newline() << "if (unlikely (c->errorcount)) goto out;"; + + { + mapvar mvar = getmap (e->operand->referent, e->tok); + varlock guard (*this, mvar); + o->newline() << mvar.seek (idx) << ";"; + c_assign (res, mvar.exists(), e->tok); + } + + o->newline() << res << ";"; } |