[svn:parrot] r46967 - in branches/gsoc_instrument: . config/gen/makefiles examples/library runtime/parrot/library/Instrument src/dynpmc
khairul at svn.parrot.org
khairul at svn.parrot.org
Mon May 24 16:08:05 UTC 2010
Author: khairul
Date: Mon May 24 16:08:04 2010
New Revision: 46967
URL: https://trac.parrot.org/parrot/changeset/46967
Log:
added instrument dynpmc, probe library and simple example.
Added:
branches/gsoc_instrument/examples/library/tracer.pir
branches/gsoc_instrument/runtime/parrot/library/Instrument/
branches/gsoc_instrument/runtime/parrot/library/Instrument/Instrument.pir
branches/gsoc_instrument/runtime/parrot/library/Instrument/Probe.pir
branches/gsoc_instrument/src/dynpmc/instrument.pmc
Modified:
branches/gsoc_instrument/MANIFEST
branches/gsoc_instrument/config/gen/makefiles/root.in
branches/gsoc_instrument/src/dynpmc/Defines.in
branches/gsoc_instrument/src/dynpmc/Rules.in
Modified: branches/gsoc_instrument/MANIFEST
==============================================================================
--- branches/gsoc_instrument/MANIFEST Mon May 24 15:31:33 2010 (r46966)
+++ branches/gsoc_instrument/MANIFEST Mon May 24 16:08:04 2010 (r46967)
@@ -1,12 +1,12 @@
# ex: set ro:
# $Id$
#
-# generated by tools/dev/mk_manifest_and_skip.pl Mon May 24 08:07:25 2010 UT
+# generated by ./tools/dev/mk_manifest_and_skip.pl Mon May 24 15:54:07 2010 UT
#
# See below for documentation on the format of this file.
#
# See docs/submissions.pod and the documentation in
-# tools/dev/mk_manifest_and_skip.pl on how to recreate this file after SVN
+# ./tools/dev/mk_manifest_and_skip.pl on how to recreate this file after SVN
# has been told about new or deleted files.
.gitignore []
CREDITS [main]doc
@@ -646,6 +646,7 @@
examples/library/md5sum.pir [examples]
examples/library/ncurses_life.pir [examples]
examples/library/pcre.pir [examples]
+examples/library/tracer.pir [examples]
examples/mops/README [examples]
examples/mops/mops.c [examples]
examples/mops/mops.cs [examples]
@@ -1155,6 +1156,8 @@
runtime/parrot/library/Getopt/Obj.pir [library]
runtime/parrot/library/HTTP/Daemon.pir [library]
runtime/parrot/library/HTTP/Message.pir [library]
+runtime/parrot/library/Instrument/Instrument.pir [library]
+runtime/parrot/library/Instrument/Probe.pir [library]
runtime/parrot/library/Iter.pir [library]
runtime/parrot/library/JSON.pir [library]
runtime/parrot/library/LWP/Protocol.pir [library]
@@ -1265,6 +1268,7 @@
src/dynpmc/foo.pmc []
src/dynpmc/foo2.pmc []
src/dynpmc/gziphandle.pmc []
+src/dynpmc/instrument.pmc []
src/dynpmc/main.pasm []
src/dynpmc/os.pmc []
src/dynpmc/pccmethod_test.pmc []
Modified: branches/gsoc_instrument/config/gen/makefiles/root.in
==============================================================================
--- branches/gsoc_instrument/config/gen/makefiles/root.in Mon May 24 15:31:33 2010 (r46966)
+++ branches/gsoc_instrument/config/gen/makefiles/root.in Mon May 24 16:08:04 2010 (r46967)
@@ -326,7 +326,9 @@
$(LIBRARY_DIR)/YAML/Dumper.pbc \
$(LIBRARY_DIR)/STM.pbc \
$(LIBRARY_DIR)/libpcre.pbc \
- $(LIBRARY_DIR)/postgres.pbc
+ $(LIBRARY_DIR)/postgres.pbc \
+ $(LIBRARY_DIR)/Instrument/Instrument.pbc \
+ $(LIBRARY_DIR)/Instrument/Probe.pbc
FLUID_FILES_1 = \
$(GEN_HEADERS) \
Added: branches/gsoc_instrument/examples/library/tracer.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_instrument/examples/library/tracer.pir Mon May 24 16:08:04 2010 (r46967)
@@ -0,0 +1,142 @@
+# Copyright (C) 2010, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+examples/library/tracer.pir - A simple op tracing example for the Instrument dynpmc
+
+=head1 SYNOPSIS
+
+ % ./parrot examples/library/tracer.pir <file>
+
+=head1 DESCRIPTION
+
+A simple example of how to use the Instrument dynpmc
+and associated libraries.
+
+=cut
+
+.sub '_init' :anon :load :init
+ # Load the Instrument libraries.
+ load_bytecode 'Instrument/Instrument.pbc'
+ load_bytecode 'Instrument/Probe.pbc'
+.end
+
+.sub 'main' :main
+ .param pmc args
+ .local pmc instr, probe, probe2
+ .local string me, file
+
+ # Create a catchall probe which will be called for
+ # each op.
+ probe = new ['Instrument';'Probe';'Catchall']
+ probe.'set_callback'('catchall_callback')
+ #probe.'set_finalize'('catchall_finalize')
+
+ # Create a probe that will be called whenever the
+ # specified ops are encountered.
+ probe2 = new ['Instrument';'Probe']
+ probe2.'inspect'('lt')
+ probe2.'inspect'('gt')
+ probe2.'set_callback'('specific_callback')
+ probe2.'set_finalize'('specific_finalize')
+
+ # Create an instance of Instrument and
+ # attach the probes to it.
+ instr = new ['Instrument']
+ instr.'attach'(probe)
+ instr.'attach'(probe2)
+
+ # Shift this file out of the command line argument list.
+ me = shift args
+ file = args[0]
+
+ # Create globals for the counters.
+ $P0 = new ['Integer']
+ $P0 = 0
+ set_global '$INSTR_CNT', $P0
+
+ $P0 = new ['Integer']
+ $P0 = 0
+ set_global '$GT_CNT', $P0
+
+ $P0 = new ['Integer']
+ $P0 = 0
+ set_global '$LT_CNT', $P0
+
+ # Execute the file.
+ instr.'run'(file, args)
+
+ .return()
+.end
+
+.sub 'catchall_callback'
+ .param string op_name
+
+ # Update instruction counter.
+ .local pmc counter
+ counter = get_global '$INSTR_CNT'
+ counter += 1
+ set_global '$INSTR_CNT', counter
+
+ .return()
+.end
+
+.sub 'catchall_finalize'
+ # Print the total instructions executed.
+ print 'Total Instruction count: '
+ $P0 = get_global '$INSTR_CNT'
+ say $P0
+
+ .return()
+.end
+
+.sub 'specific_callback'
+ .param string op_name
+ .local int ind
+ .local pmc counter
+
+ # Check if it is lt or gt
+ # and update accordingly.
+ ind = index op_name, 'gt'
+ if ind == 0 goto GT_OP
+
+LT_OP:
+ counter = get_global '$LT_CNT'
+ counter += 1
+ set_global '$LT_CNT', counter
+ goto DONE
+
+GT_OP:
+ counter = get_global '$GT_CNT'
+ counter += 1
+ set_global '$GT_CNT', counter
+
+DONE:
+ .return()
+.end
+
+
+.sub 'specific_finalize'
+ .local pmc gt_cnt, lt_cnt
+
+ gt_cnt = get_global '$GT_CNT'
+ lt_cnt = get_global '$LT_CNT'
+
+ print 'gt encountered '
+ print gt_cnt
+ say ' times'
+
+ print 'lt encountered '
+ print lt_cnt
+ say ' times'
+
+ .return()
+.end
+
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Added: branches/gsoc_instrument/runtime/parrot/library/Instrument/Instrument.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_instrument/runtime/parrot/library/Instrument/Instrument.pir Mon May 24 16:08:04 2010 (r46967)
@@ -0,0 +1,32 @@
+# Copyright (C) 2010, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+runtime/parrot/library/Instrument/Instrument.pir - Loads all libraries required by Instrument.
+
+=head1 SYNOPSIS
+
+ # Load the instrument dynpmc and required libraries.
+ load_bytecode 'Instrument/Instrument.pbc'
+
+=cut
+
+.sub '__instrument_lib_init' :init :load :anon
+ .local pmc lib
+
+ lib = loadlib 'instrument'
+ $I0 = defined lib
+ if $I0 goto END
+
+ die 'Could not load the instrument dynpmc'
+
+END:
+ .return()
+.end
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Added: branches/gsoc_instrument/runtime/parrot/library/Instrument/Probe.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_instrument/runtime/parrot/library/Instrument/Probe.pir Mon May 24 16:08:04 2010 (r46967)
@@ -0,0 +1,614 @@
+# Copyright (C) 2010, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+runtime/parrot/library/Instrument/Probe.pir - A class to automate the task of creating probes for instruments.
+
+=head1 SYNOPSIS
+
+ # Create a catchall probe which will be called for
+ # each op.
+ probe = new ['Instrument';'Probe';'Catchall']
+ probe.'set_callback'('catchall_callback')
+ probe.'set_finalize'('catchall_finalize')
+
+ # Create a probe that will be called whenever the
+ # specified ops are encountered.
+ probe2 = new ['Instrument';'Probe']
+ probe2.'inspect'('lt')
+ probe2.'inspect'('gt')
+ probe2.'set_callback'('specific_callback')
+ probe2.'set_finalize'('specific_finalize')
+
+=head2 TODO
+1. Refactor, too much copy and paste for now.
+
+=cut
+
+
+=head2 Class Instrument;Probe
+
+Class Instrument;Probe creates a probe who's callback will be called
+when the specified ops are encountered during execution.
+
+=cut
+.namespace ['Instrument';'Probe']
+
+.sub '' :anon :init :load
+ .local pmc class
+
+ class = newclass ['Instrument';'Probe']
+ addattribute class, 'instr_obj'
+ addattribute class, 'callback'
+ addattribute class, 'ops_unprocessed'
+ addattribute class, 'ops_processed'
+ addattribute class, 'enabled'
+ addattribute class, 'finalize'
+
+ .return()
+.end
+
+=item init
+
+=cut
+
+.sub 'init' :vtable :method
+ .local pmc instr_pmc, callback, ops_u, ops_p, enabled
+
+ # Probe is still unattached to an Instrument object.
+ # This attribute will be set by the Instrument object
+ # when the probe is attached to it.
+ instr_pmc = new ['Undef']
+ setattribute self, 'instr_obj', instr_pmc
+
+ # Callback is still undefined.
+ callback = new ['Undef']
+ setattribute self, 'callback', callback
+
+ # Ops is an empty Hash
+ ops_u = new ['Hash']
+ ops_p = new ['Hash']
+ setattribute self, 'ops_unprocessed', ops_u
+ setattribute self, 'ops_processed', ops_p
+
+ # Enabled is a Boolean.
+ # Each probe is initially disabled
+ enabled = new ['Boolean']
+ enabled = 0
+ setattribute self, 'enabled', enabled
+
+.end
+
+=item inspect
+
+=cut
+
+.sub 'inspect' :method
+ .param pmc ops
+ .local pmc ops_attr
+ ops_attr = getattribute self, 'ops_unprocessed'
+
+ # ops can be either:
+ # 1. String : Identify an op through a string.
+ # 2. Integer: Identify an op through the op number.
+ # 3. ResizableIntegerArray: A group of op numbers.
+ # 4. ResizableStringArray: A group of op names.
+ #
+ # Anything other than these types are rejected.
+ .local string type
+ type = typeof ops
+
+ if type == 'String' goto T_STR
+ if type == 'Integer' goto T_INT
+ if type == 'ResizableIntegerArray' goto T_ARR
+ if type == 'ResizableStringArray' goto T_ARR
+
+ # If we get here, it is an unknown type.
+ # Throw an exception.
+ .local pmc ex
+ .local string msg
+ msg = 'Unknown type: '
+ msg .= type
+
+ ex = new ['Exception']
+ ex = msg
+ throw ex
+
+T_STR:
+T_INT:
+ # Given either the op name or the op number,
+ # we do nothing other than stashing it into
+ # the ops attribute. When the probe is enabled,
+ # the ops attribute is inspected and hooks are
+ # inserted based on the contents of that hash.
+ # Each entry into the hash is simply given a boolean
+ # value.
+ # Validation of the op's name or number is done
+ # when the probe is enabled.
+ ops_attr[ops] = 1
+ .return()
+
+T_ARR:
+ # Iterate through the array and stash the current
+ # value into the ops_attr hash.
+ .local pmc it, cur
+ it = iter ops
+
+T_ARR_BEG:
+
+ unless it goto T_ARR_END
+
+ cur = shift it
+ ops_attr[cur] = 1
+
+ goto T_ARR_BEG
+
+T_ARR_END:
+ .return()
+
+.end
+
+=item set_callback
+
+=cut
+
+.sub 'set_callback' :method
+ .param pmc sub
+ .local pmc ex
+ .local string msg
+ # If sub is of type string, we need to lookup
+ # the symbol in the namespace.
+ .local string type
+
+CHECK:
+ type = typeof sub
+
+ if type == 'String' goto LOOKUP
+ if type == 'Sub' goto SET
+
+ # If we reached here, we couldn't find the
+ # symbol or a bad parameter was passed in.
+ msg = 'Unknown type of callback: '
+ msg .= type
+
+EXC:
+ ex = new ['Exception']
+ ex = msg
+ throw ex
+
+LOOKUP:
+ # Lookup the symbol in the namespace
+ # (Not sure if this is foolproof)
+ .local string name
+ name = sub
+
+ # Try relative namespace
+ sub = get_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Try HLL namespace
+ sub = get_hll_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Try root namespace
+ sub = get_root_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Cannot find the symbol!
+ msg = 'Could not find symbol '
+ msg .= name
+ msg .= '.'
+
+ goto EXC
+
+SET:
+ # Set the attribute callback and return.
+ setattribute self, 'callback', sub
+ .return()
+.end
+
+=item set_finalize
+
+=cut
+
+.sub 'set_finalize' :method
+ .param pmc sub
+ .local pmc ex
+ .local string msg
+ # If sub is of type string, we need to lookup
+ # the symbol in the namespace.
+ .local string type
+
+CHECK:
+ type = typeof sub
+
+ if type == 'String' goto LOOKUP
+ if type == 'Sub' goto SET
+
+ # If we reached here, we couldn't find the
+ # symbol or a bad parameter was passed in.
+ msg = 'Unknown type of callback: '
+ msg .= type
+
+EXC:
+ ex = new ['Exception']
+ ex = msg
+ throw ex
+
+LOOKUP:
+ # Lookup the symbol in the namespace
+ # (Not sure if this is foolproof)
+ .local string name
+ name = sub
+
+ # Try relative namespace
+ sub = get_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Try HLL namespace
+ sub = get_hll_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Try root namespace
+ sub = get_root_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Cannot find the symbol!
+ msg = 'Could not find symbol '
+ msg .= name
+ msg .= '.'
+
+ goto EXC
+
+SET:
+ # Set the attribute callback and return.
+ setattribute self, 'finalize', sub
+ .return()
+.end
+
+=item enable
+
+=cut
+
+.sub 'enable' :method
+ .local pmc instr_attr, ops_u_attr, ops_p_attr, en_attr, cb_attr
+ .local pmc it, key
+ .local string msg, type, op_name
+ .local int op_num
+
+ instr_attr = getattribute self, 'instr_obj'
+ ops_u_attr = getattribute self, 'ops_unprocessed'
+ ops_p_attr = getattribute self, 'ops_processed'
+ en_attr = getattribute self, 'enabled'
+ cb_attr = getattribute self, 'callback'
+
+ # Check to see if we are already enabled.
+ if en_attr == 1 goto ENABLE_DONE
+
+ # Check to see if the instr_pmc attribute
+ # has been set. if not we cannot do anything.
+ msg = 'Probe is not attached to an Instrument. Could not enable'
+ type = typeof instr_attr
+
+ if type != 'Instrument' goto EXCEP
+
+ # Process the unprocessed ops in ops_u_attr.
+
+ # Because we simply dump in both integers
+ # and string into the hash, first we get
+ # the key from the iterator, then we force
+ # it to be a string, then we try to convert it
+ # to an integer.
+ # If it fails to get converted into an integer,
+ # op_num will be 0. Check if op_num == 0, then we
+ # need to lookup the name by querying instr_attr.
+
+ it = iter ops_u_attr
+
+UNPROC_BEG:
+ unless it goto UNPROC_DONE
+
+ key = shift it
+ op_name = key
+ op_num = op_name
+
+UNPROC_CHECK:
+ # Check if the op is really 0
+ if op_num == 0 goto OPS_LOOKUP
+
+ # If we can convert op_name to op_num, that means that
+ # the op passed was by number. So we do not need to care
+ # about variants.
+ # Put this op into the processed hash, with the value
+ # being a reference to the callback pmc.
+ # TODO: Ensure that the value is not duplicated. Check how Hash works.
+ ops_p_attr[op_num] = cb_attr
+
+UNPROC_LOOKUPED:
+
+ goto UNPROC_BEG
+
+UNPROC_DONE:
+ENABLE_DONE:
+
+ # All unprocessed ops are done at this point.
+ # Pass ops_p_attr to the instrument pmc for hooking.
+ instr_attr.'insert_op_hooks'(ops_p_attr)
+
+ # We are done with enabling.
+ # Set the enabled attribute and return.
+ en_attr = 1
+ setattribute self, 'enabled', en_attr
+
+ .return()
+
+
+EXCEP:
+ # Throw an exception with the message
+ # in msg.
+ .local pmc ex
+ ex = new ['Exception']
+ ex = msg
+ throw ex
+
+OPS_LOOKUP:
+ # Lookup the op number from op_name
+ # This will return an array, so for each element
+ # in the array, insert it into ops_p_attr.
+ .local pmc query_ret, op_lu_it, op_lu_cur
+
+ query_ret = instr_attr.'op_query'(0, op_name)
+ op_lu_it = iter query_ret
+
+OPS_LOOKUP_BEG:
+ unless op_lu_it goto OPS_LOOKUP_END
+
+ op_lu_cur = shift op_lu_it
+ op_num = op_lu_cur
+
+ ops_p_attr[op_num] = cb_attr
+
+ goto OPS_LOOKUP_BEG
+
+OPS_LOOKUP_END:
+
+ goto UNPROC_LOOKUPED
+
+.end
+
+=item disable
+
+=cut
+
+.sub 'disable' :method
+.end
+
+
+=head2 Class Instrument;Probe;Catchall
+
+Class Instrument;Probe;Catchall creates a probe who's callback is called
+for all ops encountered during execution
+
+=cut
+
+.namespace ['Instrument';'Probe';'Catchall']
+
+.sub '' :anon :init :load
+ .local pmc class
+
+ class = newclass ['Instrument';'Probe';'Catchall']
+ addattribute class, 'instr_obj'
+ addattribute class, 'callback'
+ addattribute class, 'enabled'
+ addattribute class, 'finalize'
+
+ .return()
+.end
+
+=item init
+
+=cut
+
+.sub 'init' :vtable :method
+ .local pmc instr_pmc, callback, ops_u, ops_p, enabled
+
+ # Probe is still unattached to an Instrument object.
+ # This attribute will be set by the Instrument object
+ # when the probe is attached to it.
+ instr_pmc = new ['Undef']
+ setattribute self, 'instr_obj', instr_pmc
+
+ # Callback is still undefined.
+ callback = new ['Undef']
+ setattribute self, 'callback', callback
+
+ # Enabled is a Boolean.
+ # Each probe is initially disabled
+ enabled = new ['Boolean']
+ enabled = 0
+ setattribute self, 'enabled', enabled
+
+.end
+
+=item set_callback
+
+=cut
+
+.sub 'set_callback' :method
+ .param pmc sub
+ .local pmc ex
+ .local string msg
+ # If sub is of type string, we need to lookup
+ # the symbol in the namespace.
+ .local string type
+
+CHECK:
+ type = typeof sub
+
+ if type == 'String' goto LOOKUP
+ if type == 'Sub' goto SET
+
+ # If we reached here, we couldn't find the
+ # symbol or a bad parameter was passed in.
+ msg = 'Unknown type of callback: '
+ msg .= type
+
+EXC:
+ ex = new ['Exception']
+ ex = msg
+ throw ex
+
+LOOKUP:
+ # Lookup the symbol in the namespace
+ # (Not sure if this is foolproof)
+ .local string name
+ name = sub
+
+ # Try relative namespace
+ sub = get_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Try HLL namespace
+ sub = get_hll_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Try root namespace
+ sub = get_root_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Cannot find the symbol!
+ msg = 'Could not find symbol '
+ msg .= name
+ msg .= '.'
+
+ goto EXC
+
+SET:
+ # Set the attribute callback and return.
+ setattribute self, 'callback', sub
+ .return()
+.end
+
+=item set_finalize
+
+=cut
+
+.sub 'set_finalize' :method
+ .param pmc sub
+ .local pmc ex
+ .local string msg
+ # If sub is of type string, we need to lookup
+ # the symbol in the namespace.
+ .local string type
+
+CHECK:
+ type = typeof sub
+
+ if type == 'String' goto LOOKUP
+ if type == 'Sub' goto SET
+
+ # If we reached here, we couldn't find the
+ # symbol or a bad parameter was passed in.
+ msg = 'Unknown type of callback: '
+ msg .= type
+
+EXC:
+ ex = new ['Exception']
+ ex = msg
+ throw ex
+
+LOOKUP:
+ # Lookup the symbol in the namespace
+ # (Not sure if this is foolproof)
+ .local string name
+ name = sub
+
+ # Try relative namespace
+ sub = get_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Try HLL namespace
+ sub = get_hll_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Try root namespace
+ sub = get_root_global name
+ $I0 = defined sub
+ if $I0 goto CHECK
+
+ # Cannot find the symbol!
+ msg = 'Could not find symbol '
+ msg .= name
+ msg .= '.'
+
+ goto EXC
+
+SET:
+ # Set the attribute callback and return.
+ setattribute self, 'finalize', sub
+ .return()
+.end
+
+=item enable
+
+=cut
+
+.sub 'enable' :method
+ .local pmc instr_attr, en_attr, cb_attr
+ .local string msg, type
+
+ instr_attr = getattribute self, 'instr_obj'
+ en_attr = getattribute self, 'enabled'
+ cb_attr = getattribute self, 'callback'
+
+ # Check to see if we are already enabled.
+ if en_attr == 1 goto ENABLE_DONE
+
+ # Check to see if the instr_pmc attribute
+ # has been set. if not we cannot do anything.
+ msg = 'Probe is not attached to an Instrument. Could not enable'
+ type = typeof instr_attr
+
+ if type != 'Instrument' goto EXCEP
+
+ENABLE_DONE:
+
+ # Catchall hooks are treated separate from specific hooks.
+ # They are called first too.
+ instr_attr.'insert_op_catchall'(cb_attr)
+
+ # We are done with enabling.
+ # Set the enabled attribute and return.
+ en_attr = 1
+ setattribute self, 'enabled', en_attr
+
+ .return()
+
+
+EXCEP:
+ # Throw an exception with the message
+ # in msg.
+ .local pmc ex
+ ex = new ['Exception']
+ ex = msg
+ throw ex
+
+.end
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Modified: branches/gsoc_instrument/src/dynpmc/Defines.in
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/Defines.in Mon May 24 15:31:33 2010 (r46966)
+++ branches/gsoc_instrument/src/dynpmc/Defines.in Mon May 24 16:08:04 2010 (r46967)
@@ -10,7 +10,8 @@
$(DYNEXT_DIR)/pccmethod_test$(LOAD_EXT) \
$(DYNEXT_DIR)/rotest$(LOAD_EXT) \
$(DYNEXT_DIR)/rational$(LOAD_EXT) \
- $(DYNEXT_DIR)/subproxy$(LOAD_EXT)
+ $(DYNEXT_DIR)/subproxy$(LOAD_EXT) \
+ $(DYNEXT_DIR)/instrument$(LOAD_EXT)
DYNPMC_FOO = \
src/dynpmc/foo.pmc \
Modified: branches/gsoc_instrument/src/dynpmc/Rules.in
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/Rules.in Mon May 24 15:31:33 2010 (r46966)
+++ branches/gsoc_instrument/src/dynpmc/Rules.in Mon May 24 16:08:04 2010 (r46967)
@@ -176,3 +176,22 @@
src/dynpmc/subproxy.dump: src/dynpmc/subproxy.pmc vtable.dump $(CLASS_O_FILES)
$(PMC2CD) src/dynpmc/subproxy.pmc
+
+
+$(DYNEXT_DIR)/instrument$(LOAD_EXT): src/dynpmc/instrument$(O)
+ $(LD) @ld_out@$(DYNEXT_DIR)/instrument$(LOAD_EXT) src/dynpmc/instrument$(O) $(LINKARGS)
+#IF(win32): if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;2
+#IF(cygwin or hpux): $(CHMOD) 0775 $@
+
+src/dynpmc/pmc_instrument.h : src/dynpmc/instrument.c
+
+src/dynpmc/instrument$(O): src/dynpmc/instrument.c $(DYNPMC_H_FILES) \
+ src/dynpmc/pmc_instrument.h
+
+src/dynpmc/instrument.c: src/dynpmc/instrument.dump
+ $(PMC2CC) src/dynpmc/instrument.pmc
+
+src/dynpmc/instrument.dump: src/dynpmc/instrument.pmc vtable.dump $(CLASS_O_FILES)
+ $(PMC2CD) src/dynpmc/instrument.pmc
+
+
Added: branches/gsoc_instrument/src/dynpmc/instrument.pmc
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_instrument/src/dynpmc/instrument.pmc Mon May 24 16:08:04 2010 (r46967)
@@ -0,0 +1,699 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/dynpmc/instrument.pmc - Interface to hook into a child interpreter.
+
+=head1 DESCRIPTION
+
+C<Instrument> is a PMC class that allows dynamic execution introspection
+to be done on a child interpreter.
+
+=head2 Methods
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/parrot.h"
+#include "parrot/imcc.h"
+#include "parrot/runcore_api.h"
+#include "parrot/embed.h"
+
+/*
+ * Extend the runcore_t struct to include a reference
+ * to the supervisor interpreter.
+ */
+typedef struct Instrument_runcore_t {
+ STRING *name;
+ int id;
+ oplib_init_f opinit;
+ runcore_runops_fn_type runops;
+ runcore_destroy_fn_type destroy;
+ runcore_prepare_fn_type prepare_run;
+ INTVAL flags;
+
+ /* End of common members */
+ PMC *supervisor;
+} Instrument_runcore_t;
+
+/* Define the enumeration for op lookups */
+typedef enum {
+ OP_LOOKUP = 0,
+ OP_INFO = 1,
+ OP_FULLNAME = 2,
+ OP_NAME = 3,
+ OP_ARGS = 4,
+ OP_COUNT = 5
+} Instrument_op_query_t;
+
+/* Runcore Function Prototypes */
+static void Instrument_runcore_init (PARROT_INTERP, PMC *supervisor);
+static opcode_t * Instrument_runcore_runops(PARROT_INTERP, Parrot_runcore_t *runcore, opcode_t *pc);
+
+/* Helper Function Prototypes */
+static void gather_params(PARROT_INTERP, opcode_t *pc, PMC *supervisor, PMC *params);
+
+pmclass Instrument auto_attrs dynpmc {
+ ATTR Parrot_Interp supervisor; /* The interpreter that created this instance */
+ ATTR Parrot_Interp supervised; /* The interpreter running the code */
+ ATTR PMC *op_hooks; /* A ResizablePMCArray for holding references to op hooks */
+ ATTR PMC *op_catchall; /* These callbacks are to be called on each op */
+ ATTR PMC *probes; /* A list of probes registered. */
+
+/*
+
+=item C<void init()>
+
+Initializes the pmc and creates a child interpreter.
+
+=cut
+
+*/
+
+ VTABLE void init () {
+ struct parrot_interp_t *in;
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+
+ /* Create the child interpreter PMC */
+ attr->supervisor = INTERP;
+ attr->supervised = Parrot_new(attr->supervisor);
+ attr->op_hooks = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+ attr->op_catchall = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+ attr->probes = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+
+ /* Initialize the runcore for the child interpreter */
+ Instrument_runcore_init(attr->supervised, SELF);
+
+ /* Set self to destroy manually */
+ PObj_custom_mark_destroy_SETALL(SELF);
+ }
+
+/*
+
+=item C<void destroy()>
+
+Cleans up after the PMC.
+
+=cut
+
+*/
+
+ VTABLE void destroy () {
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+
+ /* Delete the supervised interpreter */
+ Parrot_destroy(attr->supervised);
+
+ /* Set the references to null */
+ /* TODO: Is there a better way to delete them? */
+ attr->supervisor = NULL;
+ attr->supervised = NULL;
+ attr->op_hooks = NULL;
+ attr->op_catchall = NULL;
+ attr->probes = NULL;
+ }
+
+/*
+
+=item C<void mark()>
+
+Marks internal data structures as live to the gc.
+
+=cut
+
+*/
+
+ VTABLE void mark () {
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+
+ /* Mark attributes as alive */
+ Parrot_gc_mark_PMC_alive_fun(INTERP, attr->op_hooks);
+ Parrot_gc_mark_PMC_alive_fun(INTERP, attr->op_catchall);
+ Parrot_gc_mark_PMC_alive_fun(INTERP, attr->probes);
+ }
+
+/*
+
+=item C<void * get_pointer()>
+
+Returns a reference to the supervising interpreter,
+meaning the interpreter that runs the instruments.
+
+=cut
+
+*/
+
+ VTABLE void * get_pointer () {
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+ return attr->supervisor;
+ }
+
+/*
+
+=item C<void set_pointer(void *pc_pointer)>
+
+With the pc_pointer passed in, execute the current op at
+the given address after firing all hooks that apply.
+
+=cut
+
+*/
+
+ VTABLE void set_pointer (void *pc_pointer) {
+ opcode_t *pc = (opcode_t *) pc_pointer;
+ INTVAL hook_count, cur_hook, catchall_count, cur_catchall;
+ PMC *hooks;
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+ STRING *full_name;
+
+ /* Set the full name of the op. */
+ full_name = CONST_STRING(INTERP, attr->supervised->op_info_table[*pc].full_name);
+
+ /* Fire the catchall hooks first */
+ catchall_count = VTABLE_get_integer(INTERP, attr->op_catchall);
+ for(cur_catchall = 0; cur_catchall < catchall_count; cur_catchall++) {
+ PMC *cur_catchall_sub;
+
+ cur_catchall_sub = VTABLE_get_pmc_keyed_int(INTERP, attr->op_catchall,
+ cur_catchall);
+ if(!PMC_IS_NULL(cur_catchall_sub))
+ Parrot_ext_call(INTERP, cur_catchall_sub, "S->", full_name);
+ }
+
+ /* Fire the specific probes */
+ hooks = VTABLE_get_pmc_keyed_int(INTERP, attr->op_hooks, *pc);
+ if(!PMC_IS_NULL(hooks)) {
+
+ hook_count = VTABLE_get_integer(INTERP, hooks);
+ for(cur_hook = 0; cur_hook < hook_count; cur_hook++) {
+ PMC *cur_hook_sub;
+
+ cur_hook_sub = VTABLE_get_pmc_keyed_int(INTERP, hooks, cur_hook);
+ if(!PMC_IS_NULL(cur_hook_sub))
+ Parrot_ext_call(INTERP, cur_hook_sub, "S->", full_name);
+ }
+ }
+
+ /* Done firing hooks */
+ return;
+ }
+
+/*
+
+=item C<void run(STRING file, PMC *args)>
+
+Loads the given file and run it with the args given.
+
+=cut
+
+*/
+
+ METHOD run (STRING file, PMC *args) {
+ PMC *entry_point;
+ int argc = 0, status;
+ char * default_argv[] = {NULL};
+ char ** argv = default_argv;
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+ PMC *probe_iter;
+
+ /* If args is not null, is of type ResizableStringArray and has at
+ least 1 element, process it so we can pass it to the child interpreter.
+ */
+ if(!Parrot_pmc_is_null(INTERP, args)
+ && VTABLE_type(INTERP, args) == enum_class_ResizableStringArray
+ && VTABLE_get_integer(INTERP, args) > 0) {
+ /* There are some arguments to be passed to
+ the child interpreter. We need to convert
+ them from Parrot strings to c-strings so
+ that we can pass it to imcc.
+ */
+
+ /* Get the number of argument values */
+ int count = VTABLE_get_integer(INTERP, args);
+
+ /* Allocate enough memory for the argv pointer array */
+ argv = (char **) mem_gc_allocate_n_zeroed_typed(INTERP, count, char *);
+
+ /* Populate the argv array, updating argc in the process */
+ for(argc = 0; argc < count; argc++) {
+ STRING *cur;
+
+ cur = VTABLE_get_string_keyed_int(INTERP, args, argc);
+ argv[argc] = Parrot_str_to_cstring(INTERP, cur);
+ }
+ }
+
+ /* Begin Execution */
+ status = imcc_run(attr->supervised,
+ Parrot_str_cstring(attr->supervised, file),
+ argc, (const char **) argv);
+ if (status)
+ imcc_run_pbc(attr->supervised,
+ attr->supervised->output_file,
+ argc,(const char **) argv);
+
+ /* Finalize the instruments */
+ probe_iter = VTABLE_get_iter(INTERP, attr->probes);
+ while(VTABLE_get_bool(INTERP, probe_iter)) {
+ PMC *cur_probe, *finalize_sub;
+
+ /* For the current probe, get the finalize attribute. */
+ cur_probe = VTABLE_shift_pmc(INTERP, probe_iter);
+ finalize_sub = VTABLE_get_attr_str(INTERP, cur_probe,
+ CONST_STRING(INTERP, "finalize"));
+
+ /* If it is set, call that sub. */
+ if(!PMC_IS_NULL(finalize_sub)) {
+ Parrot_ext_call(INTERP, finalize_sub, "->");
+ }
+ }
+
+ /* We should free the cstrings allocated above if needed */
+ if(argc > 0) {
+ for(; argc > 0; argc--) {
+ Parrot_str_free_cstring(argv[argc - 1]);
+ argv[argc - 1] = NULL;
+ }
+
+ /* Free the memory allocated to hold the string pointers */
+ mem_gc_free(INTERP, argv);
+ argv = NULL;
+ }
+ }
+
+/*
+
+=item C<void attach(PMC *obj)>
+
+With the passed in object, assume it is a class with the method 'enable'
+and attribute 'instr_obj'. Set the 'instr_obj' to SELF and call the
+'enable' method of the object for the object to commence attaching the hooks.
+
+=cut
+
+*/
+
+ METHOD attach (PMC *obj) {
+ PMC *enable_method;
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+
+ /* We do not care what type of object it is,
+ as long as the object has the attribute instr_obj and
+ the method enable. */
+
+ /* Set the instrument reference attribute of the object,
+ and call its enable method. */
+ VTABLE_set_attr_str(
+ INTERP, obj,
+ CONST_STRING(INTERP, "instr_obj"),
+ SELF
+ );
+
+ /* Find the enable method */
+ enable_method = VTABLE_find_method(INTERP, obj, CONST_STRING(INTERP, "enable"));
+ if(PMC_IS_NULL(enable_method)) {
+ /* Error! Could not find the enable method. */
+ Parrot_ex_throw_from_c_args(
+ INTERP, NULL, 1,
+ "Could not locate the method 'enable'."
+ );
+ }
+
+ /* Call the method.
+ The first parameter to a method is the object itself.
+ The enable method will be calling insert_hooks(HASH) to register the hooks. */
+ Parrot_ext_call(INTERP, enable_method, "P->", obj);
+
+ /* Register the probe. */
+ VTABLE_push_pmc(INTERP, attr->probes, obj);
+ }
+
+/*
+
+=item C<void *op_query(INTVAL query_type, PMC *key :optional)>
+
+Performs a op query, based on the query_type.
+0: Lookup the op number given the ops' name. Returns an array of all the indexes with that name.
+1: Returns a hash with the key and data as in the op's op_info_t entry.
+2: Returns the op's full name.
+3: Returns the op's short name.
+4: Returns an array with the type of arguments the op expects.
+5: Returns the total number of ops in the op_lib.
+
+TODO: Create a .pasm file for the constants.
+
+=cut
+
+*/
+
+ METHOD op_query (INTVAL query_type, PMC *key :optional) {
+ PMC *res;
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+
+ /* Perform the required lookup */
+ switch (query_type) {
+ case OP_LOOKUP:
+ {
+ /* Given the name of the op, return its number.
+ Name given can be either short or long name.
+ Return value is in the form of a ResizableIntegerArray */
+ int index;
+ op_info_t *head = attr->supervised->op_info_table;
+ STRING *name = VTABLE_get_string(INTERP, key);
+ char const *c_name = Parrot_str_cstring(INTERP, name);
+ res = Parrot_pmc_new(INTERP, enum_class_ResizableIntegerArray);
+
+
+
+ /* Find the first index of the op. */
+ index = attr->supervised->op_lib->op_code(attr->supervised, c_name, 0);
+ if(index < 0) {
+ index = attr->supervised->op_lib->op_code(attr->supervised, c_name, 1);
+ }
+
+ /* Check if long or short name lookups fail. */
+ if(index < 0) {
+ break;
+ }
+
+ /* Iterate onwards until the name does not match. */
+ do {
+
+ VTABLE_push_integer(INTERP, res, index);
+ index++;
+
+ } while (STREQ(c_name, head[index].name)
+ || STREQ(c_name, head[index].full_name));
+
+ break;
+ }
+
+ case OP_INFO:
+ /* Returns a Hash with the op info as shown in
+ the op_info_table */
+ /* TODO */
+ res = Parrot_pmc_new(INTERP, enum_class_Undef);
+
+ break;
+
+ case OP_FULLNAME:
+ {
+ /* Given the op number, return the full name of the op */
+ size_t index;
+ STRING *name;
+ char const *c_name;
+ index = VTABLE_get_integer(INTERP, key);
+
+ if(index > attr->supervised->op_lib->op_count) {
+ /* Error! Index given is out of range. */
+ Parrot_ex_throw_from_c_args(
+ INTERP, NULL, 1,
+ "Op index out of range."
+ );
+ }
+
+ c_name = attr->supervised->op_info_table[index].full_name;
+ name = Parrot_str_new(INTERP, c_name, strlen(c_name));
+ res = Parrot_pmc_new(INTERP, enum_class_String);
+
+ VTABLE_set_string_native(INTERP, res, name);
+
+ break;
+ }
+
+ case OP_NAME:
+ {
+ /* Given the op number, return the short name of the op */
+ size_t index;
+ STRING *name;
+ char const *c_name;
+ index = VTABLE_get_integer(INTERP, key);
+
+ if(index > attr->supervised->op_lib->op_count) {
+ /* Error! Index given is out of range. */
+ Parrot_ex_throw_from_c_args(
+ INTERP, NULL, 1,
+ "Op index out of range."
+ );
+ }
+
+ c_name = attr->supervised->op_info_table[index].name;
+ name = Parrot_str_new(INTERP, c_name, strlen(c_name));
+ res = Parrot_pmc_new(INTERP, enum_class_String);
+
+ VTABLE_set_string_native(INTERP, res, name);
+
+ break;
+ }
+
+ case OP_ARGS:
+ /* Return a ResizablePMCArray with the types of arguments
+ in order of how the op expects it. */
+ /* TODO */
+ res = Parrot_pmc_new(INTERP, enum_class_Undef);
+
+ break;
+
+ case OP_COUNT:
+ {
+ /* Return the total number of ops in the supervised
+ ops table */
+ INTVAL count;
+ res = Parrot_pmc_new(INTERP, enum_class_Integer);
+ count = attr->supervised->op_count;
+ VTABLE_set_integer_native(INTERP, res, count);
+
+ break;
+ }
+ default:
+ res = Parrot_pmc_new(INTERP, enum_class_Undef);
+ }
+
+ RETURN(PMC* res);
+ }
+
+/*
+
+=item C<void *insert_op_hooks(PMC *hook_hash)>
+
+Insert hooks based on what is given in hook_hash.
+Keys are op numbers and values are sub pmcs.
+
+=cut
+
+*/
+
+ METHOD insert_op_hooks (PMC *hook_hash) {
+ PMC *iter;
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+
+ /* Iterate through hook_hash. For each
+ key (op_num), push the callback to the
+ appropriate entry in op_hooks. */
+ iter = VTABLE_get_iter(INTERP, hook_hash);
+ while(VTABLE_get_bool(INTERP, iter)) {
+ INTVAL op_num;
+ PMC *iter_key, *cur, *callback, *op_num_hooks;
+
+ iter_key = VTABLE_shift_pmc(INTERP, iter);
+ cur = VTABLE_get_pmc(INTERP, iter_key);
+ op_num = VTABLE_get_integer(INTERP, cur);
+ callback = VTABLE_get_pmc_keyed(INTERP, hook_hash, cur);
+
+ op_num_hooks = VTABLE_get_pmc_keyed_int(INTERP, attr->op_hooks, op_num);
+ if(PMC_IS_NULL(op_num_hooks)) {
+ op_num_hooks = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+ VTABLE_set_pmc_keyed_int(INTERP, attr->op_hooks, op_num, op_num_hooks);
+ }
+
+ VTABLE_push_pmc(INTERP, op_num_hooks, callback);
+ }
+ }
+
+/*
+=item C<void *insert_op_catchall(PMC *callback)>
+
+Register a catchall op callback
+
+=cut
+*/
+
+ METHOD insert_op_catchall (PMC *callback) {
+ Parrot_Instrument_attributes * const attr = PARROT_INSTRUMENT(SELF);
+
+ VTABLE_push_pmc(INTERP, attr->op_catchall, callback);
+ }
+}
+
+/*
+ * Runcore Function Implementations
+ */
+
+/*
+ * This is the simplified custom runops function.
+ * This is based on the PARROT_FAST_RUNCORE.
+ */
+static
+opcode_t *
+Instrument_runcore_runops(PARROT_INTERP, Parrot_runcore_t *runcore, opcode_t *pc)
+{
+ Instrument_runcore_t *core = (Instrument_runcore_t *) runcore;
+
+ PMC *pmc = core->supervisor;
+ Parrot_Interp supervisor = (Parrot_Interp) VTABLE_get_pointer(interp, pmc);
+
+ while (pc) {
+ Parrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), pc);
+
+ /* Fire the hooks */
+ VTABLE_set_pointer(supervisor, pmc, pc);
+
+ DO_OP(pc, interp);
+ }
+
+ return pc;
+
+}
+
+/*
+ * This is the initializer for the runcore.
+ * Sets up runcore_t.
+ */
+static
+void
+Instrument_runcore_init (PARROT_INTERP, PMC *supervisor) {
+ Instrument_runcore_t * const coredata =
+ mem_gc_allocate_zeroed_typed(interp, Instrument_runcore_t);
+
+ /* Ensure the current loaded runcore is the slow core */
+ Parrot_set_run_core(interp, PARROT_SLOW_CORE);
+
+ /* Copy the runcore entry for the PARROT_SLOW_CORE,
+ and then make modifications to it.
+ Copy so that we get the opinit function pointer.
+ */
+ mem_copy_n_typed(coredata, interp->run_core, 1, Parrot_runcore_t);
+
+ coredata->name = string_from_literal(interp, "instrument");
+ coredata->runops = Instrument_runcore_runops;
+ coredata->prepare_run = NULL;
+ coredata->destroy = NULL;
+ coredata->flags = 0;
+ coredata->supervisor = supervisor;
+
+ PARROT_RUNCORE_FUNC_TABLE_SET((Parrot_runcore_t *)coredata);
+
+ Parrot_runcore_register(interp, (Parrot_runcore_t *) coredata);
+
+ //Switch to this runcore.
+ Parrot_runcore_switch(interp, coredata->name);
+}
+
+/*
+ * Helper function to gather the parameters of an op
+ * and put it into the passed in ResizablePMCArray.
+ * TODO: This is incomplete and currently unused.
+ */
+static
+void
+gather_params(Parrot_Interp interp, opcode_t *pc, PMC *supervisor, PMC *params) {
+ INTVAL no_params, cur_param;
+ PMC *cc; /* Current context */
+ Parrot_Interp instr_in = (Parrot_Interp) VTABLE_get_pointer(interp, supervisor);
+
+ /* Retrieve the current context.
+ Current context refers to the registers + some other stuff */
+ cc = CURRENT_CONTEXT(interp); /* defined in parrot/interpreter.h */
+
+ /* Figure out how many parameters the op takes,
+ referring to op_info_table
+ We want the op_count field of the current op's
+ op_info_t, which also includes the op as a parameter. */
+ no_params = interp->op_info_table[*pc].op_count - 1;
+
+ /* Begin gathering the parameters.
+ Each parameter is of a certain type, and based on this
+ type, we can access the current_context and get the
+ parameter.
+
+ The types are listed in parrot/op.h.
+ */
+ for(cur_param = 0; cur_param < no_params; cur_param++) {
+ arg_type_t type; /* parrot/op.h */
+
+ /* Get the type of the current param */
+ type = interp->op_info_table[*pc].types[cur_param];
+
+ /* For keyed types, remove the keyed flag,
+ instead treating it as a normal ARG type. */
+ if((type & PARROT_ARG_KEYED) == PARROT_ARG_KEYED) {
+ type &= ~PARROT_ARG_KEYED;
+ }
+
+ /* Gather the params and put it into the
+ ResizablePMCArray pointed to by params.
+ */
+ switch(type) {
+ case PARROT_ARG_IC:
+ /* Integer constants are stored as part of the opcode
+ in the packfile */
+ VTABLE_push_integer(instr_in, params, pc[cur_param + 1]);
+
+ break;
+ case PARROT_ARG_I:
+ VTABLE_push_integer(instr_in, params,
+ *Parrot_pcc_get_INTVAL_reg(interp, cc, pc[cur_param + 1]));
+ break;
+ case PARROT_ARG_NC:
+ VTABLE_push_float(instr_in, params,
+ Parrot_pcc_get_num_constant_func(interp, cc, pc[cur_param + 1]));
+
+ break;
+ case PARROT_ARG_N:
+ VTABLE_push_float(instr_in, params,
+ *Parrot_pcc_get_FLOATVAL_reg(interp, cc, pc[cur_param + 1]));
+ break;
+ case PARROT_ARG_PC:
+ VTABLE_push_pmc(instr_in, params,
+ Parrot_pcc_get_pmc_constant_func(interp, cc, pc[cur_param + 1]));
+
+ break;
+ case PARROT_ARG_P:
+ VTABLE_push_pmc(instr_in, params,
+ *Parrot_pcc_get_PMC_reg(interp, cc, pc[cur_param + 1]));
+ break;
+ case PARROT_ARG_SC:
+ VTABLE_push_string(instr_in, params,
+ Parrot_pcc_get_string_constant_func(interp, cc, pc[cur_param + 1]));
+
+ break;
+ case PARROT_ARG_S:
+ VTABLE_push_string(instr_in, params,
+ *Parrot_pcc_get_STRING_reg(interp, cc, pc[cur_param + 1]));
+ break;
+ default:
+ /* printf("\tUnhandled arg type: %d\n", type); */
+ break;
+ };
+ }
+}
+
+/*
+=back
+
+=head1 SEE ALS0
+
+=cut
+*/
+
+/*
+ * Local Variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
More information about the parrot-commits
mailing list