From: Justin Seyster Date: Fri, 12 Feb 2010 02:41:41 +0000 (-0500) Subject: Added weaving function. X-Git-Tag: release-v1.0~122 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=7a5feb266b2cddb8fe8d5bf4b1d52502aa1ae8e8;p=interaspect.git Added weaving function. --- diff --git a/src/Makefile.am b/src/Makefile.am index cb075f2..3555dbe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 0000000..770d4c3 --- /dev/null +++ b/src/aop-weave.c @@ -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 . +*/ + + +/* 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 + +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/src/aop.h b/src/aop.h index b46ffdd..33a2f56 100644 --- 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