Added weaving function.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Fri, 12 Feb 2010 02:41:41 +0000 (21:41 -0500)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Fri, 12 Feb 2010 02:41:41 +0000 (21:41 -0500)
src/Makefile.am
src/aop-weave.c [new file with mode: 0644]
src/aop.h

index cb075f2f2a76489f015c71409a8ed41fb2a2b2dc..3555dbe99d1bcd067338936afa605269615699c1 100644 (file)
@@ -1,5 +1,5 @@
 lib_LTLIBRARIES = libinteraspect.la
-libinteraspect_la_SOURCES = aop-pc-assign.c aop-main.c aop-type.c
+libinteraspect_la_SOURCES = aop-pc-assign.c aop-main.c aop-type.c aop-weave.c
 libinteraspect_la_CFLAGS = -Wall -Werror -fvisibility=hidden -prefer-pic
 libinteraspect_la_LDFLAGS = -static -prefer-pic -version-info 1:0:0
 libinteraspect_la_CPPFLAGS = -DHAVE_CONFIG_H -DIN_GCC -I$(gcc_includes)
diff --git a/src/aop-weave.c b/src/aop-weave.c
new file mode 100644 (file)
index 0000000..770d4c3
--- /dev/null
@@ -0,0 +1,128 @@
+/* This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation, either version 3 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/* Whether we want them or not (we don't), Autoconf _insists_ on
+   defining these.  Since GCC's config.h (which we must include) also
+   defines them, we have to undef them here. */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <stdarg.h>
+
+#include <config.h>
+#include <system.h>
+#include <coretypes.h>
+#include <tm.h>
+#include <tree.h>
+#include <gimple.h>
+
+#include "aop.h"
+#include "aop-pointcut.h"
+
+static tree
+build_string_ptr (const char *string)
+{
+  size_t string_len;
+  tree string_tree;
+
+  tree string_ref;
+  tree ret;
+
+  string_len = strlen (string) + 1;
+
+  string_tree = build_string (string_len, string);
+  TREE_TYPE (string_tree) =
+    build_array_type (char_type_node, build_index_type (size_int (string_len)));
+
+  string_ref = build4(ARRAY_REF,
+                     char_type_node,
+                     string_tree,
+                     build_int_cst (TYPE_DOMAIN (TREE_TYPE (string_tree)), 0),
+                     NULL,
+                     NULL);
+
+  ret = build1(ADDR_EXPR,
+              build_pointer_type (TREE_TYPE (string_ref)),
+              string_ref);
+
+  return ret;
+}
+
+/* Weaving functions all take varags parameters that represent the
+   arguments to pass to the new advice function.  This function
+   iterates through those arguments and creates GIMPLE tree nodes for
+   each of them. 
+
+   The new nodes get stored in arglist. */
+static gimple
+build_gcc_call (const char *func_name, tree return_type, va_list argp)
+{
+  enum aop_argkind kind;
+  VEC(tree, heap) *arg_list;
+  tree argtype_list;
+
+  tree func_type;
+  tree func_decl;
+  gimple func_call;
+
+  arg_list = VEC_alloc (tree, heap, 2);
+  argtype_list = void_list_node;
+
+  while ((kind = va_arg (argp, enum aop_argkind)) != AOP_TERM_ARG)
+    {
+      tree new_arg;
+      const char *str_cst;
+
+      switch (kind)
+       {
+       case ATA_STR_CST:
+         str_cst = va_arg (argp, const char *);
+         new_arg = build_string_ptr (str_cst);
+         VEC_safe_push (tree, heap, arg_list, new_arg);
+         break;
+       default:
+         aop_assert (0);
+       }
+
+      argtype_list = tree_cons (NULL_TREE, TREE_TYPE (new_arg), argtype_list);
+    }
+
+  /* Using tree_cons builds the list backwards!  Un-backwards it. */
+  argtype_list = nreverse (argtype_list);
+
+  func_type = build_function_type (return_type, argtype_list);
+  func_decl = build_fn_decl (func_name, func_type);
+  func_call = gimple_build_call_vec (func_decl, arg_list);
+
+  VEC_free (tree, heap, arg_list);
+
+  return func_call;
+}
+
+void
+aop_do_weave (struct aop_joinpoint *jp, const char *func_name, ...)
+{
+  va_list argp;
+  gimple func_call;
+
+  va_start (argp, func_name);
+  func_call = build_gcc_call (func_name, void_type_node, argp);
+  va_end (argp);
+
+  gsi_insert_before (jp->gsi, func_call, GSI_SAME_STMT);
+}
index b46ffdd7962a2322d44b240102eae1953d209e95..33a2f56a1aea2c1ddefe8e89c9a274bc89a37ccc 100644 (file)
--- a/src/aop.h
+++ b/src/aop.h
@@ -58,6 +58,8 @@ extern struct aop_pointcut *aop_match_assignment_by_type (struct aop_type *type)
 
 extern const char *aop_capture_lhs_name (struct aop_joinpoint *jp);
 
+extern void aop_do_weave (struct aop_joinpoint *jp, const char *name, ...);
+
 extern void aop_register_pass (const char *pass_name, pass_callback callback);
 extern void aop_join_on (struct aop_pointcut *pc, join_callback callback);
 extern void aop_main ();
@@ -65,4 +67,16 @@ extern void aop_main ();
 extern void aop_abort (const char *filename, int lineno, const char *function)
   __attribute__((noreturn));
 
+/* Fancy macro magic used for the varargs component of do_weave
+   functions. */
+
+enum aop_argkind {
+  ATA_STR_CST,
+  ATA_DYNVAL,
+  AOP_TERM_ARG,
+};
+
+#define AOP_STR_CST(VAL) ATA_STR_CST, VAL
+#define AOP_DYNVAL(VAL) ATA_DYNVAL, VAL
+
 #endif