[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