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

khairul at svn.parrot.org khairul at svn.parrot.org
Sat Jun 19 15:16:53 UTC 2010


Author: khairul
Date: Sat Jun 19 15:16:52 2010
New Revision: 47713
URL: https://trac.parrot.org/parrot/changeset/47713

Log:
fleshed out instrumentop.pmc.

Modified:
   branches/gsoc_instrument/examples/library/tracer.nqp
   branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp
   branches/gsoc_instrument/src/dynpmc/instrument.pmc
   branches/gsoc_instrument/src/dynpmc/instrumentop.pmc

Modified: branches/gsoc_instrument/examples/library/tracer.nqp
==============================================================================
--- branches/gsoc_instrument/examples/library/tracer.nqp	Sat Jun 19 14:49:20 2010	(r47712)
+++ branches/gsoc_instrument/examples/library/tracer.nqp	Sat Jun 19 15:16:52 2010	(r47713)
@@ -31,20 +31,19 @@
 $instr.attach($probe);
 $instr.run($args[0], $args);
 
-sub tracer ($pc, $op, $instr_obj) {
-    my $op_lib       := Q:PIR { %r = new ['OpLib'] };
-    my $op_code      := pir::set_p_p_ki__PPI($op_lib, $op[0]);
-    my $sprintf_args := [$pc];
+sub tracer ($op, $instr_obj) {
+    my $sprintf_args := [$op.pc()];
     my $pc_hex       := pir::sprintf__SSP("%04x", $sprintf_args);
-    my $op_name      := $op_code.family_name();
-    my $param_cnt    := pir::elements($op_code);
+    my $op_name      := $op.family();
+    my $param_cnt    := $op.count();
     my $params       := '';
     my $cur_arg      := 0;
 
     my $arg_list     := [];
     while $cur_arg < $param_cnt {
         my $arg_str;
-        my $arg_type := pir::set_i_p_ki__IPI($op_code, $cur_arg);
+        my $arg_type := $op.arg_type($cur_arg);
+        my $arg      := $op.get_arg($cur_arg, 1);
 
         # Evaluate in order of:
         # 1. keys
@@ -57,22 +56,22 @@
                 # Constant keys are int constants or strings.
                 if pir::band__III($arg_type, 2) == 2 {
                     # String constant key.
-                    my $arg := $instr_obj.get_op_arg($op[$cur_arg + 1], $arg_type);
-                    $arg_str := '["' ~ $arg ~ '"]';
+                    my $arg_val := $op.get_arg($cur_arg);
+                    $arg_str := '["' ~ $arg_val ~ '"]';
 
                 } else {
                     # Integer constant key.
-                    $arg_str := '[' ~ $op[$cur_arg + 1] ~ ']';
+                    $arg_str := '[' ~ $arg ~ ']';
                 }
             } else {
                 # Non-constant keys. Reference regs only.
                 if !$arg_type {
                     # 0 is int reg.
-                    $arg_str := '[I' ~ $op[$cur_arg + 1] ~ ']';
+                    $arg_str := '[I' ~ $arg ~ ']';
                     
                 } elsif pir::band__III($arg_type, 2) == 2 {
                     # 2 is pmc.
-                    $arg_str := '[P' ~ $op[$cur_arg + 1] ~ ']';
+                    $arg_str := '[P' ~ $arg ~ ']';
                 }
             }
 
@@ -81,35 +80,35 @@
 
         } elsif pir::band__III($arg_type, 16) == 16
                 && pir::band__III($arg_type, 2) != 2 {
-            my $arg := $instr_obj.get_op_arg($op[$cur_arg + 1], $arg_type);
 
             if pir::band__III($arg_type, 1) == 1 {
-                $arg_str := '"' ~ $arg ~ '"';
+                my $arg_val := $op.get_arg($cur_arg);
+                $arg_str := '"' ~ $arg_val ~ '"';
 
             } else {
                 $arg_str := $arg;
             }
         }  elsif !$arg_type {
             # 0 is int reg.
-            $arg_str := 'I' ~ $op[$cur_arg + 1];
+            $arg_str := 'I' ~ $arg;
 
         } elsif pir::band__III($arg_type, 1) == 1{
             # 1 is string reg.
-            $arg_str := 'S' ~ $op[$cur_arg + 1];
+            $arg_str := 'S' ~ $arg;
 
         } elsif pir::band__III($arg_type, 2) == 2 {
             # 2 is pmc.
             if pir::band__III($arg_type, 16) == 16 {
                 # Constant pmc.
-                $arg_str := 'PC' ~ $op[$cur_arg + 1];
+                $arg_str := 'PC' ~ $arg;
             } else {
                 # Normal reg.
-                $arg_str := 'P' ~ $op[$cur_arg + 1];
+                $arg_str := 'P' ~ $arg;
             }
 
         } elsif pir::band__III($arg_type, 3) == 3 {
             # 3 is num reg.
-            $arg_str := 'N' ~ $op[$cur_arg + 1];
+            $arg_str := 'N' ~ $arg;
 
         }
 

Modified: branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp
==============================================================================
--- branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp	Sat Jun 19 14:49:20 2010	(r47712)
+++ branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp	Sat Jun 19 15:16:52 2010	(r47713)
@@ -8,7 +8,7 @@
     
 runtime/parrot/library/Instrument/EventLibrary.nqp
 
-	Library for the many classes that provide handlers for Events.
+    Library for the many classes that provide handlers for Events.
 
 =head1 SYNOPSIS
 
@@ -22,8 +22,8 @@
     evt = new ['Instrument';'Event';'Internal';'loadlib']
     evt.'set_callback'('loadlib_callback')
 
-	instr = new ['Instrument']
-	instr.attach(evt)
+    instr = new ['Instrument']
+    instr.attach(evt)
 
 =cut
 
@@ -41,8 +41,8 @@
 
 class Instrument::Event::Internal::loadlib is Instrument::Event {
 
-	method _self_init() {
-		$!event_type := 'Instrument::Event::Internal::loadlib';
+    method _self_init() {
+        $!event_type := 'Instrument::Event::Internal::loadlib';
     };
 };
 
@@ -58,29 +58,25 @@
 
 class Instrument::Event::Class::instantiate is Instrument::Event {
 
-	method _self_init() {
-		$!event_type := 'Instrument::Event::Class::instantiate';
+    method _self_init() {
+        $!event_type := 'Instrument::Event::Class::instantiate';
 
-		$!probe_obj := Instrument::Probe.new();
+        $!probe_obj := Instrument::Probe.new();
 
-		$!probe_obj.inspect('new');
-		$!probe_obj.set_callback(pir::get_global__PS('callback'));
-	};
-
-	sub callback ($pc, $op, $instr_obj) {
-		my $op_lib   := Q:PIR { %r = new ['OpLib'] };
-    	my $op_code  := pir::set_p_p_ki__PPI($op_lib, $op[0]);
-    	my $arg_type := pir::set_i_p_ki__IPI($op_code, 1);
-    	my $class    := $instr_obj.get_op_arg($op[2], $arg_type);
-
-		my $data := Q:PIR { %r = new ['ResizablePMCArray'] };
-		$data.push($class);
-		$data.push($pc);
-		$data.push($op);
-		$data.push($instr_obj);
+        $!probe_obj.inspect('new');
+        $!probe_obj.set_callback(pir::get_global__PS('callback'));
+    };
+
+    sub callback ($op, $instr_obj) {
+        my $class    := $op.get_arg(1);
 
-		Instrument::Event::_raise_event('Instrument::Event::Class::instantiate', $data);
-	};
+        my $data := Q:PIR { %r = new ['ResizablePMCArray'] };
+        $data.push($class);
+        $data.push($op);
+        $data.push($instr_obj);
+
+        Instrument::Event::_raise_event('Instrument::Event::Class::instantiate', $data);
+    };
 };
 
 =begin
@@ -95,30 +91,26 @@
 
 class Instrument::Event::Class::callmethod is Instrument::Event {
 
-	method _self_init() {
-		$!event_type := 'Instrument::Event::Class::callmethod';
+    method _self_init() {
+        $!event_type := 'Instrument::Event::Class::callmethod';
 
-		$!probe_obj := Instrument::Probe.new();
+        $!probe_obj := Instrument::Probe.new();
 
-		$!probe_obj.inspect('callmethod');
-		$!probe_obj.inspect('callmethodcc');
-		$!probe_obj.set_callback(pir::get_global__PS('callback'));
-	};
-
-	sub callback ($pc, $op, $instr_obj) {
-		my $op_lib   := Q:PIR { %r = new ['OpLib'] };
-    	my $op_code  := pir::set_p_p_ki__PPI($op_lib, $op[0]);
-    	my $arg_type := pir::set_i_p_ki__IPI($op_code, 1);
-    	my $method   := $instr_obj.get_op_arg($op[2], $arg_type);
-
-		my $data := Q:PIR { %r = new ['ResizablePMCArray'] };
-		$data.push($method);
-		$data.push($pc);
-		$data.push($op);
-		$data.push($instr_obj);
+        $!probe_obj.inspect('callmethod');
+        $!probe_obj.inspect('callmethodcc');
+        $!probe_obj.set_callback(pir::get_global__PS('callback'));
+    };
+
+    sub callback ($op, $instr_obj) {
+        my $method    := $op.get_arg(1);
 
-		Instrument::Event::_raise_event('Instrument::Event::Class::callmethod', $data);
-	};
+        my $data := Q:PIR { %r = new ['ResizablePMCArray'] };
+        $data.push($method);
+        $data.push($op);
+        $data.push($instr_obj);
+
+        Instrument::Event::_raise_event('Instrument::Event::Class::callmethod', $data);
+    };
 };
 
 # vim: ft=perl6 expandtab shiftwidth=4:

Modified: branches/gsoc_instrument/src/dynpmc/instrument.pmc
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/instrument.pmc	Sat Jun 19 14:49:20 2010	(r47712)
+++ branches/gsoc_instrument/src/dynpmc/instrument.pmc	Sat Jun 19 15:16:52 2010	(r47713)
@@ -511,108 +511,6 @@
 
         RETURN(INTVAL count);
     }
-
-/*
-=item C<PMC *get_op_arg(INTVAL arg, INTVAL arg_type)>
-
-Interprets arg according to arg_type and returns the value as a PMC.
-Eg, get_op_arg(0, PARROT_ARG_I) => Returns the value in register I0.
-
-arg_type is as defined in parrot/op.h
-
-=cut
-*/
-
-    METHOD get_op_arg(INTVAL arg, INTVAL arg_type) {
-        Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
-        PMC *ret, *cc, *key;
-        arg_type_t type = (arg_type_t) arg_type;
-
-        cc = CURRENT_CONTEXT(attr->supervised);
-
-        switch (type) {
-          case PARROT_ARG_IC:
-            /* Integer constants are stored as part of the opcode
-               in the packfile */
-            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
-            VTABLE_set_integer_native(INTERP, ret, arg);
-
-            break;
-          case PARROT_ARG_I:
-            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
-            VTABLE_set_integer_native(INTERP, ret,
-                                      *Parrot_pcc_get_INTVAL_reg(attr->supervised, cc, arg));
-
-            break;
-          case PARROT_ARG_NC:
-            ret = Parrot_pmc_new(INTERP, enum_class_Float);
-            VTABLE_set_number_native(INTERP, ret,
-                                     Parrot_pcc_get_num_constant_func(attr->supervised, cc, arg));
-
-            break;
-          case PARROT_ARG_N:
-            ret = Parrot_pmc_new(INTERP, enum_class_Float);
-            VTABLE_set_number_native(INTERP, ret,
-                                     *Parrot_pcc_get_FLOATVAL_reg(attr->supervised, cc, arg));
-
-            break;
-          case PARROT_ARG_PC:
-            ret = Parrot_pcc_get_pmc_constant_func(attr->supervised, cc, arg);
-
-            break;
-          case PARROT_ARG_P:
-            ret = *Parrot_pcc_get_PMC_reg(attr->supervised, cc, arg);
-
-            break;
-          case PARROT_ARG_SC:
-            ret = Parrot_pmc_new(INTERP, enum_class_String);
-            VTABLE_set_string_native(INTERP, ret,
-                                     Parrot_pcc_get_string_constant_func(attr->supervised,
-                                                                         cc, arg));
-
-            break;
-          case PARROT_ARG_S:
-            ret = Parrot_pmc_new(INTERP, enum_class_String);
-            VTABLE_set_string_native(INTERP, ret,
-                                     *Parrot_pcc_get_STRING_reg(attr->supervised, cc, arg));
-
-            break;
-          case PARROT_ARG_K:
-            /* Key is PMC */
-            ret = *Parrot_pcc_get_PMC_reg(attr->supervised, cc, arg);
-
-            break;
-          case PARROT_ARG_KC:
-            /* Key is String reg or String const */
-            ret = Parrot_pmc_new(INTERP, enum_class_String);
-            {
-                PMC *key;
-                key = (Parrot_pcc_get_constants(attr->supervised, cc)[arg])->u.key;
-
-                VTABLE_set_string_native(INTERP, ret, VTABLE_get_string(attr->supervised, key));
-            }
-
-            break;
-          case PARROT_ARG_KI:
-            /* Key is integer reg */
-            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
-            VTABLE_set_integer_native(INTERP, ret,
-                                      *Parrot_pcc_get_INTVAL_reg(attr->supervised, cc, arg));
-
-            break;
-          case PARROT_ARG_KIC:
-            /* Key is integer constant */
-            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
-            VTABLE_set_integer_native(INTERP, ret, arg);
-
-            break;
-          default:
-            Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
-                                        "Currently unhandled op arg type %d.", type);
-        };
-
-        RETURN(PMC *ret);
-    }
 }
 
 /*
@@ -765,8 +663,9 @@
     probe_node_t *cur_probe;
     Instrument_runcore_t    *core;
     Parrot_Interp            supervisor;
-    PMC                     *instrument, *op_data;
+    PMC                     *instrument, *op_data, *interp_pmc;
     INTVAL                   op_params, cur_op_param, pc_relative, done_catchalls;
+    INTVAL                   instr_op_type;
 
     core         = (Instrument_runcore_t *) interp->run_core;
     to_recall    = NULL; /* TODO: Implement probe recalls */
@@ -778,17 +677,12 @@
     /* Calculate the relative position of the pc. */
     pc_relative = pc - interp->code->base.data;
 
-    /* Grab the opcode params */
-    /* TODO: Apparently some ops like set_args_pc have extra args.
-             see src/runcore/trace.c line 312.
-    */
-    op_params = interp->op_info_table[*pc].op_count;
-    op_data   = Parrot_pmc_new(supervisor, enum_class_ResizableIntegerArray);
-    cur_op_param = 0;
-    while (cur_op_param <= op_params) {
-        VTABLE_push_integer(supervisor, op_data, pc[cur_op_param]);
-        cur_op_param++;
-    }
+    /* Create the InstrumentOp instance and set it. */
+    interp_pmc    = VTABLE_get_pmc_keyed_int(interp, interp->iglobals, IGLOBALS_INTERPRETER);
+    instr_op_type = Parrot_pmc_get_type_str(supervisor, CONST_STRING(supervisor, "InstrumentOp"));
+    op_data       = Parrot_pmc_new_init(supervisor, instr_op_type, interp_pmc);
+
+    VTABLE_set_pointer(supervisor, op_data, pc);
 
     /* Execute any probes. */
     done_catchalls = 0;
@@ -808,7 +702,7 @@
         callback = cur_probe->list_obj;
         next     = cur_probe->next;
         if (!PMC_IS_NULL(callback)) {
-            Parrot_ext_call(supervisor, callback, "IPP->", pc_relative, op_data, instrument);
+            Parrot_ext_call(supervisor, callback, "PP->", op_data, instrument);
         }
         cur_probe = next;
     }

Modified: branches/gsoc_instrument/src/dynpmc/instrumentop.pmc
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/instrumentop.pmc	Sat Jun 19 14:49:20 2010	(r47712)
+++ branches/gsoc_instrument/src/dynpmc/instrumentop.pmc	Sat Jun 19 15:16:52 2010	(r47713)
@@ -20,16 +20,37 @@
 */
 
 #include "parrot/parrot.h"
+#include "parrot/opsenum.h"
 
 pmclass InstrumentOp auto_attrs dynpmc group instrument_group {
-    ATTR Parrot_Interp  interp;
-    ATTR opcode_t      *pc;
+    ATTR Parrot_Interp  interp; /* Interpreter to get op values from. */
+    ATTR opcode_t      *pc;     /* Current progam counter of interp above. */
+
+/*
+
+=item C<void init()>
+
+Initializes the pmc, setting the interp and pc to NULL.
+
+=cut
+
+*/
 
     VTABLE void init() {
         SETATTR_InstrumentOp_interp(INTERP, SELF, NULL);
         SETATTR_InstrumentOp_pc(INTERP, SELF, NULL);
     }
 
+/*
+
+=item C<void init_pmc(PMC *interp_pmc)>
+
+Initializes the pmc, setting the interp to the given value and pc to NULL.
+
+=cut
+
+*/
+
     VTABLE void init_pmc(PMC *interp_pmc) {
         Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
 
@@ -37,10 +58,30 @@
         attr->pc     = NULL;
     }
 
+/*
+
+=item C<void set_pointer(void *vptr_pc)>
+
+Sets the current pc to the given pointer.
+
+=cut
+
+*/
+
     VTABLE void set_pointer(void *vptr_pc) {
         SETATTR_InstrumentOp_pc(INTERP, SELF, (opcode_t *) vptr_pc);
     }
 
+/*
+
+=item C<void * get_pointer()>
+
+Returns the current pc pointer.
+
+=cut
+
+*/
+
     VTABLE void * get_pointer() {
         opcode_t *pc;
         GETATTR_InstrumentOp_pc(INTERP, SELF, pc);
@@ -48,6 +89,322 @@
         return (void *) pc;
     }
 
+/*
+
+=item C<STRING* name()>
+
+Returns the full name of the current op.
+
+=cut
+
+*/
+
+    METHOD name() {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        UINTVAL op = *(attr->pc);
+
+        STRING *name = CONST_STRING(INTERP, attr->interp->op_info_table[op].full_name);
+
+        RETURN(STRING *name);
+    }
+
+/*
+
+=item C<STRING* family()>
+
+Returns the name of the current op family (short name).
+
+=cut
+
+*/
+
+    METHOD family() {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        UINTVAL op = *(attr->pc);
+
+        STRING *name = CONST_STRING(INTERP, attr->interp->op_info_table[op].name);
+
+        RETURN(STRING *name);
+    }
+
+/*
+
+=item C<INTVAL count()>
+
+Returns the number of arguments of the current op.
+For special ops like set_args_pc, add the variable argument count to the total count.
+
+=cut
+
+*/
+
+    METHOD count() {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        UINTVAL op = *(attr->pc);
+        INTVAL count = attr->interp->op_info_table[op].op_count - 1;
+
+        if (op == enum_ops_set_args_pc
+         || op == enum_ops_get_results_pc
+         || op == enum_ops_get_params_pc
+         || op == enum_ops_set_returns_pc) {
+            PMC * const sig = attr->interp->code->const_table->constants[(attr->pc)[1]]->u.key;
+            count += VTABLE_elements(attr->interp, sig);
+        }
+
+        RETURN(INTVAL count);
+    }
+
+/*
+
+=item C<INTVAL arg_type(INTVAL arg_index)>
+
+Returns the argument type at the given index.
+Takes into account the special ops with variable arguments.
+
+=cut
+
+*/
+
+    METHOD arg_type(INTVAL arg_index) {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        UINTVAL op = *(attr->pc);
+        INTVAL type;
+
+        if ((op == enum_ops_set_args_pc
+           || op == enum_ops_get_results_pc
+           || op == enum_ops_get_params_pc
+           || op == enum_ops_set_returns_pc)
+         && arg_index >= 1) {
+            PMC * const sig = attr->interp->code->const_table->constants[(attr->pc)[1]]->u.key;
+            type = VTABLE_get_integer_keyed_int(attr->interp, sig, arg_index - 1) &
+                    (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT);
+        }
+        else {
+            type = attr->interp->op_info_table[op].types[arg_index];
+        }
+
+        RETURN(INTVAL type);
+    }
+
+/*
+
+=item C<INTVAL pc()>
+
+Returns the current relative pc value.
+
+=cut
+
+*/
+
+    METHOD pc() {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        INTVAL pc_rel = attr->pc - attr->interp->code->base.data;
+
+        RETURN(INTVAL pc_rel);
+    }
+
+/*
+
+=item C<PMC* get_arg(INTVAL arg_index, INTVAL raw :optional)>
+
+Returns the argument as interpreted according to its type at the given index.
+If raw is defined and is not 0, returns the raw INTVAL value at that index.
+Takes into account the special ops with variable arguments.
+
+=cut
+
+*/
+
+    METHOD get_arg(INTVAL arg_index, INTVAL raw :optional, INTVAL has_raw :opt_flag) {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        PMC *ret, *cc, *key;
+        arg_type_t type;
+        INTVAL arg = (attr->pc)[arg_index + 1];
+        INTVAL op  = *(attr->pc);
+
+
+         if (has_raw && raw != 0) {
+            /* Raw is always an integer. */
+            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
+            VTABLE_set_integer_native(INTERP, ret, arg);
+
+            RETURN(PMC *ret);
+         }
+
+        cc = CURRENT_CONTEXT(attr->interp);
+
+        if ((op == enum_ops_set_args_pc
+           || op == enum_ops_get_results_pc
+           || op == enum_ops_get_params_pc
+           || op == enum_ops_set_returns_pc)
+         && arg_index >= 1) {
+            PMC * const sig = attr->interp->code->const_table->constants[(attr->pc)[1]]->u.key;
+            type = VTABLE_get_integer_keyed_int(attr->interp, sig, arg_index - 1) &
+                    (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT);
+        }
+        else {
+            type = attr->interp->op_info_table[(*attr->pc)].types[arg_index];
+        }
+
+        switch (type) {
+          case PARROT_ARG_IC:
+            /* Integer constants are stored as part of the opcode
+               in the packfile */
+            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
+            VTABLE_set_integer_native(INTERP, ret, arg);
+
+            break;
+          case PARROT_ARG_I:
+            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
+            VTABLE_set_integer_native(INTERP, ret,
+                                      *Parrot_pcc_get_INTVAL_reg(attr->interp, cc, arg));
+
+            break;
+          case PARROT_ARG_NC:
+            ret = Parrot_pmc_new(INTERP, enum_class_Float);
+            VTABLE_set_number_native(INTERP, ret,
+                                     Parrot_pcc_get_num_constant_func(attr->interp, cc, arg));
+
+            break;
+          case PARROT_ARG_N:
+            ret = Parrot_pmc_new(INTERP, enum_class_Float);
+            VTABLE_set_number_native(INTERP, ret,
+                                     *Parrot_pcc_get_FLOATVAL_reg(attr->interp, cc, arg));
+
+            break;
+          case PARROT_ARG_PC:
+            ret = Parrot_pcc_get_pmc_constant_func(attr->interp, cc, arg);
+
+            break;
+          case PARROT_ARG_P:
+            ret = *Parrot_pcc_get_PMC_reg(attr->interp, cc, arg);
+
+            break;
+          case PARROT_ARG_SC:
+            ret = Parrot_pmc_new(INTERP, enum_class_String);
+            VTABLE_set_string_native(INTERP, ret,
+                                     Parrot_pcc_get_string_constant_func(attr->interp,
+                                                                         cc, arg));
+
+            break;
+          case PARROT_ARG_S:
+            ret = Parrot_pmc_new(INTERP, enum_class_String);
+            VTABLE_set_string_native(INTERP, ret,
+                                     *Parrot_pcc_get_STRING_reg(attr->interp, cc, arg));
+
+            break;
+          case PARROT_ARG_K:
+            /* Key is PMC */
+            ret = *Parrot_pcc_get_PMC_reg(attr->interp, cc, arg);
+
+            break;
+          case PARROT_ARG_KC:
+            /* Key is String reg or String const */
+            ret = Parrot_pmc_new(INTERP, enum_class_String);
+            {
+                PMC *key;
+                key = (Parrot_pcc_get_constants(attr->interp, cc)[arg])->u.key;
+
+                VTABLE_set_string_native(INTERP, ret, VTABLE_get_string(attr->interp, key));
+            }
+
+            break;
+          case PARROT_ARG_KI:
+            /* Key is integer reg */
+            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
+            VTABLE_set_integer_native(INTERP, ret,
+                                      *Parrot_pcc_get_INTVAL_reg(attr->interp, cc, arg));
+
+            break;
+          case PARROT_ARG_KIC:
+            /* Key is integer constant */
+            ret = Parrot_pmc_new(INTERP, enum_class_Integer);
+            VTABLE_set_integer_native(INTERP, ret, arg);
+
+            break;
+          default:
+            Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
+                                        "Currently unhandled op arg type %d.", type);
+        };
+
+        RETURN(PMC *ret);
+    }
+
+/*
+
+=item C<STRING* file()>
+
+Returns the filename where the current op resides in.
+
+=cut
+
+*/
+
+    METHOD file() {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        Parrot_Context_info info;
+
+        INTVAL ret = Parrot_Context_get_info(attr->interp, CURRENT_CONTEXT(attr->interp), &info);
+        STRING *file = info.file;
+        RETURN(STRING *file);
+    }
+
+/*
+
+=item C<INTVAL line()>
+
+Returns the line number of the file where the current op resides in.
+
+=cut
+
+*/
+
+    METHOD line() {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        Parrot_Context_info info;
+
+        INTVAL ret = Parrot_Context_get_info(attr->interp, CURRENT_CONTEXT(attr->interp), &info);
+        INTVAL line = info.line;
+        RETURN(INTVAL line);
+    }
+
+/*
+
+=item C<STRING* sub()>
+
+Returns the name of the subroutine containing the current op.
+
+=cut
+
+*/
+
+    METHOD sub() {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        Parrot_Context_info info;
+
+        INTVAL ret = Parrot_Context_get_info(attr->interp, CURRENT_CONTEXT(attr->interp), &info);
+        STRING *sub = info.subname;
+        RETURN(STRING *sub);
+    }
+
+/*
+
+=item C<STRING* sub()>
+
+Returns the namespace of the subroutine containing the current op.
+
+=cut
+
+*/
+
+    METHOD namespace() {
+        Parrot_InstrumentOp_attributes * const attr = PARROT_INSTRUMENTOP(SELF);
+        Parrot_Context_info info;
+
+        INTVAL ret = Parrot_Context_get_info(attr->interp, CURRENT_CONTEXT(attr->interp), &info);
+        STRING *nsname = info.nsname;
+        RETURN(STRING *nsname);
+    }
 }
 
 /*


More information about the parrot-commits mailing list