[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc-python-plugin-commits
Subject:    [gcc-python-plugin] track which event we're within when a callback fires
From:       dmalcolm () fedoraproject ! org (dmalcolm)
Date:       2011-10-25 19:55:03
Message-ID: 20111025195503.CF5E412020B () lists ! fedorahosted ! org
[Download RAW message or body]

commit 2143f3f09a10f522a506ec6792f7bc7d0aab3e50
Author: David Malcolm <dmalcolm at redhat.com>
Date:   Tue Oct 25 15:49:51 2011 -0400

    track which event we're within when a callback fires
    
    This will be of use when bulletproofing certain APIs that can only
    be called at certain times within the compilation.

 gcc-python-closure.c |   15 ++++++++++++++-
 gcc-python-closure.h |   12 +++++++++++-
 gcc-python-gimple.c  |    2 +-
 gcc-python.c         |   25 ++++++++++++++++++++++++-
 gcc-python.h         |    5 +++++
 5 files changed, 55 insertions(+), 4 deletions(-)
---
diff --git a/gcc-python-closure.c b/gcc-python-closure.c
index c6f83dc..5c9b8ae 100644
--- a/gcc-python-closure.c
+++ b/gcc-python-closure.c
@@ -25,7 +25,7 @@
 #include "function.h"
 
 struct callback_closure *
-gcc_python_closure_new(PyObject *callback, PyObject *extraargs, PyObject *kwargs)
+gcc_python_closure_new_generic(PyObject *callback, PyObject *extraargs, PyObject *kwargs)
 {
     struct callback_closure *closure;
 
@@ -59,6 +59,19 @@ gcc_python_closure_new(PyObject *callback, PyObject *extraargs, PyObject *kwargs
 	Py_INCREF(kwargs);
     }
 
+    closure->event = GCC_PYTHON_PLUGIN_BAD_EVENT;
+
+    return closure;
+}
+
+struct callback_closure *
+gcc_python_closure_new_for_plugin_event(PyObject *callback, PyObject *extraargs, PyObject *kwargs,
+                                        enum plugin_event event)
+{
+    struct callback_closure *closure = gcc_python_closure_new_generic(callback, extraargs, kwargs);
+    if (closure) {
+        closure->event = event;
+    }
     return closure;
 }
 
diff --git a/gcc-python-closure.h b/gcc-python-closure.h
index 99dc170..7950fbc 100644
--- a/gcc-python-closure.h
+++ b/gcc-python-closure.h
@@ -25,10 +25,20 @@ struct callback_closure
     PyObject *callback;
     PyObject *extraargs;
     PyObject *kwargs;
+    enum plugin_event event;
+      /* or GCC_PYTHON_PLUGIN_BAD_EVENT if not an event */
 };
 
 struct callback_closure *
-gcc_python_closure_new(PyObject *callback, PyObject *extraargs, PyObject *kwargs);
+gcc_python_closure_new_generic(PyObject *callback,
+                               PyObject *extraargs,
+                               PyObject *kwargs);
+
+struct callback_closure *
+gcc_python_closure_new_for_plugin_event(PyObject *callback,
+                                        PyObject *extraargs,
+                                        PyObject *kwargs,
+                                        enum plugin_event event);
 
 PyObject *
 gcc_python_closure_make_args(struct callback_closure * closure,
diff --git a/gcc-python-gimple.c b/gcc-python-gimple.c
index 7baec2b..8e24408 100644
--- a/gcc-python-gimple.c
+++ b/gcc-python-gimple.c
@@ -119,7 +119,7 @@ gcc_Gimple_walk_tree(struct PyGccGimple * self, PyObject *args, PyObject *kwargs
     callback = PyTuple_GetItem(args, 0);
     extraargs = PyTuple_GetSlice(args, 1, PyTuple_Size(args));
 
-    closure = gcc_python_closure_new(callback, extraargs, kwargs);
+    closure = gcc_python_closure_new_generic(callback, extraargs, kwargs);
     if (!closure) {
         return NULL;
     }
diff --git a/gcc-python.c b/gcc-python.c
index 30a6a17..544415f 100644
--- a/gcc-python.c
+++ b/gcc-python.c
@@ -149,6 +149,21 @@ static void trace_callback_for_##NAME(void *gcc_data, void *user_data) \
 # undef DEFEVENT
 #endif /* GCC_PYTHON_TRACE_ALL_EVENTS */
 
+static enum plugin_event current_event = GCC_PYTHON_PLUGIN_BAD_EVENT;
+
+int gcc_python_is_within_event(enum plugin_event *out_event)
+{
+    if (current_event != GCC_PYTHON_PLUGIN_BAD_EVENT) {
+        if (out_event) {
+            *out_event = current_event;
+        }
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+
 static void
 gcc_python_finish_invoking_callback(PyGILState_STATE gstate,
                                     int expect_wrapped_data, PyObject *wrapped_gcc_data,
@@ -158,6 +173,7 @@ gcc_python_finish_invoking_callback(PyGILState_STATE gstate,
     PyObject *args = NULL;
     PyObject *result = NULL;
     location_t saved_loc = input_location;
+    enum plugin_event saved_event;
 
     assert(closure);
     /* We take ownership of wrapped_gcc_data.
@@ -176,8 +192,14 @@ gcc_python_finish_invoking_callback(PyGILState_STATE gstate,
     if (!args) {
         goto cleanup;
     }
+
+    saved_event = current_event;
+    current_event = closure->event;
+
     result = PyObject_Call(closure->callback, args, closure->kwargs);
 
+    current_event = saved_event;
+
     if (!result) {
         /* Treat an unhandled Python error as a compilation error: */
         gcc_python_print_exception("Unhandled Python exception raised within callback");
@@ -277,7 +299,8 @@ gcc_python_register_callback(PyObject *self, PyObject *args, PyObject *kwargs)
 
     //printf("%s:%i:gcc_python_register_callback\n", __FILE__, __LINE__);
 
-    closure = gcc_python_closure_new(callback, extraargs, kwargs);
+    closure = gcc_python_closure_new_for_plugin_event(callback, extraargs, kwargs,
+                                                      (enum plugin_event)event);
     if (!closure) {
         return PyErr_NoMemory();
     }
diff --git a/gcc-python.h b/gcc-python.h
index f350ea7..55af6fa 100644
--- a/gcc-python.h
+++ b/gcc-python.h
@@ -25,6 +25,9 @@
 #include "gimple.h"
 #include "params.h"
 
+/* GCC doesn't seem to give us an ID for "invalid event", so invent one: */
+#define GCC_PYTHON_PLUGIN_BAD_EVENT (0xffff)
+
 /*
   Macro DECLARE_SIMPLE_WRAPPER():
     ARG_structname:
@@ -217,6 +220,8 @@ gcc_python_insert_new_wrapper_into_cache(PyObject **cache,
 
 
 /* gcc-python.c */
+int gcc_python_is_within_event(enum plugin_event *out_event);
+
 char * gcc_python_strdup(const char *str);
 
 void gcc_python_print_exception(const char *msg);

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic