[svn:parrot] r48164 - in branches/gsoc_instrument: runtime/parrot/library/Instrument src/dynpmc

khairul at svn.parrot.org khairul at svn.parrot.org
Thu Jul 22 06:26:56 UTC 2010


Author: khairul
Date: Thu Jul 22 06:26:55 2010
New Revision: 48164
URL: https://trac.parrot.org/parrot/changeset/48164

Log:
Implemented the NYIs in InstrumentClass.

Modified:
   branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp
   branches/gsoc_instrument/src/dynpmc/instrumentclass.pmc
   branches/gsoc_instrument/src/dynpmc/instrumentvtable.pmc

Modified: branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp
==============================================================================
--- branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp	Thu Jul 22 06:21:11 2010	(r48163)
+++ branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp	Thu Jul 22 06:26:55 2010	(r48164)
@@ -266,6 +266,7 @@
                 # We are trying to disable a hook that wasn't inserted.
                 # TODO: Ensure that the exception came from a place that we are expecting.
                 #       Otherwise rethrow. (How to do that in NQP?)
+                say("Disable: " ~ $!);
             }
         }
 

Modified: branches/gsoc_instrument/src/dynpmc/instrumentclass.pmc
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/instrumentclass.pmc	Thu Jul 22 06:21:11 2010	(r48163)
+++ branches/gsoc_instrument/src/dynpmc/instrumentclass.pmc	Thu Jul 22 06:26:55 2010	(r48164)
@@ -62,7 +62,8 @@
     METHOD get_method_list() {
         Parrot_InstrumentClass_attributes * const attr = PARROT_INSTRUMENTCLASS(SELF);
         PMC *_class;
-        PMC *methods;
+        PMC *methods, *method_list;
+        PMC *iter;
         Parrot_Interp supervised;
 
         GETATTR_Instrument_supervised(INTERP, attr->instrument, supervised);
@@ -70,7 +71,17 @@
         _class  = Parrot_oo_get_class_str(supervised, attr->class_name);
         methods = VTABLE_inspect_str(supervised, _class, CONST_STRING(INTERP, "methods"));
 
-        RETURN(PMC *methods);
+        method_list = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray);
+        iter        = VTABLE_get_iter(supervised, methods);
+
+        while(VTABLE_get_bool(supervised, iter)) {
+            PMC *key;
+
+            key = VTABLE_shift_pmc(supervised, iter);
+            VTABLE_push_pmc(INTERP, method_list, key);
+        }
+
+        RETURN(PMC *method_list);
     }
 
 /*
@@ -89,7 +100,8 @@
         PMC *_class, *methods, *method_sub;
         PMC *instr_obj, *rename, *rename_hash;
         STRING *invoke;
-         Parrot_Interp supervised;
+        INTVAL count;
+        Parrot_Interp supervised;
 
         invoke = CONST_STRING(INTERP, "invoke");
 
@@ -99,22 +111,38 @@
         (PMC *methods) = PCCINVOKE(INTERP, _class, "methods");
         method_sub     = VTABLE_get_pmc_keyed_str(INTERP, methods, method);
 
-        (PMC *instr_obj) =
-            PCCINVOKE(INTERP, attr->instrument, "instrument_object", PMC *method_sub);
-
-        /* Instrument its invoke vtable entry. */
-        () = PCCINVOKE(INTERP, instr_obj, "insert_hook", STRING *invoke);
-
-        /* Add an entry into the rename_hash attribute so that when an event
-           is raised, the event properly named. */
-        rename = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray);
-        VTABLE_push_string(INTERP, rename , CONST_STRING(INTERP, "Class"));
-        VTABLE_push_string(INTERP, rename , attr->class_name);
-        VTABLE_push_string(INTERP, rename , CONST_STRING(INTERP, "method"));
-        VTABLE_push_string(INTERP, rename , method);
-
-        GETATTR_InstrumentVtable_rename_hash(INTERP, instr_obj, rename_hash);
-        VTABLE_set_pmc_keyed_str(INTERP, rename_hash, invoke, rename);
+        /* Ensure that method exists. */
+        if (PMC_IS_NULL(method_sub)) {
+            Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
+                                        "Class %Ss does not have a method named %Ss.",
+                                        attr->class_name, method);
+        }
+
+        /* Check the count for this method. */
+        count = VTABLE_get_integer_keyed_str(INTERP, attr->instrumented_methods, method);
+        if (count == 0) {
+            /* Method was not instrumented before. */
+            (PMC *instr_obj) =
+                PCCINVOKE(INTERP, attr->instrument, "instrument_object", PMC *method_sub);
+
+            /* Instrument its invoke vtable entry. */
+            () = PCCINVOKE(INTERP, instr_obj, "insert_hook", STRING *invoke);
+
+            /* Add an entry into the rename_hash attribute so that when an event
+               is raised, the event properly named. */
+            rename = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray);
+            VTABLE_push_string(INTERP, rename , CONST_STRING(INTERP, "Class"));
+            VTABLE_push_string(INTERP, rename , attr->class_name);
+            VTABLE_push_string(INTERP, rename , CONST_STRING(INTERP, "method"));
+            VTABLE_push_string(INTERP, rename , method);
+
+            GETATTR_InstrumentVtable_rename_hash(INTERP, instr_obj, rename_hash);
+            VTABLE_set_pmc_keyed_str(INTERP, rename_hash, invoke, rename);
+        }
+
+        /* Update count. */
+        count++;
+        VTABLE_set_integer_keyed_str(INTERP, attr->instrumented_methods, method, count);
     }
 
 /*
@@ -128,14 +156,54 @@
 */
 
     METHOD remove_method_hook(STRING *method) {
-        /*
-        TODO: NYI
-        */
+        Parrot_InstrumentClass_attributes * const attr = PARROT_INSTRUMENTCLASS(SELF);
+        PMC *_class, *methods, *method_sub;
+        PMC *instr_obj, *rename_hash;
+        STRING *invoke;
+        INTVAL count;
+        Parrot_Interp supervised;
+
+        GETATTR_Instrument_supervised(INTERP, attr->instrument, supervised);
+
+        _class  = Parrot_oo_get_class_str(supervised, attr->class_name);
+        (PMC *methods) = PCCINVOKE(INTERP, _class, "methods");
+        method_sub     = VTABLE_get_pmc_keyed_str(INTERP, methods, method);
+
+        /* Ensure that method exists. */
+        if (PMC_IS_NULL(method_sub)) {
+            Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
+                                        "Class %Ss does not have a method named %Ss.",
+                                        attr->class_name, method);
+        }
+
+        /* Check the count for this method. */
+        count = VTABLE_get_integer_keyed_str(INTERP, attr->instrumented_methods, method);
+        if (count == 0) {
+            /* Not instrumented before. */
+        }
+        else if (count == 1) {
+            /* Remove the instrumentation. */
+            invoke = CONST_STRING(INTERP, "invoke");
+
+            /* The InstrumentObject instance for the override can
+               be obtained from the registry using the vtable pointer. */
+            instr_obj = (PMC *) parrot_hash_get(INTERP, attr->registry, method_sub->vtable);
+
+            /* Instrument its invoke vtable entry. */
+            () = PCCINVOKE(INTERP, instr_obj, "remove_hook", STRING *invoke);
+
+            GETATTR_InstrumentVtable_rename_hash(INTERP, instr_obj, rename_hash);
+            VTABLE_delete_keyed_str(INTERP, rename_hash, invoke);
+        }
+
+        /* Update count. */
+        count--;
+        VTABLE_set_integer_keyed_str(INTERP, attr->instrumented_methods, method, count);
     }
 
 /*
 
-=item C<PMC* get_method_instrumented_list()>
+=item C<PMC* get_instrumented_method_list()>
 
 Returns a list of methods that has active instrumentation.
 
@@ -143,10 +211,26 @@
 
 */
 
-    METHOD get_method_instrumented_list() {
-        /*
-        TODO: NYI
-        */
+    METHOD get_instrumented_method_list() {
+        Parrot_InstrumentClass_attributes * const attr = PARROT_INSTRUMENTCLASS(SELF);
+        PMC *list, *iter;
+
+        list = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray);
+
+        iter = VTABLE_get_iter(INTERP, attr->instrumented_methods);
+        while (VTABLE_get_bool(INTERP, iter)) {
+            PMC *key;
+            INTVAL count;
+
+            key = VTABLE_shift_pmc(INTERP, iter);
+            count = VTABLE_get_integer_keyed(INTERP, attr->instrumented_methods, key);
+
+            if(count > 0) {
+                VTABLE_push_pmc(INTERP, list, key);
+            }
+        }
+
+        RETURN(PMC *list);
     }
 }
 

Modified: branches/gsoc_instrument/src/dynpmc/instrumentvtable.pmc
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/instrumentvtable.pmc	Thu Jul 22 06:21:11 2010	(r48163)
+++ branches/gsoc_instrument/src/dynpmc/instrumentvtable.pmc	Thu Jul 22 06:26:55 2010	(r48164)
@@ -49,6 +49,7 @@
     ATTR STRING        *class_name;
     ATTR Parrot_Interp  supervisor;
     ATTR PMC           *rename_hash;
+    ATTR PMC           *vtable_overrides;
 
 /*
 
@@ -67,8 +68,9 @@
 
         /* Initialise the attributes.
            Other attributes are deferred to after attaching to a class. */
-        attr->supervisor  = INTERP;
-        attr->rename_hash = Parrot_pmc_new(INTERP, enum_class_Hash);
+        attr->supervisor       = INTERP;
+        attr->rename_hash      = Parrot_pmc_new(INTERP, enum_class_Hash);
+        attr->vtable_overrides = Parrot_pmc_new(INTERP, enum_class_Hash);
 
         /* Initialise the static hashes. */
         setup_vtable_common_hashes(INTERP);
@@ -156,7 +158,6 @@
     METHOD insert_hook(STRING *name) {
         Parrot_InstrumentVtable_attributes * const attr = PARROT_INSTRUMENTVTABLE(SELF);
         PMC *_class;
-        PMC *override;
         Parrot_Interp supervised;
         PMC *list;
         PMC *iter;
@@ -177,6 +178,7 @@
             count = VTABLE_get_integer_keyed_str(INTERP, attr->hook_count, item);
             if (count == 0) {
                 /* Look for a vtable override. */
+                PMC *override;
                 override = Parrot_oo_find_vtable_override_for_class(supervised, _class, name);
 
                 if (PMC_IS_NULL(override)) {
@@ -228,6 +230,89 @@
             VTABLE_set_integer_keyed_str(INTERP, attr->hook_count, item, count);
         }
     }
+
+/*
+
+=item C<void remove_hook(STRING *name)>
+
+Removes the stub function for the given entry given by name.
+If name denotes a group, removes stubs for all functions in that group.
+
+=cut
+
+*/
+
+    METHOD remove_hook(STRING *name) {
+        Parrot_InstrumentVtable_attributes * const attr = PARROT_INSTRUMENTVTABLE(SELF);
+        PMC *list;
+        PMC *iter;
+        PMC *_class;
+        Parrot_Interp supervised;
+
+        GETATTR_Instrument_supervised(INTERP, attr->instrument, supervised);
+        _class   = Parrot_oo_get_class_str(supervised, attr->class_name);
+
+        (PMC *list) = PCCINVOKE(INTERP, SELF, "get_hook_list", STRING *name);
+
+        iter = VTABLE_get_iter(INTERP, list);
+        while (VTABLE_get_bool(INTERP, iter)) {
+            INTVAL count;
+            PMC *item_pmc = VTABLE_shift_pmc(INTERP, iter);
+            STRING *item  = VTABLE_get_string(INTERP, item_pmc);
+            size_t **entry, *func;
+
+            /* Only remove the stub if request count == 1 => Last request. */
+            count = VTABLE_get_integer_keyed_str(INTERP, attr->hook_count, item);
+            if (count <= 0) {
+                /* Tried to remove 1 time too many. */
+                Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
+                                                "%Ss : Unknown function, '%Ss'",
+                                                VTABLE_name(INTERP, SELF), item);
+            }
+            else if (count == 1) {
+                /* Look for a vtable override. */
+                PMC *override;
+                override = Parrot_oo_find_vtable_override_for_class(supervised, _class, name);
+
+                if(PMC_IS_NULL(override)) {
+                    /* No override. */
+                    /* Simply replace the stub with the original entry. */
+                    entry = (size_t **) parrot_hash_get(INTERP, attr->name_offset, item);
+                    func  = (size_t *)  parrot_hash_get(INTERP, attr->name_original, item);
+                    if (entry == NULL || func == NULL) {
+                        Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
+                                                    "%Ss : Unknown function, '%Ss'",
+                                                    VTABLE_name(INTERP, SELF), item);
+                    }
+                    *entry = func;
+                }
+                else {
+                    /* It appears that there is a vtable override.
+                       Remove the instrumentation of the override's invoke
+                       vtable entry. */
+                    PMC *instr_obj, *rename, *rename_hash, *group;
+                    STRING *invoke;
+
+                    invoke = CONST_STRING(INTERP, "invoke");
+
+                    /* The InstrumentObject instance for the override can
+                       be obtained from the registry using the vtable pointer. */
+                    instr_obj = (PMC *) parrot_hash_get(INTERP, attr->registry, override->vtable);
+
+                    /* Instrument its invoke vtable entry. */
+                    () = PCCINVOKE(INTERP, instr_obj, "remove_hook", STRING *invoke);
+
+                    GETATTR_InstrumentVtable_rename_hash(INTERP, instr_obj, rename_hash);
+                    VTABLE_delete_keyed_str(INTERP, rename_hash, invoke);
+                }
+            }
+
+            /* Update the count. */
+            count--;
+            VTABLE_set_integer_keyed_str(INTERP, attr->hook_count, item, count);
+        }
+    }
+
 }
 
 /*


More information about the parrot-commits mailing list