Generic param capture for pointcut
authorKetan Dixit <ketan.dixit@gmail.com>
Thu, 16 Sep 2010 00:06:29 +0000 (20:06 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Wed, 22 Sep 2010 02:59:03 +0000 (22:59 -0400)
src/aop-dynval.h
src/aop-pc-entry.c
src/aop-pointcut.c
src/aop-pointcut.h
src/aop.h

index 3c32266121f70fd565d7a8cd06e0406658844eb3..bb706f78f0e057ac0cbfcf9772f45bff3da3d058 100644 (file)
@@ -28,6 +28,10 @@ enum aop_dvkind {
   ADV_ASSIGN_VAL,
 };
 
+struct aop_dynval_in_param {
+  int param_index;
+};
+
 struct aop_dynval_fun_call {
   int param_index;
 };
@@ -44,6 +48,7 @@ struct aop_dynval
  
   union {
     struct aop_dynval_fun_call dynval_call;
+    struct aop_dynval_in_param dynval_in_param;
   };
 
   /* Ops vector for aop_dynval. */
index b1afec8523dc177dcc369c0d7fddb2eeee727552..49157fc43717c885d4aed26b76fcb55d05e88033 100644 (file)
 #include <gimple.h>
 #include <string.h>
 #include <tree-flow.h>
+#include <toplev.h>
 
 #include "aop.h"
 #include "aop-duplicate.h"
+#include "aop-dynval.h"
 #include "aop-pointcut.h"
 #include "aop-type.h"
 
@@ -84,7 +86,8 @@ is_function_entry_matching (struct aop_pointcut *pc)
       const char *func_name =
        IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
       return (strcmp (func_name, pc->pc_entry.function_name) == 0);
-    }  
+    }
+  return check_in_params (pc);
 }
 
 /* We represent the function's entry as a control-flow graph edge.
@@ -199,6 +202,7 @@ aop_match_function_entry ()
   pc->prepare_for_weave = op_prepare_entry;
 
   pc->pc_entry.function_name = NULL;
+  pc->in_param_list_head = NULL;
   return pc;
 }
 
@@ -208,6 +212,54 @@ void aop_filter_entry_by_name(struct aop_pointcut *pc_function_entry,
   pc_function_entry->pc_entry.function_name = advice_function_entry;
 }
 
+/**
+ * Filter a function entry pointcut to only include function entries
+ * with a parameter that matches a specified type.  This filter removes join
+ * points when parameter n does not match type or when there is no
+ * parameter n.
+ *
+ * Filters on the same parameter do not stack on top of each other.
+ * If multiple parameter filters with the same n are applied a
+ * pointcut, only the last one will have any effect.
+ *
+ * Note that you must filter a parameter by its type in order to
+ * capture it with aop_capture_in_param().
+ * \param pc The function call pointcut to filter.  Function entry
+ * pointcuts are created with aop_match_function_entry().
+ * \param n The index of the parameter to filter on.  Parameters are
+ * indexed from zero.
+ * \param The parameter type to filter by.
+ */
+void
+aop_filter_entry_by_in_param (struct aop_pointcut *pc, int n,
+                            const struct aop_type *type)
+{
+  struct aop_param_desc *param = NULL;
+  struct aop_param_desc *iter;
+  /* Is there already a filter for this parameter? */
+  for (iter = pc->in_param_list_head ; iter != NULL ; iter = iter->next)
+    {
+      if (iter->param_index == n)
+       {
+         param = iter;
+         break;
+       }
+    }
+
+  /* No? Then create one and add it to the list. */
+  if (param == NULL)
+    {
+      param = ggc_alloc (sizeof (struct aop_param_desc));
+
+      param->next = pc->in_param_list_head;
+      pc->in_param_list_head = param;
+    }
+
+  param->param_index = n;
+  param->type = type;
+}
+
 /* Close Doxygen defgroup block. */
 /**
  * \}
index 36636666fa4c7bdb9cb7393297aebc7eec2733f8..7d61d69c7c2bebe8d080d55751293cf4661a19a2 100644 (file)
 #include <config.h>
 #include <system.h>
 #include <coretypes.h>
+#include <toplev.h>
 #include <tm.h>
 #include <ggc.h>
 #include <gimple.h>
 
 #include "aop.h"
+#include "aop-dynval.h"
 #include "aop-pointcut.h"
+#include "aop-type.h"
 
 /* Allocates a pointcut and initializes it with default values. */
 struct aop_pointcut *
@@ -78,3 +81,123 @@ aop_capture_file_name (struct aop_joinpoint *jp)
 {
   return jp->file;
 }
+
+static tree
+op_get_in_param (struct aop_dynval *dv)
+{
+  gimple stmt;
+  tree param;
+  tree param_iter;
+  struct aop_joinpoint *jp = dv->jp;
+  int index = 0;
+
+  aop_assert (dv->kind == ADV_FUN_PARAM);
+  aop_assert (jp->pc->kind == ATP_ENTRY);
+
+  stmt = jp->stmt;
+  
+  for (param_iter = DECL_ARGUMENTS (current_function_decl);
+       param_iter; param_iter = TREE_CHAIN (param_iter))
+    {
+      if (index == dv->dynval_in_param.param_index)
+       {
+         param = param_iter;
+         param = stabilize_reference (param);
+         break;
+       }
+      index++;       
+    }  
+  return param;
+}
+
+/**
+ * Get a dynval representing parameter n passed to a function call.
+ * Note that you must use aop_filter_entry_by_in_param() to filter a
+ * pointcut by parameter type for any parameter you wish to capture
+ * with this function.
+ * \param jp A function call join point.  Function entry join points
+ * are obtained by joining on an aop_match_function_entry() pointcut.
+ * \param n The index of the parameter to capture.  Parameters are
+ * indexed from zero.
+ * \return A dynval with its type determined by
+ * aop_filter_call_pc_by_param().
+ */
+struct aop_dynval *
+aop_capture_in_param (struct aop_joinpoint *jp, int n)
+{
+  struct aop_pointcut *pc;
+  struct aop_dynval *dv;
+  struct aop_param_desc *param;
+
+  pc = jp->pc;
+  if (pc->kind != ATP_ENTRY)
+    fatal_error ("(InterAspect) Attempt to capture parameter from an"
+                " unsupported join point.");
+
+  /* Search for an aop_param_desc for this parameter, so that we know
+     its type. */
+  for (param = pc->in_param_list_head; param != NULL; param = param->next)
+    if (param->param_index == n)
+      break;  /* Found it. */
+
+  /* If we don't find the appropriate aop_param_desc, param will be NULL. */
+  if (param == NULL)
+    fatal_error ("(InterAspect) Attempt to capture parameter without specifying"
+                " type.");
+
+  dv = ggc_alloc (sizeof (struct aop_dynval));
+  dv->kind = ADV_FUN_PARAM;
+  dv->type = param->type;
+  dv->jp = jp;
+  dv->get_dynval = op_get_in_param;
+  dv->dynval_in_param.param_index = n;
+  return dv;
+}
+
+bool
+check_in_param (struct aop_param_desc *param_desc)
+{
+   tree param_type;
+   tree param_decl;
+   int index = 0;
+   bool index_found = false;
+   for (param_decl = DECL_ARGUMENTS (current_function_decl);
+       param_decl; param_decl = TREE_CHAIN (param_decl))
+     {
+       if (index == param_desc->param_index)
+        {
+          /* Index found check the type */
+          if ((param_type = TREE_TYPE (param_decl)) == NULL
+              || !does_type_match (param_type, param_desc->type))
+            index_found = false;
+          else
+            index_found = true;
+
+          break;
+        }
+       index++;
+     }
+   return index_found;
+}
+
+bool
+check_in_params (struct aop_pointcut *pc)
+{
+  struct aop_param_desc *param_desc;
+  bool params_matched = false;
+    /* Check parameter types. */
+  for (param_desc = pc->in_param_list_head ; param_desc != NULL ;
+       param_desc = param_desc->next)
+    {     
+      if(!check_in_param (param_desc))
+       {
+         params_matched = false;
+         break;
+       }
+      else
+       {
+         params_matched = true;
+       }
+    }
+  return params_matched;
+}
index 1cd103c6c45736ffee4ebe4ebf4b232ab6a9ea3d..00a7bce04ba1ef0298aadfbd3b88cf4ca7644ee6 100644 (file)
@@ -76,6 +76,8 @@ struct aop_pointcut {
      any advice gets inserted at that joinpoint.  */
   void (*prepare_for_weave) (struct aop_joinpoint *);
 
+  struct aop_param_desc *in_param_list_head;
+
   union {
     struct aop_pc_assign pc_assign;
     struct aop_pc_entry pc_entry;
@@ -124,4 +126,5 @@ void op_default_prepare_for_weave (struct aop_joinpoint *jp);
 void op_default_insert_before (struct aop_joinpoint *jp, gimple stmt);
 void op_default_insert_after (struct aop_joinpoint *jp, gimple stmt);
 
+bool check_in_params (struct aop_pointcut *pc);
 #endif
index fb322dc605294e2299139c68ca22dc9164751fd6..2e5393dbb084ec70943f2b99a76b071f496033e1 100644 (file)
--- a/src/aop.h
+++ b/src/aop.h
@@ -254,6 +254,11 @@ enum aop_argkind {
 extern const char *aop_capture_function_name (struct aop_joinpoint *jp);
 
 extern struct aop_pointcut *aop_match_function_entry ();
+extern void aop_filter_entry_by_in_param (struct aop_pointcut *pc, int n,
+                                        const struct aop_type *type);
+extern struct aop_dynval *aop_capture_in_param (struct aop_joinpoint *jp,
+                                            int param_index);
+
 extern struct aop_pointcut *aop_match_function_exit ();
 
 extern void aop_filter_entry_by_name(struct aop_pointcut *pc_function_entry,