[svn:parrot] r38803 - in branches/pmc_pct: . compilers/imcc compilers/nqp/src compilers/nqp/src/Grammar compilers/nqp/t compilers/pct/src/PCT compilers/pmcc/src/emitter config/auto config/auto/gmp config/auto/sizes config/gen config/gen/makefiles config/gen/platform/generic docs docs/book docs/book/draft docs/dev docs/pdds docs/project docs/user/pir examples/languages/abc examples/languages/squaak examples/library examples/opengl examples/pir examples/streams examples/tutorial ext/Parrot-Embed/lib/Parrot include/parrot lib/Parrot lib/Parrot/Docs lib/Parrot/Pmc2c lib/Parrot/Pmc2c/PMC ports/cpan ports/cygwin ports/debian ports/fedora ports/mandriva ports/suse ports/ubuntu runtime/parrot/library runtime/parrot/library/Data runtime/parrot/library/Data/Dumper runtime/parrot/library/Digest runtime/parrot/library/Getopt runtime/parrot/library/HTTP runtime/parrot/library/Math runtime/parrot/library/NCI runtime/parrot/library/PGE runtime/parrot/library/Parrot runtime/parrot/l ibrary/Stream runtime/parrot/library/Test runtime/parrot/library/Test/Builder runtime/parrot/library/YAML runtime/parrot/library/YAML/Dumper src src/call src/dynpmc src/gc src/interp src/io src/ops src/pmc src/runcore src/string src/string/charset src/string/encoding t/codingstd t/compilers/imcc/syn t/compilers/json t/compilers/pct t/compilers/pge t/compilers/pge/p5regex t/compilers/pge/perl6regex t/compilers/tge t/dynpmc t/examples t/library t/oo t/op t/pmc t/src tools/dev tools/util

cotto at svn.parrot.org cotto at svn.parrot.org
Fri May 15 21:49:54 UTC 2009


Author: cotto
Date: Fri May 15 21:49:40 2009
New Revision: 38803
URL: https://trac.parrot.org/parrot/changeset/38803

Log:
bring pmc_pct branch up-to-date with trunk

Added:
   branches/pmc_pct/tools/dev/branch_status.pl
      - copied unchanged from r38802, trunk/tools/dev/branch_status.pl
Deleted:
   branches/pmc_pct/include/parrot/gc_mark_sweep.h
   branches/pmc_pct/include/parrot/gc_pools.h
   branches/pmc_pct/include/parrot/resources.h
Modified:
   branches/pmc_pct/   (props changed)
   branches/pmc_pct/CREDITS
   branches/pmc_pct/DEPRECATED.pod
   branches/pmc_pct/MANIFEST
   branches/pmc_pct/MANIFEST.SKIP
   branches/pmc_pct/MANIFEST.generated
   branches/pmc_pct/PLATFORMS
   branches/pmc_pct/compilers/imcc/imc.h
   branches/pmc_pct/compilers/imcc/imcc.y
   branches/pmc_pct/compilers/imcc/imcparser.c
   branches/pmc_pct/compilers/imcc/imcparser.h
   branches/pmc_pct/compilers/imcc/pbc.c
   branches/pmc_pct/compilers/nqp/src/Grammar.pg
   branches/pmc_pct/compilers/nqp/src/Grammar/Actions.pir
   branches/pmc_pct/compilers/nqp/t/18-inline.t
   branches/pmc_pct/compilers/pct/src/PCT/HLLCompiler.pir
   branches/pmc_pct/compilers/pmcc/src/emitter/pmc.pm
   branches/pmc_pct/config/auto/arch.pm
   branches/pmc_pct/config/auto/gmp/gmp_c.in
   branches/pmc_pct/config/auto/sizes/intval_maxmin_c.in   (props changed)
   branches/pmc_pct/config/gen/core_pmcs.pm
   branches/pmc_pct/config/gen/makefiles/root.in
   branches/pmc_pct/config/gen/parrot_include.pm
   branches/pmc_pct/config/gen/platform/generic/itimer.c
   branches/pmc_pct/docs/book/appb_patch_submission.pod   (props changed)
   branches/pmc_pct/docs/book/ch01_introduction.pod   (props changed)
   branches/pmc_pct/docs/book/ch03_pir.pod   (contents, props changed)
   branches/pmc_pct/docs/book/ch04_compiler_tools.pod   (props changed)
   branches/pmc_pct/docs/book/ch05_pge.pod
   branches/pmc_pct/docs/book/ch06_nqp.pod
   branches/pmc_pct/docs/book/ch07_dynpmcs.pod   (props changed)
   branches/pmc_pct/docs/book/ch08_dynops.pod   (props changed)
   branches/pmc_pct/docs/book/ch09_pasm.pod   (contents, props changed)
   branches/pmc_pct/docs/book/ch10_opcode_reference.pod   (props changed)
   branches/pmc_pct/docs/book/draft/chXX_hlls.pod   (contents, props changed)
   branches/pmc_pct/docs/book/draft/chXX_library.pod   (props changed)
   branches/pmc_pct/docs/book/draft/chXX_testing_and_debugging.pod   (props changed)
   branches/pmc_pct/docs/dev/c_functions.pod   (props changed)
   branches/pmc_pct/docs/dev/pmc_freeze.pod
   branches/pmc_pct/docs/embed.pod
   branches/pmc_pct/docs/pdds/pdd09_gc.pod
   branches/pmc_pct/docs/pdds/pdd30_install.pod   (props changed)
   branches/pmc_pct/docs/pmc.pod
   branches/pmc_pct/docs/project/release_manager_guide.pod
   branches/pmc_pct/docs/user/pir/exceptions.pod
   branches/pmc_pct/examples/languages/abc/   (props changed)
   branches/pmc_pct/examples/languages/squaak/   (props changed)
   branches/pmc_pct/examples/library/ncurses_life.pir
   branches/pmc_pct/examples/opengl/shapes.pir
   branches/pmc_pct/examples/opengl/static-triangle.pir
   branches/pmc_pct/examples/opengl/triangle.pir
   branches/pmc_pct/examples/pir/sudoku.pir
   branches/pmc_pct/examples/streams/Bytes.pir
   branches/pmc_pct/examples/streams/Combiner.pir
   branches/pmc_pct/examples/streams/Coroutine.pir
   branches/pmc_pct/examples/streams/FileLines.pir
   branches/pmc_pct/examples/streams/Filter.pir
   branches/pmc_pct/examples/streams/Include.pir
   branches/pmc_pct/examples/streams/Lines.pir
   branches/pmc_pct/examples/streams/ParrotIO.pir
   branches/pmc_pct/examples/streams/Replay.pir
   branches/pmc_pct/examples/streams/SubCounter.pir
   branches/pmc_pct/examples/streams/SubHello.pir
   branches/pmc_pct/examples/streams/Writer.pir
   branches/pmc_pct/examples/tutorial/90_writing_tests.pir
   branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/Embed.pm
   branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/Interpreter.pm
   branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/PMC.pm
   branches/pmc_pct/include/parrot/call.h   (props changed)
   branches/pmc_pct/include/parrot/exceptions.h
   branches/pmc_pct/include/parrot/gc_api.h   (contents, props changed)
   branches/pmc_pct/include/parrot/hash.h
   branches/pmc_pct/include/parrot/interpreter.h
   branches/pmc_pct/include/parrot/io.h
   branches/pmc_pct/include/parrot/memory.h
   branches/pmc_pct/include/parrot/misc.h
   branches/pmc_pct/include/parrot/multidispatch.h
   branches/pmc_pct/include/parrot/packfile.h
   branches/pmc_pct/include/parrot/parrot.h
   branches/pmc_pct/include/parrot/runcore_api.h   (props changed)
   branches/pmc_pct/include/parrot/runcore_trace.h   (props changed)
   branches/pmc_pct/include/parrot/stacks.h
   branches/pmc_pct/lib/Parrot/Docs/File.pm
   branches/pmc_pct/lib/Parrot/Docs/POD2HTML.pm
   branches/pmc_pct/lib/Parrot/Pmc2c/PMC/RO.pm
   branches/pmc_pct/lib/Parrot/Pmc2c/PMC/default.pm
   branches/pmc_pct/lib/Parrot/Pmc2c/PMCEmitter.pm
   branches/pmc_pct/lib/Parrot/Revision.pm
   branches/pmc_pct/ports/cpan/pause_guide.pod   (props changed)
   branches/pmc_pct/ports/cygwin/parrot-1.0.0-1.cygport   (props changed)
   branches/pmc_pct/ports/debian/libparrot-dev.install.in   (props changed)
   branches/pmc_pct/ports/debian/libparrot.install.in   (props changed)
   branches/pmc_pct/ports/debian/parrot-doc.install.in   (props changed)
   branches/pmc_pct/ports/debian/parrot.install.in   (props changed)
   branches/pmc_pct/ports/fedora/parrot.spec.fedora   (props changed)
   branches/pmc_pct/ports/mandriva/parrot.spec.mandriva   (props changed)
   branches/pmc_pct/ports/suse/parrot.spec.suse   (props changed)
   branches/pmc_pct/ports/ubuntu/changelog
   branches/pmc_pct/ports/ubuntu/control.in
   branches/pmc_pct/runtime/parrot/library/Data/Dumper.pir
   branches/pmc_pct/runtime/parrot/library/Data/Dumper/Default.pir
   branches/pmc_pct/runtime/parrot/library/Data/Replace.pir
   branches/pmc_pct/runtime/parrot/library/Digest/MD5.pir
   branches/pmc_pct/runtime/parrot/library/Getopt/Obj.pir
   branches/pmc_pct/runtime/parrot/library/HTTP/Daemon.pir
   branches/pmc_pct/runtime/parrot/library/Math/Rand.pir   (contents, props changed)
   branches/pmc_pct/runtime/parrot/library/NCI/call_toolkit_init.pir
   branches/pmc_pct/runtime/parrot/library/OpenGL.pir
   branches/pmc_pct/runtime/parrot/library/PGE/Perl6Grammar.pir
   branches/pmc_pct/runtime/parrot/library/Parrot/Coroutine.pir
   branches/pmc_pct/runtime/parrot/library/Pg.pir
   branches/pmc_pct/runtime/parrot/library/Stream/Base.pir
   branches/pmc_pct/runtime/parrot/library/Stream/Combiner.pir
   branches/pmc_pct/runtime/parrot/library/Stream/Coroutine.pir
   branches/pmc_pct/runtime/parrot/library/Stream/Filter.pir
   branches/pmc_pct/runtime/parrot/library/Stream/Lines.pir
   branches/pmc_pct/runtime/parrot/library/Stream/ParrotIO.pir
   branches/pmc_pct/runtime/parrot/library/Stream/Replay.pir
   branches/pmc_pct/runtime/parrot/library/Stream/Sub.pir
   branches/pmc_pct/runtime/parrot/library/Stream/Writer.pir
   branches/pmc_pct/runtime/parrot/library/Test/Builder.pir
   branches/pmc_pct/runtime/parrot/library/Test/Builder/Tester.pir
   branches/pmc_pct/runtime/parrot/library/Test/More.pir
   branches/pmc_pct/runtime/parrot/library/YAML/   (props changed)
   branches/pmc_pct/runtime/parrot/library/YAML/Dumper/   (props changed)
   branches/pmc_pct/runtime/parrot/library/YAML/Dumper.pir
   branches/pmc_pct/runtime/parrot/library/YAML/Dumper/Default.pir
   branches/pmc_pct/runtime/parrot/library/dumper.pir
   branches/pmc_pct/runtime/parrot/library/pcre.pir
   branches/pmc_pct/runtime/parrot/library/tcpstream.pir
   branches/pmc_pct/runtime/parrot/library/yaml_dumper.pir
   branches/pmc_pct/src/call/ops.c   (props changed)
   branches/pmc_pct/src/call/pcc.c   (contents, props changed)
   branches/pmc_pct/src/dynpmc/dynlexpad.pmc
   branches/pmc_pct/src/dynpmc/pair.pmc
   branches/pmc_pct/src/extend.c
   branches/pmc_pct/src/gc/api.c   (contents, props changed)
   branches/pmc_pct/src/gc/gc_private.h
   branches/pmc_pct/src/gc/generational_ms.c   (contents, props changed)
   branches/pmc_pct/src/gc/incremental_ms.c   (contents, props changed)
   branches/pmc_pct/src/gc/mark_sweep.c   (contents, props changed)
   branches/pmc_pct/src/gc/memory.c
   branches/pmc_pct/src/gc/pools.c   (contents, props changed)
   branches/pmc_pct/src/gc/res_lea.c
   branches/pmc_pct/src/gc/resources.c
   branches/pmc_pct/src/gc/system.c   (contents, props changed)
   branches/pmc_pct/src/global.c
   branches/pmc_pct/src/hash.c
   branches/pmc_pct/src/interp/inter_cb.c   (contents, props changed)
   branches/pmc_pct/src/interp/inter_create.c   (contents, props changed)
   branches/pmc_pct/src/interp/inter_misc.c   (contents, props changed)
   branches/pmc_pct/src/io/api.c
   branches/pmc_pct/src/io/buffer.c
   branches/pmc_pct/src/io/core.c
   branches/pmc_pct/src/io/filehandle.c
   branches/pmc_pct/src/io/io_string.c
   branches/pmc_pct/src/io/socket_api.c
   branches/pmc_pct/src/io/socket_unix.c
   branches/pmc_pct/src/io/socket_win32.c
   branches/pmc_pct/src/io/unix.c
   branches/pmc_pct/src/io/utf8.c
   branches/pmc_pct/src/jit.c
   branches/pmc_pct/src/key.c
   branches/pmc_pct/src/list.c
   branches/pmc_pct/src/malloc-trace.c
   branches/pmc_pct/src/multidispatch.c
   branches/pmc_pct/src/oo.c
   branches/pmc_pct/src/ops/core.ops
   branches/pmc_pct/src/ops/io.ops
   branches/pmc_pct/src/ops/string.ops
   branches/pmc_pct/src/packfile.c
   branches/pmc_pct/src/parrot_debugger.c
   branches/pmc_pct/src/pmc.c
   branches/pmc_pct/src/pmc/addrregistry.pmc
   branches/pmc_pct/src/pmc/array.pmc
   branches/pmc_pct/src/pmc/bigint.pmc
   branches/pmc_pct/src/pmc/bignum.pmc
   branches/pmc_pct/src/pmc/boolean.pmc
   branches/pmc_pct/src/pmc/callsignature.pmc
   branches/pmc_pct/src/pmc/capture.pmc
   branches/pmc_pct/src/pmc/class.pmc
   branches/pmc_pct/src/pmc/codestring.pmc
   branches/pmc_pct/src/pmc/complex.pmc
   branches/pmc_pct/src/pmc/continuation.pmc
   branches/pmc_pct/src/pmc/coroutine.pmc
   branches/pmc_pct/src/pmc/cpointer.pmc
   branches/pmc_pct/src/pmc/default.pmc
   branches/pmc_pct/src/pmc/env.pmc
   branches/pmc_pct/src/pmc/eval.pmc
   branches/pmc_pct/src/pmc/eventhandler.pmc
   branches/pmc_pct/src/pmc/exception.pmc
   branches/pmc_pct/src/pmc/exceptionhandler.pmc
   branches/pmc_pct/src/pmc/exporter.pmc
   branches/pmc_pct/src/pmc/file.pmc
   branches/pmc_pct/src/pmc/filehandle.pmc
   branches/pmc_pct/src/pmc/fixedbooleanarray.pmc
   branches/pmc_pct/src/pmc/fixedfloatarray.pmc
   branches/pmc_pct/src/pmc/fixedintegerarray.pmc
   branches/pmc_pct/src/pmc/fixedpmcarray.pmc
   branches/pmc_pct/src/pmc/fixedstringarray.pmc
   branches/pmc_pct/src/pmc/float.pmc
   branches/pmc_pct/src/pmc/hash.pmc
   branches/pmc_pct/src/pmc/integer.pmc
   branches/pmc_pct/src/pmc/iterator.pmc
   branches/pmc_pct/src/pmc/key.pmc
   branches/pmc_pct/src/pmc/lexinfo.pmc
   branches/pmc_pct/src/pmc/lexpad.pmc
   branches/pmc_pct/src/pmc/managedstruct.pmc
   branches/pmc_pct/src/pmc/multisub.pmc
   branches/pmc_pct/src/pmc/namespace.pmc
   branches/pmc_pct/src/pmc/nci.pmc
   branches/pmc_pct/src/pmc/null.pmc
   branches/pmc_pct/src/pmc/object.pmc
   branches/pmc_pct/src/pmc/orderedhash.pmc
   branches/pmc_pct/src/pmc/os.pmc
   branches/pmc_pct/src/pmc/packfile.pmc
   branches/pmc_pct/src/pmc/packfileannotation.pmc
   branches/pmc_pct/src/pmc/packfileannotationkeys.pmc
   branches/pmc_pct/src/pmc/packfileannotations.pmc
   branches/pmc_pct/src/pmc/packfileconstanttable.pmc
   branches/pmc_pct/src/pmc/packfiledirectory.pmc
   branches/pmc_pct/src/pmc/packfilefixupentry.pmc
   branches/pmc_pct/src/pmc/packfilefixuptable.pmc
   branches/pmc_pct/src/pmc/packfilerawsegment.pmc
   branches/pmc_pct/src/pmc/packfilesegment.pmc
   branches/pmc_pct/src/pmc/parrotinterpreter.pmc
   branches/pmc_pct/src/pmc/parrotlibrary.pmc
   branches/pmc_pct/src/pmc/parrotrunningthread.pmc
   branches/pmc_pct/src/pmc/parrotthread.pmc
   branches/pmc_pct/src/pmc/pccmethod_test.pmc
   branches/pmc_pct/src/pmc/pmcproxy.pmc
   branches/pmc_pct/src/pmc/pointer.pmc
   branches/pmc_pct/src/pmc/random.pmc
   branches/pmc_pct/src/pmc/resizablebooleanarray.pmc
   branches/pmc_pct/src/pmc/resizablefloatarray.pmc
   branches/pmc_pct/src/pmc/resizableintegerarray.pmc
   branches/pmc_pct/src/pmc/resizablepmcarray.pmc
   branches/pmc_pct/src/pmc/resizablestringarray.pmc
   branches/pmc_pct/src/pmc/retcontinuation.pmc
   branches/pmc_pct/src/pmc/role.pmc
   branches/pmc_pct/src/pmc/scalar.pmc
   branches/pmc_pct/src/pmc/scheduler.pmc
   branches/pmc_pct/src/pmc/schedulermessage.pmc
   branches/pmc_pct/src/pmc/sockaddr.pmc
   branches/pmc_pct/src/pmc/socket.pmc
   branches/pmc_pct/src/pmc/string.pmc
   branches/pmc_pct/src/pmc/stringhandle.pmc
   branches/pmc_pct/src/pmc/sub.pmc
   branches/pmc_pct/src/pmc/task.pmc
   branches/pmc_pct/src/pmc/timer.pmc
   branches/pmc_pct/src/pmc/undef.pmc
   branches/pmc_pct/src/pmc/unmanagedstruct.pmc
   branches/pmc_pct/src/pmc_freeze.c
   branches/pmc_pct/src/runcore/cores.c   (contents, props changed)
   branches/pmc_pct/src/runcore/main.c   (props changed)
   branches/pmc_pct/src/runcore/trace.c   (props changed)
   branches/pmc_pct/src/scheduler.c
   branches/pmc_pct/src/stacks.c
   branches/pmc_pct/src/string/api.c
   branches/pmc_pct/src/string/charset/ascii.c
   branches/pmc_pct/src/string/charset/iso-8859-1.c
   branches/pmc_pct/src/string/charset/unicode.c
   branches/pmc_pct/src/string/encoding/utf16.c
   branches/pmc_pct/src/string/encoding/utf8.c
   branches/pmc_pct/src/sub.c
   branches/pmc_pct/src/thread.c
   branches/pmc_pct/src/utils.c
   branches/pmc_pct/src/vtables.c
   branches/pmc_pct/t/codingstd/c_function_docs.t
   branches/pmc_pct/t/codingstd/copyright.t
   branches/pmc_pct/t/compilers/imcc/syn/regressions.t
   branches/pmc_pct/t/compilers/imcc/syn/subflags.t
   branches/pmc_pct/t/compilers/json/to_parrot.t
   branches/pmc_pct/t/compilers/pct/past.t
   branches/pmc_pct/t/compilers/pct/post.t
   branches/pmc_pct/t/compilers/pge/00-basic.t
   branches/pmc_pct/t/compilers/pge/03-optable.t
   branches/pmc_pct/t/compilers/pge/06-grammar.t
   branches/pmc_pct/t/compilers/pge/p5regex/p5rx.t
   branches/pmc_pct/t/compilers/pge/perl6regex/01-regex.t
   branches/pmc_pct/t/compilers/pge/perl6regex/context.t
   branches/pmc_pct/t/compilers/pge/pge_text.t
   branches/pmc_pct/t/compilers/pge/pge_util.t
   branches/pmc_pct/t/compilers/tge/NoneGrammar.tg   (props changed)
   branches/pmc_pct/t/dynpmc/pair.t   (contents, props changed)
   branches/pmc_pct/t/examples/pod.t
   branches/pmc_pct/t/library/coroutine.t
   branches/pmc_pct/t/library/getopt_obj.t
   branches/pmc_pct/t/library/iter.t
   branches/pmc_pct/t/library/mime_base64.t
   branches/pmc_pct/t/library/pcre.t
   branches/pmc_pct/t/library/range.t
   branches/pmc_pct/t/library/streams.t
   branches/pmc_pct/t/library/string_utils.t
   branches/pmc_pct/t/library/tcl_lib.t
   branches/pmc_pct/t/library/test_builder_tester.t
   branches/pmc_pct/t/library/test_class.t
   branches/pmc_pct/t/library/test_more.t
   branches/pmc_pct/t/oo/metamodel.t
   branches/pmc_pct/t/op/io.t
   branches/pmc_pct/t/op/lexicals.t
   branches/pmc_pct/t/op/sprintf.t
   branches/pmc_pct/t/op/trans.t
   branches/pmc_pct/t/pmc/array.t
   branches/pmc_pct/t/pmc/bigint.t
   branches/pmc_pct/t/pmc/bignum.t
   branches/pmc_pct/t/pmc/class.t
   branches/pmc_pct/t/pmc/exceptionhandler.t
   branches/pmc_pct/t/pmc/exporter.t
   branches/pmc_pct/t/pmc/fixedbooleanarray.t
   branches/pmc_pct/t/pmc/fixedintegerarray.t
   branches/pmc_pct/t/pmc/fixedpmcarray.t
   branches/pmc_pct/t/pmc/fixedstringarray.t
   branches/pmc_pct/t/pmc/float.t
   branches/pmc_pct/t/pmc/resizablefloatarray.t
   branches/pmc_pct/t/pmc/resizableintegerarray.t
   branches/pmc_pct/t/pmc/ro.t
   branches/pmc_pct/t/pmc/string.t
   branches/pmc_pct/t/src/embed.t   (props changed)
   branches/pmc_pct/tools/dev/fetch_languages.pl   (props changed)
   branches/pmc_pct/tools/dev/mk_gitignore.pl   (props changed)
   branches/pmc_pct/tools/util/crow.pir
   branches/pmc_pct/tools/util/perlcritic-cage.conf   (props changed)

Modified: branches/pmc_pct/CREDITS
==============================================================================
--- branches/pmc_pct/CREDITS	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/CREDITS	Fri May 15 21:49:40 2009	(r38803)
@@ -272,6 +272,9 @@
 D: imcc optimizer and register allocator patches and tests
 E: cgrawls at gmail.com
 
+U: cxreg
+D: copyright test cleanup
+
 N: Damian Miles Knopp
 U: dmknopp
 E: dmknopp at loyola.edu
@@ -400,6 +403,10 @@
 N: H.Merijn Brand
 D: HP-UX fixes and smoke tests
 
+N: Igor Rafael Sanchez-Puls
+D: extending test_file_coverage to test PMC coverage
+E: quevlar at ymail.com
+
 N: Ibotty
 D: parrotbench ruby benchmarks
 

Modified: branches/pmc_pct/DEPRECATED.pod
==============================================================================
--- branches/pmc_pct/DEPRECATED.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/DEPRECATED.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -38,7 +38,7 @@
 
 =over 4
 
-=item pointer [eligible in 1.1]
+=item pair (dynamic PMC) [eligible in 1.5]
 
 L<https://trac.parrot.org/parrot/ticket/187>
 
@@ -78,6 +78,15 @@
 
 L<https://trac.parrot.org/parrot/ticket/450>
 
+=item get_addr and set_addr [eligible in 1.5]
+
+L<https://trac.parrot.org/parrot/ticket/218>
+
+These opcodes are being repurposed. They will always return a unique memory
+address of the PMC. Uses of get_addr and set_addr that would set label values
+for Sub, Exception, and related PMC types will instead be handled by
+get_label and set_label.
+
 =back
 
 =head1 Bytecode
@@ -221,6 +230,10 @@
 
 L<https://trac.parrot.org/parrot/ticket/625>
 
+=item pobject_lives [eligible in 1.5]
+
+L<https://trac.parrot.org/parrot/ticket/664>
+
 =back
 
 =head1 Compiler tools

Modified: branches/pmc_pct/MANIFEST
==============================================================================
--- branches/pmc_pct/MANIFEST	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/MANIFEST	Fri May 15 21:49:40 2009	(r38803)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Thu May  7 23:48:29 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Fri May 15 21:43:28 2009 UT
 #
 # See tools/dev/install_files.pl for documentation on the
 # format of this file.
@@ -199,8 +199,11 @@
 compilers/pmcc/src/builtins.pir                             [pmcc]
 compilers/pmcc/src/emitter.pm                               [pmcc]
 compilers/pmcc/src/emitter/c.pir                            [pmcc]
+compilers/pmcc/src/emitter/c.pm                             [pmcc]
 compilers/pmcc/src/emitter/pmc.pir                          [pmcc]
 compilers/pmcc/src/emitter/pmc.pm                           [pmcc]
+compilers/pmcc/src/emitter/pmc/default.pir                  [pmcc]
+compilers/pmcc/src/emitter/pmc/default.pm                   [pmcc]
 compilers/pmcc/src/nodes.pir                                [pmcc]
 compilers/pmcc/src/parser/actions.pm                        [pmcc]
 compilers/pmcc/src/parser/grammar.pg                        [pmcc]
@@ -212,7 +215,9 @@
 compilers/pmcc/t/04-vtable-info.t                           [test]
 compilers/pmcc/t/05-header.t                                [test]
 compilers/pmcc/t/06-body.t                                  [test]
+compilers/pmcc/t/07-default.t                               [test]
 compilers/pmcc/t/common.pir                                 [test]
+compilers/pmcc/t/data/child.pmc                             [test]
 compilers/pmcc/t/data/class.pmc                             [test]
 compilers/pmcc/t/data/class00.pmc                           [test]
 compilers/pmcc/t/data/class01.pmc                           [test]
@@ -239,6 +244,10 @@
 compilers/pmcc/t/data/class22.pmc                           [test]
 compilers/pmcc/t/data/class23.pmc                           [test]
 compilers/pmcc/t/data/class24.pmc                           [test]
+compilers/pmcc/t/data/class25.pmc                           [test]
+compilers/pmcc/t/data/class26.pmc                           [test]
+compilers/pmcc/t/data/default.pmc                           [test]
+compilers/pmcc/t/data/parent.pmc                            [test]
 compilers/pmcc/t/harness                                    [test]
 compilers/pmcc/tools/vtable_pm.pl                           [pmcc]
 compilers/tge/README                                        []doc
@@ -1001,8 +1010,6 @@
 include/parrot/exit.h                                       [main]include
 include/parrot/extend.h                                     [main]include
 include/parrot/gc_api.h                                     [main]include
-include/parrot/gc_mark_sweep.h                              [main]include
-include/parrot/gc_pools.h                                   [main]include
 include/parrot/global.h                                     [main]include
 include/parrot/global_setup.h                               [main]include
 include/parrot/hash.h                                       [main]include
@@ -1032,7 +1039,6 @@
 include/parrot/pmc_freeze.h                                 [main]include
 include/parrot/pobj.h                                       [main]include
 include/parrot/register.h                                   [main]include
-include/parrot/resources.h                                  [main]include
 include/parrot/runcore_api.h                                [main]include
 include/parrot/runcore_trace.h                              [main]include
 include/parrot/scheduler.h                                  [main]include
@@ -2114,6 +2120,7 @@
 tools/dev/.gdbinit                                          []
 tools/dev/as2c.pl                                           []
 tools/dev/bench_op.pir                                      []
+tools/dev/branch_status.pl                                  []
 tools/dev/cc_flags.pl                                       []
 tools/dev/create_language.pl                                []
 tools/dev/debian_docs.sh                                    []

Modified: branches/pmc_pct/MANIFEST.SKIP
==============================================================================
--- branches/pmc_pct/MANIFEST.SKIP	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/MANIFEST.SKIP	Fri May 15 21:49:40 2009	(r38803)
@@ -1,6 +1,6 @@
 # ex: set ro:
 # $Id$
-# generated by tools/dev/mk_manifest_and_skip.pl Sun Apr 26 13:09:44 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Fri May 15 17:05:40 2009 UT
 #
 # This file should contain a transcript of the svn:ignore properties
 # of the directories in the Parrot subversion repository. (Needed for
@@ -602,6 +602,12 @@
 # generated from svn:ignore of 'runtime/parrot/library/Test/Builder/'
 ^runtime/parrot/library/Test/Builder/.*\.pbc$
 ^runtime/parrot/library/Test/Builder/.*\.pbc/
+# generated from svn:ignore of 'runtime/parrot/library/YAML/'
+^runtime/parrot/library/YAML/.*\.pbc$
+^runtime/parrot/library/YAML/.*\.pbc/
+# generated from svn:ignore of 'runtime/parrot/library/YAML/Dumper/'
+^runtime/parrot/library/YAML/Dumper/.*\.pbc$
+^runtime/parrot/library/YAML/Dumper/.*\.pbc/
 # generated from svn:ignore of 'runtime/parrot/library/YAML/Parser/'
 ^runtime/parrot/library/YAML/Parser/.*\.pbc$
 ^runtime/parrot/library/YAML/Parser/.*\.pbc/

Modified: branches/pmc_pct/MANIFEST.generated
==============================================================================
--- branches/pmc_pct/MANIFEST.generated	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/MANIFEST.generated	Fri May 15 21:49:40 2009	(r38803)
@@ -138,12 +138,15 @@
 runtime/parrot/library/Data/Dumper.pbc            [main]
 runtime/parrot/library/dumper.pbc                 [main]
 runtime/parrot/library/Getopt/Obj.pbc             [main]
+runtime/parrot/library/Iter.pbc                   [main]
+runtime/parrot/library/JSON.pbc                   [main]
 runtime/parrot/library/Math/Random/mt19937ar.pbc  [main]
 runtime/parrot/library/Math/Rand.pbc              [main]
 runtime/parrot/library/MIME/Base64.pbc            [main]
 runtime/parrot/library/NCI/call_toolkit_init.pbc  [main]
 runtime/parrot/library/ncurses.pbc                [main]
 runtime/parrot/library/OpenGL_funcs.pir           [main]
+runtime/parrot/library/OpenGL_funcs.pbc           [main]
 runtime/parrot/library/OpenGL.pbc                 [main]
 runtime/parrot/library/P6object.pbc               [main]
 runtime/parrot/library/Parrot/Capture_PIR.pbc     [main]
@@ -151,6 +154,7 @@
 runtime/parrot/library/Parrot/Exception.pbc       [main]
 runtime/parrot/library/Parrot/HLLCompiler.pbc     [main]
 runtime/parrot/library/parrotlib.pbc              [main]
+runtime/parrot/library/pcore.pbc                  [main]
 runtime/parrot/library/pcre.pbc                   [main]
 runtime/parrot/library/PCT/Grammar.pbc            [pct]
 runtime/parrot/library/PCT/HLLCompiler.pbc        [pct]
@@ -164,6 +168,7 @@
 runtime/parrot/library/PGE/Text.pbc               [main]
 runtime/parrot/library/PGE/Util.pbc               [main]
 runtime/parrot/library/Protoobject.pbc            [main]
+runtime/parrot/library/Range.pbc                  [main]
 runtime/parrot/library/Stream/Base.pbc            [main]
 runtime/parrot/library/Stream/Combiner.pbc        [main]
 runtime/parrot/library/Stream/Coroutine.pbc       [main]
@@ -173,7 +178,11 @@
 runtime/parrot/library/Stream/Replay.pbc          [main]
 runtime/parrot/library/Stream/Sub.pbc             [main]
 runtime/parrot/library/Stream/Writer.pbc          [main]
+runtime/parrot/library/TclLibrary.pbc             [main]
 runtime/parrot/library/TGE.pbc                    [tge]
+runtime/parrot/library/YAML/Dumper/Base.pmc       [main]
+runtime/parrot/library/YAML/Dumper/Default.pmc    [main]
+runtime/parrot/library/YAML/Dumper.pbc            [main]
 src/call_list.txt                                 [devel]src
 src/glut_callbacks.c                              []
 src/jit_emit.h                                    []

Modified: branches/pmc_pct/PLATFORMS
==============================================================================
--- branches/pmc_pct/PLATFORMS	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/PLATFORMS	Fri May 15 21:49:40 2009	(r38803)
@@ -54,7 +54,6 @@
 netbsd5.0-sparc64-gcc-4.1.3  B8   Y    -    -     Y   Y   Y    Y     ?  20090421
 netbsd5.0-x86_64-gcc-4.1.3    8   Y    -    -     Y   Y   Y    Y     ?  20090419
 opensolaris-x86-gcc_4.0.3     4   Y    Y    ?     ?   ?   Y    Y/2   ?  20080325
-sol8-sparc-cc                B    -    -    -     -   -   -    Y     ?  20090317
 sol8-sparc-gcc_4.1.0         B    -    -    -     -   -   -    Y/42  ?  20090317
 win32-x86-mingw_gcc4.3.0          Y    Y    -     -   -   Y    Y/88  ?  20081203
 win32-x86-msvc_6.0            4   -    Y    -     -   -   Y    Y/8   ?  20090315

Modified: branches/pmc_pct/compilers/imcc/imc.h
==============================================================================
--- branches/pmc_pct/compilers/imcc/imc.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/imcc/imc.h	Fri May 15 21:49:40 2009	(r38803)
@@ -27,20 +27,18 @@
 
 /* For people without unistd.h to compile Flex lexer
  * unistd.h probably isn't required on most if any
- * platforms anyway.
- */
+ * platforms anyway.  */
 #ifndef PARROT_HAS_HEADER_UNISTD
 #  define YY_NO_UNISTD_H 1
 #endif
 
 #define IMCC_MAX_FIX_REGS PARROT_MAX_ARGS
 #if IMCC_MAX_FIX_REGS > 16
- #  error: flags wont fit
+#  error: flags wont fit
 #endif
 
-/* IMCC reserves this character for internally generated labels
- * and identifiers that won't collide with high level compiler generated names.
- */
+/* IMCC reserves this character for internally generated labels and identifiers
+ * that won't collide with high level compiler generated names.  */
 #define IMCC_INTERNAL_CHAR '@'
 
 typedef struct _IMC_Unit IMC_Unit;
@@ -594,7 +592,7 @@
     /* some values that were global... */
     SymReg               *cur_call;
     SymReg               *cur_obj;
-    const char           *adv_named_id;
+    SymReg               *adv_named_id;
 
     /* Lex globals */
     char                 *heredoc_end;

Modified: branches/pmc_pct/compilers/imcc/imcc.y
==============================================================================
--- branches/pmc_pct/compilers/imcc/imcc.y	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/imcc/imcc.y	Fri May 15 21:49:40 2009	(r38803)
@@ -44,7 +44,7 @@
 
 static void add_pcc_named_arg(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(const char *name),
+    ARGIN(SymReg *name),
     ARGIN(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -64,7 +64,7 @@
 
 static void add_pcc_named_param(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(const char *name),
+    ARGIN(SymReg *name),
     ARGIN(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -74,7 +74,7 @@
 
 static void add_pcc_named_result(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(const char *name),
+    ARGIN(SymReg *name),
     ARGIN(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -84,7 +84,7 @@
 
 static void add_pcc_named_return(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(const char *name),
+    ARGIN(SymReg *name),
     ARGIN(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -92,7 +92,11 @@
         __attribute__nonnull__(4)
         FUNC_MODIFIES(*cur_call);
 
-static void adv_named_set(PARROT_INTERP, ARGIN(char *name))
+static void adv_named_set(PARROT_INTERP, ARGIN(const char *name))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+static void adv_named_set_u(PARROT_INTERP, ARGIN(const char *name))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -262,6 +266,9 @@
 #define ASSERT_ARGS_adv_named_set __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(name)
+#define ASSERT_ARGS_adv_named_set_u __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(name)
 #define ASSERT_ARGS_begin_return_or_yield __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_clear_state __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -863,23 +870,22 @@
 
 /*
 
-=item C<static void add_pcc_named_arg(PARROT_INTERP, SymReg *cur_call, const
-char *name, SymReg *value)>
+=item C<static void add_pcc_named_arg(PARROT_INTERP, SymReg *cur_call, SymReg
+*name, SymReg *value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_arg(PARROT_INTERP, ARGMOD(SymReg *cur_call), ARGIN(const char *name),
+add_pcc_named_arg(PARROT_INTERP, ARGMOD(SymReg *cur_call),
+        ARGIN(SymReg *name),
         ARGIN(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_arg)
-    SymReg * const r = mk_const(interp, name, 'S');
-
-    r->type  |= VT_NAMED;
+    name->type  |= VT_NAMED;
 
-    add_pcc_arg(cur_call, r);
+    add_pcc_arg(cur_call, name);
     add_pcc_arg(cur_call, value);
 }
 
@@ -904,85 +910,99 @@
 
 /*
 
-=item C<static void add_pcc_named_result(PARROT_INTERP, SymReg *cur_call, const
-char *name, SymReg *value)>
+=item C<static void add_pcc_named_result(PARROT_INTERP, SymReg *cur_call, SymReg
+*name, SymReg *value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_result(PARROT_INTERP, ARGMOD(SymReg *cur_call), ARGIN(const char *name),
+add_pcc_named_result(PARROT_INTERP, ARGMOD(SymReg *cur_call),
+        ARGIN(SymReg *name),
         ARGIN(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_result)
-    SymReg * const r = mk_const(interp, name, 'S');
-    r->type         |= VT_NAMED;
+    name->type         |= VT_NAMED;
 
-    add_pcc_result(cur_call, r);
+    add_pcc_result(cur_call, name);
     add_pcc_result(cur_call, value);
 }
 
 /*
 
-=item C<static void add_pcc_named_param(PARROT_INTERP, SymReg *cur_call, const
-char *name, SymReg *value)>
+=item C<static void add_pcc_named_param(PARROT_INTERP, SymReg *cur_call, SymReg
+*name, SymReg *value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_param(PARROT_INTERP, ARGMOD(SymReg *cur_call), ARGIN(const char *name),
+add_pcc_named_param(PARROT_INTERP, ARGMOD(SymReg *cur_call),
+        ARGIN(SymReg *name),
         ARGIN(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_param)
-    SymReg * const r = mk_const(interp, name, 'S');
-    r->type         |= VT_NAMED;
+    name->type         |= VT_NAMED;
 
-    add_pcc_arg(cur_call, r);
+    add_pcc_arg(cur_call, name);
     add_pcc_arg(cur_call, value);
 }
 
 /*
 
-=item C<static void add_pcc_named_return(PARROT_INTERP, SymReg *cur_call, const
-char *name, SymReg *value)>
+=item C<static void add_pcc_named_return(PARROT_INTERP, SymReg *cur_call, SymReg
+*name, SymReg *value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_return(PARROT_INTERP, ARGMOD(SymReg *cur_call), ARGIN(const char *name),
+add_pcc_named_return(PARROT_INTERP, ARGMOD(SymReg *cur_call),
+        ARGIN(SymReg *name),
         ARGIN(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_return)
-    SymReg * const r = mk_const(interp, name, 'S');
-    r->type         |= VT_NAMED;
+    name->type         |= VT_NAMED;
 
-    add_pcc_result(cur_call, r);
+    add_pcc_result(cur_call, name);
     add_pcc_result(cur_call, value);
 }
 
 /*
 
-=item C<static void adv_named_set(PARROT_INTERP, char *name)>
+=item C<static void adv_named_set(PARROT_INTERP, const char *name)>
+
+Sets the name of the current named argument.
+
+C<adv_named_set_u> is the Unicode version of this function.
 
 =cut
 
 */
 
-/* XXX Can name be consted? */
 static void
-adv_named_set(PARROT_INTERP, ARGIN(char *name))
+adv_named_set(PARROT_INTERP, ARGIN(const char *name))
 {
     ASSERT_ARGS(adv_named_set)
-    if (IMCC_INFO(interp)->adv_named_id) {
+    if (IMCC_INFO(interp)->adv_named_id)
         IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
                     "Named parameter with more than one name.\n");
-    }
-    IMCC_INFO(interp)->adv_named_id = name;
+
+    IMCC_INFO(interp)->adv_named_id = mk_const(interp, name, 'S');
+}
+
+static void
+adv_named_set_u(PARROT_INTERP, ARGIN(const char *name))
+{
+    ASSERT_ARGS(adv_named_set_u)
+    if (IMCC_INFO(interp)->adv_named_id)
+        IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
+                    "Named parameter with more than one name.\n");
+
+    IMCC_INFO(interp)->adv_named_id = mk_const(interp, name, 'U');
 }
 
 /*
@@ -1644,12 +1664,13 @@
    ;
 
 paramtype:
-     ADV_SLURPY                { $$ = VT_FLAT;   }
-   | ADV_OPTIONAL              { $$ = VT_OPTIONAL; }
-   | ADV_OPT_FLAG              { $$ = VT_OPT_FLAG; }
-   | ADV_NAMED                 { $$ = VT_NAMED; }
-   | ADV_NAMED '(' STRINGC ')' { adv_named_set(interp, $3); $$ = 0; }
-   | UNIQUE_REG                { $$ = VT_UNIQUE_REG; }
+     ADV_SLURPY                 { $$ = VT_FLAT;   }
+   | ADV_OPTIONAL               { $$ = VT_OPTIONAL; }
+   | ADV_OPT_FLAG               { $$ = VT_OPT_FLAG; }
+   | ADV_NAMED                  { $$ = VT_NAMED; }
+   | ADV_NAMED '(' STRINGC ')'  { adv_named_set(interp, $3);   $$ = 0; }
+   | ADV_NAMED '(' USTRINGC ')' { adv_named_set_u(interp, $3); $$ = 0; }
+   | UNIQUE_REG                 { $$ = VT_UNIQUE_REG; }
    ;
 
 
@@ -1738,7 +1759,8 @@
          }
    | STRINGC ADV_ARROW var
          {
-           add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, $1, $3);
+            SymReg *name = mk_const(interp, $1, 'S');
+            add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, name, $3);
          }
    | var_returns COMMA arg
          {
@@ -1752,7 +1774,8 @@
          }
    | var_returns COMMA STRINGC ADV_ARROW var
          {
-           add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, $3, $5);
+           SymReg *name = mk_const(interp, $3, 'S');
+           add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, name, $5);
          }
    ;
 
@@ -2130,7 +2153,8 @@
    | arglist COMMA STRINGC ADV_ARROW var
          {
            $$ = 0;
-           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call, $3, $5);
+           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call,
+                mk_const(interp, $3, 'S'), $5);
            mem_sys_free($3);
          }
    | var ADV_ARROW var
@@ -2141,7 +2165,8 @@
    | STRINGC ADV_ARROW var
          {
            $$ = 0;
-           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call, $1, $3);
+           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call,
+                mk_const(interp, $1, 'S'), $3);
            mem_sys_free($1);
          }
    ;
@@ -2160,7 +2185,8 @@
    | ADV_NAMED                 { $$ = VT_NAMED; }
 
    /* don't free $3 here; adv_named_set uses the pointer directly */
-   | ADV_NAMED '(' STRINGC ')' { adv_named_set(interp, $3); $$ = 0; }
+   | ADV_NAMED '(' USTRINGC ')' { adv_named_set_u(interp, $3); $$ = 0; }
+   | ADV_NAMED '(' STRINGC  ')' { adv_named_set(interp, $3);   $$ = 0; }
    ;
 
 result:
@@ -2180,8 +2206,9 @@
          }
    | targetlist COMMA STRINGC ADV_ARROW target
          {
-           add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, $3, $5);
-           mem_sys_free($3);
+            add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call,
+            mk_const(interp, $3, 'S'), $5);
+            mem_sys_free($3);
          }
    | result
          {
@@ -2195,7 +2222,7 @@
          }
    | STRINGC ADV_ARROW target
          {
-           add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, $1, $3);
+           add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, mk_const(interp, $1, 'S'), $3);
            mem_sys_free($1);
          }
    | /* empty */                { $$ = 0; }

Modified: branches/pmc_pct/compilers/imcc/imcparser.c
==============================================================================
--- branches/pmc_pct/compilers/imcc/imcparser.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/imcc/imcparser.c	Fri May 15 21:49:40 2009	(r38803)
@@ -368,8 +368,8 @@
 
 static void add_pcc_named_arg(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(const char *name),
-    ARGIN(SymReg *value))
+    ARGIN(SymReg  *name),
+    ARGIN(SymReg  *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
@@ -378,8 +378,8 @@
 
 static void add_pcc_named_arg_var(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGIN(SymReg  *name),
+    ARGIN(SymReg  *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
@@ -388,8 +388,8 @@
 
 static void add_pcc_named_param(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(const char *name),
-    ARGIN(SymReg *value))
+    ARGIN(SymReg  *name),
+    ARGIN(SymReg  *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
@@ -398,8 +398,8 @@
 
 static void add_pcc_named_result(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(const char *name),
-    ARGIN(SymReg *value))
+    ARGIN(SymReg  *name),
+    ARGIN(SymReg  *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
@@ -408,15 +408,19 @@
 
 static void add_pcc_named_return(PARROT_INTERP,
     ARGMOD(SymReg *cur_call),
-    ARGIN(const char *name),
-    ARGIN(SymReg *value))
+    ARGIN(SymReg  *name),
+    ARGIN(SymReg  *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
         __attribute__nonnull__(4)
         FUNC_MODIFIES(*cur_call);
 
-static void adv_named_set(PARROT_INTERP, ARGIN(char *name))
+static void adv_named_set(PARROT_INTERP, ARGIN(const char *name))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+static void adv_named_set_u(PARROT_INTERP, ARGIN(const char *name))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -586,6 +590,9 @@
 #define ASSERT_ARGS_adv_named_set __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(name)
+#define ASSERT_ARGS_adv_named_set_u __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(name)
 #define ASSERT_ARGS_begin_return_or_yield __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_clear_state __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -1195,15 +1202,14 @@
 */
 
 static void
-add_pcc_named_arg(PARROT_INTERP, ARGMOD(SymReg *cur_call), ARGIN(const char *name),
+add_pcc_named_arg(PARROT_INTERP, ARGMOD(SymReg *cur_call),
+        ARGIN(SymReg *name),
         ARGIN(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_arg)
-    SymReg * const r = mk_const(interp, name, 'S');
-
-    r->type  |= VT_NAMED;
+    name->type  |= VT_NAMED;
 
-    add_pcc_arg(cur_call, r);
+    add_pcc_arg(cur_call, name);
     add_pcc_arg(cur_call, value);
 }
 
@@ -1236,35 +1242,35 @@
 */
 
 static void
-add_pcc_named_result(PARROT_INTERP, ARGMOD(SymReg *cur_call), ARGIN(const char *name),
+add_pcc_named_result(PARROT_INTERP, ARGMOD(SymReg *cur_call),
+        ARGIN(SymReg *name),
         ARGIN(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_result)
-    SymReg * const r = mk_const(interp, name, 'S');
-    r->type         |= VT_NAMED;
+    name->type         |= VT_NAMED;
 
-    add_pcc_result(cur_call, r);
+    add_pcc_result(cur_call, name);
     add_pcc_result(cur_call, value);
 }
 
 /*
 
-=item C<static void add_pcc_named_param(PARROT_INTERP, SymReg *cur_call, const
-char *name, SymReg *value)>
+=item C<static void add_pcc_named_param(PARROT_INTERP, SymReg *cur_call, SymReg 
+*name, SymReg *value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_param(PARROT_INTERP, ARGMOD(SymReg *cur_call), ARGIN(const char *name),
+add_pcc_named_param(PARROT_INTERP, ARGMOD(SymReg *cur_call),
+        ARGIN(SymReg *name),
         ARGIN(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_param)
-    SymReg * const r = mk_const(interp, name, 'S');
-    r->type         |= VT_NAMED;
+    name->type         |= VT_NAMED;
 
-    add_pcc_arg(cur_call, r);
+    add_pcc_arg(cur_call, name);
     add_pcc_arg(cur_call, value);
 }
 
@@ -1278,14 +1284,14 @@
 */
 
 static void
-add_pcc_named_return(PARROT_INTERP, ARGMOD(SymReg *cur_call), ARGIN(const char *name),
+add_pcc_named_return(PARROT_INTERP, ARGMOD(SymReg *cur_call),
+        ARGIN(SymReg *name),
         ARGIN(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_return)
-    SymReg * const r = mk_const(interp, name, 'S');
-    r->type         |= VT_NAMED;
+    name->type         |= VT_NAMED;
 
-    add_pcc_result(cur_call, r);
+    add_pcc_result(cur_call, name);
     add_pcc_result(cur_call, value);
 }
 
@@ -1293,20 +1299,34 @@
 
 =item C<static void adv_named_set(PARROT_INTERP, char *name)>
 
+Sets the name of the current named argument.
+
+C<adv_named_set_u> is the Unicode version of this function.
+
 =cut
 
 */
 
-/* XXX Can name be consted? */
 static void
-adv_named_set(PARROT_INTERP, ARGIN(char *name))
+adv_named_set(PARROT_INTERP, ARGIN(const char *name))
 {
     ASSERT_ARGS(adv_named_set)
-    if (IMCC_INFO(interp)->adv_named_id) {
+    if (IMCC_INFO(interp)->adv_named_id)
         IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
                     "Named parameter with more than one name.\n");
-    }
-    IMCC_INFO(interp)->adv_named_id = name;
+
+    IMCC_INFO(interp)->adv_named_id = mk_const(interp, name, 'S');
+}
+
+static void
+adv_named_set_u(PARROT_INTERP, ARGIN(const char *name))
+{
+    ASSERT_ARGS(adv_named_set_u)
+    if (IMCC_INFO(interp)->adv_named_id)
+        IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
+                    "Named parameter with more than one name.\n");
+
+    IMCC_INFO(interp)->adv_named_id = mk_const(interp, name, 'U');
 }
 
 /*
@@ -1351,7 +1371,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 1010 "compilers/imcc/imcc.y"
+#line 1030 "compilers/imcc/imcc.y"
 {
     IdList * idlist;
     int t;
@@ -1360,7 +1380,7 @@
     Instruction *i;
 }
 /* Line 187 of yacc.c.  */
-#line 1353 "compilers/imcc/imcparser.c"
+#line 1373 "compilers/imcc/imcparser.c"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -1373,7 +1393,7 @@
 
 
 /* Line 216 of yacc.c.  */
-#line 1366 "compilers/imcc/imcparser.c"
+#line 1386 "compilers/imcc/imcparser.c"
 
 #ifdef short
 # undef short
@@ -1588,16 +1608,16 @@
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  31
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   673
+#define YYLAST   676
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  138
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  126
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  334
+#define YYNRULES  336
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  538
+#define YYNSTATES  542
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -1667,27 +1687,27 @@
      286,   288,   290,   292,   294,   296,   298,   300,   302,   304,
      310,   314,   318,   322,   326,   332,   338,   339,   343,   346,
      347,   351,   355,   356,   361,   362,   365,   367,   369,   371,
-     373,   378,   380,   381,   387,   389,   390,   396,   397,   400,
-     404,   405,   408,   412,   416,   420,   421,   427,   429,   431,
-     432,   434,   438,   442,   448,   450,   453,   454,   457,   460,
-     462,   464,   466,   468,   469,   471,   474,   476,   478,   482,
-     485,   487,   491,   494,   495,   497,   499,   501,   502,   507,
-     512,   517,   518,   525,   527,   528,   535,   538,   541,   544,
-     547,   549,   551,   553,   555,   556,   558,   560,   562,   564,
-     566,   570,   575,   581,   588,   595,   603,   607,   608,   618,
-     620,   622,   624,   628,   630,   632,   634,   636,   638,   640,
-     642,   644,   646,   648,   650,   652,   654,   656,   658,   660,
-     662,   664,   666,   668,   670,   672,   674,   676,   678,   680,
-     681,   687,   691,   693,   695,   697,   699,   701,   703,   705,
-     707,   709,   711,   713,   715,   717,   722,   724,   726,   728,
-     730,   734,   738,   742,   743,   749,   750,   754,   756,   762,
-     766,   770,   773,   774,   777,   779,   781,   786,   789,   793,
-     799,   801,   805,   806,   808,   810,   817,   823,   828,   833,
-     840,   846,   848,   850,   852,   854,   856,   858,   860,   862,
-     864,   866,   867,   869,   873,   875,   877,   882,   886,   888,
-     890,   892,   894,   896,   898,   900,   902,   904,   906,   908,
-     909,   912,   913,   916,   918,   922,   924,   926,   928,   930,
-     932,   934,   936,   938,   940
+     373,   378,   383,   385,   386,   392,   394,   395,   401,   402,
+     405,   409,   410,   413,   417,   421,   425,   426,   432,   434,
+     436,   437,   439,   443,   447,   453,   455,   458,   459,   462,
+     465,   467,   469,   471,   473,   474,   476,   479,   481,   483,
+     487,   490,   492,   496,   499,   500,   502,   504,   506,   507,
+     512,   517,   522,   523,   530,   532,   533,   540,   543,   546,
+     549,   552,   554,   556,   558,   560,   561,   563,   565,   567,
+     569,   571,   575,   580,   586,   593,   600,   608,   612,   613,
+     623,   625,   627,   629,   633,   635,   637,   639,   641,   643,
+     645,   647,   649,   651,   653,   655,   657,   659,   661,   663,
+     665,   667,   669,   671,   673,   675,   677,   679,   681,   683,
+     685,   686,   692,   696,   698,   700,   702,   704,   706,   708,
+     710,   712,   714,   716,   718,   720,   722,   727,   729,   731,
+     733,   735,   739,   743,   747,   748,   754,   755,   759,   761,
+     767,   771,   775,   778,   779,   782,   784,   786,   791,   796,
+     799,   803,   809,   811,   815,   816,   818,   820,   827,   833,
+     838,   843,   850,   856,   858,   860,   862,   864,   866,   868,
+     870,   872,   874,   876,   877,   879,   883,   885,   887,   892,
+     896,   898,   900,   902,   904,   906,   908,   910,   912,   914,
+     916,   918,   919,   922,   923,   926,   928,   932,   934,   936,
+     938,   940,   942,   944,   946,   948,   950
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
@@ -1730,47 +1750,48 @@
      190,     4,    -1,    10,   237,    -1,    -1,   191,   192,     4,
       -1,    62,   247,   194,    -1,    -1,    28,   193,   222,   216,
       -1,    -1,   194,   195,    -1,    17,    -1,    18,    -1,    19,
-      -1,    20,    -1,    20,   125,   112,   126,    -1,   100,    -1,
-      -1,    78,     4,   197,   200,    79,    -1,   204,    -1,    -1,
-      80,     4,   199,   201,    81,    -1,    -1,   200,     4,    -1,
-     200,   202,     4,    -1,    -1,   201,     4,    -1,   201,   203,
-       4,    -1,    14,   255,   238,    -1,    15,   255,   238,    -1,
-      -1,   206,   125,   205,   207,   126,    -1,    63,    -1,    65,
-      -1,    -1,   237,    -1,   112,    21,   255,    -1,   207,    71,
-     237,    -1,   207,    71,   112,    21,   255,    -1,   210,    -1,
-     208,   210,    -1,    -1,   209,   214,    -1,   110,     4,    -1,
-     119,    -1,   118,    -1,   143,    -1,   144,    -1,    -1,   212,
-      -1,   212,   213,    -1,   213,    -1,   101,    -1,   211,   218,
-       4,    -1,     1,     4,    -1,   216,    -1,   215,    71,   216,
-      -1,   108,   217,    -1,    -1,   100,    -1,   224,    -1,   242,
-      -1,    -1,    28,   219,   222,   215,    -1,    29,   112,    71,
-     247,    -1,    29,   115,    71,   247,    -1,    -1,    30,   220,
-     222,   108,   122,   263,    -1,   148,    -1,    -1,    34,   221,
-     222,   108,   122,   263,    -1,    64,   234,    -1,     9,   253,
-      -1,   116,   248,    -1,    13,   255,    -1,   234,    -1,   181,
-      -1,   196,    -1,   198,    -1,    -1,    51,    -1,    52,    -1,
-      53,    -1,    54,    -1,   108,    -1,   247,   122,   255,    -1,
-     247,   122,   226,   255,    -1,   247,   122,   255,   227,   255,
-      -1,   247,   122,   255,   123,   256,   124,    -1,   247,   123,
-     256,   124,   122,   255,    -1,   247,   122,   127,   223,   123,
-     256,   124,    -1,   247,   122,   234,    -1,    -1,   125,   225,
-     241,   126,   122,   233,   125,   236,   126,    -1,   228,    -1,
-     230,    -1,   232,    -1,   247,   122,    13,    -1,   128,    -1,
-     129,    -1,   130,    -1,   130,    -1,   131,    -1,   132,    -1,
-     133,    -1,   134,    -1,    43,    -1,    67,    -1,   121,    -1,
-      56,    -1,    57,    -1,    58,    -1,    59,    -1,    60,    -1,
-      61,    -1,    49,    -1,    50,    -1,    68,    -1,    69,    -1,
-      70,    -1,    55,    -1,   135,    -1,   136,    -1,   129,    -1,
-      -1,    66,   229,   125,   241,   126,    -1,   247,   231,   255,
-      -1,    35,    -1,    36,    -1,    37,    -1,    38,    -1,    45,
-      -1,    44,    -1,    39,    -1,    40,    -1,    41,    -1,    42,
-      -1,    46,    -1,    47,    -1,    48,    -1,   247,   122,   116,
-     157,    -1,   108,    -1,   112,    -1,   115,    -1,   247,    -1,
-     247,   120,   252,    -1,   247,   120,   112,    -1,   247,   120,
-     247,    -1,    -1,   233,   235,   125,   236,   126,    -1,    -1,
-     236,    71,   237,    -1,   237,    -1,   236,    71,   112,    21,
-     255,    -1,   255,    21,   255,    -1,   112,    21,   255,    -1,
-     255,   238,    -1,    -1,   238,   239,    -1,    16,    -1,    20,
+      -1,    20,    -1,    20,   125,   112,   126,    -1,    20,   125,
+     115,   126,    -1,   100,    -1,    -1,    78,     4,   197,   200,
+      79,    -1,   204,    -1,    -1,    80,     4,   199,   201,    81,
+      -1,    -1,   200,     4,    -1,   200,   202,     4,    -1,    -1,
+     201,     4,    -1,   201,   203,     4,    -1,    14,   255,   238,
+      -1,    15,   255,   238,    -1,    -1,   206,   125,   205,   207,
+     126,    -1,    63,    -1,    65,    -1,    -1,   237,    -1,   112,
+      21,   255,    -1,   207,    71,   237,    -1,   207,    71,   112,
+      21,   255,    -1,   210,    -1,   208,   210,    -1,    -1,   209,
+     214,    -1,   110,     4,    -1,   119,    -1,   118,    -1,   143,
+      -1,   144,    -1,    -1,   212,    -1,   212,   213,    -1,   213,
+      -1,   101,    -1,   211,   218,     4,    -1,     1,     4,    -1,
+     216,    -1,   215,    71,   216,    -1,   108,   217,    -1,    -1,
+     100,    -1,   224,    -1,   242,    -1,    -1,    28,   219,   222,
+     215,    -1,    29,   112,    71,   247,    -1,    29,   115,    71,
+     247,    -1,    -1,    30,   220,   222,   108,   122,   263,    -1,
+     148,    -1,    -1,    34,   221,   222,   108,   122,   263,    -1,
+      64,   234,    -1,     9,   253,    -1,   116,   248,    -1,    13,
+     255,    -1,   234,    -1,   181,    -1,   196,    -1,   198,    -1,
+      -1,    51,    -1,    52,    -1,    53,    -1,    54,    -1,   108,
+      -1,   247,   122,   255,    -1,   247,   122,   226,   255,    -1,
+     247,   122,   255,   227,   255,    -1,   247,   122,   255,   123,
+     256,   124,    -1,   247,   123,   256,   124,   122,   255,    -1,
+     247,   122,   127,   223,   123,   256,   124,    -1,   247,   122,
+     234,    -1,    -1,   125,   225,   241,   126,   122,   233,   125,
+     236,   126,    -1,   228,    -1,   230,    -1,   232,    -1,   247,
+     122,    13,    -1,   128,    -1,   129,    -1,   130,    -1,   130,
+      -1,   131,    -1,   132,    -1,   133,    -1,   134,    -1,    43,
+      -1,    67,    -1,   121,    -1,    56,    -1,    57,    -1,    58,
+      -1,    59,    -1,    60,    -1,    61,    -1,    49,    -1,    50,
+      -1,    68,    -1,    69,    -1,    70,    -1,    55,    -1,   135,
+      -1,   136,    -1,   129,    -1,    -1,    66,   229,   125,   241,
+     126,    -1,   247,   231,   255,    -1,    35,    -1,    36,    -1,
+      37,    -1,    38,    -1,    45,    -1,    44,    -1,    39,    -1,
+      40,    -1,    41,    -1,    42,    -1,    46,    -1,    47,    -1,
+      48,    -1,   247,   122,   116,   157,    -1,   108,    -1,   112,
+      -1,   115,    -1,   247,    -1,   247,   120,   252,    -1,   247,
+     120,   112,    -1,   247,   120,   247,    -1,    -1,   233,   235,
+     125,   236,   126,    -1,    -1,   236,    71,   237,    -1,   237,
+      -1,   236,    71,   112,    21,   255,    -1,   255,    21,   255,
+      -1,   112,    21,   255,    -1,   255,   238,    -1,    -1,   238,
+     239,    -1,    16,    -1,    20,    -1,    20,   125,   115,   126,
       -1,    20,   125,   112,   126,    -1,   247,   194,    -1,   241,
       71,   240,    -1,   241,    71,   112,    21,   247,    -1,   240,
       -1,   112,    21,   247,    -1,    -1,   244,    -1,   243,    -1,
@@ -1793,40 +1814,40 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,  1105,  1105,  1109,  1110,  1114,  1115,  1116,  1122,  1128,
-    1129,  1130,  1131,  1135,  1136,  1145,  1150,  1157,  1169,  1181,
-    1181,  1190,  1190,  1196,  1196,  1203,  1204,  1208,  1209,  1213,
-    1214,  1215,  1216,  1217,  1218,  1219,  1222,  1222,  1231,  1230,
-    1242,  1246,  1255,  1259,  1263,  1263,  1275,  1277,  1281,  1296,
-    1304,  1309,  1313,  1317,  1308,  1329,  1330,  1331,  1344,  1344,
-    1348,  1362,  1366,  1372,  1381,  1387,  1396,  1402,  1411,  1417,
-    1426,  1434,  1439,  1450,  1453,  1458,  1466,  1467,  1468,  1469,
-    1470,  1481,  1492,  1495,  1497,  1502,  1501,  1534,  1535,  1539,
-    1540,  1544,  1545,  1549,  1550,  1554,  1555,  1556,  1557,  1558,
-    1559,  1560,  1561,  1562,  1563,  1564,  1565,  1566,  1567,  1571,
-    1576,  1580,  1585,  1589,  1593,  1598,  1607,  1608,  1612,  1617,
-    1618,  1626,  1627,  1627,  1642,  1643,  1647,  1648,  1649,  1650,
-    1651,  1652,  1657,  1657,  1660,  1668,  1668,  1674,  1675,  1680,
-    1688,  1689,  1694,  1702,  1706,  1711,  1710,  1723,  1724,  1728,
-    1729,  1739,  1743,  1753,  1761,  1762,  1774,  1778,  1780,  1781,
-    1782,  1783,  1784,  1788,  1789,  1793,  1794,  1798,  1807,  1808,
-    1819,  1826,  1835,  1845,  1846,  1851,  1852,  1853,  1853,  1869,
-    1874,  1879,  1879,  1886,  1887,  1887,  1893,  1899,  1903,  1915,
-    1916,  1917,  1918,  1919,  1920,  1924,  1925,  1926,  1927,  1931,
-    1944,  1946,  1948,  1950,  1952,  1957,  1960,  1967,  1966,  1975,
-    1976,  1977,  1978,  1986,  1987,  1988,  1992,  1993,  1994,  1995,
-    1996,  1997,  1998,  1999,  2000,  2001,  2002,  2003,  2004,  2005,
-    2006,  2007,  2008,  2009,  2010,  2011,  2012,  2013,  2014,  2020,
-    2019,  2031,  2038,  2039,  2040,  2041,  2042,  2043,  2044,  2045,
-    2046,  2047,  2048,  2049,  2050,  2055,  2066,  2067,  2068,  2069,
-    2075,  2089,  2095,  2101,  2100,  2109,  2110,  2120,  2130,  2136,
-    2141,  2150,  2154,  2155,  2159,  2160,  2163,  2167,  2171,  2181,
-    2186,  2196,  2201,  2205,  2206,  2210,  2214,  2218,  2225,  2229,
-    2233,  2240,  2241,  2245,  2246,  2247,  2248,  2249,  2250,  2254,
-    2255,  2259,  2260,  2264,  2265,  2269,  2270,  2277,  2284,  2285,
-    2286,  2290,  2291,  2295,  2296,  2300,  2301,  2305,  2306,  2310,
-    2310,  2323,  2323,  2336,  2337,  2345,  2354,  2355,  2356,  2357,
-    2358,  2362,  2363,  2364,  2365
+       0,  1125,  1125,  1129,  1130,  1134,  1135,  1136,  1142,  1148,
+    1149,  1150,  1151,  1155,  1156,  1165,  1170,  1177,  1189,  1201,
+    1201,  1210,  1210,  1216,  1216,  1223,  1224,  1228,  1229,  1233,
+    1234,  1235,  1236,  1237,  1238,  1239,  1242,  1242,  1251,  1250,
+    1262,  1266,  1275,  1279,  1283,  1283,  1295,  1297,  1301,  1316,
+    1324,  1329,  1333,  1337,  1328,  1349,  1350,  1351,  1364,  1364,
+    1368,  1382,  1386,  1392,  1401,  1407,  1416,  1422,  1431,  1437,
+    1446,  1454,  1459,  1470,  1473,  1478,  1486,  1487,  1488,  1489,
+    1490,  1501,  1512,  1515,  1517,  1522,  1521,  1554,  1555,  1559,
+    1560,  1564,  1565,  1569,  1570,  1574,  1575,  1576,  1577,  1578,
+    1579,  1580,  1581,  1582,  1583,  1584,  1585,  1586,  1587,  1591,
+    1596,  1600,  1605,  1609,  1613,  1618,  1627,  1628,  1632,  1637,
+    1638,  1646,  1647,  1647,  1662,  1663,  1667,  1668,  1669,  1670,
+    1671,  1672,  1673,  1678,  1678,  1681,  1689,  1689,  1695,  1696,
+    1701,  1709,  1710,  1715,  1723,  1727,  1732,  1731,  1744,  1745,
+    1749,  1750,  1760,  1765,  1775,  1784,  1785,  1797,  1801,  1803,
+    1804,  1805,  1806,  1807,  1811,  1812,  1816,  1817,  1821,  1830,
+    1831,  1842,  1849,  1858,  1868,  1869,  1874,  1875,  1876,  1876,
+    1892,  1897,  1902,  1902,  1909,  1910,  1910,  1916,  1922,  1926,
+    1938,  1939,  1940,  1941,  1942,  1943,  1947,  1948,  1949,  1950,
+    1954,  1967,  1969,  1971,  1973,  1975,  1980,  1983,  1990,  1989,
+    1998,  1999,  2000,  2001,  2009,  2010,  2011,  2015,  2016,  2017,
+    2018,  2019,  2020,  2021,  2022,  2023,  2024,  2025,  2026,  2027,
+    2028,  2029,  2030,  2031,  2032,  2033,  2034,  2035,  2036,  2037,
+    2043,  2042,  2054,  2061,  2062,  2063,  2064,  2065,  2066,  2067,
+    2068,  2069,  2070,  2071,  2072,  2073,  2078,  2089,  2090,  2091,
+    2092,  2098,  2112,  2118,  2124,  2123,  2132,  2133,  2143,  2153,
+    2160,  2165,  2175,  2179,  2180,  2184,  2185,  2188,  2189,  2193,
+    2197,  2207,  2213,  2223,  2228,  2232,  2233,  2237,  2241,  2245,
+    2252,  2256,  2260,  2267,  2268,  2272,  2273,  2274,  2275,  2276,
+    2277,  2281,  2282,  2286,  2287,  2291,  2292,  2296,  2297,  2304,
+    2311,  2312,  2313,  2317,  2318,  2322,  2323,  2327,  2328,  2332,
+    2333,  2337,  2337,  2350,  2350,  2363,  2364,  2372,  2381,  2382,
+    2383,  2384,  2385,  2389,  2390,  2391,  2392
 };
 #endif
 
@@ -1921,27 +1942,27 @@
      187,   187,   187,   187,   187,   187,   187,   187,   187,   188,
      188,   188,   188,   188,   188,   188,   189,   189,   190,   191,
      191,   192,   193,   192,   194,   194,   195,   195,   195,   195,
-     195,   195,   197,   196,   196,   199,   198,   200,   200,   200,
-     201,   201,   201,   202,   203,   205,   204,   206,   206,   207,
-     207,   207,   207,   207,   208,   208,   209,   210,   210,   210,
-     210,   210,   210,   211,   211,   212,   212,   213,   214,   214,
-     215,   215,   216,   217,   217,   218,   218,   219,   218,   218,
-     218,   220,   218,   218,   221,   218,   218,   218,   218,   218,
-     218,   218,   218,   218,   218,   222,   222,   222,   222,   223,
-     224,   224,   224,   224,   224,   224,   224,   225,   224,   224,
-     224,   224,   224,   226,   226,   226,   227,   227,   227,   227,
+     195,   195,   195,   197,   196,   196,   199,   198,   200,   200,
+     200,   201,   201,   201,   202,   203,   205,   204,   206,   206,
+     207,   207,   207,   207,   207,   208,   208,   209,   210,   210,
+     210,   210,   210,   210,   211,   211,   212,   212,   213,   214,
+     214,   215,   215,   216,   217,   217,   218,   218,   219,   218,
+     218,   218,   220,   218,   218,   221,   218,   218,   218,   218,
+     218,   218,   218,   218,   218,   218,   222,   222,   222,   222,
+     223,   224,   224,   224,   224,   224,   224,   224,   225,   224,
+     224,   224,   224,   224,   226,   226,   226,   227,   227,   227,
+     227,   227,   227,   227,   227,   227,   227,   227,   227,   227,
      227,   227,   227,   227,   227,   227,   227,   227,   227,   227,
-     227,   227,   227,   227,   227,   227,   227,   227,   227,   229,
-     228,   230,   231,   231,   231,   231,   231,   231,   231,   231,
-     231,   231,   231,   231,   231,   232,   233,   233,   233,   233,
-     233,   233,   233,   235,   234,   236,   236,   236,   236,   236,
-     236,   237,   238,   238,   239,   239,   239,   240,   241,   241,
-     241,   241,   241,   242,   242,   243,   243,   243,   244,   244,
-     244,   245,   245,   246,   246,   246,   246,   246,   246,   247,
-     247,   248,   248,   249,   249,   250,   250,   250,   251,   251,
-     251,   252,   252,   253,   253,   254,   254,   255,   255,   257,
-     256,   259,   258,   260,   260,   261,   262,   262,   262,   262,
-     262,   263,   263,   263,   263
+     229,   228,   230,   231,   231,   231,   231,   231,   231,   231,
+     231,   231,   231,   231,   231,   231,   232,   233,   233,   233,
+     233,   233,   233,   233,   235,   234,   236,   236,   236,   236,
+     236,   236,   237,   238,   238,   239,   239,   239,   239,   240,
+     241,   241,   241,   241,   241,   242,   242,   243,   243,   243,
+     244,   244,   244,   245,   245,   246,   246,   246,   246,   246,
+     246,   247,   247,   248,   248,   249,   249,   250,   250,   250,
+     251,   251,   251,   252,   252,   253,   253,   254,   254,   255,
+     255,   257,   256,   259,   258,   260,   260,   261,   262,   262,
+     262,   262,   262,   263,   263,   263,   263
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -1960,27 +1981,27 @@
        1,     1,     1,     1,     1,     1,     1,     1,     1,     5,
        3,     3,     3,     3,     5,     5,     0,     3,     2,     0,
        3,     3,     0,     4,     0,     2,     1,     1,     1,     1,
-       4,     1,     0,     5,     1,     0,     5,     0,     2,     3,
-       0,     2,     3,     3,     3,     0,     5,     1,     1,     0,
-       1,     3,     3,     5,     1,     2,     0,     2,     2,     1,
-       1,     1,     1,     0,     1,     2,     1,     1,     3,     2,
-       1,     3,     2,     0,     1,     1,     1,     0,     4,     4,
-       4,     0,     6,     1,     0,     6,     2,     2,     2,     2,
-       1,     1,     1,     1,     0,     1,     1,     1,     1,     1,
-       3,     4,     5,     6,     6,     7,     3,     0,     9,     1,
-       1,     1,     3,     1,     1,     1,     1,     1,     1,     1,
+       4,     4,     1,     0,     5,     1,     0,     5,     0,     2,
+       3,     0,     2,     3,     3,     3,     0,     5,     1,     1,
+       0,     1,     3,     3,     5,     1,     2,     0,     2,     2,
+       1,     1,     1,     1,     0,     1,     2,     1,     1,     3,
+       2,     1,     3,     2,     0,     1,     1,     1,     0,     4,
+       4,     4,     0,     6,     1,     0,     6,     2,     2,     2,
+       2,     1,     1,     1,     1,     0,     1,     1,     1,     1,
+       1,     3,     4,     5,     6,     6,     7,     3,     0,     9,
+       1,     1,     1,     3,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       0,     5,     3,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     4,     1,     1,     1,
+       1,     3,     3,     3,     0,     5,     0,     3,     1,     5,
+       3,     3,     2,     0,     2,     1,     1,     4,     4,     2,
+       3,     5,     1,     3,     0,     1,     1,     6,     5,     4,
+       4,     6,     5,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     0,     1,     3,     1,     1,     4,     3,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     0,
-       5,     3,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     4,     1,     1,     1,     1,
-       3,     3,     3,     0,     5,     0,     3,     1,     5,     3,
-       3,     2,     0,     2,     1,     1,     4,     2,     3,     5,
-       1,     3,     0,     1,     1,     6,     5,     4,     4,     6,
-       5,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     0,     1,     3,     1,     1,     4,     3,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     0,
-       2,     0,     2,     1,     3,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1
+       1,     0,     2,     0,     2,     1,     3,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -1990,58 +2011,59 @@
 {
        0,    12,     0,     0,     0,     0,    51,    19,     0,    44,
        0,     0,     2,     3,    10,    11,     0,     6,     8,     5,
-       7,    18,     0,     0,   319,     0,     0,     0,     0,   163,
+       7,    18,     0,     0,   321,     0,     0,     0,     0,   164,
        9,     1,     4,    13,     0,    16,    50,     0,     0,    48,
-     311,   309,   310,   312,    52,   308,   195,   196,   197,   198,
-       0,    14,    21,   167,     0,    32,    31,    35,    34,   163,
-      27,     0,    33,    36,   164,   166,     0,    49,   326,   327,
-     328,   329,   330,   333,   331,   332,   334,   299,   317,   325,
-     320,   323,   300,   318,    91,     0,     0,     0,    30,    28,
-      45,     0,     0,    38,     0,     0,   165,    15,     0,    97,
+     313,   311,   312,   314,    52,   310,   196,   197,   198,   199,
+       0,    14,    21,   168,     0,    32,    31,    35,    34,   164,
+      27,     0,    33,    36,   165,   167,     0,    49,   328,   329,
+     330,   331,   332,   335,   333,   334,   336,   301,   319,   327,
+     322,   325,   302,   320,    91,     0,     0,     0,    30,    28,
+      45,     0,     0,    38,     0,     0,   166,    15,     0,    97,
       95,    96,    98,    99,    66,   100,     0,   101,     0,    64,
        0,    71,    68,   102,   103,   104,   105,   106,   107,   108,
        0,    92,    93,     0,     0,     0,    40,     0,    91,    29,
-     301,   324,     0,     0,    73,     0,     0,     0,     0,    53,
-      94,    20,   313,   314,   315,     0,   316,     0,     0,     0,
-     321,    37,   317,    43,   302,   304,   305,    25,    26,     0,
-       0,     0,    76,    77,    79,    78,    80,    81,   319,     0,
+     303,   326,     0,     0,    73,     0,     0,     0,     0,    53,
+      94,    20,   315,   316,   317,     0,   318,     0,     0,     0,
+     323,    37,   319,    43,   304,   306,   307,    25,    26,     0,
+       0,     0,    76,    77,    79,    78,    80,    81,   321,     0,
       75,     0,     0,     0,     0,    55,     0,     0,    41,    39,
-       0,     0,   319,     0,    67,    63,    62,     0,     0,    61,
-      65,    70,    72,    69,    56,   156,    22,    24,   307,   322,
-       0,   303,    82,    74,    58,     0,     0,   160,   159,   161,
-     162,     0,     0,   156,     0,   154,   306,     0,     0,   158,
-      57,    54,   155,     0,   194,   157,    59,     0,     0,   169,
-       0,     0,     0,     0,   177,     0,   181,   184,   147,     0,
-     148,   239,     0,     0,     0,   256,   257,   258,   301,   207,
-     183,   191,   192,   193,   134,     0,     0,   175,   209,   210,
-     211,   263,   190,   176,   284,   283,   259,   124,    17,   187,
-       0,     0,     0,     0,   189,     0,     0,     0,     0,     0,
-     186,   259,     0,    85,   132,   135,   188,   282,   145,   168,
-       0,   242,   243,   244,   245,   248,   249,   250,   251,   247,
-     246,   252,   253,   254,     0,     0,   319,     0,    60,     0,
-     292,   293,   294,   295,   296,   297,   298,   291,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,   282,   116,
-     137,   140,     0,   280,     0,   124,   149,   265,   261,   262,
-     260,   212,   333,   334,   301,     0,   213,   214,   215,     0,
-     206,   317,   200,     0,   241,   126,   127,   128,   129,   131,
-     125,     0,   288,     0,     0,   287,     0,   173,   178,   170,
-     179,   180,     0,     0,     0,    89,     0,     0,     0,     0,
-       0,   277,   333,     0,   150,   272,   333,     0,   267,   272,
-     255,   199,     0,   201,   221,   230,   231,   235,   224,   225,
-     226,   227,   228,   229,   222,   232,   233,   234,   223,   319,
-     238,   216,   217,   218,   219,   220,   236,   237,     0,     0,
-       0,   290,     0,   286,     0,   174,   172,     0,     0,     0,
-     240,     0,     0,     0,     0,   138,     0,   133,     0,   141,
-       0,   136,     0,   281,     0,   278,     0,     0,     0,   146,
-     271,     0,     0,   264,     0,   319,     0,   202,     0,     0,
-     289,   285,   171,   182,   185,   118,     0,     0,     0,     0,
-      87,   117,   272,   139,   272,   142,     0,     0,   151,   333,
-     152,   274,   275,   273,   270,   333,   266,   269,     0,   203,
-     204,   130,    90,     0,     0,     0,     0,   119,     0,   143,
-     144,   279,   265,     0,     0,     0,   205,   110,     0,   111,
-     113,     0,   112,     0,     0,    88,     0,   153,     0,   268,
-       0,     0,     0,   122,     0,    86,     0,   208,   276,   109,
-     115,   114,     0,   124,   120,     0,   121,   123
+       0,     0,   321,     0,    67,    63,    62,     0,     0,    61,
+      65,    70,    72,    69,    56,   157,    22,    24,   309,   324,
+       0,   305,    82,    74,    58,     0,     0,   161,   160,   162,
+     163,     0,     0,   157,     0,   155,   308,     0,     0,   159,
+      57,    54,   156,     0,   195,   158,    59,     0,     0,   170,
+       0,     0,     0,     0,   178,     0,   182,   185,   148,     0,
+     149,   240,     0,     0,     0,   257,   258,   259,   303,   208,
+     184,   192,   193,   194,   135,     0,     0,   176,   210,   211,
+     212,   264,   191,   177,   286,   285,   260,   124,    17,   188,
+       0,     0,     0,     0,   190,     0,     0,     0,     0,     0,
+     187,   260,     0,    85,   133,   136,   189,   284,   146,   169,
+       0,   243,   244,   245,   246,   249,   250,   251,   252,   248,
+     247,   253,   254,   255,     0,     0,   321,     0,    60,     0,
+     294,   295,   296,   297,   298,   299,   300,   293,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   284,   116,
+     138,   141,     0,   282,     0,   124,   150,   266,   262,   263,
+     261,   213,   335,   336,   303,     0,   214,   215,   216,     0,
+     207,   319,   201,     0,   242,   126,   127,   128,   129,   132,
+     125,     0,   290,     0,     0,   289,     0,   174,   179,   171,
+     180,   181,     0,     0,     0,    89,     0,     0,     0,     0,
+       0,   279,   335,     0,   151,   273,   335,     0,   268,   273,
+     256,   200,     0,   202,   222,   231,   232,   236,   225,   226,
+     227,   228,   229,   230,   223,   233,   234,   235,   224,   321,
+     239,   217,   218,   219,   220,   221,   237,   238,     0,     0,
+       0,   292,     0,   288,     0,   175,   173,     0,     0,     0,
+     241,     0,     0,     0,     0,   139,     0,   134,     0,   142,
+       0,   137,     0,   283,     0,   280,     0,     0,     0,   147,
+     272,     0,     0,   265,     0,   321,     0,   203,     0,     0,
+       0,   291,   287,   172,   183,   186,   118,     0,     0,     0,
+       0,    87,   117,   273,   140,   273,   143,     0,     0,   152,
+     335,   153,   275,   276,   274,   271,   335,   267,   270,     0,
+     204,   205,   130,   131,    90,     0,     0,     0,     0,   119,
+       0,   144,   145,   281,   266,     0,     0,     0,   206,   110,
+       0,   111,   113,     0,   112,     0,     0,    88,     0,   154,
+       0,     0,   269,     0,     0,     0,   122,     0,    86,     0,
+     209,   278,   277,   109,   115,   114,     0,   124,   120,     0,
+     121,   123
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
@@ -2051,243 +2073,244 @@
       58,    86,    87,   159,    59,    60,    94,    95,   128,   151,
       18,    29,    61,    19,    25,    20,    26,    84,   175,   195,
      211,   217,   226,   113,   114,   115,   116,   117,   118,   119,
-     169,   170,   212,   251,   329,   497,   433,   120,   121,   122,
-     470,   375,   434,   514,   526,   532,   308,   360,   252,   330,
+     169,   170,   212,   251,   329,   499,   433,   120,   121,   122,
+     471,   375,   434,   516,   529,   536,   308,   360,   252,   330,
      253,   331,   376,   377,   438,   442,   254,   336,   255,   383,
      213,   214,   215,    63,    64,    65,   225,   368,   369,   426,
      256,   275,   278,   279,    50,   392,   257,   287,   349,   418,
      258,   282,   259,   307,   260,   261,   262,   290,   387,   388,
-     450,   483,   333,   334,   263,   264,   265,   318,   319,    78,
+     450,   484,   333,   334,   263,   264,   265,   318,   319,    78,
      153,   154,   155,    44,    45,   144,   156,   146,    37,    38,
      180,   181,    80,    81,    82,    83
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -414
+#define YYPACT_NINF -422
 static const yytype_int16 yypact[] =
 {
-     264,  -414,   -85,   -71,   -58,   -53,  -414,  -414,   -26,  -414,
-      74,   101,   264,  -414,  -414,  -414,   109,  -414,  -414,  -414,
-    -414,  -414,    55,   128,    36,   169,   -64,    97,   170,     9,
-    -414,  -414,  -414,  -414,    66,  -414,  -414,    58,   486,  -414,
-    -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,
-      76,  -414,    79,  -414,   182,  -414,  -414,  -414,  -414,    44,
-    -414,    89,  -414,    17,   104,  -414,   194,  -414,  -414,  -414,
-    -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,
-      65,  -414,  -414,  -414,   454,    85,    95,   103,  -414,  -414,
-    -414,   486,   106,  -414,   215,   117,  -414,  -414,   486,  -414,
-    -414,  -414,  -414,  -414,   112,  -414,   113,  -414,   114,   115,
-     116,   121,   124,  -414,  -414,  -414,  -414,  -414,  -414,  -414,
-     238,   454,  -414,    43,   472,   472,  -414,   187,   454,  -414,
-     345,  -414,    52,    -5,   136,   154,   161,    52,    52,  -414,
-    -414,  -414,  -414,  -414,  -414,   152,  -414,   157,   171,   181,
-    -414,  -414,   162,  -414,   218,  -414,  -414,  -414,  -414,   160,
-     174,   175,  -414,  -414,  -414,  -414,  -414,  -414,  -414,   -43,
-    -414,   186,   188,   190,   191,   283,    52,    52,  -414,  -414,
-     172,   486,  -414,   345,  -414,  -414,  -414,   200,   136,  -414,
-    -414,  -414,  -414,  -414,  -414,     5,  -414,  -414,  -414,    65,
-     202,  -414,  -414,  -414,  -414,   183,   293,  -414,  -414,  -414,
-    -414,   323,   260,   173,   105,  -414,  -414,    97,   269,  -414,
-    -414,  -414,  -414,   342,   413,  -414,  -414,   241,    43,  -414,
-     -45,   216,   230,   486,  -414,    60,    40,  -414,  -414,   198,
-    -414,  -414,   346,   347,   363,  -414,  -414,  -414,   345,  -414,
-    -414,  -414,  -414,  -414,  -414,   243,   365,  -414,  -414,  -414,
-    -414,  -414,  -414,  -414,  -414,  -414,   317,  -414,  -414,  -414,
-     486,   329,   486,   329,  -414,    97,   305,   306,    97,    97,
-    -414,   259,   256,  -414,  -414,  -414,  -414,   -48,  -414,  -414,
-     257,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,
-    -414,  -414,  -414,  -414,   119,   148,  -414,   486,    -1,   375,
-    -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,   -45,   486,
-     382,   -45,   486,   284,   327,   327,   287,   289,   -48,  -414,
-    -414,  -414,   378,  -414,   -42,  -414,   500,   514,  -414,  -414,
-    -414,  -414,   276,   278,   345,   296,  -414,  -414,  -414,   486,
-    -414,   -44,   439,   281,  -414,  -414,  -414,  -414,   286,  -414,
-    -414,   -45,  -414,   397,   -45,  -414,   399,   312,   344,  -414,
-    -414,  -414,   295,   297,   -39,    -2,    21,     7,   327,   266,
-     299,    -1,   402,   -37,  -414,  -414,   406,   -34,  -414,   407,
-    -414,  -414,   315,  -414,  -414,  -414,  -414,  -414,  -414,  -414,
-    -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,
-    -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,   486,   313,
-     333,  -414,   -45,  -414,   -45,  -414,  -414,   284,    43,    43,
-    -414,   486,   486,    54,   414,  -414,   486,  -414,   442,  -414,
-     486,  -414,   444,  -414,   434,  -414,   198,   486,   528,  -414,
-     126,   486,   542,  -414,   486,  -414,   332,  -414,   486,   337,
-    -414,  -414,  -414,  -414,  -414,  -414,   462,   486,   486,   556,
-     104,  -414,  -414,  -414,  -414,  -414,   327,   349,  -414,   448,
-    -414,  -414,   355,  -414,  -414,   450,  -414,  -414,   348,  -414,
-    -414,  -414,  -414,    19,   477,    20,    22,  -414,   479,   126,
-     126,  -414,   514,   486,   372,   486,  -414,  -414,   486,  -414,
-    -414,   486,  -414,   486,    10,  -414,   -24,  -414,   359,  -414,
-     482,   488,   497,  -414,   327,  -414,   498,  -414,  -414,  -414,
-    -414,  -414,    97,  -414,  -414,   284,    -1,  -414
+       4,  -422,   -77,   -34,   -46,   -31,  -422,  -422,    -4,  -422,
+     106,   139,     4,  -422,  -422,  -422,   186,  -422,  -422,  -422,
+    -422,  -422,   104,   187,    68,   194,   221,   127,   199,    53,
+    -422,  -422,  -422,  -422,    92,  -422,  -422,    84,   489,  -422,
+    -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,
+     107,  -422,   101,  -422,   217,  -422,  -422,  -422,  -422,    64,
+    -422,   122,  -422,    14,   125,  -422,   223,  -422,  -422,  -422,
+    -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,
+      98,  -422,  -422,  -422,   493,   118,   129,   131,  -422,  -422,
+    -422,   489,   132,  -422,   241,   130,  -422,  -422,   489,  -422,
+    -422,  -422,  -422,  -422,   123,  -422,   134,  -422,   135,   136,
+     138,   141,   146,  -422,  -422,  -422,  -422,  -422,  -422,  -422,
+     245,   493,  -422,    74,   239,   239,  -422,   181,   493,  -422,
+     437,  -422,    40,    56,    -7,   152,   170,    40,    40,  -422,
+    -422,  -422,  -422,  -422,  -422,   163,  -422,   165,   183,   193,
+    -422,  -422,   173,  -422,   226,  -422,  -422,  -422,  -422,   180,
+     188,   189,  -422,  -422,  -422,  -422,  -422,  -422,  -422,   -50,
+    -422,   190,   191,   195,   202,   303,    40,    40,  -422,  -422,
+     206,   489,  -422,   437,  -422,  -422,  -422,   207,    -7,  -422,
+    -422,  -422,  -422,  -422,  -422,    32,  -422,  -422,  -422,    98,
+     208,  -422,  -422,  -422,  -422,   211,   315,  -422,  -422,  -422,
+    -422,   316,   262,    43,   261,  -422,  -422,   127,   267,  -422,
+    -422,  -422,  -422,   336,   415,  -422,  -422,   242,    74,  -422,
+     -36,   105,   124,   489,  -422,    54,    16,  -422,  -422,   171,
+    -422,  -422,   353,   360,   368,  -422,  -422,  -422,   437,  -422,
+    -422,  -422,  -422,  -422,  -422,   249,   371,  -422,  -422,  -422,
+    -422,  -422,  -422,  -422,  -422,  -422,   416,  -422,  -422,  -422,
+     489,   197,   489,   197,  -422,   127,   308,   310,   127,   127,
+    -422,   268,   264,  -422,  -422,  -422,  -422,   278,  -422,  -422,
+     266,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,
+    -422,  -422,  -422,  -422,   196,    18,  -422,   489,    -3,   383,
+    -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,   -36,   489,
+     387,   -36,   489,   289,   254,   254,   292,   293,   278,  -422,
+    -422,  -422,   382,  -422,   -42,  -422,   503,   517,  -422,  -422,
+    -422,  -422,   279,   280,   437,   298,  -422,  -422,  -422,   489,
+    -422,   -47,   441,   283,  -422,  -422,  -422,  -422,   286,  -422,
+    -422,   -36,  -422,   403,   -36,  -422,   406,   317,   347,  -422,
+    -422,  -422,   297,   299,   -23,     3,    28,    21,   254,   329,
+     300,    -3,   402,   -14,  -422,  -422,   404,   -13,  -422,   408,
+    -422,  -422,   309,  -422,  -422,  -422,  -422,  -422,  -422,  -422,
+    -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,
+    -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,   489,   318,
+      58,  -422,   -36,  -422,   -36,  -422,  -422,   289,    74,    74,
+    -422,   489,   489,    -1,   433,  -422,   489,  -422,   435,  -422,
+     489,  -422,   438,  -422,   426,  -422,   171,   489,   531,  -422,
+      69,   489,   545,  -422,   489,  -422,   324,  -422,   489,   333,
+     339,  -422,  -422,  -422,  -422,  -422,  -422,   446,   489,   489,
+     559,   125,  -422,  -422,  -422,  -422,  -422,   254,   343,  -422,
+     449,  -422,  -422,   346,  -422,  -422,   452,  -422,  -422,   350,
+    -422,  -422,  -422,  -422,  -422,    15,   472,    19,    22,  -422,
+     478,    69,    69,  -422,   517,   489,    90,   489,  -422,  -422,
+     489,  -422,  -422,   489,  -422,   489,    -6,  -422,    -9,  -422,
+     357,   359,  -422,   482,   483,   484,  -422,   254,  -422,   488,
+    -422,  -422,  -422,  -422,  -422,  -422,   127,  -422,  -422,   289,
+      -3,  -422
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -414,  -414,  -414,   478,    14,  -146,  -414,  -414,  -414,  -414,
-     279,  -414,  -414,   -97,  -414,   445,  -414,  -414,  -414,   166,
-    -414,  -414,  -414,    16,  -414,  -414,  -414,  -414,  -414,  -414,
-    -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,
-    -414,   324,  -414,  -414,  -414,  -414,  -414,   377,  -414,   390,
-    -414,  -414,  -414,  -414,  -414,  -414,  -330,  -414,  -414,  -414,
-    -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,  -414,
-    -414,  -414,   300,   301,  -414,   -63,  -414,  -414,  -413,  -414,
-    -414,  -414,  -414,  -414,  -213,  -414,  -414,  -414,  -414,  -414,
-    -414,  -414,  -414,  -414,  -414,    68,  -208,  -414,    24,  -327,
-    -343,  -414,   137,   195,  -414,  -414,  -414,   251,   254,  -128,
-     285,  -414,   351,  -414,   227,  -223,    41,   -38,  -162,  -414,
-    -414,  -414,   354,   438,  -414,  -120
+    -422,  -422,  -422,   491,     9,  -146,  -422,  -422,  -422,  -422,
+     270,  -422,  -422,    47,  -422,   445,  -422,  -422,  -422,   161,
+    -422,  -422,  -422,    12,  -422,  -422,  -422,  -422,  -422,  -422,
+    -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,
+    -422,   319,  -422,  -422,  -422,  -422,  -422,   378,  -422,   391,
+    -422,  -422,  -422,  -422,  -422,  -422,  -330,  -422,  -422,  -422,
+    -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,  -422,
+    -422,  -422,   301,   302,  -422,   -63,  -422,  -422,  -418,  -422,
+    -422,  -422,  -422,  -422,  -214,  -422,  -422,  -422,  -422,  -422,
+    -422,  -422,  -422,  -422,  -422,    67,  -206,  -422,    11,  -312,
+    -421,  -422,   147,   200,  -422,  -422,  -422,   244,   252,  -128,
+     281,  -422,   335,  -422,   229,  -223,    33,   -38,  -162,  -422,
+    -422,  -422,   354,   436,  -422,  -119
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -260
+#define YYTABLE_NINF -261
 static const yytype_int16 yytable[] =
 {
-      79,    96,   152,   141,   227,   381,   187,   269,   431,   384,
-     204,   439,     3,     4,   462,     2,   355,   356,   357,   358,
-     200,   -42,   440,   507,   510,   435,   512,    21,   188,   379,
-      91,   280,   379,     5,   448,   436,   205,   452,   523,    52,
-     173,   174,    22,    57,    40,    62,    92,   452,    41,   209,
-       2,    42,    43,   126,    23,   152,    68,    69,    70,    71,
-      79,    72,   323,   142,   332,   326,   327,   209,     5,    77,
-      24,   143,   524,    57,    52,    62,   304,   -83,    30,   196,
-     197,  -259,   432,   189,   380,   525,    28,   430,   441,   449,
-     508,   511,   453,   513,    93,   362,   266,   350,   365,   359,
-     437,    31,   527,   160,   465,     8,   223,   161,   268,  -163,
-      53,   281,   -46,    33,  -163,   206,  -163,  -163,  -163,    54,
-     152,   480,   537,   207,   208,   486,    34,    55,    56,   499,
-     467,   500,    35,  -163,  -163,  -163,   468,   469,   421,  -163,
-       8,   423,   481,    79,   353,    53,   482,   -47,    46,    47,
-      48,    49,   -23,   -21,    54,    73,    74,    75,    76,   335,
-      36,   341,    55,    56,   157,   145,   147,   158,  -163,  -163,
-    -163,  -163,   276,    39,    51,   277,   339,   351,    66,  -163,
-       3,     4,    67,  -163,    85,  -163,    88,   162,   163,   164,
-     165,   -23,    90,   271,   273,   274,   370,   371,    97,   460,
-     335,   461,    98,   536,   205,    53,    53,   123,   124,  -163,
-    -163,  -163,  -163,  -163,  -163,   125,   152,  -163,   127,   129,
-    -163,  -163,  -163,    68,    69,    70,    71,    40,    72,   270,
-    -163,   338,   309,   130,   320,    43,    77,   132,   133,   134,
-     135,   136,   139,   272,   166,   -84,   137,   456,   167,   138,
-     443,   335,    68,    69,    70,    71,   245,    72,   148,   168,
-     342,    74,    75,   343,   344,    77,   171,   352,     1,   354,
-       2,     3,     4,   172,   176,   345,   346,   347,   348,   177,
-     178,   363,   179,   206,   366,   182,   184,   194,     5,   183,
-       6,   207,   208,   488,     7,   218,   198,   219,   385,   389,
-     185,   186,    68,    69,    70,    71,   245,    72,   463,   464,
-     246,   393,   190,   247,   191,    77,   192,   193,   281,   535,
-      68,    69,    70,    71,   202,    72,   216,   220,    73,    74,
-      75,    76,   221,    77,    68,    69,    70,    71,   310,    72,
-     228,   496,    73,    74,    75,    76,   229,    77,   501,   267,
-     283,   284,   291,   292,   293,   294,   295,   296,   297,   298,
-       8,   299,   300,   301,   302,   303,     9,   285,   288,   289,
-      68,    69,    70,    71,    10,    72,   324,   325,   444,   304,
-     457,   328,   337,    77,   361,   311,   312,   313,   314,   315,
-     316,   364,   367,   385,   466,   372,   533,   373,   472,   378,
-     317,  -257,   474,  -258,   391,   419,   422,   498,   424,   478,
-     385,   420,   425,   484,   385,   427,   487,   428,   471,   429,
-     490,   446,   230,   447,   231,   232,   233,   451,   454,   493,
-     494,    68,    69,    70,    71,   458,    72,   304,   455,   305,
-     306,   234,   235,   236,    77,   459,   473,   237,   475,    68,
-      69,    70,    71,   142,    72,   476,   489,    73,    74,    75,
-      76,   143,    77,   491,   389,   517,   492,   519,   150,   503,
-     520,   505,   506,   521,   502,   522,   238,   239,   240,   241,
-     504,   509,   394,   515,   518,   528,   529,   242,   395,   396,
-      32,   243,   530,   244,   397,   398,   399,   400,   401,   402,
-     403,   531,   534,   250,    89,   149,   404,   405,   406,   407,
-     390,   140,   203,   222,   477,   224,   445,    68,    69,    70,
-      71,   245,    72,   374,   321,   246,   516,   322,   247,   248,
-      77,   340,     0,   286,   201,   199,   131,     0,   249,    99,
-     100,   101,   102,   103,   104,   105,   106,   107,   108,   109,
-       0,   110,   111,   112,     0,     0,     0,     0,     0,     0,
-     408,     0,   409,     0,     0,     0,     0,     0,   410,   411,
-     412,   413,   414,   415,   416,   417,    68,    69,    70,    71,
-     142,    72,     0,     0,    73,    74,    75,    76,   143,    77,
-      68,    69,    70,    71,     0,    72,     0,     0,    73,    74,
-      75,    76,     0,    77,    68,    69,    70,    71,     0,    72,
-       0,     0,   382,    74,    75,    76,     0,    77,    68,    69,
-      70,    71,     0,    72,     0,     0,   386,    74,    75,    76,
-       0,    77,    68,    69,    70,    71,     0,    72,     0,     0,
-     479,    74,    75,    76,     0,    77,    68,    69,    70,    71,
-       0,    72,     0,     0,   485,    74,    75,    76,     0,    77,
-      68,    69,    70,    71,     0,    72,     0,     0,   495,     0,
-       0,     0,     0,    77
+      79,    96,   152,   227,   141,   381,   187,   269,     1,   463,
+       2,     3,     4,   431,   355,   356,   357,   358,   -42,   509,
+     200,   188,   526,   512,   384,   439,   514,    91,     5,   379,
+       6,   341,   435,   280,     7,    21,   440,   204,    57,     3,
+       4,    62,   436,    92,   162,   163,   164,   165,   379,   209,
+       3,     4,   501,   126,   502,   152,   527,   448,   452,     2,
+      79,   323,   452,   205,   326,   327,    23,   209,    57,   528,
+       2,    62,   142,   304,   205,   468,   189,     5,  -260,    22,
+     143,   469,   470,    52,   380,   482,   510,   432,     5,   483,
+     513,    93,    24,   515,    52,   362,   266,   359,   365,   350,
+       8,   166,   441,   430,   -83,   167,     9,   437,    28,   268,
+      30,   281,   449,   453,    10,   -84,   168,   530,   270,   466,
+     152,   541,    68,    69,    70,    71,   245,    72,   -23,   -21,
+     342,    74,    75,   343,   344,    77,   481,   272,   421,    31,
+     487,   423,   206,    79,   353,   345,   346,   347,   348,     8,
+     207,   208,   157,   206,    53,   158,   -46,   145,   147,   335,
+       8,   207,   208,    54,   160,    53,   276,   -47,   161,   277,
+     459,    55,    56,   460,    54,    34,   339,   351,    46,    47,
+      48,    49,    55,    56,   173,   174,    73,    74,    75,    76,
+      33,    35,    36,   271,   273,   274,   370,   371,    39,   461,
+     335,   462,   520,    51,    66,   521,   310,   540,    67,    68,
+      69,    70,    71,   -23,    72,    85,   152,    73,    74,    75,
+      76,    88,    77,   196,   197,    90,    53,    97,    68,    69,
+      70,    71,   309,    72,   320,    98,    73,    74,    75,    76,
+     123,    77,   124,   125,   127,   129,   130,   456,   132,   139,
+     443,   335,   148,   311,   312,   313,   314,   315,   316,   133,
+     134,   135,   223,   136,   171,  -164,   137,   352,   317,   354,
+    -164,   138,  -164,  -164,  -164,    68,    69,    70,    71,   245,
+      72,   363,   172,   246,   366,   176,   247,   177,    77,  -164,
+    -164,  -164,   178,   489,   179,  -164,   182,   183,   385,   389,
+      68,    69,    70,    71,    40,    72,   184,   194,   338,   464,
+     465,   393,    43,    77,   185,   186,   190,   191,   281,   219,
+     220,   192,   539,   218,  -164,  -164,  -164,  -164,   193,    40,
+     198,   202,   216,    41,   221,  -164,    42,    43,   228,  -164,
+     229,  -164,   498,    68,    69,    70,    71,   142,    72,   503,
+     267,    73,    74,    75,    76,   143,    77,   283,    68,    69,
+      70,    71,    53,    72,   284,  -164,  -164,  -164,  -164,  -164,
+    -164,    77,   285,  -164,   288,   289,  -164,  -164,  -164,   324,
+     457,   325,    68,    69,    70,    71,  -164,    72,   304,   328,
+     332,   337,   361,   385,   467,    77,   364,   367,   473,   537,
+     372,   373,   475,   378,  -258,  -259,   391,   419,   500,   479,
+     385,   420,   422,   485,   385,   424,   488,   425,   427,   428,
+     491,   429,   446,   447,   230,   451,   231,   232,   233,   454,
+     495,   496,   455,    68,    69,    70,    71,   472,    72,   474,
+     458,   444,   476,   234,   235,   236,    77,   477,   490,   237,
+     494,   291,   292,   293,   294,   295,   296,   297,   298,   492,
+     299,   300,   301,   302,   303,   493,   389,   519,   504,   522,
+     505,   506,   523,   507,   508,   524,   511,   525,   238,   239,
+     240,   241,   517,   531,   394,   532,   533,   534,   535,   242,
+     395,   396,   538,   243,   250,   244,   397,   398,   399,   400,
+     401,   402,   403,    32,    89,   390,   149,   203,   404,   405,
+     406,   407,   140,   478,   222,   518,   224,   321,   201,    68,
+      69,    70,    71,   245,    72,   322,   445,   246,   374,   286,
+     247,   248,    77,   340,   131,   199,   304,     0,   305,   306,
+     249,    68,    69,    70,    71,   142,    72,     0,     0,    73,
+      74,    75,    76,   143,    77,     0,     0,     0,     0,     0,
+     150,     0,   408,     0,   409,     0,     0,     0,     0,     0,
+     410,   411,   412,   413,   414,   415,   416,   417,    99,   100,
+     101,   102,   103,   104,   105,   106,   107,   108,   109,     0,
+     110,   111,   112,    68,    69,    70,    71,     0,    72,     0,
+       0,    73,    74,    75,    76,     0,    77,    68,    69,    70,
+      71,     0,    72,     0,     0,   382,    74,    75,    76,     0,
+      77,    68,    69,    70,    71,     0,    72,     0,     0,   386,
+      74,    75,    76,     0,    77,    68,    69,    70,    71,     0,
+      72,     0,     0,   480,    74,    75,    76,     0,    77,    68,
+      69,    70,    71,     0,    72,     0,     0,   486,    74,    75,
+      76,     0,    77,    68,    69,    70,    71,     0,    72,     0,
+       0,   497,     0,     0,     0,     0,    77
 };
 
 static const yytype_int16 yycheck[] =
 {
-      38,    64,   130,   123,   217,   335,   168,   230,    10,   336,
-       5,     4,     7,     8,   427,     6,    17,    18,    19,    20,
-     182,     4,    15,     4,     4,     4,     4,   112,    71,    71,
-      13,   239,    71,    24,    71,    14,    31,    71,    28,    30,
-     137,   138,   113,    29,   108,    29,    29,    71,   112,   195,
-       6,   115,   116,    91,   112,   183,   104,   105,   106,   107,
-      98,   109,   275,   108,   112,   278,   279,   213,    24,   117,
-     123,   116,    62,    59,    30,    59,   120,    72,     4,   176,
-     177,   125,    84,   126,   126,    75,   112,   126,    81,   126,
-      71,    71,   126,    71,    77,   318,   224,   305,   321,   100,
-      79,     0,   126,   108,   431,    96,     1,   112,   228,     4,
-     101,   239,   103,     4,     9,   110,    11,    12,    13,   110,
-     248,   448,   535,   118,   119,   452,    71,   118,   119,   472,
-      76,   474,     4,    28,    29,    30,    82,    83,   361,    34,
-      96,   364,    16,   181,   306,   101,    20,   103,    51,    52,
-      53,    54,   112,   113,   110,   112,   113,   114,   115,   287,
-     124,    13,   118,   119,   112,   124,   125,   115,    63,    64,
-      65,    66,   112,     4,     4,   115,   304,   305,   112,    74,
-       7,     8,   124,    78,   108,    80,     4,    51,    52,    53,
-      54,   112,   103,   231,   232,   233,   324,   325,     4,   422,
-     328,   424,   137,   533,    31,   101,   101,   122,   113,   104,
-     105,   106,   107,   108,   109,   112,   344,   112,   112,     4,
-     115,   116,   117,   104,   105,   106,   107,   108,   109,    13,
-     125,   112,   270,   116,   272,   116,   117,   125,   125,   125,
-     125,   125,     4,    13,   108,    72,   125,   409,   112,   125,
-     378,   379,   104,   105,   106,   107,   108,   109,    71,   123,
-     112,   113,   114,   115,   116,   117,   112,   305,     4,   307,
-       6,     7,     8,   112,   122,   127,   128,   129,   130,   122,
-     109,   319,   101,   110,   322,   123,   126,     4,    24,    71,
-      26,   118,   119,   455,    30,   112,   124,     4,   336,   337,
-     126,   126,   104,   105,   106,   107,   108,   109,   428,   429,
-     112,   349,   126,   115,   126,   117,   126,   126,   446,   532,
-     104,   105,   106,   107,   124,   109,   124,     4,   112,   113,
-     114,   115,    72,   117,   104,   105,   106,   107,     9,   109,
-      71,   469,   112,   113,   114,   115,     4,   117,   476,   108,
-       4,     4,    35,    36,    37,    38,    39,    40,    41,    42,
-      96,    44,    45,    46,    47,    48,   102,     4,   125,     4,
-     104,   105,   106,   107,   110,   109,    71,    71,   112,   120,
-     418,   125,   125,   117,     9,    56,    57,    58,    59,    60,
-      61,     9,   108,   431,   432,   108,   524,   108,   436,    21,
-      71,   125,   440,   125,   108,   124,     9,   470,     9,   447,
-     448,   125,   100,   451,   452,    71,   454,   122,     4,   122,
-     458,   122,     9,    21,    11,    12,    13,    21,    21,   467,
-     468,   104,   105,   106,   107,   122,   109,   120,   123,   122,
-     123,    28,    29,    30,   117,   112,     4,    34,     4,   104,
-     105,   106,   107,   108,   109,    21,   124,   112,   113,   114,
-     115,   116,   117,   126,   502,   503,     4,   505,   123,    21,
-     508,    21,   124,   511,   125,   513,    63,    64,    65,    66,
-     125,     4,    43,     4,   112,   126,     4,    74,    49,    50,
-      12,    78,     4,    80,    55,    56,    57,    58,    59,    60,
-      61,     4,     4,   224,    59,   128,    67,    68,    69,    70,
-     344,   121,   188,   213,   446,   214,   379,   104,   105,   106,
-     107,   108,   109,   328,   273,   112,   502,   273,   115,   116,
-     117,   304,    -1,   248,   183,   181,    98,    -1,   125,    85,
-      86,    87,    88,    89,    90,    91,    92,    93,    94,    95,
-      -1,    97,    98,    99,    -1,    -1,    -1,    -1,    -1,    -1,
-     121,    -1,   123,    -1,    -1,    -1,    -1,    -1,   129,   130,
-     131,   132,   133,   134,   135,   136,   104,   105,   106,   107,
-     108,   109,    -1,    -1,   112,   113,   114,   115,   116,   117,
-     104,   105,   106,   107,    -1,   109,    -1,    -1,   112,   113,
-     114,   115,    -1,   117,   104,   105,   106,   107,    -1,   109,
-      -1,    -1,   112,   113,   114,   115,    -1,   117,   104,   105,
-     106,   107,    -1,   109,    -1,    -1,   112,   113,   114,   115,
-      -1,   117,   104,   105,   106,   107,    -1,   109,    -1,    -1,
-     112,   113,   114,   115,    -1,   117,   104,   105,   106,   107,
-      -1,   109,    -1,    -1,   112,   113,   114,   115,    -1,   117,
-     104,   105,   106,   107,    -1,   109,    -1,    -1,   112,    -1,
-      -1,    -1,    -1,   117
+      38,    64,   130,   217,   123,   335,   168,   230,     4,   427,
+       6,     7,     8,    10,    17,    18,    19,    20,     4,     4,
+     182,    71,    28,     4,   336,     4,     4,    13,    24,    71,
+      26,    13,     4,   239,    30,   112,    15,     5,    29,     7,
+       8,    29,    14,    29,    51,    52,    53,    54,    71,   195,
+       7,     8,   473,    91,   475,   183,    62,    71,    71,     6,
+      98,   275,    71,    31,   278,   279,   112,   213,    59,    75,
+       6,    59,   108,   120,    31,    76,   126,    24,   125,   113,
+     116,    82,    83,    30,   126,    16,    71,    84,    24,    20,
+      71,    77,   123,    71,    30,   318,   224,   100,   321,   305,
+      96,   108,    81,   126,    72,   112,   102,    79,   112,   228,
+       4,   239,   126,   126,   110,    72,   123,   126,    13,   431,
+     248,   539,   104,   105,   106,   107,   108,   109,   112,   113,
+     112,   113,   114,   115,   116,   117,   448,    13,   361,     0,
+     452,   364,   110,   181,   306,   127,   128,   129,   130,    96,
+     118,   119,   112,   110,   101,   115,   103,   124,   125,   287,
+      96,   118,   119,   110,   108,   101,   112,   103,   112,   115,
+     112,   118,   119,   115,   110,    71,   304,   305,    51,    52,
+      53,    54,   118,   119,   137,   138,   112,   113,   114,   115,
+       4,     4,   124,   231,   232,   233,   324,   325,     4,   422,
+     328,   424,   112,     4,   112,   115,     9,   537,   124,   104,
+     105,   106,   107,   112,   109,   108,   344,   112,   113,   114,
+     115,     4,   117,   176,   177,   103,   101,     4,   104,   105,
+     106,   107,   270,   109,   272,   137,   112,   113,   114,   115,
+     122,   117,   113,   112,   112,     4,   116,   409,   125,     4,
+     378,   379,    71,    56,    57,    58,    59,    60,    61,   125,
+     125,   125,     1,   125,   112,     4,   125,   305,    71,   307,
+       9,   125,    11,    12,    13,   104,   105,   106,   107,   108,
+     109,   319,   112,   112,   322,   122,   115,   122,   117,    28,
+      29,    30,   109,   455,   101,    34,   123,    71,   336,   337,
+     104,   105,   106,   107,   108,   109,   126,     4,   112,   428,
+     429,   349,   116,   117,   126,   126,   126,   126,   446,     4,
+       4,   126,   536,   112,    63,    64,    65,    66,   126,   108,
+     124,   124,   124,   112,    72,    74,   115,   116,    71,    78,
+       4,    80,   470,   104,   105,   106,   107,   108,   109,   477,
+     108,   112,   113,   114,   115,   116,   117,     4,   104,   105,
+     106,   107,   101,   109,     4,   104,   105,   106,   107,   108,
+     109,   117,     4,   112,   125,     4,   115,   116,   117,    71,
+     418,    71,   104,   105,   106,   107,   125,   109,   120,   125,
+     112,   125,     9,   431,   432,   117,     9,   108,   436,   527,
+     108,   108,   440,    21,   125,   125,   108,   124,   471,   447,
+     448,   125,     9,   451,   452,     9,   454,   100,    71,   122,
+     458,   122,   122,    21,     9,    21,    11,    12,    13,    21,
+     468,   469,   123,   104,   105,   106,   107,     4,   109,     4,
+     122,   112,     4,    28,    29,    30,   117,    21,   124,    34,
+       4,    35,    36,    37,    38,    39,    40,    41,    42,   126,
+      44,    45,    46,    47,    48,   126,   504,   505,   125,   507,
+      21,   125,   510,    21,   124,   513,     4,   515,    63,    64,
+      65,    66,     4,   126,    43,   126,     4,     4,     4,    74,
+      49,    50,     4,    78,   224,    80,    55,    56,    57,    58,
+      59,    60,    61,    12,    59,   344,   128,   188,    67,    68,
+      69,    70,   121,   446,   213,   504,   214,   273,   183,   104,
+     105,   106,   107,   108,   109,   273,   379,   112,   328,   248,
+     115,   116,   117,   304,    98,   181,   120,    -1,   122,   123,
+     125,   104,   105,   106,   107,   108,   109,    -1,    -1,   112,
+     113,   114,   115,   116,   117,    -1,    -1,    -1,    -1,    -1,
+     123,    -1,   121,    -1,   123,    -1,    -1,    -1,    -1,    -1,
+     129,   130,   131,   132,   133,   134,   135,   136,    85,    86,
+      87,    88,    89,    90,    91,    92,    93,    94,    95,    -1,
+      97,    98,    99,   104,   105,   106,   107,    -1,   109,    -1,
+      -1,   112,   113,   114,   115,    -1,   117,   104,   105,   106,
+     107,    -1,   109,    -1,    -1,   112,   113,   114,   115,    -1,
+     117,   104,   105,   106,   107,    -1,   109,    -1,    -1,   112,
+     113,   114,   115,    -1,   117,   104,   105,   106,   107,    -1,
+     109,    -1,    -1,   112,   113,   114,   115,    -1,   117,   104,
+     105,   106,   107,    -1,   109,    -1,    -1,   112,   113,   114,
+     115,    -1,   117,   104,   105,   106,   107,    -1,   109,    -1,
+      -1,   112,    -1,    -1,    -1,    -1,   117
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -2340,14 +2363,15 @@
      126,    10,    84,   184,   190,     4,    14,    79,   202,     4,
       15,    81,   203,   247,   112,   240,   122,    21,    71,   126,
      238,    21,    71,   126,    21,   123,   256,   255,   122,   112,
-     253,   253,   216,   263,   263,   237,   255,    76,    82,    83,
-     188,     4,   255,     4,   255,     4,    21,   233,   255,   112,
-     237,    16,    20,   239,   255,   112,   237,   255,   256,   124,
-     255,   126,     4,   255,   255,   112,   247,   183,   213,   238,
-     238,   247,   125,    21,   125,    21,   124,     4,    71,     4,
-       4,    71,     4,    71,   191,     4,   236,   255,   112,   255,
-     255,   255,   255,    28,    62,    75,   192,   126,   126,     4,
-       4,     4,   193,   247,     4,   222,   194,   216
+     115,   253,   253,   216,   263,   263,   237,   255,    76,    82,
+      83,   188,     4,   255,     4,   255,     4,    21,   233,   255,
+     112,   237,    16,    20,   239,   255,   112,   237,   255,   256,
+     124,   255,   126,   126,     4,   255,   255,   112,   247,   183,
+     213,   238,   238,   247,   125,    21,   125,    21,   124,     4,
+      71,     4,     4,    71,     4,    71,   191,     4,   236,   255,
+     112,   115,   255,   255,   255,   255,    28,    62,    75,   192,
+     126,   126,   126,     4,     4,     4,   193,   247,     4,   222,
+     194,   216
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -3175,22 +3199,22 @@
   switch (yyn)
     {
         case 2:
-#line 1105 "compilers/imcc/imcc.y"
+#line 1125 "compilers/imcc/imcc.y"
     { if (yynerrs) YYABORT; (yyval.i) = 0; }
     break;
 
   case 5:
-#line 1114 "compilers/imcc/imcc.y"
+#line 1134 "compilers/imcc/imcc.y"
     { (yyval.i) = (yyvsp[(1) - (1)].i); }
     break;
 
   case 6:
-#line 1115 "compilers/imcc/imcc.y"
+#line 1135 "compilers/imcc/imcc.y"
     { (yyval.i) = (yyvsp[(1) - (1)].i); }
     break;
 
   case 7:
-#line 1117 "compilers/imcc/imcc.y"
+#line 1137 "compilers/imcc/imcc.y"
     {
            (yyval.i) = (yyvsp[(1) - (1)].i);
            imc_close_unit(interp, IMCC_INFO(interp)->cur_unit);
@@ -3199,7 +3223,7 @@
     break;
 
   case 8:
-#line 1123 "compilers/imcc/imcc.y"
+#line 1143 "compilers/imcc/imcc.y"
     {
            (yyval.i) = (yyvsp[(1) - (1)].i);
            imc_close_unit(interp, IMCC_INFO(interp)->cur_unit);
@@ -3208,32 +3232,32 @@
     break;
 
   case 9:
-#line 1128 "compilers/imcc/imcc.y"
+#line 1148 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
   case 10:
-#line 1129 "compilers/imcc/imcc.y"
+#line 1149 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
   case 11:
-#line 1130 "compilers/imcc/imcc.y"
+#line 1150 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
   case 12:
-#line 1131 "compilers/imcc/imcc.y"
+#line 1151 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
   case 13:
-#line 1135 "compilers/imcc/imcc.y"
+#line 1155 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
   case 14:
-#line 1137 "compilers/imcc/imcc.y"
+#line 1157 "compilers/imcc/imcc.y"
     {
            (yyval.i) = 0;
            do_loadlib(interp, (yyvsp[(2) - (3)].s));
@@ -3242,7 +3266,7 @@
     break;
 
   case 15:
-#line 1146 "compilers/imcc/imcc.y"
+#line 1166 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->line = atoi((yyvsp[(2) - (5)].s));
            set_filename(interp, (yyvsp[(4) - (5)].s));
@@ -3250,14 +3274,14 @@
     break;
 
   case 16:
-#line 1151 "compilers/imcc/imcc.y"
+#line 1171 "compilers/imcc/imcc.y"
     {
            set_filename(interp, (yyvsp[(2) - (3)].s));
          }
     break;
 
   case 17:
-#line 1158 "compilers/imcc/imcc.y"
+#line 1178 "compilers/imcc/imcc.y"
     {
           /* We'll want to store an entry while emitting instructions, so just
            * store annotation like it's an instruction. */
@@ -3268,7 +3292,7 @@
     break;
 
   case 18:
-#line 1170 "compilers/imcc/imcc.y"
+#line 1190 "compilers/imcc/imcc.y"
     {
             STRING * const hll_name = Parrot_str_unescape(interp, (yyvsp[(2) - (2)].s) + 1, '"', NULL);
             CONTEXT(interp)->current_HLL =
@@ -3280,12 +3304,12 @@
     break;
 
   case 19:
-#line 1181 "compilers/imcc/imcc.y"
+#line 1201 "compilers/imcc/imcc.y"
     { pesky_global__is_def = 1; }
     break;
 
   case 20:
-#line 1182 "compilers/imcc/imcc.y"
+#line 1202 "compilers/imcc/imcc.y"
     {
              mk_const_ident(interp, (yyvsp[(4) - (6)].s), (yyvsp[(3) - (6)].t), (yyvsp[(6) - (6)].sr), 1);
              mem_sys_free((yyvsp[(4) - (6)].s));
@@ -3294,12 +3318,12 @@
     break;
 
   case 21:
-#line 1190 "compilers/imcc/imcc.y"
+#line 1210 "compilers/imcc/imcc.y"
     { pesky_global__is_def=1; }
     break;
 
   case 22:
-#line 1191 "compilers/imcc/imcc.y"
+#line 1211 "compilers/imcc/imcc.y"
     {
            (yyval.i) = mk_pmc_const(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (6)].s), (yyvsp[(4) - (6)].sr), (yyvsp[(6) - (6)].s));
            pesky_global__is_def = 0;
@@ -3307,12 +3331,12 @@
     break;
 
   case 23:
-#line 1196 "compilers/imcc/imcc.y"
+#line 1216 "compilers/imcc/imcc.y"
     { pesky_global__is_def=1; }
     break;
 
   case 24:
-#line 1197 "compilers/imcc/imcc.y"
+#line 1217 "compilers/imcc/imcc.y"
     {
            (yyval.i) = mk_pmc_const_named(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (6)].s), (yyvsp[(4) - (6)].sr), (yyvsp[(6) - (6)].s));
            pesky_global__is_def = 0;
@@ -3320,37 +3344,37 @@
     break;
 
   case 29:
-#line 1213 "compilers/imcc/imcc.y"
+#line 1233 "compilers/imcc/imcc.y"
     { (yyval.i) = 0;  }
     break;
 
   case 30:
-#line 1214 "compilers/imcc/imcc.y"
+#line 1234 "compilers/imcc/imcc.y"
     { (yyval.i) = 0;  }
     break;
 
   case 31:
-#line 1215 "compilers/imcc/imcc.y"
+#line 1235 "compilers/imcc/imcc.y"
     { (yyval.i) = 0;  }
     break;
 
   case 32:
-#line 1216 "compilers/imcc/imcc.y"
+#line 1236 "compilers/imcc/imcc.y"
     { (yyval.i) = 0;  }
     break;
 
   case 33:
-#line 1217 "compilers/imcc/imcc.y"
+#line 1237 "compilers/imcc/imcc.y"
     { (yyval.i) = (yyvsp[(1) - (1)].i); }
     break;
 
   case 36:
-#line 1222 "compilers/imcc/imcc.y"
+#line 1242 "compilers/imcc/imcc.y"
     { clear_state(interp); }
     break;
 
   case 37:
-#line 1224 "compilers/imcc/imcc.y"
+#line 1244 "compilers/imcc/imcc.y"
     {
            (yyval.i) = INS(interp, IMCC_INFO(interp)->cur_unit,
                     (yyvsp[(2) - (3)].s), 0, IMCC_INFO(interp)->regs,
@@ -3360,7 +3384,7 @@
     break;
 
   case 38:
-#line 1231 "compilers/imcc/imcc.y"
+#line 1251 "compilers/imcc/imcc.y"
     {
            imc_close_unit(interp, IMCC_INFO(interp)->cur_unit);
            IMCC_INFO(interp)->cur_unit = imc_open_unit(interp, IMC_PASM);
@@ -3368,7 +3392,7 @@
     break;
 
   case 39:
-#line 1236 "compilers/imcc/imcc.y"
+#line 1256 "compilers/imcc/imcc.y"
     {
            (yyval.i) = iSUBROUTINE(interp,
                     IMCC_INFO(interp)->cur_unit,
@@ -3378,14 +3402,14 @@
     break;
 
   case 40:
-#line 1243 "compilers/imcc/imcc.y"
+#line 1263 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "null", 1, (yyvsp[(2) - (2)].sr));
          }
     break;
 
   case 41:
-#line 1247 "compilers/imcc/imcc.y"
+#line 1267 "compilers/imcc/imcc.y"
     {
            SymReg *r = mk_pasm_reg(interp, (yyvsp[(4) - (4)].s));
            SymReg *n = mk_const(interp, (yyvsp[(2) - (4)].s), 'S');
@@ -3397,17 +3421,17 @@
     break;
 
   case 42:
-#line 1255 "compilers/imcc/imcc.y"
+#line 1275 "compilers/imcc/imcc.y"
     { (yyval.i) = 0;}
     break;
 
   case 44:
-#line 1263 "compilers/imcc/imcc.y"
+#line 1283 "compilers/imcc/imcc.y"
     { IMCC_INFO(interp)->cur_unit = imc_open_unit(interp, IMC_PASM); }
     break;
 
   case 45:
-#line 1266 "compilers/imcc/imcc.y"
+#line 1286 "compilers/imcc/imcc.y"
     {
            /* if (optimizer_level & OPT_PASM)
                          imc_compile_unit(interp, IMCC_INFO(interp)->cur_unit);
@@ -3418,7 +3442,7 @@
     break;
 
   case 48:
-#line 1282 "compilers/imcc/imcc.y"
+#line 1302 "compilers/imcc/imcc.y"
     {
            int re_open = 0;
            (yyval.i) = 0;
@@ -3433,7 +3457,7 @@
     break;
 
   case 49:
-#line 1297 "compilers/imcc/imcc.y"
+#line 1317 "compilers/imcc/imcc.y"
     {
             if (IMCC_INFO(interp)->in_slice)
                 IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
@@ -3444,26 +3468,26 @@
     break;
 
   case 50:
-#line 1304 "compilers/imcc/imcc.y"
+#line 1324 "compilers/imcc/imcc.y"
     { (yyval.sr) = NULL; }
     break;
 
   case 51:
-#line 1309 "compilers/imcc/imcc.y"
+#line 1329 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->cur_unit = imc_open_unit(interp, IMC_PCCSUB);
          }
     break;
 
   case 52:
-#line 1313 "compilers/imcc/imcc.y"
+#line 1333 "compilers/imcc/imcc.y"
     {
            iSUBROUTINE(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (3)].sr));
          }
     break;
 
   case 53:
-#line 1317 "compilers/imcc/imcc.y"
+#line 1337 "compilers/imcc/imcc.y"
     {
           IMCC_INFO(interp)->cur_call->pcc_sub->pragma = (yyvsp[(5) - (6)].t);
           if (!IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->subid) {
@@ -3474,22 +3498,22 @@
     break;
 
   case 54:
-#line 1325 "compilers/imcc/imcc.y"
+#line 1345 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; }
     break;
 
   case 55:
-#line 1329 "compilers/imcc/imcc.y"
+#line 1349 "compilers/imcc/imcc.y"
     { (yyval.sr) = 0; }
     break;
 
   case 56:
-#line 1330 "compilers/imcc/imcc.y"
+#line 1350 "compilers/imcc/imcc.y"
     { (yyval.sr) = 0; }
     break;
 
   case 57:
-#line 1332 "compilers/imcc/imcc.y"
+#line 1352 "compilers/imcc/imcc.y"
     {
            if (IMCC_INFO(interp)->adv_named_id) {
                  add_pcc_named_param(interp, IMCC_INFO(interp)->cur_call,
@@ -3502,17 +3526,17 @@
     break;
 
   case 58:
-#line 1344 "compilers/imcc/imcc.y"
+#line 1364 "compilers/imcc/imcc.y"
     { pesky_global__is_def=1; }
     break;
 
   case 59:
-#line 1344 "compilers/imcc/imcc.y"
+#line 1364 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(3) - (3)].sr); pesky_global__is_def=0; }
     break;
 
   case 60:
-#line 1349 "compilers/imcc/imcc.y"
+#line 1369 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(3) - (3)].t) & VT_UNIQUE_REG)
                (yyval.sr) = mk_ident_ur(interp, (yyvsp[(2) - (3)].s), (yyvsp[(1) - (3)].t));
@@ -3524,12 +3548,12 @@
     break;
 
   case 61:
-#line 1362 "compilers/imcc/imcc.y"
+#line 1382 "compilers/imcc/imcc.y"
     { (yyval.t) = 0; }
     break;
 
   case 62:
-#line 1367 "compilers/imcc/imcc.y"
+#line 1387 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->outer = mk_sub_address_fromc(interp, (yyvsp[(3) - (4)].s));
@@ -3538,7 +3562,7 @@
     break;
 
   case 63:
-#line 1373 "compilers/imcc/imcc.y"
+#line 1393 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->outer = mk_const(interp, (yyvsp[(3) - (4)].s), 'S');
@@ -3547,7 +3571,7 @@
     break;
 
   case 64:
-#line 1382 "compilers/imcc/imcc.y"
+#line 1402 "compilers/imcc/imcc.y"
     {
            (yyval.t) = P_VTABLE;
            IMCC_INFO(interp)->cur_unit->vtable_name = NULL;
@@ -3556,7 +3580,7 @@
     break;
 
   case 65:
-#line 1388 "compilers/imcc/imcc.y"
+#line 1408 "compilers/imcc/imcc.y"
     {
            (yyval.t) = P_VTABLE;
            IMCC_INFO(interp)->cur_unit->vtable_name = (yyvsp[(3) - (4)].s);
@@ -3565,7 +3589,7 @@
     break;
 
   case 66:
-#line 1397 "compilers/imcc/imcc.y"
+#line 1417 "compilers/imcc/imcc.y"
     {
            (yyval.t) = P_METHOD;
            IMCC_INFO(interp)->cur_unit->method_name = NULL;
@@ -3574,7 +3598,7 @@
     break;
 
   case 67:
-#line 1403 "compilers/imcc/imcc.y"
+#line 1423 "compilers/imcc/imcc.y"
     {
            (yyval.t) = P_METHOD;
            IMCC_INFO(interp)->cur_unit->method_name = (yyvsp[(3) - (4)].s);
@@ -3583,7 +3607,7 @@
     break;
 
   case 68:
-#line 1412 "compilers/imcc/imcc.y"
+#line 1432 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->ns_entry_name = NULL;
@@ -3592,7 +3616,7 @@
     break;
 
   case 69:
-#line 1418 "compilers/imcc/imcc.y"
+#line 1438 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->ns_entry_name = (yyvsp[(3) - (4)].s);
@@ -3601,7 +3625,7 @@
     break;
 
   case 70:
-#line 1427 "compilers/imcc/imcc.y"
+#line 1447 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->instance_of = (yyvsp[(3) - (4)].s);
@@ -3609,7 +3633,7 @@
     break;
 
   case 71:
-#line 1435 "compilers/imcc/imcc.y"
+#line 1455 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->subid = NULL;
@@ -3617,7 +3641,7 @@
     break;
 
   case 72:
-#line 1440 "compilers/imcc/imcc.y"
+#line 1460 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->subid = mk_const(interp, (yyvsp[(3) - (4)].s), 'S');
@@ -3627,14 +3651,14 @@
     break;
 
   case 73:
-#line 1450 "compilers/imcc/imcc.y"
+#line 1470 "compilers/imcc/imcc.y"
     {
            add_pcc_multi(IMCC_INFO(interp)->cur_call, NULL);
          }
     break;
 
   case 74:
-#line 1454 "compilers/imcc/imcc.y"
+#line 1474 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            add_pcc_multi(IMCC_INFO(interp)->cur_call, (yyvsp[(3) - (3)].sr));
@@ -3642,7 +3666,7 @@
     break;
 
   case 75:
-#line 1459 "compilers/imcc/imcc.y"
+#line 1479 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            add_pcc_multi(IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (1)].sr));
@@ -3650,27 +3674,27 @@
     break;
 
   case 76:
-#line 1466 "compilers/imcc/imcc.y"
+#line 1486 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_const(interp, "INTVAL",   'S'); }
     break;
 
   case 77:
-#line 1467 "compilers/imcc/imcc.y"
+#line 1487 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_const(interp, "FLOATVAL", 'S'); }
     break;
 
   case 78:
-#line 1468 "compilers/imcc/imcc.y"
+#line 1488 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_const(interp, "PMC",      'S'); }
     break;
 
   case 79:
-#line 1469 "compilers/imcc/imcc.y"
+#line 1489 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_const(interp, "STRING",   'S'); }
     break;
 
   case 80:
-#line 1471 "compilers/imcc/imcc.y"
+#line 1491 "compilers/imcc/imcc.y"
     {
            SymReg *r;
            if (strcmp((yyvsp[(1) - (1)].s), "_") != 0)
@@ -3684,7 +3708,7 @@
     break;
 
   case 81:
-#line 1482 "compilers/imcc/imcc.y"
+#line 1502 "compilers/imcc/imcc.y"
     {
            SymReg *r;
            if (strcmp((yyvsp[(1) - (1)].s), "_") != 0)
@@ -3698,12 +3722,12 @@
     break;
 
   case 82:
-#line 1492 "compilers/imcc/imcc.y"
+#line 1512 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(2) - (3)].sr); }
     break;
 
   case 85:
-#line 1502 "compilers/imcc/imcc.y"
+#line 1522 "compilers/imcc/imcc.y"
     {
            char name[128];
            SymReg *r, *r1;
@@ -3730,82 +3754,82 @@
     break;
 
   case 86:
-#line 1530 "compilers/imcc/imcc.y"
+#line 1550 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; }
     break;
 
   case 87:
-#line 1534 "compilers/imcc/imcc.y"
+#line 1554 "compilers/imcc/imcc.y"
     { (yyval.i) = NULL; IMCC_INFO(interp)->cur_call->pcc_sub->label = 0; }
     break;
 
   case 88:
-#line 1535 "compilers/imcc/imcc.y"
+#line 1555 "compilers/imcc/imcc.y"
     { (yyval.i) = NULL; IMCC_INFO(interp)->cur_call->pcc_sub->label = 1; }
     break;
 
   case 89:
-#line 1539 "compilers/imcc/imcc.y"
+#line 1559 "compilers/imcc/imcc.y"
     { (yyval.i) = NULL; }
     break;
 
   case 90:
-#line 1540 "compilers/imcc/imcc.y"
+#line 1560 "compilers/imcc/imcc.y"
     { (yyval.i) = NULL;  IMCC_INFO(interp)->cur_call->pcc_sub->object = (yyvsp[(2) - (3)].sr); }
     break;
 
   case 91:
-#line 1544 "compilers/imcc/imcc.y"
+#line 1564 "compilers/imcc/imcc.y"
     { (yyval.t) = 0; }
     break;
 
   case 93:
-#line 1549 "compilers/imcc/imcc.y"
+#line 1569 "compilers/imcc/imcc.y"
     { (yyval.t) = (yyvsp[(1) - (1)].t); }
     break;
 
   case 94:
-#line 1550 "compilers/imcc/imcc.y"
+#line 1570 "compilers/imcc/imcc.y"
     { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); }
     break;
 
   case 95:
-#line 1554 "compilers/imcc/imcc.y"
+#line 1574 "compilers/imcc/imcc.y"
     { (yyval.t) = P_LOAD; }
     break;
 
   case 96:
-#line 1555 "compilers/imcc/imcc.y"
+#line 1575 "compilers/imcc/imcc.y"
     { (yyval.t) = P_INIT; }
     break;
 
   case 97:
-#line 1556 "compilers/imcc/imcc.y"
+#line 1576 "compilers/imcc/imcc.y"
     { (yyval.t) = P_MAIN; }
     break;
 
   case 98:
-#line 1557 "compilers/imcc/imcc.y"
+#line 1577 "compilers/imcc/imcc.y"
     { (yyval.t) = P_IMMEDIATE; }
     break;
 
   case 99:
-#line 1558 "compilers/imcc/imcc.y"
+#line 1578 "compilers/imcc/imcc.y"
     { (yyval.t) = P_POSTCOMP; }
     break;
 
   case 100:
-#line 1559 "compilers/imcc/imcc.y"
+#line 1579 "compilers/imcc/imcc.y"
     { (yyval.t) = P_ANON; }
     break;
 
   case 101:
-#line 1560 "compilers/imcc/imcc.y"
+#line 1580 "compilers/imcc/imcc.y"
     { (yyval.t) = P_NEED_LEX; }
     break;
 
   case 109:
-#line 1572 "compilers/imcc/imcc.y"
+#line 1592 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (5)].sr));
            add_pcc_cc(IMCC_INFO(interp)->cur_call, (yyvsp[(4) - (5)].sr));
@@ -3813,14 +3837,14 @@
     break;
 
   case 110:
-#line 1577 "compilers/imcc/imcc.y"
+#line 1597 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
          }
     break;
 
   case 111:
-#line 1581 "compilers/imcc/imcc.y"
+#line 1601 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
            IMCC_INFO(interp)->cur_call->pcc_sub->flags |= isNCI;
@@ -3828,21 +3852,21 @@
     break;
 
   case 112:
-#line 1586 "compilers/imcc/imcc.y"
+#line 1606 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
          }
     break;
 
   case 113:
-#line 1590 "compilers/imcc/imcc.y"
+#line 1610 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, mk_const(interp, (yyvsp[(2) - (3)].s), 'S'));
          }
     break;
 
   case 114:
-#line 1594 "compilers/imcc/imcc.y"
+#line 1614 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (5)].sr));
            add_pcc_cc(IMCC_INFO(interp)->cur_call, (yyvsp[(4) - (5)].sr));
@@ -3850,7 +3874,7 @@
     break;
 
   case 115:
-#line 1599 "compilers/imcc/imcc.y"
+#line 1619 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, mk_const(interp, (yyvsp[(2) - (5)].s), 'S'));
            add_pcc_cc(IMCC_INFO(interp)->cur_call, (yyvsp[(4) - (5)].sr));
@@ -3858,27 +3882,27 @@
     break;
 
   case 116:
-#line 1607 "compilers/imcc/imcc.y"
+#line 1627 "compilers/imcc/imcc.y"
     { (yyval.sr) = 0; }
     break;
 
   case 117:
-#line 1608 "compilers/imcc/imcc.y"
+#line 1628 "compilers/imcc/imcc.y"
     { add_pcc_arg(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr)); }
     break;
 
   case 118:
-#line 1612 "compilers/imcc/imcc.y"
+#line 1632 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(2) - (2)].sr); }
     break;
 
   case 119:
-#line 1617 "compilers/imcc/imcc.y"
+#line 1637 "compilers/imcc/imcc.y"
     { (yyval.sr) = 0; }
     break;
 
   case 120:
-#line 1619 "compilers/imcc/imcc.y"
+#line 1639 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(2) - (3)].sr))
                add_pcc_result(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
@@ -3886,17 +3910,17 @@
     break;
 
   case 121:
-#line 1626 "compilers/imcc/imcc.y"
+#line 1646 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); }
     break;
 
   case 122:
-#line 1627 "compilers/imcc/imcc.y"
+#line 1647 "compilers/imcc/imcc.y"
     { pesky_global__is_def=1; }
     break;
 
   case 123:
-#line 1628 "compilers/imcc/imcc.y"
+#line 1648 "compilers/imcc/imcc.y"
     {
            IdList *l = (yyvsp[(4) - (4)].idlist);
            SymReg *ignored;
@@ -3911,158 +3935,163 @@
     break;
 
   case 124:
-#line 1642 "compilers/imcc/imcc.y"
+#line 1662 "compilers/imcc/imcc.y"
     { (yyval.t) = 0; }
     break;
 
   case 125:
-#line 1643 "compilers/imcc/imcc.y"
+#line 1663 "compilers/imcc/imcc.y"
     { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); }
     break;
 
   case 126:
-#line 1647 "compilers/imcc/imcc.y"
+#line 1667 "compilers/imcc/imcc.y"
     { (yyval.t) = VT_FLAT;   }
     break;
 
   case 127:
-#line 1648 "compilers/imcc/imcc.y"
+#line 1668 "compilers/imcc/imcc.y"
     { (yyval.t) = VT_OPTIONAL; }
     break;
 
   case 128:
-#line 1649 "compilers/imcc/imcc.y"
+#line 1669 "compilers/imcc/imcc.y"
     { (yyval.t) = VT_OPT_FLAG; }
     break;
 
   case 129:
-#line 1650 "compilers/imcc/imcc.y"
+#line 1670 "compilers/imcc/imcc.y"
     { (yyval.t) = VT_NAMED; }
     break;
 
   case 130:
-#line 1651 "compilers/imcc/imcc.y"
-    { adv_named_set(interp, (yyvsp[(3) - (4)].s)); (yyval.t) = 0; }
+#line 1671 "compilers/imcc/imcc.y"
+    { adv_named_set(interp, (yyvsp[(3) - (4)].s));   (yyval.t) = 0; }
     break;
 
   case 131:
-#line 1652 "compilers/imcc/imcc.y"
-    { (yyval.t) = VT_UNIQUE_REG; }
+#line 1672 "compilers/imcc/imcc.y"
+    { adv_named_set_u(interp, (yyvsp[(3) - (4)].s)); (yyval.t) = 0; }
     break;
 
   case 132:
-#line 1657 "compilers/imcc/imcc.y"
-    { begin_return_or_yield(interp, 0); }
+#line 1673 "compilers/imcc/imcc.y"
+    { (yyval.t) = VT_UNIQUE_REG; }
     break;
 
   case 133:
-#line 1659 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; IMCC_INFO(interp)->asm_state = AsmDefault; }
+#line 1678 "compilers/imcc/imcc.y"
+    { begin_return_or_yield(interp, 0); }
     break;
 
   case 134:
-#line 1661 "compilers/imcc/imcc.y"
+#line 1680 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; IMCC_INFO(interp)->asm_state = AsmDefault; }
+    break;
+
+  case 135:
+#line 1682 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->asm_state = AsmDefault;
            (yyval.i) = 0;
          }
     break;
 
-  case 135:
-#line 1668 "compilers/imcc/imcc.y"
+  case 136:
+#line 1689 "compilers/imcc/imcc.y"
     { begin_return_or_yield(interp, 1); }
     break;
 
-  case 136:
-#line 1670 "compilers/imcc/imcc.y"
+  case 137:
+#line 1691 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; IMCC_INFO(interp)->asm_state = AsmDefault; }
     break;
 
-  case 137:
-#line 1674 "compilers/imcc/imcc.y"
+  case 138:
+#line 1695 "compilers/imcc/imcc.y"
     { (yyval.sr) = 0; }
     break;
 
-  case 138:
-#line 1676 "compilers/imcc/imcc.y"
+  case 139:
+#line 1697 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(1) - (2)].sr))
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(1) - (2)].sr));
          }
     break;
 
-  case 139:
-#line 1681 "compilers/imcc/imcc.y"
+  case 140:
+#line 1702 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(2) - (3)].sr))
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(2) - (3)].sr));
          }
     break;
 
-  case 140:
-#line 1688 "compilers/imcc/imcc.y"
+  case 141:
+#line 1709 "compilers/imcc/imcc.y"
     { (yyval.sr) = 0; }
     break;
 
-  case 141:
-#line 1690 "compilers/imcc/imcc.y"
+  case 142:
+#line 1711 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(1) - (2)].sr))
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(1) - (2)].sr));
          }
     break;
 
-  case 142:
-#line 1695 "compilers/imcc/imcc.y"
+  case 143:
+#line 1716 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(2) - (3)].sr))
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(2) - (3)].sr));
          }
     break;
 
-  case 143:
-#line 1702 "compilers/imcc/imcc.y"
+  case 144:
+#line 1723 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); }
     break;
 
-  case 144:
-#line 1706 "compilers/imcc/imcc.y"
+  case 145:
+#line 1727 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); }
     break;
 
-  case 145:
-#line 1711 "compilers/imcc/imcc.y"
+  case 146:
+#line 1732 "compilers/imcc/imcc.y"
     {
           if (IMCC_INFO(interp)->asm_state == AsmDefault)
               begin_return_or_yield(interp, (yyvsp[(1) - (2)].t));
         }
     break;
 
-  case 146:
-#line 1716 "compilers/imcc/imcc.y"
+  case 147:
+#line 1737 "compilers/imcc/imcc.y"
     {
           IMCC_INFO(interp)->asm_state = AsmDefault;
           (yyval.t) = 0;
         }
     break;
 
-  case 147:
-#line 1723 "compilers/imcc/imcc.y"
+  case 148:
+#line 1744 "compilers/imcc/imcc.y"
     { (yyval.t) = 0; }
     break;
 
-  case 148:
-#line 1724 "compilers/imcc/imcc.y"
+  case 149:
+#line 1745 "compilers/imcc/imcc.y"
     { (yyval.t) = 1; }
     break;
 
-  case 149:
-#line 1728 "compilers/imcc/imcc.y"
+  case 150:
+#line 1749 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
-  case 150:
-#line 1730 "compilers/imcc/imcc.y"
+  case 151:
+#line 1751 "compilers/imcc/imcc.y"
     {
            if (IMCC_INFO(interp)->adv_named_id) {
                add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return,
@@ -4074,15 +4103,16 @@
          }
     break;
 
-  case 151:
-#line 1740 "compilers/imcc/imcc.y"
+  case 152:
+#line 1761 "compilers/imcc/imcc.y"
     {
-           add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, (yyvsp[(1) - (3)].s), (yyvsp[(3) - (3)].sr));
+            SymReg *name = mk_const(interp, (yyvsp[(1) - (3)].s), 'S');
+            add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, name, (yyvsp[(3) - (3)].sr));
          }
     break;
 
-  case 152:
-#line 1744 "compilers/imcc/imcc.y"
+  case 153:
+#line 1766 "compilers/imcc/imcc.y"
     {
            if (IMCC_INFO(interp)->adv_named_id) {
                add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return,
@@ -4094,67 +4124,68 @@
          }
     break;
 
-  case 153:
-#line 1754 "compilers/imcc/imcc.y"
+  case 154:
+#line 1776 "compilers/imcc/imcc.y"
     {
-           add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, (yyvsp[(3) - (5)].s), (yyvsp[(5) - (5)].sr));
+           SymReg *name = mk_const(interp, (yyvsp[(3) - (5)].s), 'S');
+           add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, name, (yyvsp[(5) - (5)].sr));
          }
     break;
 
-  case 156:
-#line 1774 "compilers/imcc/imcc.y"
-    { clear_state(interp); }
-    break;
-
   case 157:
-#line 1779 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(2) - (2)].i); }
+#line 1797 "compilers/imcc/imcc.y"
+    { clear_state(interp); }
     break;
 
   case 158:
-#line 1780 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1802 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(2) - (2)].i); }
     break;
 
   case 159:
-#line 1781 "compilers/imcc/imcc.y"
+#line 1803 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
   case 160:
-#line 1782 "compilers/imcc/imcc.y"
+#line 1804 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
   case 161:
-#line 1783 "compilers/imcc/imcc.y"
+#line 1805 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
   case 162:
-#line 1784 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(1) - (1)].i); }
+#line 1806 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; }
     break;
 
   case 163:
-#line 1788 "compilers/imcc/imcc.y"
+#line 1807 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); }
+    break;
+
+  case 164:
+#line 1811 "compilers/imcc/imcc.y"
     { (yyval.i) = NULL; }
     break;
 
-  case 167:
-#line 1799 "compilers/imcc/imcc.y"
+  case 168:
+#line 1822 "compilers/imcc/imcc.y"
     {
            (yyval.i) = iLABEL(interp, IMCC_INFO(interp)->cur_unit, mk_local_label(interp, (yyvsp[(1) - (1)].s)));
          }
     break;
 
-  case 168:
-#line 1807 "compilers/imcc/imcc.y"
+  case 169:
+#line 1830 "compilers/imcc/imcc.y"
     { (yyval.i) = (yyvsp[(2) - (3)].i); }
     break;
 
-  case 169:
-#line 1809 "compilers/imcc/imcc.y"
+  case 170:
+#line 1832 "compilers/imcc/imcc.y"
     {
            if (yynerrs >= PARROT_MAX_RECOVER_ERRORS) {
                IMCC_warning(interp, "Too many errors. Correct some first.\n");
@@ -4164,8 +4195,8 @@
          }
     break;
 
-  case 170:
-#line 1820 "compilers/imcc/imcc.y"
+  case 171:
+#line 1843 "compilers/imcc/imcc.y"
     {
            IdList* l = (yyvsp[(1) - (1)].idlist);
            l->next = NULL;
@@ -4173,8 +4204,8 @@
          }
     break;
 
-  case 171:
-#line 1827 "compilers/imcc/imcc.y"
+  case 172:
+#line 1850 "compilers/imcc/imcc.y"
     {
            IdList* l = (yyvsp[(3) - (3)].idlist);
            l->next = (yyvsp[(1) - (3)].idlist);
@@ -4182,8 +4213,8 @@
          }
     break;
 
-  case 172:
-#line 1836 "compilers/imcc/imcc.y"
+  case 173:
+#line 1859 "compilers/imcc/imcc.y"
     {
            IdList* const l = mem_allocate_n_zeroed_typed(1, IdList);
            l->id           = (yyvsp[(1) - (2)].s);
@@ -4192,23 +4223,23 @@
          }
     break;
 
-  case 173:
-#line 1845 "compilers/imcc/imcc.y"
+  case 174:
+#line 1868 "compilers/imcc/imcc.y"
     { (yyval.t) = 0; }
     break;
 
-  case 174:
-#line 1846 "compilers/imcc/imcc.y"
+  case 175:
+#line 1869 "compilers/imcc/imcc.y"
     { (yyval.t) = 1; }
     break;
 
-  case 177:
-#line 1853 "compilers/imcc/imcc.y"
+  case 178:
+#line 1876 "compilers/imcc/imcc.y"
     { pesky_global__is_def=1; }
     break;
 
-  case 178:
-#line 1854 "compilers/imcc/imcc.y"
+  case 179:
+#line 1877 "compilers/imcc/imcc.y"
     {
            IdList *l = (yyvsp[(4) - (4)].idlist);
            while (l) {
@@ -4226,29 +4257,29 @@
          }
     break;
 
-  case 179:
-#line 1870 "compilers/imcc/imcc.y"
+  case 180:
+#line 1893 "compilers/imcc/imcc.y"
     {
            SymReg *n = mk_const(interp, (yyvsp[(2) - (4)].s), 'S');
            set_lexical(interp, (yyvsp[(4) - (4)].sr), n); (yyval.i) = 0;
          }
     break;
 
-  case 180:
-#line 1875 "compilers/imcc/imcc.y"
+  case 181:
+#line 1898 "compilers/imcc/imcc.y"
     {
            SymReg *n = mk_const(interp, (yyvsp[(2) - (4)].s), 'U');
            set_lexical(interp, (yyvsp[(4) - (4)].sr), n); (yyval.i) = 0;
          }
     break;
 
-  case 181:
-#line 1879 "compilers/imcc/imcc.y"
+  case 182:
+#line 1902 "compilers/imcc/imcc.y"
     { pesky_global__is_def=1; }
     break;
 
-  case 182:
-#line 1880 "compilers/imcc/imcc.y"
+  case 183:
+#line 1903 "compilers/imcc/imcc.y"
     {
            mk_const_ident(interp, (yyvsp[(4) - (6)].s), (yyvsp[(3) - (6)].t), (yyvsp[(6) - (6)].sr), 0);
            pesky_global__is_def=0;
@@ -4256,13 +4287,13 @@
          }
     break;
 
-  case 184:
-#line 1887 "compilers/imcc/imcc.y"
+  case 185:
+#line 1910 "compilers/imcc/imcc.y"
     { pesky_global__is_def=1; }
     break;
 
-  case 185:
-#line 1888 "compilers/imcc/imcc.y"
+  case 186:
+#line 1911 "compilers/imcc/imcc.y"
     {
            mk_const_ident(interp, (yyvsp[(4) - (6)].s), (yyvsp[(3) - (6)].t), (yyvsp[(6) - (6)].sr), 1);
            pesky_global__is_def=0;
@@ -4270,8 +4301,8 @@
          }
     break;
 
-  case 186:
-#line 1894 "compilers/imcc/imcc.y"
+  case 187:
+#line 1917 "compilers/imcc/imcc.y"
     {
            (yyval.i) = NULL;
            IMCC_INFO(interp)->cur_call->pcc_sub->flags |= isTAIL_CALL;
@@ -4279,15 +4310,15 @@
          }
     break;
 
-  case 187:
-#line 1900 "compilers/imcc/imcc.y"
+  case 188:
+#line 1923 "compilers/imcc/imcc.y"
     {
             (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "branch", 1, (yyvsp[(2) - (2)].sr));
          }
     break;
 
-  case 188:
-#line 1904 "compilers/imcc/imcc.y"
+  case 189:
+#line 1927 "compilers/imcc/imcc.y"
     {
            (yyval.i) = INS(interp,
                     IMCC_INFO(interp)->cur_unit,
@@ -4301,48 +4332,48 @@
          }
     break;
 
-  case 189:
-#line 1915 "compilers/imcc/imcc.y"
+  case 190:
+#line 1938 "compilers/imcc/imcc.y"
     { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "null", 1, (yyvsp[(2) - (2)].sr)); }
     break;
 
-  case 190:
-#line 1916 "compilers/imcc/imcc.y"
+  case 191:
+#line 1939 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; }
     break;
 
-  case 191:
-#line 1917 "compilers/imcc/imcc.y"
+  case 192:
+#line 1940 "compilers/imcc/imcc.y"
     { (yyval.i) = 0; }
     break;
 
-  case 194:
-#line 1920 "compilers/imcc/imcc.y"
+  case 195:
+#line 1943 "compilers/imcc/imcc.y"
     { (yyval.i) = 0;}
     break;
 
-  case 195:
-#line 1924 "compilers/imcc/imcc.y"
+  case 196:
+#line 1947 "compilers/imcc/imcc.y"
     { (yyval.t) = 'I'; }
     break;
 
-  case 196:
-#line 1925 "compilers/imcc/imcc.y"
+  case 197:
+#line 1948 "compilers/imcc/imcc.y"
     { (yyval.t) = 'N'; }
     break;
 
-  case 197:
-#line 1926 "compilers/imcc/imcc.y"
+  case 198:
+#line 1949 "compilers/imcc/imcc.y"
     { (yyval.t) = 'S'; }
     break;
 
-  case 198:
-#line 1927 "compilers/imcc/imcc.y"
+  case 199:
+#line 1950 "compilers/imcc/imcc.y"
     { (yyval.t) = 'P'; }
     break;
 
-  case 199:
-#line 1932 "compilers/imcc/imcc.y"
+  case 200:
+#line 1955 "compilers/imcc/imcc.y"
     {
            /* there'd normally be a str_dup() here, but the lexer already
             * copied the string, so it's safe to use directly */
@@ -4354,38 +4385,38 @@
          }
     break;
 
-  case 200:
-#line 1945 "compilers/imcc/imcc.y"
+  case 201:
+#line 1968 "compilers/imcc/imcc.y"
     { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "set", 2, (yyvsp[(1) - (3)].sr), (yyvsp[(3) - (3)].sr));  }
     break;
 
-  case 201:
-#line 1947 "compilers/imcc/imcc.y"
+  case 202:
+#line 1970 "compilers/imcc/imcc.y"
     { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (4)].s), 2, (yyvsp[(1) - (4)].sr), (yyvsp[(4) - (4)].sr));  }
     break;
 
-  case 202:
-#line 1949 "compilers/imcc/imcc.y"
+  case 203:
+#line 1972 "compilers/imcc/imcc.y"
     { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(4) - (5)].s), 3, (yyvsp[(1) - (5)].sr), (yyvsp[(3) - (5)].sr), (yyvsp[(5) - (5)].sr));  }
     break;
 
-  case 203:
-#line 1951 "compilers/imcc/imcc.y"
+  case 204:
+#line 1974 "compilers/imcc/imcc.y"
     { (yyval.i) = iINDEXFETCH(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (6)].sr), (yyvsp[(3) - (6)].sr), (yyvsp[(5) - (6)].sr)); }
     break;
 
-  case 204:
-#line 1953 "compilers/imcc/imcc.y"
+  case 205:
+#line 1976 "compilers/imcc/imcc.y"
     { (yyval.i) = iINDEXSET(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (6)].sr), (yyvsp[(3) - (6)].sr), (yyvsp[(6) - (6)].sr)); }
     break;
 
-  case 205:
-#line 1958 "compilers/imcc/imcc.y"
+  case 206:
+#line 1981 "compilers/imcc/imcc.y"
     { (yyval.i) = iNEW(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (7)].sr), (yyvsp[(4) - (7)].s), (yyvsp[(6) - (7)].sr), 1); }
     break;
 
-  case 206:
-#line 1961 "compilers/imcc/imcc.y"
+  case 207:
+#line 1984 "compilers/imcc/imcc.y"
     {
            add_pcc_result((yyvsp[(3) - (3)].i)->symregs[0], (yyvsp[(1) - (3)].sr));
            IMCC_INFO(interp)->cur_call = NULL;
@@ -4393,160 +4424,160 @@
          }
     break;
 
-  case 207:
-#line 1967 "compilers/imcc/imcc.y"
+  case 208:
+#line 1990 "compilers/imcc/imcc.y"
     {
            (yyval.i) = IMCC_create_itcall_label(interp);
          }
     break;
 
-  case 208:
-#line 1971 "compilers/imcc/imcc.y"
+  case 209:
+#line 1994 "compilers/imcc/imcc.y"
     {
            IMCC_itcall_sub(interp, (yyvsp[(6) - (9)].sr));
            IMCC_INFO(interp)->cur_call = NULL;
          }
     break;
 
-  case 212:
-#line 1979 "compilers/imcc/imcc.y"
+  case 213:
+#line 2002 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "null", 1, (yyvsp[(1) - (3)].sr));
          }
     break;
 
-  case 213:
-#line 1986 "compilers/imcc/imcc.y"
+  case 214:
+#line 2009 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"not"; }
     break;
 
-  case 214:
-#line 1987 "compilers/imcc/imcc.y"
+  case 215:
+#line 2010 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"bnot"; }
     break;
 
-  case 215:
-#line 1988 "compilers/imcc/imcc.y"
+  case 216:
+#line 2011 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"neg"; }
     break;
 
-  case 216:
-#line 1992 "compilers/imcc/imcc.y"
+  case 217:
+#line 2015 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"sub"; }
     break;
 
-  case 217:
-#line 1993 "compilers/imcc/imcc.y"
+  case 218:
+#line 2016 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"add"; }
     break;
 
-  case 218:
-#line 1994 "compilers/imcc/imcc.y"
+  case 219:
+#line 2017 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"mul"; }
     break;
 
-  case 219:
-#line 1995 "compilers/imcc/imcc.y"
+  case 220:
+#line 2018 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"div"; }
     break;
 
-  case 220:
-#line 1996 "compilers/imcc/imcc.y"
+  case 221:
+#line 2019 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"mod"; }
     break;
 
-  case 221:
-#line 1997 "compilers/imcc/imcc.y"
+  case 222:
+#line 2020 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"fdiv"; }
     break;
 
-  case 222:
-#line 1998 "compilers/imcc/imcc.y"
+  case 223:
+#line 2021 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"pow"; }
     break;
 
-  case 223:
-#line 1999 "compilers/imcc/imcc.y"
+  case 224:
+#line 2022 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"concat"; }
     break;
 
-  case 224:
-#line 2000 "compilers/imcc/imcc.y"
+  case 225:
+#line 2023 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"iseq"; }
     break;
 
-  case 225:
-#line 2001 "compilers/imcc/imcc.y"
+  case 226:
+#line 2024 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"isne"; }
     break;
 
-  case 226:
-#line 2002 "compilers/imcc/imcc.y"
+  case 227:
+#line 2025 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"isgt"; }
     break;
 
-  case 227:
-#line 2003 "compilers/imcc/imcc.y"
+  case 228:
+#line 2026 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"isge"; }
     break;
 
-  case 228:
-#line 2004 "compilers/imcc/imcc.y"
+  case 229:
+#line 2027 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"islt"; }
     break;
 
-  case 229:
-#line 2005 "compilers/imcc/imcc.y"
+  case 230:
+#line 2028 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"isle"; }
     break;
 
-  case 230:
-#line 2006 "compilers/imcc/imcc.y"
+  case 231:
+#line 2029 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"shl"; }
     break;
 
-  case 231:
-#line 2007 "compilers/imcc/imcc.y"
+  case 232:
+#line 2030 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"shr"; }
     break;
 
-  case 232:
-#line 2008 "compilers/imcc/imcc.y"
+  case 233:
+#line 2031 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"lsr"; }
     break;
 
-  case 233:
-#line 2009 "compilers/imcc/imcc.y"
+  case 234:
+#line 2032 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"and"; }
     break;
 
-  case 234:
-#line 2010 "compilers/imcc/imcc.y"
+  case 235:
+#line 2033 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"or"; }
     break;
 
-  case 235:
-#line 2011 "compilers/imcc/imcc.y"
+  case 236:
+#line 2034 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"xor"; }
     break;
 
-  case 236:
-#line 2012 "compilers/imcc/imcc.y"
+  case 237:
+#line 2035 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"band"; }
     break;
 
-  case 237:
-#line 2013 "compilers/imcc/imcc.y"
+  case 238:
+#line 2036 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"bor"; }
     break;
 
-  case 238:
-#line 2014 "compilers/imcc/imcc.y"
+  case 239:
+#line 2037 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"bxor"; }
     break;
 
-  case 239:
-#line 2020 "compilers/imcc/imcc.y"
+  case 240:
+#line 2043 "compilers/imcc/imcc.y"
     {
            (yyval.i) = IMCC_create_itcall_label(interp);
            (yyval.i)->type &= ~ITCALL;
@@ -4554,85 +4585,85 @@
          }
     break;
 
-  case 240:
-#line 2025 "compilers/imcc/imcc.y"
+  case 241:
+#line 2048 "compilers/imcc/imcc.y"
     {  (yyval.i) = 0; }
     break;
 
-  case 241:
-#line 2032 "compilers/imcc/imcc.y"
+  case 242:
+#line 2055 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(2) - (3)].s), 2, (yyvsp[(1) - (3)].sr), (yyvsp[(3) - (3)].sr));
          }
     break;
 
-  case 242:
-#line 2038 "compilers/imcc/imcc.y"
+  case 243:
+#line 2061 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"add"; }
     break;
 
-  case 243:
-#line 2039 "compilers/imcc/imcc.y"
+  case 244:
+#line 2062 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"sub"; }
     break;
 
-  case 244:
-#line 2040 "compilers/imcc/imcc.y"
+  case 245:
+#line 2063 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"mul"; }
     break;
 
-  case 245:
-#line 2041 "compilers/imcc/imcc.y"
+  case 246:
+#line 2064 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"div"; }
     break;
 
-  case 246:
-#line 2042 "compilers/imcc/imcc.y"
+  case 247:
+#line 2065 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"mod"; }
     break;
 
-  case 247:
-#line 2043 "compilers/imcc/imcc.y"
+  case 248:
+#line 2066 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"fdiv"; }
     break;
 
-  case 248:
-#line 2044 "compilers/imcc/imcc.y"
+  case 249:
+#line 2067 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"concat"; }
     break;
 
-  case 249:
-#line 2045 "compilers/imcc/imcc.y"
+  case 250:
+#line 2068 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"band"; }
     break;
 
-  case 250:
-#line 2046 "compilers/imcc/imcc.y"
+  case 251:
+#line 2069 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"bor"; }
     break;
 
-  case 251:
-#line 2047 "compilers/imcc/imcc.y"
+  case 252:
+#line 2070 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"bxor"; }
     break;
 
-  case 252:
-#line 2048 "compilers/imcc/imcc.y"
+  case 253:
+#line 2071 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"shr"; }
     break;
 
-  case 253:
-#line 2049 "compilers/imcc/imcc.y"
+  case 254:
+#line 2072 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"shl"; }
     break;
 
-  case 254:
-#line 2050 "compilers/imcc/imcc.y"
+  case 255:
+#line 2073 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"lsr"; }
     break;
 
-  case 255:
-#line 2056 "compilers/imcc/imcc.y"
+  case 256:
+#line 2079 "compilers/imcc/imcc.y"
     {
         (yyval.i) = func_ins(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (4)].sr), (yyvsp[(3) - (4)].s),
                       IMCC_INFO(interp) -> regs,
@@ -4642,23 +4673,23 @@
        }
     break;
 
-  case 256:
-#line 2066 "compilers/imcc/imcc.y"
+  case 257:
+#line 2089 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s));  mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 257:
-#line 2067 "compilers/imcc/imcc.y"
+  case 258:
+#line 2090 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_sub_address_fromc(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 258:
-#line 2068 "compilers/imcc/imcc.y"
+  case 259:
+#line 2091 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_sub_address_u(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 259:
-#line 2070 "compilers/imcc/imcc.y"
+  case 260:
+#line 2093 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = (yyvsp[(1) - (1)].sr);
            if ((yyvsp[(1) - (1)].sr)->set != 'P')
@@ -4666,8 +4697,8 @@
          }
     break;
 
-  case 260:
-#line 2076 "compilers/imcc/imcc.y"
+  case 261:
+#line 2099 "compilers/imcc/imcc.y"
     {
             /* disallow bareword method names; SREG name constants are fine */
             char *name = (yyvsp[(3) - (3)].sr)->name;
@@ -4683,8 +4714,8 @@
         }
     break;
 
-  case 261:
-#line 2090 "compilers/imcc/imcc.y"
+  case 262:
+#line 2113 "compilers/imcc/imcc.y"
     {
             IMCC_INFO(interp)->cur_obj = (yyvsp[(1) - (3)].sr);
             (yyval.sr)                         = mk_const(interp, (yyvsp[(3) - (3)].s), 'S');
@@ -4692,31 +4723,31 @@
          }
     break;
 
-  case 262:
-#line 2095 "compilers/imcc/imcc.y"
+  case 263:
+#line 2118 "compilers/imcc/imcc.y"
     { IMCC_INFO(interp)->cur_obj = (yyvsp[(1) - (3)].sr); (yyval.sr) = (yyvsp[(3) - (3)].sr); }
     break;
 
-  case 263:
-#line 2101 "compilers/imcc/imcc.y"
+  case 264:
+#line 2124 "compilers/imcc/imcc.y"
     {
            (yyval.i) = IMCC_create_itcall_label(interp);
            IMCC_itcall_sub(interp, (yyvsp[(1) - (1)].sr));
          }
     break;
 
-  case 264:
-#line 2105 "compilers/imcc/imcc.y"
+  case 265:
+#line 2128 "compilers/imcc/imcc.y"
     { (yyval.i) = (yyvsp[(2) - (5)].i); }
     break;
 
-  case 265:
-#line 2109 "compilers/imcc/imcc.y"
+  case 266:
+#line 2132 "compilers/imcc/imcc.y"
     { (yyval.sr) = 0; }
     break;
 
-  case 266:
-#line 2111 "compilers/imcc/imcc.y"
+  case 267:
+#line 2134 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
@@ -4728,8 +4759,8 @@
          }
     break;
 
-  case 267:
-#line 2121 "compilers/imcc/imcc.y"
+  case 268:
+#line 2144 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
@@ -4741,69 +4772,76 @@
          }
     break;
 
-  case 268:
-#line 2131 "compilers/imcc/imcc.y"
+  case 269:
+#line 2154 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
-           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call, (yyvsp[(3) - (5)].s), (yyvsp[(5) - (5)].sr));
+           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call,
+                mk_const(interp, (yyvsp[(3) - (5)].s), 'S'), (yyvsp[(5) - (5)].sr));
            mem_sys_free((yyvsp[(3) - (5)].s));
          }
     break;
 
-  case 269:
-#line 2137 "compilers/imcc/imcc.y"
+  case 270:
+#line 2161 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            add_pcc_named_arg_var(interp, IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (3)].sr), (yyvsp[(3) - (3)].sr));
          }
     break;
 
-  case 270:
-#line 2142 "compilers/imcc/imcc.y"
+  case 271:
+#line 2166 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
-           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (3)].s), (yyvsp[(3) - (3)].sr));
+           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call,
+                mk_const(interp, (yyvsp[(1) - (3)].s), 'S'), (yyvsp[(3) - (3)].sr));
            mem_sys_free((yyvsp[(1) - (3)].s));
          }
     break;
 
-  case 271:
-#line 2150 "compilers/imcc/imcc.y"
+  case 272:
+#line 2175 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(1) - (2)].sr); (yyval.sr)->type |= (yyvsp[(2) - (2)].t); }
     break;
 
-  case 272:
-#line 2154 "compilers/imcc/imcc.y"
+  case 273:
+#line 2179 "compilers/imcc/imcc.y"
     { (yyval.t) = 0; }
     break;
 
-  case 273:
-#line 2155 "compilers/imcc/imcc.y"
+  case 274:
+#line 2180 "compilers/imcc/imcc.y"
     { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); }
     break;
 
-  case 274:
-#line 2159 "compilers/imcc/imcc.y"
+  case 275:
+#line 2184 "compilers/imcc/imcc.y"
     { (yyval.t) = VT_FLAT; }
     break;
 
-  case 275:
-#line 2160 "compilers/imcc/imcc.y"
+  case 276:
+#line 2185 "compilers/imcc/imcc.y"
     { (yyval.t) = VT_NAMED; }
     break;
 
-  case 276:
-#line 2163 "compilers/imcc/imcc.y"
-    { adv_named_set(interp, (yyvsp[(3) - (4)].s)); (yyval.t) = 0; }
+  case 277:
+#line 2188 "compilers/imcc/imcc.y"
+    { adv_named_set_u(interp, (yyvsp[(3) - (4)].s)); (yyval.t) = 0; }
     break;
 
-  case 277:
-#line 2167 "compilers/imcc/imcc.y"
+  case 278:
+#line 2189 "compilers/imcc/imcc.y"
+    { adv_named_set(interp, (yyvsp[(3) - (4)].s));   (yyval.t) = 0; }
+    break;
+
+  case 279:
+#line 2193 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(1) - (2)].sr); (yyval.sr)->type |= (yyvsp[(2) - (2)].t); }
     break;
 
-  case 278:
-#line 2172 "compilers/imcc/imcc.y"
+  case 280:
+#line 2198 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
@@ -4815,16 +4853,17 @@
          }
     break;
 
-  case 279:
-#line 2182 "compilers/imcc/imcc.y"
+  case 281:
+#line 2208 "compilers/imcc/imcc.y"
     {
-           add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, (yyvsp[(3) - (5)].s), (yyvsp[(5) - (5)].sr));
-           mem_sys_free((yyvsp[(3) - (5)].s));
+            add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call,
+            mk_const(interp, (yyvsp[(3) - (5)].s), 'S'), (yyvsp[(5) - (5)].sr));
+            mem_sys_free((yyvsp[(3) - (5)].s));
          }
     break;
 
-  case 280:
-#line 2187 "compilers/imcc/imcc.y"
+  case 282:
+#line 2214 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
@@ -4836,133 +4875,133 @@
          }
     break;
 
-  case 281:
-#line 2197 "compilers/imcc/imcc.y"
+  case 283:
+#line 2224 "compilers/imcc/imcc.y"
     {
-           add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (3)].s), (yyvsp[(3) - (3)].sr));
+           add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, mk_const(interp, (yyvsp[(1) - (3)].s), 'S'), (yyvsp[(3) - (3)].sr));
            mem_sys_free((yyvsp[(1) - (3)].s));
          }
     break;
 
-  case 282:
-#line 2201 "compilers/imcc/imcc.y"
+  case 284:
+#line 2228 "compilers/imcc/imcc.y"
     { (yyval.sr) = 0; }
     break;
 
-  case 283:
-#line 2205 "compilers/imcc/imcc.y"
+  case 285:
+#line 2232 "compilers/imcc/imcc.y"
     { (yyval.i) = (yyvsp[(1) - (1)].i); }
     break;
 
-  case 284:
-#line 2206 "compilers/imcc/imcc.y"
+  case 286:
+#line 2233 "compilers/imcc/imcc.y"
     { (yyval.i) = (yyvsp[(1) - (1)].i); }
     break;
 
-  case 285:
-#line 2211 "compilers/imcc/imcc.y"
+  case 287:
+#line 2238 "compilers/imcc/imcc.y"
     {
            (yyval.i) =MK_I(interp, IMCC_INFO(interp)->cur_unit, inv_op((yyvsp[(3) - (6)].s)), 3, (yyvsp[(2) - (6)].sr), (yyvsp[(4) - (6)].sr), (yyvsp[(6) - (6)].sr));
          }
     break;
 
-  case 286:
-#line 2215 "compilers/imcc/imcc.y"
+  case 288:
+#line 2242 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "unless_null", 2, (yyvsp[(3) - (5)].sr), (yyvsp[(5) - (5)].sr));
          }
     break;
 
-  case 287:
-#line 2219 "compilers/imcc/imcc.y"
+  case 289:
+#line 2246 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "unless", 2, (yyvsp[(2) - (4)].sr), (yyvsp[(4) - (4)].sr));
          }
     break;
 
-  case 288:
-#line 2226 "compilers/imcc/imcc.y"
+  case 290:
+#line 2253 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "if", 2, (yyvsp[(2) - (4)].sr), (yyvsp[(4) - (4)].sr));
          }
     break;
 
-  case 289:
-#line 2230 "compilers/imcc/imcc.y"
+  case 291:
+#line 2257 "compilers/imcc/imcc.y"
     {
            (yyval.i) =MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (6)].s), 3, (yyvsp[(2) - (6)].sr), (yyvsp[(4) - (6)].sr), (yyvsp[(6) - (6)].sr));
          }
     break;
 
-  case 290:
-#line 2234 "compilers/imcc/imcc.y"
+  case 292:
+#line 2261 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "if_null", 2, (yyvsp[(3) - (5)].sr), (yyvsp[(5) - (5)].sr));
          }
     break;
 
-  case 291:
-#line 2240 "compilers/imcc/imcc.y"
+  case 293:
+#line 2267 "compilers/imcc/imcc.y"
     { (yyval.t) = 0; }
     break;
 
-  case 292:
-#line 2241 "compilers/imcc/imcc.y"
+  case 294:
+#line 2268 "compilers/imcc/imcc.y"
     { (yyval.t) = 0; }
     break;
 
-  case 293:
-#line 2245 "compilers/imcc/imcc.y"
+  case 295:
+#line 2272 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"eq"; }
     break;
 
-  case 294:
-#line 2246 "compilers/imcc/imcc.y"
+  case 296:
+#line 2273 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"ne"; }
     break;
 
-  case 295:
-#line 2247 "compilers/imcc/imcc.y"
+  case 297:
+#line 2274 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"gt"; }
     break;
 
-  case 296:
-#line 2248 "compilers/imcc/imcc.y"
+  case 298:
+#line 2275 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"ge"; }
     break;
 
-  case 297:
-#line 2249 "compilers/imcc/imcc.y"
+  case 299:
+#line 2276 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"lt"; }
     break;
 
-  case 298:
-#line 2250 "compilers/imcc/imcc.y"
+  case 300:
+#line 2277 "compilers/imcc/imcc.y"
     { (yyval.s) = (char *)"le"; }
     break;
 
-  case 301:
-#line 2259 "compilers/imcc/imcc.y"
+  case 303:
+#line 2286 "compilers/imcc/imcc.y"
     { (yyval.sr) = NULL; }
     break;
 
-  case 302:
-#line 2260 "compilers/imcc/imcc.y"
+  case 304:
+#line 2287 "compilers/imcc/imcc.y"
     { (yyval.sr) = (yyvsp[(1) - (1)].sr); }
     break;
 
-  case 303:
-#line 2264 "compilers/imcc/imcc.y"
+  case 305:
+#line 2291 "compilers/imcc/imcc.y"
     { (yyval.sr) = IMCC_INFO(interp)->regs[0]; }
     break;
 
-  case 305:
-#line 2269 "compilers/imcc/imcc.y"
+  case 307:
+#line 2296 "compilers/imcc/imcc.y"
     { IMCC_INFO(interp)->regs[IMCC_INFO(interp)->nargs++] = (yyvsp[(1) - (1)].sr); }
     break;
 
-  case 306:
-#line 2271 "compilers/imcc/imcc.y"
+  case 308:
+#line 2298 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp) -> regs[IMCC_INFO(interp)->nargs++] = (yyvsp[(1) - (4)].sr);
            IMCC_INFO(interp) -> keyvec |= KEY_BIT(IMCC_INFO(interp)->nargs);
@@ -4971,54 +5010,54 @@
          }
     break;
 
-  case 307:
-#line 2278 "compilers/imcc/imcc.y"
+  case 309:
+#line 2305 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp) -> regs[IMCC_INFO(interp)->nargs++] = (yyvsp[(2) - (3)].sr);
            (yyval.sr) = (yyvsp[(2) - (3)].sr);
          }
     break;
 
-  case 309:
-#line 2285 "compilers/imcc/imcc.y"
+  case 311:
+#line 2312 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_sub_address_fromc(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 310:
-#line 2286 "compilers/imcc/imcc.y"
+  case 312:
+#line 2313 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_sub_address_u(interp, (yyvsp[(1) - (1)].s));  mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 311:
-#line 2290 "compilers/imcc/imcc.y"
+  case 313:
+#line 2317 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 312:
-#line 2291 "compilers/imcc/imcc.y"
+  case 314:
+#line 2318 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 313:
-#line 2295 "compilers/imcc/imcc.y"
+  case 315:
+#line 2322 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_label_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 314:
-#line 2296 "compilers/imcc/imcc.y"
+  case 316:
+#line 2323 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_label_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 319:
-#line 2310 "compilers/imcc/imcc.y"
+  case 321:
+#line 2337 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->nkeys    = 0;
            IMCC_INFO(interp)->in_slice = 0;
          }
     break;
 
-  case 320:
-#line 2315 "compilers/imcc/imcc.y"
+  case 322:
+#line 2342 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = link_keys(interp,
                           IMCC_INFO(interp)->nkeys,
@@ -5026,16 +5065,16 @@
          }
     break;
 
-  case 321:
-#line 2323 "compilers/imcc/imcc.y"
+  case 323:
+#line 2350 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->nkeys = 0;
            IMCC_INFO(interp)->in_slice = 0;
          }
     break;
 
-  case 322:
-#line 2328 "compilers/imcc/imcc.y"
+  case 324:
+#line 2355 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = link_keys(interp,
                           IMCC_INFO(interp)->nkeys,
@@ -5043,21 +5082,21 @@
          }
     break;
 
-  case 323:
-#line 2336 "compilers/imcc/imcc.y"
+  case 325:
+#line 2363 "compilers/imcc/imcc.y"
     { IMCC_INFO(interp)->keys[IMCC_INFO(interp)->nkeys++] = (yyvsp[(1) - (1)].sr); }
     break;
 
-  case 324:
-#line 2338 "compilers/imcc/imcc.y"
+  case 326:
+#line 2365 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->keys[IMCC_INFO(interp)->nkeys++] = (yyvsp[(3) - (3)].sr);
            (yyval.sr) = IMCC_INFO(interp)->keys[0];
          }
     break;
 
-  case 325:
-#line 2346 "compilers/imcc/imcc.y"
+  case 327:
+#line 2373 "compilers/imcc/imcc.y"
     {
            if (IMCC_INFO(interp)->in_slice)
                (yyvsp[(1) - (1)].sr)->type |= VT_START_SLICE | VT_END_SLICE;
@@ -5065,54 +5104,54 @@
          }
     break;
 
-  case 326:
-#line 2354 "compilers/imcc/imcc.y"
+  case 328:
+#line 2381 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'I'); }
     break;
 
-  case 327:
-#line 2355 "compilers/imcc/imcc.y"
+  case 329:
+#line 2382 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'N'); }
     break;
 
-  case 328:
-#line 2356 "compilers/imcc/imcc.y"
+  case 330:
+#line 2383 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'S'); }
     break;
 
-  case 329:
-#line 2357 "compilers/imcc/imcc.y"
+  case 331:
+#line 2384 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'P'); }
     break;
 
-  case 330:
-#line 2358 "compilers/imcc/imcc.y"
+  case 332:
+#line 2385 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_pasm_reg(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 331:
-#line 2362 "compilers/imcc/imcc.y"
+  case 333:
+#line 2389 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'I'); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 332:
-#line 2363 "compilers/imcc/imcc.y"
+  case 334:
+#line 2390 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'N'); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 333:
-#line 2364 "compilers/imcc/imcc.y"
+  case 335:
+#line 2391 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'S'); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
-  case 334:
-#line 2365 "compilers/imcc/imcc.y"
+  case 336:
+#line 2392 "compilers/imcc/imcc.y"
     { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'U'); mem_sys_free((yyvsp[(1) - (1)].s)); }
     break;
 
 
 /* Line 1267 of yacc.c.  */
-#line 5105 "compilers/imcc/imcparser.c"
+#line 5144 "compilers/imcc/imcparser.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -5326,7 +5365,7 @@
 }
 
 
-#line 2371 "compilers/imcc/imcc.y"
+#line 2398 "compilers/imcc/imcc.y"
 
 
 /* I need this prototype somewhere... */

Modified: branches/pmc_pct/compilers/imcc/imcparser.h
==============================================================================
--- branches/pmc_pct/compilers/imcc/imcparser.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/imcc/imcparser.h	Fri May 15 21:49:40 2009	(r38803)
@@ -295,7 +295,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 1010 "compilers/imcc/imcc.y"
+#line 1030 "compilers/imcc/imcc.y"
 {
     IdList * idlist;
     int t;

Modified: branches/pmc_pct/compilers/imcc/pbc.c
==============================================================================
--- branches/pmc_pct/compilers/imcc/pbc.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/imcc/pbc.c	Fri May 15 21:49:40 2009	(r38803)
@@ -313,25 +313,29 @@
 imcc_globals_destroy(PARROT_INTERP, SHIM(int ex), SHIM(void *param))
 {
     ASSERT_ARGS(imcc_globals_destroy)
-    code_segment_t *cs = IMCC_INFO(interp)->globals->cs;
 
-    while (cs) {
-        subs_t         *s              = cs->subs;
-        code_segment_t * const prev_cs = cs->prev;
+    /* This is an allowed condition? See TT #629 */
+    if (IMCC_INFO(interp)->globals) {
+        code_segment_t *cs = IMCC_INFO(interp)->globals->cs;
+
+        while (cs) {
+            subs_t         *s              = cs->subs;
+            code_segment_t * const prev_cs = cs->prev;
+
+            while (s) {
+                subs_t * const prev_s = s->prev;
+                clear_sym_hash(&s->fixup);
+                mem_sys_free(s);
+                s = prev_s;
+            }
 
-        while (s) {
-            subs_t * const prev_s = s->prev;
-            clear_sym_hash(&s->fixup);
-            mem_sys_free(s);
-            s      = prev_s;
+            clear_sym_hash(&cs->key_consts);
+            mem_sys_free(cs);
+            cs = prev_cs;
         }
-
-        clear_sym_hash(&cs->key_consts);
-        mem_sys_free(cs);
-        cs      = prev_cs;
+        IMCC_INFO(interp)->globals->cs = NULL;
     }
 
-    IMCC_INFO(interp)->globals->cs = NULL;
 }
 
 
@@ -1084,8 +1088,10 @@
     const int      k = add_const_table(interp);
     STRING * const s = Parrot_str_new(interp, buf, 0);
 
-    interp->code->const_table->constants[k]->type     = PFC_NUMBER;
-    interp->code->const_table->constants[k]->u.number = Parrot_str_to_num(interp, s);
+    PackFile_Constant * const constant = interp->code->const_table->constants[k];
+
+    constant->type     = PFC_NUMBER;
+    constant->u.number = Parrot_str_to_num(interp, s);
 
     return k;
 }

Modified: branches/pmc_pct/compilers/nqp/src/Grammar.pg
==============================================================================
--- branches/pmc_pct/compilers/nqp/src/Grammar.pg	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/nqp/src/Grammar.pg	Fri May 15 21:49:40 2009	(r38803)
@@ -339,11 +339,12 @@
 }
 
 token quote {
-    [ \'  <string_literal: '\''> \'
-    | '"' <string_literal: '"'> '"'
-    | 'q' <.ws> '<' <string_literal: '>'> '>'
+    [ \'  <string_literal: '\''> \' {*}                    #= string
+    | '"' <string_literal: '"'> '"' {*}                    #= string
+    | 'q' <.ws> '<' <string_literal: '>'> '>' {*}          #= string
+    | 'Q' <.ws> ':PIR' <.ws>
+        [:ratchet(0) '{{' (.*?) '}}' | '{' (.*?) '}' ] {*} #= PIR
     ]
-    {*}
 }
 
 

Modified: branches/pmc_pct/compilers/nqp/src/Grammar/Actions.pir
==============================================================================
--- branches/pmc_pct/compilers/nqp/src/Grammar/Actions.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/nqp/src/Grammar/Actions.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -921,16 +921,29 @@
 
 
 ##    method quote($/, $key) {
-##        make PAST::Val.new( :node($/), :value(~($<string_literal>)) );
+##        if $key eq 'PIR' {
+##            make PAST::Op.new( :node($/), :inline(~($[0])) );
+##        }
+##        else {
+##            make PAST::Val.new( :node($/), :value(~($<string_literal>)) );
+##        }
 ##    }
 .sub 'quote' :method
     .param pmc match
     .param pmc key             :optional
     .local string value
+    unless key == 'PIR' goto quote_string
+  quote_pir:
+    $S0 = match[0]
+    $P0 = get_hll_global ['PAST'], 'Op'
+    $P1 = $P0.'new'('node'=>match, 'inline'=>$S0)
+    goto end
+  quote_string:
     $P0 = match['string_literal']
     value = $P0.'ast'()
     $P0 = get_hll_global ['PAST'], 'Val'
     $P1 = $P0.'new'('node'=>match, 'value'=>value)
+  end:
     match.'!make'($P1)
 .end
 

Modified: branches/pmc_pct/compilers/nqp/t/18-inline.t
==============================================================================
--- branches/pmc_pct/compilers/nqp/t/18-inline.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/nqp/t/18-inline.t	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 # inline
 
-plan(5);
+plan(7);
 
 PIR q<    say 'ok 1' >;
 PIR q:to:'OK2';
@@ -17,3 +17,8 @@
 PIR q:to:"OK5";
     say 'ok 5'
 OK5
+
+Q:PIR { say 'ok 6' };
+my $x := Q:PIR { %r = box 'ok 7' };
+say($x);
+

Modified: branches/pmc_pct/compilers/pct/src/PCT/HLLCompiler.pir
==============================================================================
--- branches/pmc_pct/compilers/pct/src/PCT/HLLCompiler.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/pct/src/PCT/HLLCompiler.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -688,6 +688,9 @@
     close ifh
     goto iter_loop
   iter_end:
+    $S0 = join ' ', files
+    $P1 = box $S0
+    .lex '$?FILES', $P1
     $P0 = self.'eval'(code, args :flat, adverbs :flat :named)
     if target == '' goto end
     if target == 'pir' goto end

Modified: branches/pmc_pct/compilers/pmcc/src/emitter/pmc.pm
==============================================================================
--- branches/pmc_pct/compilers/pmcc/src/emitter/pmc.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/compilers/pmcc/src/emitter/pmc.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -378,6 +378,7 @@
           "PARROT_EXPORT void Parrot_"
         ~ self.name
         ~ "_class_init(PARROT_INTERP, int entry, int pass) {\n");
+    @res.push( self.generate_attr_defs() );
 
     my $past := self.past;
     if ($past<class_init>) {
@@ -389,6 +390,13 @@
     join('', @res);
 }
 
+=item C<generate_attr_defs>
+
+Generate a string representing the definition of this PMC's ATTRs.
+
+=cut
+
+
 =item C<get_vtable_func>
 
 Generate C-code for get_vtable_func

Modified: branches/pmc_pct/config/auto/arch.pm
==============================================================================
--- branches/pmc_pct/config/auto/arch.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/config/auto/arch.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -39,10 +39,10 @@
     $verbose and print "\n";
 
     my $archname = $conf->data->get('archname');
+    # This was added to convert IA64.ARCHREV_0 on HP-UX, TT #645, TT #653
+    $archname =~ s|\.|_|g;
     my ( $cpuarch, $osname ) = split( /-/, $archname );
 
-    # This was added to convert IA64.ARCHREV_0 on HP-UX, TT #645
-    $archname =~ s|\.|_|g;
 
     if ($verbose) {
         print "determining operating system and cpu architecture\n";

Modified: branches/pmc_pct/config/auto/gmp/gmp_c.in
==============================================================================
--- branches/pmc_pct/config/auto/gmp/gmp_c.in	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/config/auto/gmp/gmp_c.in	Fri May 15 21:49:40 2009	(r38803)
@@ -6,6 +6,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <gmp.h>
+#ifdef WIN32
+#  include <windows.h>
+#endif
 
 int
 main(int argc, char *argv[])

Modified: branches/pmc_pct/config/gen/core_pmcs.pm
==============================================================================
--- branches/pmc_pct/config/gen/core_pmcs.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/config/gen/core_pmcs.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2007, Parrot Foundation.
+# Copyright (C) 2001-2009, Parrot Foundation.
 # $Id$
 
 =head1 NAME
@@ -42,11 +42,11 @@
 sub generate_h {
     my ( $self, $conf ) = @_;
 
-    my $file = "include/parrot/core_pmcs.h";
+    my $file = 'include/parrot/core_pmcs.h';
     $conf->append_configure_log($file);
-    open( my $OUT, ">", "$file.tmp" );
+    open( my $OUT, '>', "$file.tmp" );
 
-    print {$OUT} <<"END_H";
+    print {$OUT} <<'END_H';
 /*
  * DO NOT EDIT THIS FILE
  *
@@ -56,33 +56,27 @@
 #ifndef PARROT_CORE_PMCS_H_GUARD
 #define PARROT_CORE_PMCS_H_GUARD
 
-/* &gen_from_enum(pmctypes.pasm) subst(s/enum_class_(\\w+)/\$1/e) */
+/* &gen_from_enum(pmctypes.pasm) subst(s/enum_class_(\w+)/$1/e) */
 enum {
 END_H
 
-    my @pmcs = split( / /, $conf->data->get('pmc_names') );
+    my @pmcs = split( qr/ /, $conf->data->get('pmc_names') );
     my $i = 0;
     foreach (@pmcs) {
         print {$OUT} "    enum_class_$_,\t/*  $i */\n";
         $i++;
     }
-    print {$OUT} <<"END_H";
+    print {$OUT} <<'END_H';
     enum_class_core_max
 };
 
 /* &end_gen */
 
 #endif /* PARROT_CORE_PMCS_H_GUARD */
-
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
 END_H
+    print {$OUT} coda();
 
-    close $OUT;
+    close $OUT or die "Can't close file: $!";;
 
     move_if_diff( "$file.tmp", $file );
 
@@ -93,12 +87,12 @@
     my ( $self, $conf ) = @_;
 
     my $file = "src/core_pmcs.c";
-    my @pmcs = split( / /, $conf->data->get('pmc_names') );
+    my @pmcs = split( qr/ /, $conf->data->get('pmc_names') );
 
     $conf->append_configure_log($file);
-    open( my $OUT, ">", "$file.tmp" );
+    open( my $OUT, '>', "$file.tmp" );
 
-    print {$OUT} <<"END_C";
+    print {$OUT} <<'END_C';
 /*
  * DO NOT EDIT THIS FILE
  *
@@ -114,7 +108,7 @@
 
     print {$OUT} "extern void Parrot_${_}_class_init(PARROT_INTERP, int, int);\n" foreach (@pmcs);
 
-    print {$OUT} <<"END_C";
+    print {$OUT} <<'END_C';
 
 /* This isn't strictly true, but the headerizer should not bother */
 
@@ -137,14 +131,14 @@
         foreach ( @pmcs[ -1 .. -1 ] );
     print {$OUT} "        Parrot_${_}_class_init(interp, enum_class_${_}, pass);\n"
         foreach ( @pmcs[ 0 .. $#pmcs - 1 ] );
-    print {$OUT} <<"END_C";
+    print {$OUT} <<'END_C';
         if (!pass) {
             parrot_global_setup_2(interp);
         }
     }
 }
 
-static void register_pmc(PARROT_INTERP, PMC *registry, int pmc_id)
+static void register_pmc(PARROT_INTERP, NOTNULL(PMC *registry), int pmc_id)
 {
     STRING * const key = interp->vtables[pmc_id]->whoami;
     VTABLE_set_integer_keyed_str(interp, registry, key, pmc_id);
@@ -159,15 +153,10 @@
     print {$OUT} <<'END_C';
 }
 
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */
 END_C
+    print {$OUT} coda();
 
-    close $OUT;
+    close $OUT or die "Can't close file: $!";
 
     move_if_diff( "$file.tmp", $file );
 
@@ -178,10 +167,10 @@
     my ( $self, $conf ) = @_;
 
     my $file = "lib/Parrot/PMC.pm";
-    my @pmcs = split( / /, $conf->data->get('pmc_names') );
+    my @pmcs = split( qr/ /, $conf->data->get('pmc_names') );
 
     $conf->append_configure_log($file);
-    open( my $OUT, ">", "$file.tmp" );
+    open( my $OUT, '>', "$file.tmp" );
 
     print $OUT <<'END_PM';
 # DO NOT EDIT THIS FILE
@@ -203,22 +192,36 @@
 
     for my $num ( 0 .. $#pmcs ) {
         my $id = $num + 1;
-        print $OUT "\t$pmcs[$num] => $id,\n";
+        print {$OUT} "\t$pmcs[$num] => $id,\n";
     }
 
-    print $OUT <<'END_PM';
+    print {$OUT} <<'END_PM';
 );
 
 1;
 END_PM
 
-    close $OUT;
+    close $OUT or die "Can't close file: $!";
 
     move_if_diff( "$file.tmp", $file );
 
     return;
 }
 
+sub coda {
+    my $v = 'vim';
+
+    # Translate it in code so vim doesn't think this file itself is readonly
+    return <<"HERE"
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * ${v}: readonly expandtab shiftwidth=4:
+ */
+HERE
+}
+
 1;
 
 # Local Variables:

Modified: branches/pmc_pct/config/gen/makefiles/root.in
==============================================================================
--- branches/pmc_pct/config/gen/makefiles/root.in	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/config/gen/makefiles/root.in	Fri May 15 21:49:40 2009	(r38803)
@@ -253,6 +253,7 @@
     $(LIBRARY_DIR)/dumper.pbc \
     $(LIBRARY_DIR)/yaml_dumper.pbc \
     $(LIBRARY_DIR)/Getopt/Obj.pbc \
+    $(LIBRARY_DIR)/Iter.pbc \
     $(LIBRARY_DIR)/JSON.pbc \
     $(LIBRARY_DIR)/Math/Random/mt19937ar.pbc \
     $(LIBRARY_DIR)/Math/Rand.pbc \
@@ -260,8 +261,10 @@
     $(LIBRARY_DIR)/NCI/call_toolkit_init.pbc \
     $(LIBRARY_DIR)/ncurses.pbc \
 #IF(has_opengl):    $(LIBRARY_DIR)/OpenGL.pbc \
+#IF(has_opengl):    $(LIBRARY_DIR)/OpenGL_funcs.pbc \
     $(LIBRARY_DIR)/P6object.pbc \
     $(LIBRARY_DIR)/parrotlib.pbc \
+    $(LIBRARY_DIR)/pcore.pbc \
     $(LIBRARY_DIR)/pcre.pbc \
     $(LIBRARY_DIR)/Parrot/Coroutine.pbc \
     $(LIBRARY_DIR)/Parrot/Exception.pbc \
@@ -271,6 +274,7 @@
     $(LIBRARY_DIR)/PGE/Text.pbc \
     $(LIBRARY_DIR)/PGE/Util.pbc \
     $(LIBRARY_DIR)/Protoobject.pbc \
+    $(LIBRARY_DIR)/Range.pbc \
     $(LIBRARY_DIR)/Stream/Base.pbc \
     $(LIBRARY_DIR)/Stream/Combiner.pbc \
     $(LIBRARY_DIR)/Stream/Coroutine.pbc \
@@ -289,7 +293,11 @@
     $(LIBRARY_DIR)/Test/Class.pbc \
     $(LIBRARY_DIR)/Test/More.pbc \
     $(LIBRARY_DIR)/Tcl/Glob.pbc \
+    $(LIBRARY_DIR)/TclLibrary.pbc \
     $(LIBRARY_DIR)/uuid.pbc \
+    $(LIBRARY_DIR)/YAML/Dumper/Base.pbc \
+    $(LIBRARY_DIR)/YAML/Dumper/Default.pbc \
+    $(LIBRARY_DIR)/YAML/Dumper.pbc \
     $(LIBRARY_DIR)/YAML/Parser/Syck.pbc \
     $(LIBRARY_DIR)/STM.pbc \
     $(LIBRARY_DIR)/libpcre.pbc \
@@ -834,20 +842,22 @@
 
 $(SRC_DIR)/install_config$(O) : $(SRC_DIR)/install_config.c
 
-$(SRC_DIR)/null_config$(O) : $(SRC_DIR)/null_config.c
+$(SRC_DIR)/null_config$(O) : $(INC_DIR)/parrot.h $(SRC_DIR)/null_config.c
 
-$(SRC_DIR)/oo$(O) : $(SRC_DIR)/pmc/class.c $(INC_DIR)/pbcversion.h
+$(SRC_DIR)/oo$(O) : $(INC_DIR)/parrot.h $(SRC_DIR)/pmc/class.c $(INC_DIR)/pbcversion.h
 
-$(SRC_DIR)/scheduler$(O) : $(SRC_DIR)/scheduler.str   \
+$(SRC_DIR)/scheduler$(O) : $(INC_DIR)/parrot.h \
+                           $(SRC_DIR)/scheduler.str   \
                            $(SRC_DIR)/pmc/scheduler.c \
                            $(SRC_DIR)/pmc/task.c      \
                            $(SRC_DIR)/pmc/timer.c     \
                            $(INC_DIR)/pbcversion.h
 
-$(IO_DIR)/socket_api$(O) : $(SRC_DIR)/pmc/socket.c
-$(IO_DIR)/socket_unix$(O) : $(INC_DIR)/pbcversion.h   \
+$(IO_DIR)/core$(O) : $(INC_DIR)/parrot.h $(SRC_DIR)/pmc/socket.c
+$(IO_DIR)/socket_api$(O) : $(INC_DIR)/parrot.h $(SRC_DIR)/pmc/socket.c
+$(IO_DIR)/socket_unix$(O) : $(INC_DIR)/parrot.h $(INC_DIR)/pbcversion.h   \
                             $(SRC_DIR)/pmc/socket.c
-$(IO_DIR)/socket_win32$(O) : $(INC_DIR)/pbcversion.h   \
+$(IO_DIR)/socket_win32$(O) : $(INC_DIR)/parrot.h $(INC_DIR)/pbcversion.h   \
                             $(SRC_DIR)/pmc/socket.c
 
 lib_deps_object : $(O_FILES)
@@ -934,7 +944,7 @@
 #
 # Parrot Dump
 #
-$(SRC_DIR)/packdump$(O) : $(SRC_DIR)/pmc/pmc_sub.h $(SRC_DIR)/pmc/pmc_key.h
+$(SRC_DIR)/packdump$(O) : $(INC_DIR)/parrot.h $(SRC_DIR)/pmc/pmc_sub.h $(SRC_DIR)/pmc/pmc_key.h
 
 $(PDUMP) : $(SRC_DIR)/pbc_dump$(O) $(SRC_DIR)/packdump$(O) $(LIBPARROT)
 	$(LINK) @ld_out@$@ \
@@ -942,7 +952,7 @@
     $(SRC_DIR)/packdump$(O) @rpath_blib@ $(ALL_PARROT_LIBS) $(LINKFLAGS)
 #IF(win32):	if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;1
 
-$(SRC_DIR)/pbc_dump$(O) : $(GEN_HEADERS)
+$(SRC_DIR)/pbc_dump$(O) : $(INC_DIR)/parrot.h $(GEN_HEADERS)
 
 $(INSTALLABLEPDUMP) : $(SRC_DIR)/pbc_dump$(O) $(SRC_DIR)/packdump$(O) $(LIBPARROT)
 	$(LINK) @ld_out@$@ \
@@ -959,7 +969,7 @@
     @rpath_blib@ $(ALL_PARROT_LIBS) $(LINKFLAGS)
 #IF(win32):	if exist $@.manifest mt.exe -nologo -manifest $@.manifest -outputresource:$@;1
 
-$(SRC_DIR)/pbc_info$(O) : $(GEN_HEADERS)
+$(SRC_DIR)/pbc_info$(O) : $(INC_DIR)/parrot.h $(GEN_HEADERS)
 
 $(INSTALLABLEPINFO) : $(SRC_DIR)/pbc_info$(O) $(LIBPARROT)
 	$(LINK) @ld_out@$@ \
@@ -1033,6 +1043,12 @@
 #
 ###############################################################################
 
+$(SRC_DIR)/byteorder$(O) : $(INC_DIR)/parrot.h
+
+$(SRC_DIR)/datatypes$(O) : $(INC_DIR)/parrot.h
+
+$(SRC_DIR)/extend_vtable$(O) : $(INC_DIR)/parrot.h
+
 $(SRC_DIR)/global_setup$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/global_setup.str
 
 $(SRC_DIR)/global$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/global.str \
@@ -1048,7 +1064,7 @@
 
 $(SRC_DIR)/library$(O) : $(GENERAL_H_FILES)
 
-$(SRC_DIR)/jit$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/jit_emit.h $(SRC_DIR)/pmc/pmc_sub.h
+$(SRC_DIR)/jit$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/jit_emit.h $(SRC_DIR)/pmc/pmc_sub.h $(SRC_DIR)/pmc/pmc_managedstruct.h
 
 $(SRC_DIR)/jit_debug$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/debug.str
 
@@ -1221,7 +1237,7 @@
 $(SRC_DIR)/pbc_merge$(O) : $(SRC_DIR)/pbc_merge.c $(GENERAL_H_FILES) \
 	$(SRC_DIR)/pmc/pmc_sub.h
 
-$(IO_DIR)/filehandle$(O) : $(SRC_DIR)/pmc/pmc_filehandle.h $(SRC_DIR)/io/io_private.h
+$(IO_DIR)/filehandle$(O) : $(INC_DIR)/parrot.h $(SRC_DIR)/pmc/pmc_filehandle.h $(SRC_DIR)/io/io_private.h
 
 $(OPS_DIR)/core_ops$(O) : $(GENERAL_H_FILES) $(OPS_DIR)/core_ops.c \
 	$(SRC_DIR)/pmc/pmc_continuation.h $(SRC_DIR)/pmc/pmc_parrotlibrary.h
@@ -1352,10 +1368,10 @@
 dynpmc : dynpmc.dummy
 
 # XXX this dependancy is too broad, and should be narrowed down
-dynpmc.dummy : $(PARROT)
+dynpmc.dummy : $(PARROT) $(INC_DIR)/parrot.h $(INC_DIR)/extend.h $(INC_DIR)/dynext.h
 	$(MAKE) src/dynpmc
 
-dynpmc-test :
+dynpmc-test : $(PARROT) $(INC_DIR)/parrot.h $(INC_DIR)/extend.h $(INC_DIR)/dynext.h
 	$(MAKE) src/dynpmc test
 
 dynpmc-clean :
@@ -1370,10 +1386,10 @@
 dynoplibs : dynoplibs.dummy
 
 # XXX this dependancy is too broad, and should be narrowed down
-dynoplibs.dummy : $(PARROT)
+dynoplibs.dummy : $(PARROT) $(INC_DIR)/dynext.h
 	$(MAKE) src/dynoplibs
 
-dynoplibs-test :
+dynoplibs-test : $(PARROT) $(INC_DIR)/dynext.h
 	$(MAKE) src/dynoplibs test
 
 dynoplibs-clean :
@@ -1948,22 +1964,27 @@
     -skip-posix-headers \
     \
     +ansi89-limits \
+    +num-struct-fields 255 \
     \
     -show-summary \
     +show-scan \
-    +time-dist
-
-# Watch for naming conflicts, but don't complain about str*() functions
-SPLINTFLAGS := $(SPLINTFLAGS) \
+    +time-dist \
+    \
     +ansi-reserved \
     +ansi-reserved-internal \
     -iso-reserved \
-    -iso-reserved-internal
+    -iso-reserved-internal \
+    -include-nest 10
 
 # Memory safety checks
 SPLINTFLAGS := $(SPLINTFLAGS) \
     +bufferoverflow \
     +bufferoverflowhigh \
+    +read-only-strings \
+    +read-only-trans \
+    +strict-destroy \
+    +strict-use-released \
+    +use-released \
 
 # Macro safety checks
 SPLINTFLAGS := $(SPLINTFLAGS) \
@@ -1988,90 +2009,62 @@
     -pred-bool-others \
     -boolops \
 
+# Report qualifier mismatches only if dangerous
+SPLINTFLAGS := $(SPLINTFLAGS) \
+    +relax-quals
+
 # Pointer arithmetic is OK, but watch for null pointers
 SPLINTFLAGS := $(SPLINTFLAGS) \
     -ptr-arith \
     +nullptrarith \
-    +ptr-negate
+    +ptr-negate \
+    -zero-ptr
 
-# Check on consistency of defs
+# Symbol definitions
 SPLINTFLAGS := $(SPLINTFLAGS) \
+    +decl-undef \
     +incon-defs \
     +incon-defs-lib \
 
-# The rest of the flags to be organized.
+# Check for conflicts with C++ compilers
 SPLINTFLAGS := $(SPLINTFLAGS) \
-    +char-index \
     +cpp-names \
-    +decl-undef \
+
+# Format codes
+SPLINTFLAGS := $(SPLINTFLAGS) \
+    +format-code \
+    +format-type \
+
+# Problems with evaluation and control structions
+SPLINTFLAGS := $(SPLINTFLAGS) \
+    +controlnestdepth 15 \
     +duplicate-case \
-    +enum-members \
     +eval-order \
     +eval-order-uncon \
-    +format-code \
-    +format-type \
+
+# Types and stuff
+SPLINTFLAGS := $(SPLINTFLAGS) \
+    +char-index \
+    +char-int \
+    +enum-members \
     +ignore-signs \
-    +match-fields \
-    +null \
-    +nullret \
-    +strict-destroy \
-    \
-    +use-released \
-    +strict-use-released \
-    -abstract \
+    +long-integral \
+    +match-any-integral \
+
+# TODO: Miscellaneous other flags
+SPLINTFLAGS := $(SPLINTFLAGS) \
     +aliasunique \
     +assignexpose \
-    -casebreak \
-    -castfcnptr \
-    -charint \
     +continuecomment \
-    +controlnestdepth 15 \
-    -exportlocal \
-    -fcnuse \
     +fielduse \
-    -globs \
-    +imptype \
-    -initallelements \
-    +longintegral \
-    +matchanyintegral \
+    +match-fields \
     +nestedextern \
-    -noeffect \
-    -paramuse \
-    +ptrnegate \
-    +readonlystrings \
-    -redef \
-    -retvalint \
-    -retvalother \
+    +null \
+    +nullret \
+    +paramuse \
     +shadow \
-    -shiftimplementation \
-    -shiftnegative \
-    -showsourceloc \
-    -type \
-    \
-    -branchstate \
-    -compdef \
-    -compdestroy \
-    -compmempass \
-    -globstate \
-    -mustfreefresh \
-    -mustfreeonly \
-    -nullstate \
-    -redecl \
-    -retalias \
-    \
-    -immediatetrans \
-    -kepttrans \
-    -observertrans \
-    -onlytrans \
-    -readonlytrans \
-    -statictrans \
-    -temptrans \
-    -unqualifiedtrans \
-
 
 # Other options we'd like to add back
-# +paramuse: As soon as we get SHIM()s in the ops
-# -includedepth 8 : Let's investigate why we do so many includes.
 # +initallelements : Right now, the *.ops files don't initialize all
 #  values of the arrays
 # +casebreak: Auto-generated ops have way too case fallthrus right now
@@ -2083,19 +2076,17 @@
 # added to splint target to simplify experimentation,
 # ex: make SPLINTFLAGS_TEST='-posixstrictlib +posixlib' splint
 
-# Don't complain about using pointers and ints as booleans
-SPLINTFLAGS_TEST := $(SPLINTFLAGS_TEST) -pred-bool
-
 splint : $(PARROT)
 	$(MKPATH) $(SPLINT_TMP)
 	$(SPLINT) $(CC_INC) @cc_hasjit@ "-Isrc/pmc" "-Icompilers/ast" $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) `echo $(O_FILES) | $(PERL) -pe @PQ at s/\.o/\.c/g at PQ@`
 	$(SPLINT) $(CC_INC) $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) $(IMCC_DIR)/main.c
 
+# Test a single file with limited splint options to ease cleanup -petdance
 splint-andy :
 	$(MKPATH) $(SPLINT_TMP)
 	splint $(CC_INC) @cc_hasjit@ -DNDEBUG "-Isrc/pmc" "-Icompilers/ast" $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) \
 	+partial -memchecks \
-	src/s*.c \
+	src/packfile.c \
     | grep -v 'Source code error generation point'
 
 COVER_FLAGS := -fprofile-arcs -ftest-coverage

Modified: branches/pmc_pct/config/gen/parrot_include.pm
==============================================================================
--- branches/pmc_pct/config/gen/parrot_include.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/config/gen/parrot_include.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -38,11 +38,11 @@
         include/parrot/longopt.h
         include/parrot/multidispatch.h
         include/parrot/packfile.h
-        include/parrot/resources.h
         include/parrot/stat.h
         include/parrot/string.h
         include/parrot/pmc.h
         include/parrot/warnings.h
+        include/parrot/gc_api.h
         src/pmc/timer.pmc
         src/utils.c
     ) ];

Modified: branches/pmc_pct/config/gen/platform/generic/itimer.c
==============================================================================
--- branches/pmc_pct/config/gen/platform/generic/itimer.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/config/gen/platform/generic/itimer.c	Fri May 15 21:49:40 2009	(r38803)
@@ -1,6 +1,6 @@
 /*
  * $Id$
- * Copyright (C) 2004-2006, Parrot Foundation.
+ * Copyright (C) 2004-2009, Parrot Foundation.
  */
 
 /*
@@ -98,7 +98,7 @@
 void *
 new_sys_timer_ms(void)
 {
-    return 0;
+    return NULL;
 }
 
 #else

Modified: branches/pmc_pct/docs/book/ch03_pir.pod
==============================================================================
--- branches/pmc_pct/docs/book/ch03_pir.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/book/ch03_pir.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -5,37 +5,42 @@
 Z<CHP-3>
 
 X<Parrot Intermediate Representation;;(see PIR)>
-X<PIR (Parrot intermediate representation)>
+X<PIR>
 
 Parrot Intermediate Representation (PIR) is Parrot's native low-level
-language.N<Parrot has a pure native assembly language called PASM, described in
-Chapter 9.> PIR is fundamentally an assembly language, but it has some
-higher-level features such as operator syntax, syntactic sugar for subroutine
-and method calls, automatic register allocation, and more friendly conditional
-syntax.  PIR is commonly used to write Parrot libraries -- including some of
-PCT's compilers -- and is the target form when compiling high-level languages
-to Parrot.
-
-Even so, PIR is more rigid and "close to the machine" then some higher-level
-languages like C. X<.pir files> Files containing PIR code use the F<.pir>
-extension.
+language.N<Parrot also has a pure native assembly language called PASM,
+described in Chapter 9.> PIR is fundamentally an assembly language, but
+it has some higher-level features such as operator syntax, syntactic
+sugar for subroutine and method calls, automatic register allocation,
+and more friendly conditional syntax.  PIR is commonly used to write
+Parrot libraries -- including some of Parrot's compilers -- and is the
+target form when compiling high-level languages to Parrot.  Even so, PIR
+is more rigid and "close to the machine" then some higher-level
+languages like C. X<.pir files> Files containing PIR code use the
+F<.pir> extension.
 
-=head2 Basics
+=head2 Basic Syntax
 
 PIR has a relatively simple syntax. Every line is a comment, a label, a
-statement, or a directive. Each statement or directive stands on its own line.
-There is no end-of-line symbol (such as a semicolon in other languages).
+statement, or a directive. There is no end-of-line symbol (such as a
+semicolon in C), the end of the line is the end of the statement or
+directive.
 
 =head3 Comments
 
-X<PIR comments>
+X<PIR (Parrot intermediate representation); comments>
+X<comments (PIR)>
 A comment begins with the C<#> symbol, and continues until the end of the line.
 Comments can stand alone on a line or follow a statement or directive.
 
+=begin PIR
+
     # This is a regular comment. The PIR
     # interpreter ignores this.
 
-X<PIR POD>
+=end PIR
+
+X<Pod documentation>
 PIR also treats inline documentation in Pod format as a comment. An
 equals sign as the first character of a line marks the start of a Pod
 block.  A C<=cut> marker signals the end of a Pod block.
@@ -47,21 +52,32 @@
 
   =cut
 
-=head2 Labels
+=head3 Labels
 
 Z<CHP-3-SECT-4>
 
 X<PIR (Parrot intermediate representation);labels> X<labels (PIR)> A label
-attaches to a line of code so other statements can refer to it.  Labels can
-contain letters, numbers, and underscores. By convention, labels use all
-capital letters to stand out from the rest of the source code. A label can be
-precede a line of code, though outdenting labels on separate lines improves
-readability:
+attaches a name to a line of code so other statements can refer to it.
+Labels can contain letters, numbers, and underscores. By convention,
+labels use all capital letters to stand out from the rest of the source
+code. It's fine to put a label on the same line as a statement or
+directive:
+
+=begin PIR_FRAGMENT
+
+    GREET: print "'Allo, 'allo, 'allo."
+
+=end PIR_FRAGMENT
+
+Readability is improved by putting labels on separate lines, outdented
+to stand apart from the ordiary code flow:
+
+=begin PIR_FRAGMENT
 
   GREET:
-      say "'Allo, 'allo, 'allo."
+    print "'Allo, 'allo, 'allo."
 
-Labels are vital to control flow.
+=end PIR_FRAGMENT
 
 =head3 Statements
 
@@ -73,99 +89,393 @@
 opcode is a native instruction for the virtual machine; it consists of the name
 of the instruction followed by zero or more arguments.
 
-  say "Norwegian Blue"
+=begin PIR_FRAGMENT
+
+  print "Norwegian Blue"
+
+=end PIR_FRAGMENT
 
 PIR also provides higher-level constructs, including symbol operators:
 
+=begin PIR_FRAGMENT
+
   $I1 = 2 + 5
 
+=end PIR_FRAGMENT
+
 Under the hood, these special statement forms are just syntactic sugar for
 regular opcodes. The C<+> symbol corresponds to the C<add> opcode, the C<->
-symbol to the C<sub> opcode, and so on.  The previous example is equivalent to:
+symbol to the C<sub> opcode, and so on. The previous example is equivalent to:
+
+=begin PIR_FRAGMENT
 
   add $I1, 2, 5
 
+=end PIR_FRAGMENT
+
 =head3 Directives
 
-Directives begin with a period (C<.>); Parrot's parser handles them specially.
-the parser. Some directives specify actions that occur at compile time. Other
-directives represent complex operations that require the generation of multiple
-instructions.  The C<.local> directive declares a typed register.
+Directives look similar to opcodes, but they begin with a period (C<.>).
+Parrot's parser handles them specially. Some directives specify actions
+that occur at compile time. Other directives represent complex
+operations that require the generation of multiple instructions.  The
+C<.local> directive, for example, declares a named variable.
+
+=begin PIR_FRAGMENT
 
   .local string hello
 
-PIR also has a macro facility to create user-defined directives.
+=end PIR_FRAGMENT
 
 =head3 Literals
 
 Integers and floating point numbers are numeric literals. They can be positive
 or negative.
 
+=begin PIR_FRAGMENT
+
   $I0 = 42       # positive
   $I1 = -1       # negative
 
-Integer literals can also be binary, octal, or hexadecimal:
+=end PIR_FRAGMENT
+
+Integer literals can also be binary or hexadecimal:
+
+=begin PIR_FRAGMENT
 
   $I3 = 0b01010  # binary
-  $I3 = 0o78     # octal
   $I2 = 0xA5     # hexadecimal
 
+=end PIR_FRAGMENT
+
 Floating point number literals have a decimal point, and can use scientific
 notation:
 
+=begin PIR_FRAGMENT
+
   $N0 = 3.14
   $N2 = -1.2e+4
 
+=end PIR_FRAGMENT
+
 X<strings;in PIR>
 String literals are enclosed in single or double-quotes.N<L<Strings>
 explains the differences between the quoting types.>
 
+=begin PIR_FRAGMENT
+
   $S0 = "This is a valid literal string"
   $S1 = 'This is also a valid literal string'
 
+=end PIR_FRAGMENT
+
 =head3 Variables
 
-PIR variables can store four different kinds of valuesE<mdash>integers, numbers
-(floating point), strings, and objects. The simplest way to work with these
-values is through register variables. Register variables always start with a
-dollar sign (C<$>) and a single character which specifies the type of the
-register: integer (C<I>), number (C<N>), string (C<S>), or PMC (C<P>).
-Registers have numbers as well; the "first" string register is C<$S0>.
-N<Register numbers may or may not correspond to the register used internally;
-Parrot's compiler remaps registers as appropriate.>
+PIR variables can store four different kinds of valuesE<mdash>integers,
+numbers (floating point), strings, and objects. Parrot's objects are
+called PMCs, for "I<P>olyI<M>orphic I<C>ontainer".
+
+The simplest kind of variable is a register variable. The name of a
+register variable always starts with a dollar sign (C<$>), followed by a
+single character which specifies the type of the variableE<mdash>integer
+(C<I>), number (C<N>), string (C<S>), or PMC (C<P>)E<mdash>, and end
+with a unique number. Register variables don't need to be predeclared:
+
+=begin PIR_FRAGMENT
 
   $S0 = "Who's a pretty boy, then?"
-  say $S0
+  print $S0
+
+=end PIR_FRAGMENT
 
-PIR also has named variables, which are declared with the C<.local> directive.
-As with registers, there are four valid types for named variables: C<int>,
-C<num>, C<string>, and C<pmc>.N<Again, for "I<P>olyI<M>orphic I<C>ontainer".>
-After declaring a named variable, you can use the name anywhere you would use a
-register:
+PIR also has named variables, which are declared with the C<.local>
+directive. As with register variables, there are four valid types:
+C<int>, C<num>, C<string>, and C<pmc>. Named variables have to be
+declared, but otherwise behave exactly the same as register variables.
+
+=begin PIR_FRAGMENT
 
   .local string hello
-  set hello, "'Allo, 'allo, 'allo."
-  say hello
+  hello = "'Allo, 'allo, 'allo."
+  print hello
 
-Integer (C<I>) and Number (C<N>) registers use platform-dependent sizes and
-limitationsN<There are a few exceptions to this; Parrot smooths out some of the
-bumps and inconsistencies so that PIR code behaves the same way on all
-supported platforms>. Internally, Parrot treats both I and N registers as
-signed quantities internally for the purposes of arithmetic. Parrot's floating
-point values and operations all comply with the IEEE 754 standard.
+=end PIR_FRAGMENT
 
-Strings (S) are buffers of variable-sized data. The most common use of S
-registers and variables is to store textual data. S registers I<may> also be
-buffers for binary or other non-textual data, though this is rareN<In general,
-a custom PMC is mroe useful>.  Parrot strings are flexible and powerful, to
-account for all the complexity of human-readable (and computer-representable)
-textual data.
+=head3 Constants
+
+X<PIR (Parrot intermediate representation);constants>
+X<constants (PIR)>
+
+The C<.const> directive declares a named constant. Named constants are
+similar to named variables, but their values are set in the declaration
+and can never be changed. Like C<.local>, C<.const> takes a type and a
+name. It also requires a literal argument to set the value of the
+constant.
+
+=begin PIR_FRAGMENT
+
+  .const int    frog = 4                       # integer constant
+  .const string name = "Superintendent Parrot" # string constant
+  .const num    pi   = 3.14159                 # floating point constant
+
+=end PIR_FRAGMENT
+
+Named constants may be used in all the same places as literals, but have
+to be declared beforehand. The following example declares a named string
+constant C<hello> and prints the value:
+
+=begin PIR_FRAGMENT
+
+  .const string hello = "Hello, Polly."
+  print hello
+
+=end PIR_FRAGMENT
+
+=head3 Control Structures
+
+Rather than providing a pre-packaged set of control structures like
+C<if> and C<while>, PIR gives you the building blocks to construct your
+own.N<PIR has many advanced features, but at heart it B<is> an assembly
+language.> The most basic of these building blocks is C<goto>, which
+jumps to a named label.N<This is not your father's C<goto>. It can only
+jump inside a subroutine, and only to a named label.> In the following
+code example, the C<print> statement will run immediately after the
+C<goto> statement:
+
+=begin PIR_FRAGMENT
+
+    goto GREET
+    # ... some skipped code ...
+
+  GREET:
+    print "'Allo, 'allo, 'allo."
+
+=end PIR_FRAGMENT
+
+Variations on the basic C<goto> check whether a particular condition is
+true or false before jumping:
+
+=begin PIR_FRAGMENT
+
+  if $I0 > 5 goto GREET
+
+=end PIR_FRAGMENT
+
+All of the traditional control structures can be constructed from PIR's
+control building blocks.
+
+=head3 Subroutines
+
+A PIR subroutine starts with the C<.sub> directive and ends with the
+C<.end> directive. Parameter declarations use the C<.param> directive,
+and look a lot like named variable declarations. The following example
+declares a subroutined named C<greeting>, that takes a single string
+parameter named C<hello>:
+
+=begin PIR
+
+  .sub greeting
+      .param string hello
+      print hello
+  .end
+
+=end PIR
+
+=head3 That's All Folks
+
+You now know everything you need to know about PIR. Everything else you
+read or learn about PIR will use one of these fundamental language
+structures. The rest is vocabulary.
+
+=head2 Working with Variables
 
-The final data type is the PMC. PMC resemble classes and objects are in
-object-oriented languages. They are the basis for complex data structures and
-object-oriented behavior in Parrot.
+We call the simple C<$I0>-style variables "register variables" for a
+specific reason: Parrot is a register-based virtual machine. It has 4
+typed register sets: integers, floating-point numbers, strings, and
+objects. When you're working with register variables or named variables,
+you're actually working directly with register storage locations in the
+virtual machine.
 
-=head2 Strings
+If you've ever worked with an assembly language before, you may
+immediately jump to the conclusion that C<$I0> is the zeroth integer
+register, but Parrot is a bit smarter than that. The number of a
+register variable usually does not correspond to the register used
+internally; Parrot's compiler maps registers as appropriate for speed
+and memory considerations. The only guarantee Parrot gives you is that
+you'll always get the same storage location when you use C<$I0> in the
+same subroutine.
+
+The most basic operation on a variable is assignment using the C<=>
+operator:
+
+=begin PIR_FRAGMENT
+
+  $I0 = 42        # set integer variable to the value 42
+  $N3 = 3.14159   # set number variable to an approximation of pi
+  $I1 = $I0       # set $I1 to the value of $I0
+
+=end PIR_FRAGMENT
+
+The C<exchange> opcode swaps the contents of two variables of the same
+type. The following example sets C<$I0> to the value of C<$I1>, and sets
+C<$I1> to the value of C<$I0>. 
+
+=begin PIR_FRAGMENT
+
+  exchange $I0, $I1
+
+=end PIR_FRAGMENT
+
+The C<null> opcode sets an integer or number variable to a zero value,
+and undefines a string or object.
+
+=begin PIR_FRAGMENT
+
+  null $I0  # 0
+  null $N0  # 0.0
+  null $S0  # NULL
+  null $P0  # PMCNULL
+
+=end PIR_FRAGMENT
+
+=head2 Working with Numbers
+
+X<PIR (Parrot assembly language);math operations>
+PIR has an extensive set of math instructions that work with integers,
+floating-point numbers, and numeric PMCs. Many of the math instructions
+have two- and three-argument forms:
+
+=begin PIR_FRAGMENT
+
+  $I10 = $I11 + $I2
+  $I0 += $I1
+
+=end PIR_FRAGMENT
+
+The three-argument form of C<+> stores the sum
+of the two arguments in the result variable. The two-argument form
+adds the first variable to the second and stores the result back in
+the first variable.
+
+The arguments can be Parrot variables or constants, but they
+must be compatible with the type of the result.
+Generally, "compatible" means that the result and arguments have to
+be the same type, but there are a few exceptions:
+
+=begin PIR_FRAGMENT
+
+  $P0 = $P1 - 2
+  $P0 = $P1 - 1.5
+
+=end PIR_FRAGMENT
+
+If the result is an integer type, like C<$I0>, the arguments must be
+integer variables or constants. A
+floating-point result, like C<$N0>, usually requires
+floating-point arguments, but many math instructions also allow the final
+argument to be an integer. Instructions with a PMC result may
+accept an integer, floating-point, or PMC final argument:
+
+=begin PIR_FRAGMENT
+
+  mul $P0, $P1             # $P0 *= $P1
+  mul $P0, $I1
+  mul $P0, $N1
+  mul $P0, $P1, $P2        # $P0 = $P1 * $P2
+  mul $P0, $P1, $I2
+  mul $P0, $P1, $N2
+
+=end PIR_FRAGMENT
+
+
+
+We won't list every math opcode here, but we'll list some of the most common
+ones. You can get a complete list in "PIR Opcodes" in Chapter 11.
+
+=head4 Unary math opcodes
+
+Z<CHP-9-SECT-2.3.1>
+
+The unary opcodes have either a destination argument and a source
+argument, or a single argument as destination and source. Some of the
+most common unary math opcodes are C<inc> (increment), C<dec>
+(decrement), C<abs> (absolute value), C<neg> (negate), and C<fact>
+(factorial):
+
+=begin PIR_FRAGMENT
+
+  abs $N0, -5.0  # the absolute value of -5.0 is 5.0
+  fact $I1, 5    # the factorial of 5 is 120
+  inc $I1        # 120 incremented by 1 is 121
+
+=end PIR_FRAGMENT
+
+=head4 Binary math opcodes
+
+Z<CHP-9-SECT-2.3.2>
+
+X<PIR (Parrot assembly language);math operations;binary>
+Binary opcodes have two source arguments and a destination argument, and we
+saw examples of these types above. As we mentioned before, most binary math
+opcodes have a two-argument form in which the first argument is both a source
+and the destination. Parrot provides C<add>X<add opcode (PIR)> (addition),
+C<sub>X<sub opcode (PIR)> (subtraction), C<mul>X<mul opcode (PIR)>
+(multiplication), C<div>X<div opcode (PIR)> (division), and C<pow>X<pow
+opcode (PIR)> (exponent) opcodes, as well as two different modulus
+operations. C<mod>X<mod opcode (PIR)> is Parrot's implementation of modulus,
+and C<cmod>X<cmod opcode (PIR)> performs an operation equivalent the C<%>
+operator from the C programming language. It also provides C<gcd>X<gcd opcode
+(PIR)> (greatest common divisor) and C<lcm>X<lcm opcode (PIR)> (least common
+multiple).
+
+=begin PIR_FRAGMENT
+
+  div $I0, 12, 5   # $I0 = 12 / 5
+  mod $I0, 12, 5   # $I0 = 12 % 5
+
+=end PIR_FRAGMENT
+
+=head4 Floating-point operations
+
+Z<CHP-9-SECT-2.3.3>
+
+X<PIR (Parrot assembly language);math operations;floating-point>
+Although most of the math operations work with both floating-point numbers
+and integers, a few require floating-point destination registers. Among these
+are C<ln> (natural log), C<log2> (log base 2), C<log10> (log base 10), and
+C<exp> (I<e>G<x>), as well as a full set of trigonometric opcodes such as
+C<sin> (sine), C<cos> (cosine), C<tan> (tangent), C<sec> (secant), C<cosh>
+(hyperbolic cosine), C<tanh> (hyperbolic tangent), C<sech> (hyperbolic secant),
+C<asin> (arc sine), C<acos> (arc cosine), C<atan> (arc tangent), C<asec> (arc
+secant), C<exsec> (exsecant), C<hav> (haversine), and C<vers> (versine). All
+angle arguments for the X<trigonometric functions (PIR)> trigonometric
+functions are in radians:
+
+=begin PIR_FRAGMENT
+
+  sin $N1, $N0
+  exp $N1, 2
+
+=end PIR_FRAGMENT
+
+The majority of the floating-point operations have a single source argument
+and a single destination argument. Even though the destination must be a
+floating-point register, the source can be either an integer or floating-point
+number.
+
+The C<atan>X<atan opcode (PIR)> opcode also has a three-argument variant that
+implements C's C<atan2()>:
+
+=begin PIR_FRAGMENT
+
+  atan $N0, 1, 1
+
+=end PIR_FRAGMENT
+
+
+
+
+=head2 Working with Strings
 
 Strings in double-quotes accept all sorts of escape sequences using
 backslashes. Strings in single-quotes only allow escapes for nested
@@ -206,1760 +516,3756 @@
 
   End_Token
 
-=head3 Strings: Encodings and Charsets
+=head3 Assignment
 
-X<charset>
-Strings are complicated; string declarations aren't the whole story.  In olden
-times, strings only needed to support the ASCII character set (or charset), a
-mapping of 128 bit patterns to symbols and English-language characters. This
-worked as long as everyone using a computer read and wrote English and used a
-small handful of punctuation symbols.
+Strings in Parrot are also stored as references to internal data structures
+like PMCs. However, strings use Copy-On-Write (COW) optimizations. When we
+call C<set S1, S0> we copy the pointer only, so both registers point to the
+same string memory. We don't actually make a copy of the string until one of
+two registers is modified. Here's the same example using string registers
+instead of PMC registers, which demonstrate how strings use COW:
+
+=begin PASM
+
+  set S0, "Ford"
+  set S1, S0
+  set S1, "Zaphod"
+  print S0                # prints "Ford"
+  print S1                # prints "Zaphod"
+  end
+
+=end PASM
+
+Here, we can clearly see the opposite result from how PMCs were handled in
+the previous example. Modifying one of the two registers causes a new string
+to be created, preserving the old value in C<S0> and assigning the new value
+to the new string in C<S1>. The benefits here are that we don't have to worry
+about stray references causing side effects in our code, and we don't waste
+time copying a string until it's actually time to make a copy.
 
-In other words, it was woefully insufficient for international uses, polyglots, and more.
 
-A modern string system must manage several character encodings and charsets in
-order to make sense out of all the string data in the world.  Parrot does this.
-Every string has an associated encoding and an associated character set.  The
-default charset is 8-bit ASCII, which is simple to use and is almost
-universally supported.
+Strings are buffers of variable-sized data. The most common use of string
+registers and variables is to store textual data. String registers I<may> also be
+buffers for binary or other non-textual data, though this is rareN<In general,
+a custom PMC is more useful>.  Parrot strings are flexible and powerful, to
+account for all the complexity of human-readable (and computer-representable)
+textual data.
 
-Double-quoted string constants can have an optional prefix specifying the the
-string's encoding and charsetN<As you might suspect, single-quoted strings do
-not support this.>. Parrot will maintain these values internally, and will
-automatically convert strings when necessary to preserve the information.
-String prefixes are specified as C<encoding:charset:> at the front of the
-string. Here are some examples:
+X<PIR (Parrot assembly language);string operations>
+String operations work with string registers and string-like PMCs.
+String operations on PMC registers require all their string
+arguments to be String PMCs.
 
-  $S0 = utf8:unicode:"Hello UTF8 Unicode World!"
-  $S1 = utf16:unicode:"Hello UTF16 Unicode World!"
-  $S2 = ascii:"This is 8-bit ASCII"
-  $S3 = binary:"This is raw, unformatted binary data"
+=head4 Concatenating strings
 
-The C<binary:> charset treats the string as a buffer of raw unformatted binary
-data. It isn't really a string per se, because binary data contains no readable
-characters.  As mentioned earlier, this exists to support libraries which
-manipulate binary data that doesn't easily fit into any other primitive data
-type.
+Z<CHP-9-SECT-2.4.1>
 
-When Parrot combines two strings (such as through concatenation), they must
-both use the same character set and encoding.  Parrot will automatically
-upgrade one or both of the strings to use the next highest compatible format as
-necessary. ASCII strings will automatically upgrade to UTF-8 strings if needed,
-and UTF-8 will upgrade to UTF-16. All of these conversions happen inside
-Parrot; you the programmer don't need to worry about the details.
+X<PIR (Parrot assembly language);string operations;concatenation>
+Use the C<concat>X<concat opcode (PIR)> opcode to concatenate
+strings. With string register or string constant arguments, C<concat>
+has both a two-argument and a three-argument form. The first argument
+is a source and a destination in the two-argument form:
 
-=head2 Named Variables
+=begin PIR_FRAGMENT
 
-Z<CHP-3-SECT-2.3>
+  set $S0, "ab"
+  concat $S0, "cd"     # S0 has "cd" appended
+  print $S0            # prints "abcd"
+  print "\n"
 
-X<named variables (PIR)>
-X<PIR (Parrot intermediate representation);named variables>
+  concat $S1, $S0, "xy" # S1 is the string S0 with "xy" appended
+  print $S1            # prints "abcdxy"
+  print "\n"
 
-=for author
+=end PIR_FRAGMENT
 
-The declaration section earlier alludes to this.
+The first C<concat> concatenates the string "cd" onto the string "ab" in
+C<S0>. It generates a new string "abcd" and changes C<S0> to point to the
+new string. The second C<concat> concatenates "xy" onto the string "abcd"
+in C<S0> and stores the new string in C<S1>.
 
-=end for
+X<PMCs (Polymorphic Containers);concatenation>
+For PMC registers, C<concat> has only a three-argument form with
+separate registers for source and destination:
 
-Calling a value "$S0" isn't very descriptive, and usually it's a lot
-nicer to be able to refer to values using a helpful name. For this
-reason Parrot allows registers to be given temporary variable names to
-use instead. These named variables can be used anywhere a register
-would be used normally  N<...because they actually are registers, but
-with fancier names>. They're declared with the C<.local> statement
-which requires a variable type and a name:
+=begin PIR_FRAGMENT
 
-  .local string hello
-  set hello, "Hello, Polly."
-  say hello
+  new $P0, "String"
+  new $P1, "String"
+  new $P2, "String"
+  set $P0, "ab"
+  set $P1, "cd"
+  concat $P2, $P0, $P1
+  print $P2            # prints abcd
+  print "\n"
 
-This snippet defines a string variable named C<hello>, assigns it the value
-"Hello, Polly.", and then prints the value. Under the hood these named
-variables are just normal registers of course, so any operation that a register
-can be used for a named variable can be used for as well.
-
-X<types;variable (PIR)>
-X<variables;types (PIR)>
-The valid types are C<int>, C<num>, C<string>, and C<pmc>
-It should come as no surprise that these are the same as Parrot's four
-built-in register types. Named variables are valid from the point of
-their definition to the end of the current subroutine.
-
-The name of a variable must be a valid PIR identifier. It can contain letters,
-digits and underscores but the first character has to be a letter or an
-underscore. There is no limit to the length of an identifier, other than good
-taste.
-
-As mentioned earlier, Parrot's internal compiler may remap named registers and
-symbolic registers to actual registers as necessary.  This happens
-transparently, and for the most part you never need to know about it.  There's
-one exception: when you know something outside of Parrot must refer to a
-specific register exactlyN<For example, when an NCI call takes a pointer to a
-register and returns a value through the pointer.>.  Use the C<:unique_reg>
-modifier on a variable declaration to prevent potential register allocation
-changes:
-
-  .local pmc MyUniquePMC :unique_reg
+=end PIR_FRAGMENT
 
-This attribute C<:unique_reg> will not affect the behavior of Parrot otherwise.
+Here, C<concat> concatenates the strings in C<$P0> and C<$P1> and stores
+the result in C<$P2>.
 
-=head2 PMC variables
+=head4 Repeating strings
 
-Z<CHP-3-SECT-2.4>
+Z<CHP-9-SECT-2.4.2>
 
-PMC registers and variables act much like any integer, floating-point
-number, or string register or variable, but you have to instantiate a
-new PMC object into a type before you use it. The C<new> instruction creates
-a new PMC of the specified type:
+X<PIR (Parrot assembly language);string operations;repeating strings>
+The C<repeat>X<repeat opcode (PIR)> opcode repeats a string a certain
+number of times:
 
-  $P0 = new 'String'
-  $P0 = "Hello, Polly."
-  say $P0
+=begin PIR_FRAGMENT
 
-This example creates a C<String> object, stores it in the PMC register C<$P0>,
-assigns it the value "Hello, Polly.", and prints it.  The type provided to the
-C<.local> directive is either the generic C<pmc> or a type compatible with the
-type passed to C<new>:
+  set $S0, "x"
+  repeat $S1, $S0, 5  # $S1 = $S0 x 5
+  print $S1          # prints "xxxxx"
+  print "\n"
 
-  .local String hello    # or .local pmc hello
-  hello = new 'String'
-  hello = "Hello, Polly."
-  say hello
+=end PIR_FRAGMENT
 
-PIR is a dynamic language; that dynamicism is evident in how Parrot handles PMC
-values. Primitive registers like strings, numbers, and integers perform a
-special action called X<autoboxing> when assigned to a PMC. Autoboxing is the
-process of converting a primitive type to a PMC object.  PMC classes exist for
-String, Number, and Integer; notice that the primitive types are in lower-case,
-while the PMC classes are capitalized. If you want to box a value explicitly,
-use the C<box> opcode:
+In this example, C<repeat> generates a new string with "x" repeated
+five times and stores a pointer to it in C<S1>.
 
-  $P0 = new 'Integer'       # The boxed form of int
-  $P0 = box 42
-  $P1 = new 'Number'        # The boxed form of num
-  $P1 = box 3.14
-  $P2 = new 'String'        # The boxed form of string
-  $P2 = "This is a string!"
+=head4 Length of a string
 
-The PMC classes C<Integer>, C<Number>, and C<String> are thin overlays on the
-primitive types they represent. These PMC types have the benefit of the
-X<PMC;VTABLE Interface> VTABLE interface. VTABLEs are a standard API that all
-PMCs conform to for performing standard operations. These PMC types support
-custom methods to perform various operations, may be passed to subroutines that
-expect PMC arguments, and can be subclassed by a user-defined type.
+Z<CHP-9-SECT-2.4.3>
 
-=head2 Named Constants
+X<PIR (Parrot assembly language);string operations;length>
+The C<length>X<length opcode (PIR)> opcode returns the length of a
+string in characters. This won't be the same as the length in bytes
+for multibyte encoded strings:
 
-Z<CHP-3-SECT-2.5>
+=begin PIR_FRAGMENT
 
-X<PIR (Parrot intermediate representation);named constants>
-X<named constants (PIR)>
+  set $S0, "abcd"
+  length $I0, $S0                # the length is 4
+  print $I0
+  print "\n"
 
-The C<.const> directive declares a named constant. It resembles C<.local>; it
-requires a type and a name. It also requires the assignment of a constant
-value.  As with named variables, named constants are visibl only within the
-compilation unit where they're declared. This example declares a named string
-constant C<hello> and prints the value:
+=end PIR_FRAGMENT
 
-  .const string hello = "Hello, Polly."
-  say hello
+C<length> doesn't have an equivalent for PMC strings.
 
-Named constants may be used in all the same places as literal constants,
-but have to be declared beforehand:
+=head4 Substrings
 
-  .const int    the_answer = 42        # integer constant
-  .const string mouse      = "Mouse"   # string constant
-  .const num    pi         = 3.14159   # floating point constant
+Z<CHP-9-SECT-2.4.4>
 
-In addition to normal local constants, you can also specify a global constant
-which is accessible from everywhere in the current code file:
+X<PIR (Parrot assembly language);string operations;substrings>
+The simplest version of the C<substr>X<substr opcode (PIR)> opcode
+takes four arguments: a destination register, a string, an offset
+position, and a length. It returns a substring of the original string,
+starting from the offset position (0 is the first character) and
+spanning the length:
 
-  .globalconst int days = 365
+=begin PIR_FRAGMENT
 
-Currently there is no way to specify a PMC constant in PIR source code.
+  substr $S0, "abcde", 1, 2        # $S0 is "bc"
 
-=for author
+=end PIR_FRAGMENT
 
-Why declare constants?
+This example extracts a two-character string from "abcde" at a
+one-character offset from the beginning of the string (starting with
+the second character). It generates a new string, "bc", in the
+destination register C<S0>.
 
-=end for
+When the offset position is negative, it counts backward from the end
+of the string. So an offset of -1 starts at the last character of the
+string.
 
-=head2 Symbol Operators
+C<substr> also has a five-argument form, where the fifth argument is a
+string to replace the substring. This modifies the second argument and
+returns the removed substring in the destination register.
 
-Z<CHP-3-SECT-3>
+=begin PIR_FRAGMENT
 
-X<symbol operators in PIR>
+  set $S1, "abcde"
+  substr $S0, $S1, 1, 2, "XYZ"
+  print $S0                        # prints "bc"
+  print "\n"
+  print $S1                        # prints "aXYZde"
+  print "\n"
 
-=for author
+=end PIR_FRAGMENT
 
-An earlier section described this already too.
+This replaces the substring "bc" in C<S1> with the string "XYZ", and
+returns "bc" in C<S0>.
 
-=end for
+When the offset position in a replacing C<substr> is one character
+beyond the original string length, C<substr> appends the replacement
+string just like the C<concat> opcode. If the replacement string is an
+empty string, the characters are just removed from the original
+string.
 
-PIR has many other symbolic operators: arithmetic, concatenation, comparison,
-bitwise, and logical. All PIR operators are translated into one or more Parrot
-opcodes internally, but the details of this translation stay safely hidden from
-the programmer. Consider this example snippet:
-
-  .local int sum
-  sum = $I42 + 5
-  say sum
-
-The statement C<sum = $I42 + 5> translates to the equivalent statement C<add
-sum, $I42, 5>.  PIR symbolic operations are:
-
-  $I0 = $I1 + 5      # Addition
-  $N0 = $N1 - 7      # Subtraction
-  $I3 = 4 * 6        # Multiplication
-  $N7 = 3.14 / $N2   # Division
-  $S0 = $S1 . $S2    # String concatenation
-
-PIR also provides automatic assignment operators such as C<+=>, C<-=>,
-and C<<< >>= >>>. These operators help programmers to perform common
-manipulations on a data value in place, and save a few keystrokes while
-doing them.
+When you don't need to capture the replaced string, there's an
+optimized version of C<substr> that just does a replace without
+returning the removed substring.
 
-A complete list of PIR operators is available in Chapter 13.
+=begin PIR_FRAGMENT
 
-=head2 C<=> and Type Conversion
+  set $S1, "abcde"
+  substr $S1, 1, 2, "XYZ"
+  print $S1                        # prints "aXYZde"
+  print "\n"
 
-The C<=> operator is very powerful.  Its simplest form stores a value into one
-of the Parrot registers. It can assign a string value to a C<string> register,
-an integer value to an C<int> register, a floating point value into a C<number>
-register, etc. However, the C<=> operator can assign I<any> type of value into
-I<any> type of register; Parrot will handle the conversion for you
-automatically:
+=end PIR_FRAGMENT
 
-  $I0 = 5     # Integer. 5
-  $S0 = $I0   # Stringify. "5"
-  $N0 = $S0   # Numify. 5.0
-  $I0 = $N0   # Intify. 5
+The PMC versions of C<substr> are not yet implemented.
 
-Notice that conversions between the numeric formats and strings only makes
-sense when the value to convert is a number.
+=head4 Chopping strings
 
-  $S0 = "parrot"
-  $I0 = $S0        # 0
+Z<CHP-9-SECT-2.4.5>
 
-An earlier example showed a string literal assigned to a PMC register of type
-C<String>. This works for all the primitive types and their autoboxed PMC
-equivalents:
+X<PIR (Parrot assembly language);string operations;chopping strings>
+The C<chopn>X<chopn opcode (PIR)> opcode removes characters from the
+end of a string. It takes two arguments: the string to modify and the
+count of characters to remove.
 
-  $P0 = new 'Integer'
-  $P0 = 5
-  $S0 = $P0      # Stringify. "5"
-  $N0 = $P0      # Numify. 5.0
-  $I0 = $P0      # Unbox. $I0 = 5
+=begin PIR_FRAGMENT
 
-  $P1 = new 'String'
-  $P1 = "5 birds"
-  $S1 = $P1      # Unbox. $S1 = "5 birds"
-  $I1 = $P1      # Intify. 5
-  $N1 = $P1      # Numify. 5.0
+  set $S0, "abcde"
+  chopn $S0, 2
+  print $S0         # prints "abc"
+  print "\n"
 
-  $P2 = new 'Number'
-  $P2 = 3.14
-  $S2 = $P2      # Stringify. "3.14"
-  $I2 = $P2      # Intify. 3
-  $N2 = $P2      # Unbox. $N2 = 3.14
+=end PIR_FRAGMENT
 
-=head2 Compilation Units
+This example removes two characters from the end of C<S0>. If the
+count is negative, that many characters are kept in the string:
 
-Z<CHP-3-SECT-4.1>
+=begin PIR_FRAGMENT
 
-X<PIR (Parrot intermediate representation);subroutine> X<subroutine (PIR)>
-Subroutines in PIR are roughly equivalent to the subroutines or methods of a
-high-level language.  All code in a PIR source file must occur within a
-subroutine.  The simplest syntax for a PIR subroutine starts with the C<.sub>
-directive and ends with the C<.end> directiveN<The name C<main> is only a
-convention.>:
+  set $S0, "abcde"
+  chopn $S0, -2
+  print $S0         # prints "ab"
+  print "\n"
 
-=begin PIR
+=end PIR_FRAGMENT
 
-  .sub 'main'
-      say "Hello, Polly."
-  .end
+This keeps the first two characters in C<S0> and removes the rest.
+C<chopn> also has a three-argument version that stores the chopped
+string in a separate destination register, leaving the original string
+untouched:
 
-=end PIR
+=begin PIR_FRAGMENT
 
-This example defines a subroutine named C<main> that prints a string C<"Hello,
-Polly.">. Parrot will normally execute the first subroutine it encounters in
-the first file it runs, but you can flag any subroutine as the first one to
-execute with the C<:main> marker:
+  set $S0, "abcde"
+  chopn $S1, $S0, 1
+  print $S1         # prints "abcd"
+  print "\n"
 
-=begin PIR
+=end PIR_FRAGMENT
 
-  .sub 'first'
-      say "Polly want a cracker?"
-  .end
+=head4 Copying and Cloning
 
-  .sub 'second' :main
-      say "Hello, Polly."
-  .end
+Z<CHP-9-SECT-2.4.6>
 
-=end PIR
+X<PIR (Parrot assembly language);string operations;copying> The C<clone>
+X<clone opcode (PIR)> opcode makes a deep copy of a string or PMC. Earlier
+in this chapter we saw that PMC and String values used with the C<set> opcode
+didn't create a copy of the underlying data structure, it only created
+a copy of the reference to that structure. With strings, this doesn't cause
+a problem because strings use Copy On Write (COW) semantics to automatically
+create a copy of the string when one reference is modified. However, as we
+saw, PMCs don't have this same behavior and so making a change to one PMC
+reference would modify the data that all the other references to that same
+PMC pointed to.
 
-This code prints out "Hello, Polly." but not "Polly want a cracker?".  Though
-the C<first> function appears first in the source code, C<second> has the
-C<:main> flag and gets called.  C<first> is never called.  Revising that
-program produces different results:
+Instead of just copying the pointer like C<set> would do, we can use the
+C<clone> opcode to create a I<deep copy> of the PMC, not just a I<shallow
+copy> of the reference.
 
-=begin PIR
+=begin PIR_FRAGMENT
 
-  .sub 'first' :main
-      say "Polly want a cracker?"
-  .end
+  new $P0, "String"
+  set $P0, "Ford"
+  clone $P1, $P0
+  set $P0, "Zaphod"
+  print $P0        # prints "Zaphod"
+  print $P1        # prints "Ford"
 
-  .sub 'second'
-      say "Hello, Polly."
-  .end
+=end PIR_FRAGMENT
 
-=end PIR
+This example creates an identical, independent clone of the PMC in
+C<P0> and puts a pointer to it in C<P1>. Later changes to C<P0> have
+no effect on the PMC referenced in C<P1>.
 
-The output now is "Polly want a cracker?". Execution in PIR starts at the
-C<:main> function and continues until that function ends.  To perform other
-operations, you must call other functions explicitly.  Chapter 4 describes
-subroutines and their uses.
+With simple strings, the copes created by C<clone> are COW exactly the same
+as the copy created by C<set>, so there is no difference between these two
+opcodes for strings. By convention, C<set> is used with strings more often
+then C<clone>, but there is no rule about this.
 
-=head2 Flow Control
+=head4 Converting characters
 
-Z<CHP-3-SECT-5>
+Z<CHP-9-SECT-2.4.7>
 
-X<PIR (Parrot intermediate representation);flow control>
-X<flow control;in PIR>
+X<PIR (Parrot assembly language);string operations;converting strings>
+The C<chr>X<chr opcode (PIR)> opcode takes an integer value and returns the
+corresponding character in the ASCII character set as a one-character string,
+while the C<ord>X<ord opcode (PIR)> opcode takes a single character string
+and returns the integer value of the character at the first position in the
+string. Notice that the integer value of the character will differ depending
+on the current encoding of the string:
 
-Flow control in PIR occurs entirely with conditional and unconditional branches
-to labels. This may seem simplistic and primitive, but here PIR shows its roots
-as a thin overlay on the assembly language of a virtual processor.  PIR does
-not support high-level looping structures such as C<while> or C<for> loops. PIR
-has some support for basic C<if> branching constructs, but does not support
-more complicated C<if>/C<then>/C<else> branch structures.  
+=begin PIR_FRAGMENT
 
-The control structures of high-level languages hew tightly to the semantics of
-those languages; Parrot provides the minimal feature set necessary to implement
-any semantic of an HLL without dictating how that HLL may implement its
-features.  Language agnosticism is an important design goal in Parrot, and
-creates a very flexible and powerful development environment for language
-developers.
+  chr $S0, 65                # $S0 is "A"
+  ord $I0, $S0               # $I0 is 65, if $S0 is ASCII or UTF-8
 
-X<goto instruction (PIR)>
-The most basic branching instruction is the unconditional branch, C<goto>:
+=end PIR_FRAGMENT
 
-=begin PIR
+C<ord> has a three-argument variant that takes a character offset to select
+a single character from a multicharacter string. The offset must be within
+the length of the string:
 
-  .sub 'main'
-      goto L1
-      say "never printed"
+=begin PIR_FRAGMENT
 
-  L1:
-      say "after branch"
-      end
-  .end
+  ord $I0, "ABC", 2        # $I0 is 67
 
-=end PIR
+=end PIR_FRAGMENT
 
-The first C<say> statement never runs because the C<goto> always skips over it
-to the label C<L1>.
+A negative offset counts backward from the end of the string, so -1 is
+the last character.
 
-The conditional branches combine C<if> or C<unless> with C<goto>.
+=begin PIR_FRAGMENT
 
-=begin PIR
+  ord $I0, "ABC", -1        # $I0 is 67
 
-  .sub 'main'
-      $I0 = 42
-      if $I0 goto L1
-      say "never printed"
-  L1:
-      say "after branch"
-      end
-  .end
+=end PIR_FRAGMENT
 
-=end PIR
+=head4 Formatting strings
 
-X<if (conditional);instruction (PIR)> X<unless (conditional);instruction (PIR)>
-In this example, the C<goto> branches to the label C<L1> only if the value
-stored in C<$I0> is true. The C<unless> statement is similar, but it branches
-when the tested value is false. An undefined value, 0, or an empty string are
-all false values. Any other values are true.
+Z<CHP-9-SECT-2.4.8>
 
-The comparison operators (C<E<lt>>, C<E<lt>=>, C<==>, C<!=>, C<E<gt>>,
-C<E<gt>=>) can combine with C<if ...  goto>. These branch when the
-comparison is true:
+X<PIR (Parrot assembly language);string operations;formatting strings>
+The C<sprintf>X<sprintf opcode (PIR)> opcode generates a formatted string
+from a series of values. It takes three arguments: the destination register,
+a string specifying the format, and an ordered aggregate PMC (like an
+C<Array> PMC) containing the values to be formatted. The format string and
+the destination register can be either strings or PMCs:
 
-=begin PIR
+=begin PIR_FRAGMENT
 
-  .sub 'main'
-      $I0 = 42
-      $I1 = 43
-      if $I0 < $I1 goto L1
-      say "never printed"
-  L1:
-      say "after branch"
-      end
-  .end
+  sprintf $S0, $S1, $P2
+  sprintf $P0, $P1, $P2
 
-=end PIR
+=end PIR_FRAGMENT
 
-This example compares C<$I0> to C<$I1> and branches to the label C<L1> if
-C<$I0> is less than C<$I1>. The C<if $I0 E<lt> $I1 goto L1> statement
-translates directly to the C<lt> branch operation.
+The format string is similar to the one for C's C<sprintf> function,
+but with some extensions for Parrot data types. Each format field in
+the string starts with a C<%>
+X<% (percent sign);% format strings for sprintf opcode (PIR)> and
+ends with a character specifying the output format. The output format
+characters are listed in Table 9-1.
 
-Chapter 11's "PIR Instructions" section summarizes the other comparison
-operators.
+=begin table picture Format characters
 
-X<loops;PIR>
-X<PIR (Parrot intermediate representation);loop constructs>
-PIR has no special loop constructs. A combination of conditional and
-unconditional branches handle iteration:
+Z<CHP-9-TABLE-1>
 
-=begin PIR
+=headrow
 
-  .sub 'main'
-      $I0 = 1               # product
-      $I1 = 5               # counter
+=row
 
-  REDO:                     # start of loop
-      $I0 = $I0 * $I1
-      dec $I1
-      if $I1 > 0 goto REDO  # end of loop
+=cell Format
 
-      say $I0
-      end
-  .end
+=cell Meaning
 
-=end PIR
+=bodyrows
 
-X<do-while style loop;(PIR)>
-This example calculates the factorial C<5!>. Each time through the
-loop it multiplies C<$I0> by the current value of the counter C<$I1>,
-decrements the counter, and then branches to the start of the loop.
-The loop ends when C<$I1> counts down to 0 so that the C<if> doesn't
-branch to C<REDO>. This is a I<do while>-style loop with the condition
-test at the end, so the code always runs the first time through.
+=row
 
-X<while-style loop (PIR)>
-For a I<while>-style loop with the condition test at the start, use a
-conditional branch together with an unconditional branch:
+=cell C<%c>
 
-=begin PIR
+=cell A single character.
 
-  .sub _main
-      $I0 = 1               # product
-      $I1 = 5               # counter
+=row
 
-  REDO:                     # start of loop
-      if $I1 <= 0 goto LAST
-      $I0 = $I0 * $I1
-      dec $I1
-      goto REDO
-  LAST:                     # end of loop
+=cell C<%d>
 
-      print $I0
-      print "\n"
-      end
-  .end
+=cell A decimal integer.
 
-=end PIR
+=row
 
-This example tests the counter C<$I1> at the start of the loop. At the
-end of the loop, it unconditionally branches back to the start of the
-loop and tests the condition again. The loop ends when the counter
-C<$I1> reaches 0 and the C<if> branches to the C<LAST> label. If the
-counter isn't a positive number before the loop, the loop never
-executes.
+=cell C<%i>
 
-Any high-level flow control construct can be built from conditional
-and unconditional branches, because this is the way almost all computer
-hardware operates at the lowest-level, so all modern programming
-languages use branching constructs to implement their most complex
-flow control devices.
-
-Fortunately, libraries of macros have been developed that can implement
-more familiar syntax for many of these control structures. We will discuss
-these libraries in more detail in "PIR Standard Library".
+=cell A decimal integer.
 
-=head2 Macros
+=row
 
-=head2 Subroutines
+=cell C<%u>
 
-Z<CHP-4>
+=cell An unsigned integer.
 
-X<PIR (Parrot intermediate representation);subroutines>
-X<subroutines;in PIR>
-Code reuse has become a cornerstone of modern software engineering.
-Common tasks are routinely packaged as libraries for later reuse
-by other developers. The most basic building block of code reuse is
-the "function" or "subroutine". A calculation like "the factorial of
-a number", for example, may be used several times in a large program.
-Subroutines allow this kind of functionality to be abstracted into a
-single stand-alone unit for reuse. PIR is a subroutine-based language
-in that all code in PIR must exist in a subroutine. Execution starts,
-as we have seen, in the C<:main> subroutine, and others can be called
-to perform the tasks of a program. From subroutines we can construct
-more elaborate chunks of code reusability methods and objects. In
-this chapter we will talk about how subroutines work in PIR, and how
-they can be used by developers to create programs for Parrot.
-
-Parrot supports multiple high-level languages, and each language uses
-a different syntax for defining and calling subroutines. The goal of
-PIR is not to be a high-level language in itself, but to provide the
-basic tools that other languages can use to implement them. PIR's
-syntax for subroutines may seem very primitive for this reason.
+=row
 
-=head2 Parrot Calling Conventions
+=cell C<%o>
 
-Z<CHP-4-SECT-1>
+=cell An octal integer.
 
-X<PIR (Parrot intermediate representation);subroutines;Parrot calling conventions>
-X<subroutines;Parrot calling conventions;in PIR>
-The way that Parrot calls a subroutine--by passing arguments, altering
-control flow, and returning results--is called the "Parrot Calling
-Conventions", or PCC. The details of PCC are generally hidden from the
-programmer, being partially implemented in C and being partially
-implemented in PASM. PIR has several constructs to gloss over these
-details, and the average programmer will not need to worry about them.
-PCC uses the Continuation Passing Style X<Continuation Passing Style
-(CPS)>X<CPS (Continuation Passing Style)> (CPS) to pass control to
-subroutines and back again. Again, the details of this can be largely
-ignored for developers who don't need it, but the power of this approach
-can be harnessed by those who do. We'll talk more about PCC and CPS in
-this and in later chapters as well.
+=row
 
-=head3 Subroutine Calls
+=cell C<%x>
 
-X<PIR (Parrot intermediate representation);subroutine calls>
-PIR's simplest subroutine call syntax looks much like a subroutine
-call from a high-level language. This example calls the subroutine
-C<fact> with two arguments and assigns the result to C<$I0>:
+=cell A hex integer, preceded by 0x when # is specified.
 
-  $I0 = 'fact'(count, product)
+=row
 
-This simple statement hides a great deal of complexity. It generates a
-subroutine PMC object, creates a continuation PMC object to return
-control flow after the subroutine, passes the arguments, looks up the
-subroutine by name (and by signature if it's been overloaded), it calls
-the subroutine, and finally it assigns the results of the call to the
-given register variables. This is quite a lot of work for a single
-statement, and that's ignoring the computational logic that the
-subroutine itself implements.
-
-=head3 Expanded Subroutine Syntax
-
-The single line subroutine call is incredibly convenient, but it isn't
-always flexible enough. So PIR also has a more verbose call syntax
-that is still more convenient than manual calls. This example pulls
-the subroutine C<fact> out of the global symbol table into a PMC
-register and calls it:
+=cell C<%X>
 
-  find_global $P1, "fact"
+=cell A hex integer with a capital X (when # is specified).
 
-  .begin_call
-    .arg count
-    .arg product
-    .call $P1
-    .result $I0
-  .end_call
+=row
 
-X<.arg directive>
-X<.result directive>
-The whole chunk of code from C<.begin_call> to C<.end_call> acts as a
-single unit. The C<.arg> directive sets up and passes arguments to
-the call. The C<.call> directive calls the subroutine, returns control
-flow after the subroutine has completed. The C<.result> directive
-retrieves returned values from the call.
+=cell C<%b>
 
-=head3 Subroutine Declarations
+=cell A binary integer, preceded by 0b when # is specified.
 
-X<.param directive>
-In addition to syntax for subroutine calls, PIR provides syntax for
-subroutine definitions. Subroutines are defined with the C<.sub>
-directive, and end with the C<.end> directive. We've already seen
-this syntax in our earlier examples. The C<.param> defines input
-parameters and creates local named variables for them:
+=row
 
-  .param int c
+=cell C<%B>
 
-X<.return directive>
-The C<.return> directive allows the subroutine to return control flow
-to the calling subroutine, and optionally returns result output values.
+=cell A binary integer with a capital B (when # is specified).
 
-Here's a complete code example that implements the factorial algorithm.
-The subroutine C<fact> is a separate subroutine, assembled and
-processed after the C<main> function.  Parrot resolves global symbols
-like the C<fact> label between different units.
+=row
 
-=begin PIR
+=cell C<%p>
 
-  # factorial.pir
-  .sub main
-     .local int count
-     .local int product
-     count = 5
-     product = 1
+=cell A pointer address in hex.
 
-     $I0 = 'fact'(count, product)
+=row
 
-     print $I0
-     print "\n"
-     end
-  .end
+=cell C<%f>
 
-  .sub fact
-     .param int c
-     .param int p
+=cell A floating-point number.
 
-  loop:
-     if c <= 1 goto fin
-     p = c * p
-     dec c
-     branch loop
-  fin:
-     .return (p)
-  .end
+=row
 
-=end PIR
+=cell C<%e>
 
-This example defines two local named variables, C<count> and
-C<product>, and assigns them the values 1 and 5. It calls the C<fact>
-subroutine passing the two variables as arguments. In the call, the
-two arguments are assigned to consecutive integer registers, because
-they're stored in typed integer variables. The C<fact> subroutine
-uses C<.param> and the C<.return> directives for retrieving parameters
-and returning results. The final printed result is 120.
-
-Execution of the program starts at the C<:main> subroutine or, if no
-subroutines are declared with C<:main> at the first subroutine in the file.
-If multiple subroutines are declared with C<:main>, the last of them is
-treated as the starting point. Eventually, declaring multiple subroutines
-with C<:main> might cause a syntax error or some other bad behavior, so it's
-not a good idea to rely on it now.
-
-=head3 Named Parameters
-
-Parameters that are passed in a strict order like we've seen above are
-called I<positional arguments>. Positional arguments are
-differentiated from one another by their position in the function call.
-Putting positional arguments in a different order will produce different
-effects, or may cause errors. Parrot supports a second type of parameter,
-a I<named parameter>. Instead of passing parameters by their position
-in the string, parameters are passed by name and can be in any order.
-Here's an example:
+=cell A floating-point number in scientific notation (displayed with a
+lowercase "e").
 
-=begin PIR
+=row
 
- .sub 'MySub'
-    .param string yrs :named("age")
-    .param string call :named("name")
-    $S0 = "Hello " . call
-    $S1 = "You are " . yrs
-    $S1 = $S1 . " years old"
-    print $S0
-    print $S1
- .end
+=cell C<%E>
 
- .sub main :main
-    'MySub'("age" => 42, "name" => "Bob")
- .end
+=cell The same as C<%e>, but displayed with an uppercase E.
 
-=end PIR
+=row
 
-In the example above, we could have easily reversed the order too:
+=cell C<%g>
 
-=begin PIR
+=cell The same as either C<%e> or C<%f>, whichever fits best.
 
- .sub main :main
-    'MySub'("name" => "Bob", "age" => 42)    # Same!
- .end
+=row
 
-=end PIR
+=cell C<%G>
 
-Named arguments can be a big help because you don't have to worry about
-the exact order of variables, especially as argument lists get very long.
+=cell The same as C<%g>, but displayed with an uppercase E.
 
-=head3 Optional Parameters
+=row
 
-Sometimes there are parameters to a function that don't always need to be
-passed, or values for a parameter which should be given a default value
-if a different value hasn't been explicitly provided. Parrot provides
-a mechanism for allowing optional parameters to be specified, so an
-error won't be raised if the parameter isn't provided. Parrot also
-provides a flag value that can be tested to determine if an optional
-parameter has been provided or not, so a default value can be supplied.
-
-Optional parameters are actually treated like two parameters: The value
-that may or may not be passed, and the flag value to determine if it
-has been or not. Here's an example declaration of an optional parameter:
-
-  .param string name :optional
-  .param int has_name :opt_flag
-
-The C<:optional> flag specifies that the given parameter is optional and
-does not necessarily need to be provided. The C<:opt_flag> specifies that
-an integer parameter contains a boolean flag. This flag is true if the
-value was passed, and false otherwise. This means we can use logic like
-this to provide a default value:
-
-  .param string name :optional
-  .param int has_name :opt_flag
-  if has_name goto we_have_a_name
-      name = "Default value"
-  we_have_a_name:
+=cell C<%s>
 
-Optional parameters can be positional or named parameters. When using them
-with positional parameters, they must appear at the end of the list of
-positional parameters. Also, the C<:opt_flag> parameter must always appear
-directly after the C<:optional> parameter.
+=cell A string.
 
-  .sub 'Foo'
-    .param int optvalue :optional
-    .param int hasvalue :opt_flag
-    .param pmc notoptional          # WRONG!
-    ...
+=end table
 
-  .sub 'Bar'
-     .param int hasvalue :opt_flag
-     .param int optvalue :optional  # WRONG!
-     ...
+Each format field can be specified with several options: R<flags>,
+R<width>, R<precision>, and R<size>. The format flags are listed in
+Table 9-2.
 
-  .sub 'Baz'
-    .param int optvalue :optional
-    .param pmc notoptional
-    .param int hasvalue :opt_flag   # WRONG!
-    ...
+=begin table picture Format flags
 
-Optional parameters can also be mixed with named parameters:
+Z<CHP-9-TABLE-2>
 
-  .sub 'MySub'
-    .param int value :named("answer") :optional
-    .param int has_value :opt_flag
-    ...
+=headrow
 
-This could be called in two ways:
+=row
 
-  'MySub'("answer" => 42)  # with a value
-  'MySub'()                # without
+=cell Flag
 
-=head3 Sub PMCs
+=cell Meaning
 
-Subroutines are a PMC type in Parrot, and references to them can be stored
-in PMC registers and manipulated like other PMC types. You can get a subroutine
-in the current namespace with the C<get_global> opcode:
+=bodyrows
 
-  $P0 = get_global "MySubName"
+=row
 
-Or, if you want to find a subroutine from a different namespace, you need
-to first select the namespace PMC and then pass that to C<get_global>:
+=cell 0
 
-  $P0 = get_namespace "MyNamespace"
-  $P1 = get_global $P0, "MySubName"
+=cell Pad with zeros.
 
-With a Sub PMC, there are lots of things you can do. You can obviously invoke
-it:
+=row
 
-  $P0(1, 2, 3)
+=cell E<lt>spaceE<gt>
 
-You can get its name or I<change> its name:
+=cell Pad with spaces.
 
-  $S0 = $P0               # Get the current name
-  $P0 = "MyNewSubName"    # Set a new name
+=row
 
-You can get a hash of the complete metadata for the subroutine:
+=cell C<+>
 
-  $P1 = inspect $P0
+=cell Prefix numbers with a sign.
 
-The metadata fields in this hash are
+=row
 
-=over 4
+=cell C<->
 
-=item * pos_required
+=cell Align left.
 
-The number of required positional parameters to the Sub
+=row
 
-=item * pos_optional
+=cell C<#>
 
-The number of optional positional parameters to the Sub
+=cell Prefix a leading 0 for octal, 0x for hex, or force a decimal point.
 
-=item * named_required
+=end table
 
-The number of required named parameters to the Sub
+The R<width> is a number defining the minimum width of the output from
+a field. The R<precision> is the maximum width for strings or
+integers, and the number of decimal places for floating-point fields.
+If either R<width> or R<precision> is an asterisk (C<*>), it takes its
+value from the next argument in the PMC.
 
-=item * named_optional
+The R<size> modifier defines the type of the argument the field takes.
+The flags are listed in Table 9-3.
 
-The number of optional named parameters to the Sub
+=begin table picture Size flags
 
-=item * pos_slurpy
+Z<CHP-9-TABLE-3>
 
-Returns 1 if the sub has a slurpy parameter to eat up extra positional args
+=headrow
 
-=item * named_slurpy
+=row
 
-Returns 1 if the sub has a slurpy parameter to eat up extra named args
+=cell Character
 
-=back
+=cell Meaning
 
-Instead of getting the whole inspection hash, you can look for individual
-data items that you want:
+=bodyrows
 
-  $I0 = inspect $P0, "pos_required"
+=row
 
-If you want to get the total number of defined parameters to the Sub, you can
-call the C<arity> method:
+=cell C<h>
 
-  $I0 = $P0.'arity'()
+=cell short integer or single-precision float
 
-To get the namespace PMC that the Sub was defined into, you can call the
-C<get_namespace> method:
+=row
 
-  $P1 = $P0.'get_namespace'()
+=cell C<l>
 
-Subroutine PMCs are very useful things, and we will show more of their uses
-throughout this chapter.
+=cell long
 
-=head2 The Commandline
+=row
 
-Programs written in Parrot have access to arguments passed on the command
-line like any other program would.
+=cell C<H>
 
-  .sub MyMain :main
-    .param pmc all_args :slurpy
-    ...
-  .end
+=cell huge value (long long or long double)
 
+=row
 
-=head2 Continuation Passing Style
+=cell C<v>
 
-Continuations are snapshots, a frozen image of the current execution
-state of the VM. Once we have a continuation we can invoke it to
-return to the point where the continuation was first created. It's
-like a magical timewarp that allows the developer to arbitrarily move
-control flow back to any previous point in the program N<there's actually
-no magic involved, just a lot of interesting ideas and involved code>.
-
-Continuations are not a new concept, they've been boggling the minds
-of Lisp and Scheme programmers for many years. However, despite all
-their power and flexibility they haven't been well-utilized in most
-modern programming languages or in their underlying libraries and
-virtual machines. Parrot aims to change that: In Parrot, almost every
-control flow manipulation including all subroutine, method, and
-coroutine calls, are performed using continuations. This mechanism
-is mostly hidden from developers who build applications on top of
-Parrot. The power and flexibility is available if people want to use
-it, but it's hidden behind more familiar constructs if not.
-
-Doing all sorts of flow control using continuations is called
-X<Continuation Passing Style;CPS> Continuation Passing Style (CPS).
-CPS allows parrot to offer all sorts of neat features, such as tail-call
-optimizations and lexical subroutines.
-
-=head3 Tailcalls
-
-In many cases, a subroutine will set up and call another subroutine,
-and then return the result of the second call directly. This is called
-a X<tailcall> tailcall, and is an important opportunity for optimization.
-Here's a contrived example in pseudocode:
+=cell Parrot INTVAL or FLOATVAL
 
-  call add_two(5)
+=row
 
-  subroutine add_two(value)
-    value = add_one(value)
-    return add_one(value)
+=cell C<O>
 
-In this example, the subroutine C<add_two> makes two calls to c<add_one>. The
-second call to C<add_one> is used as the return value. C<add_one> is called
-and its result is immediately returned to the caller of C<add_two>, it is
-never stored in a local register or variable in C<add_two>, it's immediately
-returned. We can optimize this situation if we realize that the second call to
-C<add_one> is returning to the same place that C<add_two> is, and therefore
-can utilize the same return continuation as C<add_two> uses. The two
-subroutine calls can share a return continuation, instead of having to create
-a new continuation for each call.
+=cell opcode_t pointer
 
-X<.tailcall directive>
-In PIR code, we use the C<.tailcall> directive to make a tailcall like this,
-instead of the C<.return> directive. C<.tailcall> performs this optimization
-by reusing the return continuation of the parent function to make the
-tailcall. In PIR, we can write this example:
+=row
 
-=begin PIR
+=cell C<P>
 
-  .sub main :main
-      .local int value
-      value = add_two(5)
-      say value
-  .end
+=cell C<PMC>
 
-  .sub add_two
-      .param int value
-      .local int val2
-      val2 = add_one(value)
-      .tailcall add_one(val2)
-  .end
+=row
 
-  .sub add_one
-      .param int a
-      .local int b
-      b = a + 1
-      .return (b)
-  .end
+=cell C<S>
 
-=end PIR
+=cell String
 
-This example above will print out the correct value "7".
+=end table
 
-=head3 Creating and Using Continuations
+The values in the aggregate PMC must have a type compatible with the
+specified R<size>.
 
-Most often continuations are used implicitly by the other control-flow
-operations in Parrot. However, they can also be created and used explicitly
-when required. Continuations are like any other PMC, and can be created
-using the C<new> keyword:
+Here's a short illustration of string formats:
 
-  $P0 = new 'Continuation'
+=begin PIR_FRAGMENT
 
-The new continuation starts off in an undefined state. Attempting to invoke
-a new continuation after it's first been created will raise an exception. To
-prepare the continuation for use, a destination label must be assigned to it
-with the C<set_addr> opcode:
+  new $P2, "Array"
+  new $P0, "Int"
+  set $P0, 42
+  push $P2, $P0
+  new $P1, "Num"
+  set $P1, 10
+  push $P2, $P1
+  sprintf $S0, "int %#Px num %+2.3Pf\n", $P2
+  print $S0     # prints "int 0x2a num +10.000"
+  print "\n"
 
-    $P0 = new 'Continuation'
-    set_addr $P0, my_label
+=end PIR_FRAGMENT
 
-  my_label:
-    ...
+The first eight lines create a C<Array> with two elements: a
+C<Int> and a C<Num>. The format string of the C<sprintf> has
+two format fields. The first, C<%#Px>, takes a PMC argument from the
+aggregate (C<P>) and formats it as a hexadecimal integer (C<x>), with
+a leading 0x (C<#>). The second format field, C<%+2.3Pf>, takes a PMC
+argument (C<P>) and formats it as a floating-point number (C<f>), with
+a minimum of two whole digits and a maximum of three decimal places
+(C<2.3>) and a leading sign (C<+>).
 
-To jump to the continuation's stored label and return the context to the
-state it was in when the continuation was created, use the C<invoke> opcode
-or the C<()> notation:
+The test files F<t/op/string.t> and F<t/src/sprintf.t> have many more
+examples of format strings.
 
-  invoke $P0  # Explicit using "invoke" opcode
-  $P0()       # Same, but nicer syntax
+=head4 Testing for substrings
 
-Notice that even though you can use the subroutine notation C<$P0()> to
-invoke the continuation, it doesn't make any sense to try and pass arguments
-to it or to try and return values from it:
+Z<CHP-9-SECT-2.4.9>
 
-  $P0 = new 'Continuation'
-  set_addr $P0, my_label
+X<PIR (Parrot assembly language);string operations;testing for substrings>
+The C<index>X<index opcode (PIR)> opcode searches for a substring
+within a string. If it finds the substring, it returns the position
+where the substring was found as a character offset from the beginning
+of the string. If it fails to find the substring, it returns -1:
 
-  $P0(1, 2)      # WRONG!
+=begin PIR_FRAGMENT
 
-  $P1 = $P0()    # WRONG!
+  index $I0, "Beeblebrox", "eb"
+  print $I0                       # prints 2
+  print "\n"
+  index $I0, "Beeblebrox", "Ford"
+  print $I0                       # prints -1
+  print "\n"
 
-=head2 Lexical Subroutines
+=end PIR_FRAGMENT
 
-X<Lexical Subroutines>
-As we've mentioned above, Parrot offers support for lexical subroutines.
-What this means is that we can define a subroutine by name inside a
-larger subroutine, and our "inner" subroutine is only visible and callable
-from the "outer" outer. The "inner" subroutine inherits all the lexical
-variables from the outer subroutine, but is able to define its
-own lexical variables that cannot be seen or modified by the outer subroutine.
-This is important because PIR doesn't have anything corresponding to blocks
-or nested scopes like some other languages have. Lexical subroutines play
-the role of nested scopes when they are needed.
+C<index> also has a four-argument version, where the fourth argument
+defines an offset position for starting the search:
 
-If the subroutine is lexical, you can get its C<:outer> with the C<get_outer>
-method on the Sub PMC:
+=begin PIR_FRAGMENT
 
-  $P1 = $P0.'get_outer'()
+  index $I0, "Beeblebrox", "eb", 3
+  print $I0                         # prints 5
+  print "\n"
 
-If there is no C<:outer> PMC, this returns a NULL PMC. Conversely, you can
-set the outer sub:
+=end PIR_FRAGMENT
 
-  $P0.'set_outer'($P1)
+This finds the second "eb" in "Beeblebrox" instead of the first,
+because the search skips the first three characters in the
+string.
 
-=head3 Scope and HLLs
+=head4 Joining strings
 
-Let us diverge for a minute and start looking forward at the idea of X<High
-Level Languages;HLL> High Level Languages (HLLs) such as Perl, Python, and
-Ruby. All of these languages allow nested scopes, or blocks within blocks
-that can have their own lexical variables. Let's look back at the C
-programming language, where this kind of construct is not uncommon:
+The C<join> opcode joins the elements of an array PMC into a single
+string. The second argument separates the individual elements of the
+PMC in the final string result.
 
-  {
-      int x = 0;
-      int y = 1;
-      {
-          int z = 2;
-          // x, y, and z are all visible here
-      }
-      // only x and y are visible here
-  }
+=begin PIR_FRAGMENT
 
-The code above illustrates this idea perfectly without having to get into a
-detailed and convoluted example: In the inner block, we define the variable
-C<z> which is only visible inside that block. The outer block has no
-knowledge of C<z> at all. However, the inner block does have access to the
-variables C<x> and C<y>. This is an example of nested scopes where the
-visibility of different data items can change in a single subroutine. As
-we've discussed above, Parrot doesn't have any direct analog for this
-situation: If we tried to write the code above directly, we would end up
-with this PIR code:
+  new $P0, "Array"
+  push $P0, "hi"
+  push $P0, 0
+  push $P0, 1
+  push $P0, 0
+  push $P0, "parrot"
+  join $S0, "__", $P0
+  print $S0              # prints "hi__0__1__0__parrot"
 
-  .param int x
-  .param int y
-  .param int z
-  x = 0
-  y = 1
-  z = 2
-  ...
+=end PIR_FRAGMENT
 
-This PIR code is similar, but the handling of the variable C<z> is
-different: C<z> is visible throughout the entire current subroutine, where it
-is not visible throughout the entire C function. To help approximate this
-effect, PIR supplies lexical subroutines to create nested lexical scopes.
+This example builds a C<Array> in C<P0> with the values C<"hi">,
+C<0>, C<1>, C<0>, and C<"parrot">. It then joins those values (separated
+by the string C<"__">) into a single string, and stores it in C<S0>.
 
-=head3 PIR Scoping
+=head4 Splitting strings
 
-In PIR, there is only one structure that supports scoping like this: the
-subroutine N<and objects that inherit from subroutines, such as methods,
-coroutines, and multisubs, which we will discuss later>. There are no blocks
-in PIR that have their own scope besides subroutines. Fortunately, we can use
-these lexical subroutines to simulate this behavior that HLLs require:
+Splitting a string yields a new array containing the resulting
+substrings of the original string.
 
-=begin PIR
-
-  .sub 'MyOuter'
-      .local int x,y
-      .lex 'x', x
-      .lex 'y', y
-      'MyInner'()
-      # only x and y are visible here
-  .end
-
-  .sub 'MyInner' :outer('MyOuter')
-      .local int z
-      .lex 'z', z
-      #x, y, and z are all "visible" here
-  .end
+=begin PIR_FRAGMENT
 
-=end PIR
+  split $P0, "", "abc"
+  set $P1, $P0[0]
+  print $P1              # 'a'
+  set $P1, $P0[2]
+  print $P1              # 'c'
 
-In the example above we put the word C<"visible"> in quotes. This is because
-lexically-defined variables need to be accessed with the C<get_lex> and
-C<set_lex> opcodes. These two opcodes don't just access the value of a
-register, where the value is stored while it's being used, but they also make
-sure to interact with the C<LexPad> PMC that's storing the data. If the value
-isn't properly stored in the LexPad, then they won't be available in nested
-inner subroutines, or available from C<:outer> subroutines either.
+=end PIR_FRAGMENT
 
-=head3 Lexical Variables
+This example splits the string "abc" into individual characters and
+stores them in an array in C<P0>. It then prints out the first and
+third elements of the array. For now, the split pattern (the second
+argument to the opcode) is ignored except for a test to make sure that
+its length is zero.
 
-As we have seen above, we can declare a new subroutine to be a nested inner
-subroutine of an existing outer subroutine using the C<:outer> flag. The
-outer flag is used to specify the name of the outer subroutine. Where there
-may be multiple subroutines with the same name N<such is the case with
-multisubs, which we will discuss soon>, we can use the C<:subid> flag on the
-outer subroutine to give it a different--and unique--name that the lexical
-subroutines can reference in their C<:outer> declarations. Within lexical
-subroutines, the C<.lex> command defines a local variable that follows these
-scoping rules.
+=head3 Logical and Bitwise Operations
 
-=head3 LexPad and LexInfo PMCs
+Z<CHP-9-SECT-2.6>
 
-Information about lexical variables in a subroutine is stored in two different
-types of PMCs: The LexPad PMC that we already mentioned briefly, and the
-LexInfo PMCs which we haven't. Neither of these PMC types are really usable
-from PIR code, but are instead used by Parrot internally to store information
-about lexical variables.
+X<PIR (Parrot assembly language);bitwise operations>
+X<PIR (Parrot assembly language);logical operations>
+The X<logical opcodes> logical opcodes evaluate the truth of their
+arguments. They're often used to make decisions on control flow.
+Logical operations are implemented for integers and PMCs. Numeric
+values are false if they're 0, and true otherwise. Strings are false
+if they're the empty string or a single character "0", and true
+otherwise. PMCs are true when their
+C<get_bool>X<get_bool vtable method (PIR)> vtable method returns a
+nonzero value.
 
-C<LexInfo> PMCs are used to store information about lexical variables at
-compile time. This is read-only information that is generated during
-compilation to represent what is known about lexical variables. Not all
-subroutines get a LexInfo PMC by default, you need to indicate to Parrot
-somehow that you require a LexInfo PMC to be created. One way to do this is
-with the C<.lex> directive that we looked at above. Of course, the C<.lex>
-directive only works for languages where the names of lexical variables are
-all known at compile time. For languages where this information isn't known,
-the subroutine can be flagged with C<:lex> instead.
+The C<and>X<and opcode (PIR)> opcode returns the second argument if
+it's false and the third argument otherwise:
 
-C<LexPad> PMCs are used to store run-time information about lexical variables.
-This includes their current values and their type information. LexPad PMCs are
-created at runtime for subs that have a C<LexInfo> PMC already. These are
-created each time the subroutine is invoked, which allows for recursive
-subroutine calls without overwriting variable names.
+=begin PIR_FRAGMENT
 
-With a Subroutine PMC, you can get access to the associated LexInfo PMC by
-calling the C<'get_lexinfo'> method:
+  and $I0, 0, 1  # returns 0
+  and $I0, 1, 2  # returns 2
 
-  $P0 = find_global "MySubroutine"
-  $P1 = $P0.'get_lexinfo'()
+=end PIR_FRAGMENT
 
-Once you have the LexInfo PMC, there are a limited number of operations that
-you can call with it:
+The C<or>X<or opcode (PIR)> opcode returns the second argument if
+it's true and the third argument otherwise:
 
-  $I0 = elements $P1    # Get the number of lexical variables from it
-  $P0 = $P1["name"]     # Get the entry for lexical variable "name"
+=begin PIR_FRAGMENT
 
-There really isn't much else useful to do with LexInfo PMCs, they're mostly
-used by Parrot internally and aren't helpful to the PIR programmer.
+  or $I0, 1, 0  # returns 1
+  or $I0, 0, 2  # returns 2
 
-There is no easy way to get a reference to the current LexPad PMC in a given
-subroutine, but like LexInfo PMCs that doesn't matter because they aren't
-useful from PIR anyway. Remember that subroutines themselves can be lexical
-and that therefore the lexical environment of a given variable can extend to
-multiple subroutines and therefore multiple LexPads. The opcodes C<find_lex>
-and C<store_lex> automatically search through nested LexPads recursively to
-find the proper environment information about the given variables.
+  or $P0, $P1, $P2
 
-=head2 Compilation Units Revisited
+=end PIR_FRAGMENT
 
-Z<CHP-4-SECT-1.1>
+Both C<and> and C<or> are short-circuiting. If they can determine what
+value to return from the second argument, they'll never evaluate the
+third.  This is significant only for PMCs, as they might have side
+effects on evaluation.
 
-The term "subroutine" is one that's been bandied about throughout the
-chapter and it's worth some amount of explanation here. A subroutine
-is a section of code that forms a single unit. In some instances the term
-can be used to describe an entire file. In most other cases, it's used to
-describe a single subroutine. Our earlier example which created a C<'fact'>
-subroutine for calculating factorials could be considered to have used two
-separate subroutine: The C<main> subroutine and the C<fact> subroutine.
-Here is a way to rewrite that algorithm using only a single subroutine instead:
+The C<xor>X<xor opcode (PIR)> opcode returns the second argument if
+it is the only true value, returns the third argument if it is the
+only true value, and returns false if both values are true or both are
+false:
 
-=begin PIR
+=begin PIR_FRAGMENT
 
-  .sub main
-      $I1 = 5           # counter
-      bsr fact
-      say $I0
-      $I1 = 6           # counter
-      bsr fact
-      say $I0
-      end
+  xor $I0, 1, 0  # returns 1
+  xor $I0, 0, 1  # returns 1
+  xor $I0, 1, 1  # returns 0
+  xor $I0, 0, 0  # returns 0
 
-  fact:
-      $I0 = 1           # product
-  L1:
-      $I0 = $I0 * $I1
-      dec $I1
-      if $I1 > 0 goto L1
-      ret
-  .end
+=end PIR_FRAGMENT
 
-=end PIR
+The C<not>X<not opcode (PIR)> opcode returns a true value when the
+second argument is false, and a false value if the second argument is
+true:
 
-The unit of code from the C<fact> label definition to C<ret> is a reusable
-routine, but is only usable from within the C<main> subroutine. There are
-several problems with this simple approach. In terms of the interface, the
-caller has to know to pass the argument to C<fact> in C<$I1> and to get the
-result from C<$I0>. This is different from how subroutines are normally
-invoked in PIR.
-
-Another disadvantage of this approach is that C<main> and C<fact> share the
-same subroutine, so they're parsed and processed as one piece of code.
-They share registers. They would also share LexInfo and LexPad PMCs, if any
-were needed by C<main>. The C<fact> routine is also not easily usable from
-outside the c<main> subroutine, so other parts of your code won't have access
-to it. This is a problem when trying to follow normal encapsulation guidelines.
+=begin PIR_FRAGMENT
 
-=head2 Namespaces, Methods, and VTABLES
+  not $I0, $I1
+  not $P0, $P1
 
-Z<CHP-4-SECT-2>
+=end PIR_FRAGMENT
 
-X<PIR (Parrot intermediate representation);methods>
-X<methods;in PIR>
-X<classes;methods>
-X<. (dot);. (method call);instruction (PIR)>
-PIR provides syntax to simplify writing methods and method calls for
-object-oriented programming. We've seen some method calls in the examples
-above, especially when we were talking about the interfaces to certain PMC
-types. We've also seen a little bit of information about classes and objects
-in the previous chapter. PIR allows you to define your own classes, and with
-those classes you can define method interfaces to them. Method calls follow
-the same Parrot calling conventions that we have seen above, including all the
-various parameter configurations, lexical scoping, and other aspects we have
-already talked about.
+The X<bitwise;opcodes (PIR)> bitwise opcodes operate on their values
+a single bit at a time. C<band>X<band opcode (PIR)>,
+C<bor>X<bor opcode (PIR)>, and C<bxor>X<bxor opcode (PIR)> return a
+value that is the logical AND, OR, or XOR of each bit in the source
+arguments. They each take a destination register and two source
+registers. They also have two-argument forms where the destination is
+also a source.  C<bnot>X<bnot opcode (PIR)> is the logical NOT of
+each bit in a single source argument.
 
-Classes can be defined in two ways: in C and compiled to machine code, and
-in PIR. The former is how the built-in PMC types are defined, like
-C<ResizablePMCArray>, or C<Integer>. These PMC types are either built with
-Parrot at compile time, or are compiled into a shared library called a
-I<dynpmc> and loaded into Parrot at runtime. We will talk about writing PMCs
-in C, and dealing with dynpmcs in chapter 11.
+=begin PIR_FRAGMENT
 
-The second type of class can be defined in PIR at runtime. We saw some
-examples of this in the last chapter using the C<newclass> and C<subclass>
-opcodes. We also talked about class attribute values. Now, we're going to talk
-about associating subroutines with these classes, and they're called
-I<methods>. Methods are just like other normal subroutines with two major
-changes: they are marked with the C<:method> flag, and they exist in a
-I<namespace>. Before we can talk about methods, we need to discuss
-namespaces first.
+  bnot $I0, $I1
+  band $P0, $P1
+  bor $I0, $I1, $I2
+  bxor $P0, $P1, $I2
 
-=head3 Namespaces
+=end PIR_FRAGMENT
 
-Z<CHP-4-SECT-2.1>
+X<bitwise;string opcodes>
+The bitwise opcodes also have string variants for AND, OR, and XOR:
+C<bors>X<bors opcode (PIR)>, C<bands>X<bands opcode (PIR)>, and
+C<bxors>X<bxors opcode (PIR)>. These take string register or PMC
+string source arguments and perform the logical operation on each byte
+of the strings to produce the final string.
 
-X<Namespaces>
-X<.namespace>
-Namespaces provide a mechanism where names can be reused. This may not
-sound like much, but in large complicated systems, or systems with
-many included libraries, it can be very handy. Each namespace gets its
-own area for function names and global variables. This way you can have
-multiple functions named C<create> or C<new> or C<convert>, for
-instance, without having to use I<Multi-Method Dispatch> (MMD) which we
-will describe later. Namespaces are also vital for defining classes and their
-methods, which we already mentioned. We'll talk about all those uses here.
+=begin PIR_FRAGMENT
 
-Namespaces are specified with the C<.namespace []> directive. The brackets
-are not optional, but the keys inside them are. Here are some examples:
+  bors $S0, $S1
+  bands $P0, $P1
+  bors $S0, $S1, $S2
+  bxors $P0, $P1, $S2
 
-  .namespace [ ]               # The root namespace
-  .namespace [ "Foo" ]         # The namespace "Foo"
-  .namespace [ "Foo" ; "Bar" ] # Namespace Foo::Bar
-  .namespace                   # WRONG! The [] are needed
+=end PIR_FRAGMENT
 
-Using semicolons, namespaces can be nested to any arbitrary depth.
-Namespaces are special types of PMC, so we can access them and manipulate
-them just like other data objects. We can get the PMC for the root
-namespace using the C<get_root_namespace> opcode:
+The bitwise string opcodes only have meaningful results when they're
+used with simple ASCII strings because the bitwise operation is done
+per byte.
 
-  $P0 = get_root_namespace
+The logical and arithmetic shift operations shift their values by a
+specified number of bits:
 
-The current namespace, which might be different from the root namespace
-can be retrieved with the C<get_namespace> opcode:
+=begin PIR_FRAGMENT
 
-  $P0 = get_namespace             # get current namespace PMC
-  $P0 = get_namespace ["Foo"]     # get PMC for namespace "Foo"
+  shl  $I0, $I1, $I2        # shift I1 left by count I2 giving I0
+  shr  $I0, $I1, $I2        # arithmetic shift right
+  lsr  $P0, $P1, $P2        # logical shift right
 
-Namespaces are arranged into a large n-ary tree. There is the root namespace
-at the top of the tree, and in the root namespace are various special HLL
-namespaces. Each HLL compiler gets its own HLL namespace where it can store
-its data during compilation and runtime. Each HLL namespace may have a large
-hierarchy of other namespaces. We'll talk more about HLL namespaces and their
-significance in chapter 10.
+=end PIR_FRAGMENT
 
-The root namespace is a busy place. Everybody could be lazy and use it to store
-all their subroutines and global variables, and then we would run into all
-sorts of collisions. One library would define a function "Foo", and then
-another library could try to create another subroutine with the same name.
-This is called I<namespace pollution>, because everybody is trying to put
-things into the root namespace, and those things are all unrelated to each
-other. Best practices requires that namespaces be used to hold private
-information away from public information, and to keep like things together.
+=head3 Encodings and Charsets
 
-As an example, the namespace C<Integers> could be used to store subroutines
-that deal with integers. The namespace C<images> could be used to store
-subroutines that deal with creating and manipulating images. That way, when
-we have a subroutine that adds two numbers together, and a subroutine that
-performs additive image composition, we can name them both C<add> without any
-conflict or confusion. And within the C<image> namespace we could have sub
-namespaces for C<jpeg> and C<MRI> and C<schematics>, and each of these could
-have a C<add> method without getting into each other's way.
+X<charset>
+A modern string system must manage several character encodings and charsets in
+order to make sense out of all the string data in the world.  Parrot does this.
+Every string has an associated encoding and an associated character set.  The
+default charset is 8-bit ASCII, which is simple to use and is almost
+universally supported.
 
-The short version is this: use namespaces. There aren't any penalties to them,
-and they do a lot of work to keep things organized and separated.
+Double-quoted string constants can have an optional prefix specifying the the
+string's encoding and charsetN<As you might suspect, single-quoted strings do
+not support this.>. Parrot will maintain these values internally, and will
+automatically convert strings when necessary to preserve the information.
+String prefixes are specified as C<encoding:charset:> at the front of the
+string. Here are some examples:
 
-=head3 Namespace PMC
+=begin PIR_FRAGMENT
 
-The C<.namespace> directive that we've seen sets the current namespace. In
-PIR code, we have multiple ways to address a namespace:
+  $S0 = utf8:unicode:"Hello UTF8 Unicode World!"
+  $S1 = utf16:unicode:"Hello UTF16 Unicode World!"
+  $S2 = ascii:"This is 8-bit ASCII"
+  $S3 = binary:"This is raw, unformatted binary data"
 
-  # Get namespace "a/b/c" starting at the root namespace
-  $P0 = get_root_namespace ["a" ; "b" ; "c"]
+=end PIR_FRAGMENT
 
-  # Get namespace "a/b/c" starting in the current HLL namespace.
-  $P0 = get_hll_namespace ["a" ; "b" ; "c"]
-  # Same
-  $P0 = get_root_namespace ["hll" ; "a" ; "b" ; "c"]
+The C<binary:> charset treats the string as a buffer of raw unformatted binary
+data. It isn't really a string per se, because binary data contains no readable
+characters.  As mentioned earlier, this exists to support libraries which
+manipulate binary data that doesn't easily fit into any other primitive data
+type.
 
-  # Get namespace "a/b/c" starting in the current namespace
-  $P0 = get_namespace ["a" ; "b" ; "c"]
+When Parrot combines two strings (such as through concatenation), they must
+both use the same character set and encoding.  Parrot will automatically
+upgrade one or both of the strings to use the next highest compatible format as
+necessary. ASCII strings will automatically upgrade to UTF-8 strings if needed,
+and UTF-8 will upgrade to UTF-16. All of these conversions happen inside
+Parrot; you the programmer don't need to worry about the details.
 
-Once we have a namespace PMC we can retrieve global variables and
-subroutine PMCs from it using the following functions:
+=head2 Working with PMCs
 
-  $P1 = get_global $S0            # Get global in current namespace
-  $P1 = get_global ["Foo"], $S0   # Get global in namespace "Foo"
-  $P1 = get_global $P0, $S0       # Get global in $P0 namespace PMC
+Polymorphic Containers (PMCs) are the basis for complex data types and
+object-oriented behavior in Parrot. In PIR, any variable that isn't a
+low-level integer, number, or string is a PMC
 
-=head3 Operations on the Namespace PMC
+Operations on a PMC are implemented by vtable functions. The result of
+an operation is entirely determined by the behavior of
+the PMCs vtable. Since PMCs define their own behavior for these vtable
+functions, it's important to familiarize yourself with the behavior
+of the particular PMC before you start performing a lot of operations on it.
 
-We've seen above how to find a Namespace PMC. Once you have it, there are a
-few things you can do with it. You can find methods and variables that are
-stored in the namespace, or you can add new ones:
+=head3 Assignment
 
-  $P0 = get_namespace
-  $P0.'add_namespace'($P1)      # Add Namespace $P1 to $P0
-  $P1 = $P0.'find_namespace'("MyOtherNamespace")
+PMC registers contain references to PMC structures internally. So, the set
+opcode doesn't copy the entire PMC, it only copies the reference to the
+PMC data. Here's an example that shows a side effect of this operation:
 
-  # Find namespace "MyNamespace" in $P0, create it if it
-  #    doesn't exist
-  $P1 = $P0.'make_namespace'("MyNamespace")
+=begin PASM
 
-  $P0.'add_sub'("MySub", $P2)   # Add Sub PMC $P2 to the namespace
-  $P1 = $P0.'find_sub'("MySub") # Find it
+  new P0, "String"
+  set P0, "Ford"
+  set P1, P0
+  set P1, "Zaphod"
+  print P0                # prints "Zaphod"
+  print P1                # prints "Zaphod"
+  end
 
-  $P0.'add_var'("MyVar", $P3)   # Add variable "MyVar" in $P3
-  $P1 = $P0.'find_var'("MyVar") # Find it
+=end PASM
 
-  # Return the name of Namespace $P0 as a ResizableStringArray
-  $P3 = $P0.'get_name'()
+In this example, both C<P0> and C<P1> are both references to the same
+internal data structure, so when we set C<P1> to the string literal
+C<"Zaphod">, it overwrites the previous value C<"Ford">. Now, both C<P0>
+and C<P1> point to the String PMC C<"Zaphod">, even though it appears that
+we only set one of those two registers to that value.
 
-  # Find the parent namespace that contains this one:
-  $P5 = $P0.'get_parent'()
+=head4 PMC object types
 
-  # Get the Class PMC associated with this namespace:
-  $P6 = $P0.'get_class'()
+Z<CHP-9-SECT-2.2.2>
 
-There are a few other operations that can be done on Namespaces, but none
-as interesting as these. We'll talk about Namespaces throughout the rest
-of this chapter.
+X<PMCs (Polymorphic Containers);object types>
+Every PMC has a distinct type that determines its behavior through the
+vtable interface. In the chapter on PIR, we've seen a number of these vtable
+functions already, and seen how they implement the behaviors found inside
+the various opcodes. The vtable interface is standard, and all PMCs implement
+the exact same set of vtables. We've seen some of the vtables and their uses,
+and more of them will be discussed in this chapter and later in the various
+reference chapters.
 
-=head3 Calling Methods
+The C<typeof> opcode can be used to determine the type of a PMC. When
+the source argument is a PMC and the destination is a string register,
+C<typeof> returns the name of the type:
 
-Z<CHP-4-SECT-2.2>
+=begin PIR_FRAGMENT
 
-Now that we've discussed namespaces, we can start to discuss all the
-interesting things that namespaces enable, like object-oriented
-programming and method calls. Methods are just like subroutines, except
-they are invoked on a object PMC, and that PMC is passed as the c<self>
-parameter.
+  new $P0, "String"
+  typeof $S0, $P0               # $S0 is "String"
+  print $S0
+  print "\n"
 
-The basic syntax for a method call is similar to the single line
-subroutine call above. It takes a variable for the invocant PMC and a
-string with the name of the method:
+=end PIR_FRAGMENT
 
-  object."methodname"(arguments)
+Using C<typeof> with a PMC output parameter instead, it returns the Class
+PMC for that type.
 
-Notice that the name of the method must be contained in quotes. If the
-name of the method is not contained in quotes, it's treated as a named
-variable that does. Here's an example:
 
-  .local string methname = "Foo"
-  object.methname()               # Same as object."Foo"()
-  object."Foo"()                  # Same
 
-The invocant can be a variable or register, and the method name can be
-a literal string, string variable, or method object PMC.
+=head3 Scalars
 
-=head3 Defining Methods
+Parrot provides a set of
 
-Methods are defined like any other subroutine except with two major
-differences: They must be inside a namespace named after the class
-they are a part of, and they must use the C<:method> flag.
+In most of the examples we've shown so far, X<PMCs (Polymorphic
+Containers);working with> PMCs just duplicate the functionality of integers,
+numbers, and strings.
 
-  .namespace [ "MyClass"]
+PMCs act much like any integer, floating-point
+number, or string register or variable, but you have to instantiate a
+new PMC object into a type before you use it. The C<new> instruction creates
+a new PMC of the specified type:
 
-  .sub "MyMethod" :method
-    ...
+=begin PIR_FRAGMENT
 
-Inside the method, the invocant object can be accessed using the C<self>
-keyword. C<self> isn't the only name you can call this value, however.
-You can also use the C<:invocant> flag to define a new name for the invocant
-object:
+  $P0 = new 'String'
+  $P0 = "That's a bollard and not a parrot."
+  print $P0
 
-(See TT #483)
+=end PIR_FRAGMENT
 
-=begin PIR
+This example creates a C<String> object, stores it in the PMC register variable C<$P0>,
+assigns it the value "Hello, Polly.", and prints it:
 
-  .sub "MyMethod" :method
-    $S0 = self                    # Already defined as "self"
-    say $S0
-  .end
+=end PIR_FRAGMENT
 
-  .sub "MyMethod2" :method
-    .param pmc item :invocant     # "self" is now called "item"
-    $S0 = item
-    say $S0
-  .end
+  .local pmc hello    # or .local pmc hello
+  hello = new 'String'
+  hello = "Hello, Polly."
+  print hello
 
-=end PIR
+=end PIR_FRAGMENT
 
-This example defines two methods in the C<Foo> class. It calls one
-from the main body of the subroutine and the other from within the
-first method:
+PIR is a dynamic language; that dynamicism is evident in how Parrot handles PMC
+values. Primitive registers like strings, numbers, and integers perform a
+special action called X<autoboxing> when assigned to a PMC. Autoboxing is the
+process of converting a primitive type to a PMC object.  PMC classes exist for
+String, Number, and Integer; notice that the primitive types are in lower-case,
+while the PMC classes are capitalized. If you want to box a value explicitly,
+use the C<box> opcode:
 
-=begin PIR
+=begin PIR_FRAGMENT
 
-  .sub main
-    .local pmc class
-    .local pmc obj
-    newclass class, "Foo"       # create a new Foo class
-    new obj, "Foo"              # instantiate a Foo object
-    obj."meth"()                # call obj."meth" which is actually
-    print "done\n"              # in the "Foo" namespace
-    end
-  .end
+  $P0 = new 'Integer'       # The boxed form of int
+  $P0 = box 42
+  $P1 = new 'Number'        # The boxed form of num
+  $P1 = box 3.14
+  $P2 = new 'String'        # The boxed form of string
+  $P2 = "This is a string!"
 
-  .namespace [ "Foo" ]          # start namespace "Foo"
+=end PIR_FRAGMENT
 
-  .sub meth :method             # define Foo::meth global
-     print "in meth\n"
-     $S0 = "other_meth"         # method names can be in a register too
-     self.$S0()                 # self is the invocant
-  .end
+The PMC classes C<Integer>, C<Number>, and C<String> are thin overlays on the
+primitive types they represent. These PMC types have the benefit of the
+X<PMC;VTABLE Interface> VTABLE interface. VTABLEs are a standard API that all
+PMCs conform to for performing standard operations. These PMC types support
+custom methods to perform various operations, may be passed to subroutines that
+expect PMC arguments, and can be subclassed by a user-defined type.
 
-  .sub other_meth :method       # define another method
-     print "in other_meth\n"    # as above Parrot provides a return
-  .end                          # statement
 
-=end PIR
+PMCs are are polymorphic data items that
+can be one of a large variety of predefined types. As we have seen briefly,
+and as we will see in more depth later, PMCs have a standard interface called
+the VTABLE interface. VTABLEs are a standard list of functions that all PMCs
+implement N<or, PMCs can choose not to implement each interface explicitly and
+instead let Parrot call the default implementations>.
 
-Each method call looks up the method name in the object's class namespace.
-The C<.sub> directive automatically makes a symbol table entry for the
-subroutine in the current namespace.
+VTABLEs are very strict: There are a fixed number with fixed names and
+fixed argument lists. You can't just create any random VTABLE interface that
+you want to create, you can only make use of the ones that Parrot supplies
+and expects. To circumvent this limitation, PMCs may have METHODS in
+addition to VTABLEs. METHODs are arbitrary code functions that can be
+written in C, may have any name, and may implement any behavior.
 
-When a C<.sub> is declared as a C<:method>, it automatically creates a
-local variable named C<self> and assigns it the object passed in
-C<P2>. You don't need to write C<.param pmc self> to get it, it comes
-free with the method.
+=head4 Boxing and Unboxing
 
-You can pass multiple arguments to a method and retrieve multiple
-return values just like a single line subroutine call:
+Z<CHP-9-SECT-2.2.3>
 
-  (res1, res2) = obj."method"(arg1, arg2)
+As we've seen in the previous chapters about PIR, we can convert between
+primitive string, integer, and number types and PMCs. PIR used the C<=>
+operator to make these conversions. PIR uses the C<set> opcode to do the
+same thing. C<set> will perform the type conversions for us automatically,
+in a process called I<autoboxing>.
 
-=head3 VTABLEs
+Assigning a primitive data type to a PMC of a String, Integer, or Float type
+converts that PMC to the new type. So, assigning a string to a Number PMC
+converts it into a String PMC. Assigning an integer value converts it to a
+C<Integer>, and assigning C<undef> converts it to an C<Undef> PMC:
 
-PMCs all subscribe to a common interface of functions called X<VTABLE>
-VTABLEs. Every PMC implements the same set of these interfaces, which
-perform very specific low-level tasks on the PMC. The term VTABLE was
-originally a shortened form of the name "virtual function table",
-although that name isn't used any more by the developers, or in any of
-the documentation N<In fact, if you say "virtual function table" to
-one of the developers, they probably won't know what you are talking
-about>. The virtual functions in the VTABLE, called X<VTABLE
-interfaces> VTABLE interfaces, are similar to ordinary functions and
-methods in many respects. VTABLE interfaces are occasionally called
-"VTABLE functions", or "VTABLE methods" or even "VTABLE entries" in
-casual conversation. A quick comparison shows that VTABLE interfaces
-are not really subroutines or methods in the way that those terms have
-been used throughout the rest of Parrot. Like methods on an object,
-VTABLE interfaces are defined for a specific class of PMC, and can be
-invoked on any member of that class. Likewise, in a VTABLE interface
-declaration, the C<self> keyword is used to describe the object that
-it is invoked upon. That's where the similarities end, however. Unlike
-ordinary subroutines or methods, VTABLE methods cannot be invoked
-directly, they are also not inherited through class hierarchies like
-how methods are. With all this terminology discussion out of the way,
-we can start talking about what VTABLES are and how they are used in
-Parrot.
+=begin PIR_FRAGMENT
 
-VTABLE interfaces are the primary way that data in the PMC is accessed
-and modified. VTABLES also provide a way to invoke the PMC if it's a
-subroutine or subroutine-like PMC. VTABLE interfaces are not called
-directly from PIR code, but are instead called internally by Parrot to
-implement specific opcodes and behaviors. For instance, the C<invoke>
-opcode calls the C<invoke> VTABLE interface of the subroutine PMC,
-while the C<inc> opcode on a PMC calls the C<increment> VTABLE
-interface on that PMC. What VTABLE interface overrides do, in essence,
-is to allow the programmer to change the very way that Parrot accesses
-PMC data in the most fundamental way, and changes the very way that the
-opcodes act on that data.
+  new $P0, "String"
+  set $P0, "Ford\n"
+  print $P0           # prints "Ford\n"
+  set $P0, 42
+  print $P0           # prints 42
+  print "\n"
+  typeof $S0, $P0
+  print $S0           # prints "Integer"
+  print "\n"
 
-PMCs, as we will look at more closely in later chapters, are typically
-implemented using X<PMC Script> PMC Script, a layer of syntax and macros
-over ordinary C code. A X<PMC Compiler> PMC compiler program converts the
-PMC files into C code for compilation as part of the ordinary build
-process. However, VTABLE interfaces can be written I<and overwritten> in
-PIR using the C<:vtable> flag on a subroutine declaration. This technique
-is used most commonly when subclassing an existing PMC class in PIR code
-to create a new data type with custom access methods.
+=end PIR_FRAGMENT
 
-VTABLE interfaces are declared with the C<:vtable> flag:
+C<P0> starts as a C<String>, but when C<set> assigns it an integer
+value 42 (replacing the old string value C<"Ford">), it changes type
+to C<Integer>. This behavior only works for the wrapper PMC types for the
+primitive values string, int, and num. Other PMC classes will have different
+behaviors when you try to assign a primitive value to them.
 
-  .sub 'set_integer' :vtable
-      #set the integer value of the PMC here
-  .end
+We can also use the C<box> opcode to explicitly convert an integer, a float,
+or a string into an appropriate PMC type.
 
-in which case the subroutine must have the same name as the VTABLE
-interface it is intended to implement. VTABLE interfaces all have very
-specific names, and you can't override one with just any arbitrary name.
-However, if you would like to name the function something different but
-still use it as a VTABLE interface, you could add an additional name
-parameter to the flag:
+=begin PIR_FRAGMENT
 
-  .sub 'MySetInteger' :vtable('set_integer')
-      #set the integer value of the PMC here
-  .end
+  box $P0, 3
+  typeof $S0, $P0         # $P0 is an "Integer"
+  box $P1, "hello"
+  typeof $S0, $P1         # $P1 is a "String"
+  box $P2, 3.14
+  typeof $S0, $P2         # $P2 is a "Number"
 
-VTABLE interfaces are often given the C<:method> flag also, so that they can
-be used directly in PIR code as methods, in addition to being used by Parrot
-as VTABLE interfaces. This means we can have the following:
+=end PIR_FRAGMENT
 
-  .namespace [ "MyClass" ]
 
-  .sub 'ToString' :vtable('get_string') :method
-      $S0 = "hello!"
-      .return($S0)
-  .end
+=head3 Aggregates
 
-  .namespace [ "OtherClass" ]
+Z<CHP-9-SECT-3.1>
 
-  .local pmc myclass = new "MyClass"
-  say myclass                 # say converts to string internally
-  $S0 = myclass               # Convert to a string, store in $S0
-  $S0 = myclass.'ToString'()  # The same
+PMCs can define complex types that hold multiple values. These are
+commonly called "X<PMCs (Polymorphic Containers);aggregate>
+X<aggregate PMCs> aggregates." The most important feature added for
+aggregates is keyed access. Elements within an aggregate PMC can be
+stored and retrieved by a numeric or string key. PIR also offers a
+full set of operations for manipulating aggregate data types.
 
-Inside a VTABLE interface definition, the C<self> local variable contains
-the PMC on which the VTABLE interface is invoked, just like in a method
-declaration.
+Two of the most basic aggregate types are arrays and hashes. The primary
+difference between these two is that arrays are indexed using integer keys,
+and hashes are indexed with string keys. The term "hash" in this context is
+derived from the data type in Perl 5 of the same name. Other programming
+languages might refer to the same concept using different terms such as
+"dictionary" or "hash table" or "associative array".
 
-=head2 Roles
+Arrays and hashes are not the only types of aggregates available, although
+they are the most simple demonstrations of using integer and strings as
+keys in an aggregate, respectively.
 
-As we've seen above and in the previous chapter, Class PMCs and NameSpace
-PMCs work to keep classes and methods together in a logical way. There is
-another factor to add to this mix: The Role PMC.
+=head4 Arrays
 
-Roles are like classes, but don't stand on their own. They represent
-collections of methods and VTABLES that can be added into an existing class.
-Adding a role to a class is called I<composing> that role, and any class
-that has been composed with a role C<does> that role.
+Z<CHP-9-SECT-3.1.1>
 
-Roles are created as PMC and can be manipulated through opcodes and methods
-like other PMCs:
+X<arrays>
+The C<Array>X<Array PMC> PMC is an ordered aggregate with zero-based integer
+keys. The syntax for X<keyed access to PMCs> keyed access to a PMC puts the
+key in square brackets after the register name:
 
-  $P0 = new 'Role'
-  $P1 = get_global "MyRoleSub"
-  $P0.'add_method'("MyRoleSub", $P1)
+=begin PIR_FRAGMENT
 
-Once we've created a role and added methods to it, we can add that role to
-a class, or even to another role:
+  new $P0, "Array"     # obtain a new array object
+  set $P0, 2           # set its length
+  set $P0[0], 10       # set first element to 10
+  set $P0[1], $I31     # set second element to $I31
+  set $I0, $P0[0]      # get the first element
+  set $I1, $P0         # get array length
 
-  $P1 = new 'Role'
-  $P2 = new 'Class'
-  $P1.'add_role'($P0)
-  $P2.'add_role'($P0)
-  add_role $P2, $P0    # Same!
+=end PIR_FRAGMENT
 
-Now that we have added the role, we can check whether we implement it:
+A key on the destination register of a C<set> operation sets a value
+for that key in the aggregate. A key on the source register of a
+C<set> returns the value for that key. If you set C<P0> without a key,
+you set the length of the array, not one of its values.N<C<Array>
+is an autoextending array, so you never need to set its length. Other
+array types may require the length to be set explicitly.> And if you
+assign the C<Array> to an integer, you get the length of the
+array.
 
-  $I0 = does $P2, $P0  # Yes
+We mention "other array types" above, not as a vague suggestion that there may
+be other types of arrays eventually, but as an indication that we actually
+have several types of array PMCs in Parrot's core. Parrot comes with
+C<FixedPMCArray>, C<ResizablePMCArray>, C<FixedIntegerArray>,
+C<ResizableIntegerArray>, C<FixedFloatArray>, C<ResizableFloatArray>,
+C<FixedStringArray>, C<ResizableStringArray>, C<FixedBooleanArray>,
+and C<ResizableBooleanArray> types. These various types of arrays use
+various packing methods to create higher memory efficiency for their contents
+then using a single generic array type would be able to. The trade-off for
+higher memory efficiency is that these array PMCs can only hold a single type
+of data.
 
-We can get a list of roles from our Class PMC:
+The array PMC types that start with "Fixed" have a fixed size and do not
+automatically extend themselves if you attempt to add data to a higher index
+then the array contains. The "Resizable" variants will automatically extend
+themselves as more data are added, but the cost is in algorithmic complexity
+of checking array bounds and reallocating array memory.
 
-  $P3 = $P2.'roles'()
+To retrieve the number of items currently in an array, you can use the
+C<elements> opcode.
 
-Roles are very useful for ensuring that related classes all implement a common
-interface.  
+=begin PIR_FRAGMENT
 
-=head2 Coroutines
+  set $P0, 100         # allocate store for 100 elements
+  set $I0, $P0          # obtain current allocation size
+  elements $I0, $P0     # get element count
 
-X<PIR;Coroutines>
-X<Coroutines>
-We've mentioned coroutines several times before, and we're finally going
-to explain what they are. Coroutines are similar to subroutines except
-that they have an internal notion of I<state> N<And the cool new name!>.
-Coroutines, in addition to performing a normal C<.return> to return
-control flow back to the caller and destroy the lexical environment of
-the subroutine, may also perform a C<.yield> operation. C<.yield> returns
-a value to the caller like C<.return> can, but it does not destroy the
-lexical state of the coroutine. The next time the coroutine is called, it
-continues execution from the point of the last C<.yield>, not at the
-beginning of the coroutine.
+=end PIR_FRAGMENT
 
-In a Coroutine, when we continue from a C<.yield>, the entire lexical
-environment is the same as it was when C<.yield> was called. This
-means that the parameter values don't change, even if we call the
-coroutine with different arguments later.
+Some other useful instructions for working with arrays are C<push>,
+C<pop>, C<shift>, and C<unshift> (you'll find them in
+"PIR Opcodes" in Chapter 11).
 
-=head3 Defining Coroutines
+=head4 Hashes
 
-Coroutines are defined like any ordinary subroutine. They do not require
-any special flag or any special syntax to mark them as being a
-coroutine. However, what sets them apart is the use of the C<.yield>
-directive. C<.yield> plays several roles:
+Z<CHP-9-SECT-3.1.2>
 
-=over 4
+X<PMCs (Polymorphic Containers);hashes>
+The C<Hash>X<Hash PMC> PMC is an unordered aggregate which uses string keys
+to identify elements within it.
 
-=item * Identifies coroutines
+=begin PIR_FRAGMENT
 
-When Parrot sees a yield, it knows to create a Coroutine PMC object
-instead of a Sub PMC.
+  new $P1, "Hash"      # generate a new hash object
+  set $P1["key"], 10   # set key and value
+  set $I0, $P1["key"]   # obtain value for key
+  set $I1, $P1          # number of entries in hash
 
-=item * Creates a continuation
+=end PIR_FRAGMENT
 
-Continuations, as we have already seen, allow us to continue
-execution at the point of the continuation later. It's like a snapshot of
-the current execution environment. C<.yield> creates a continuation in
-the coroutine and stores the continuation object in the coroutine object
-or later resuming from the point of the C<.yield>.
+The C<exists>X<exists opcode (PIR)> opcode tests whether a keyed
+value exists in an aggregate. It returns 1 if it finds the key in the
+aggregate, and returns 0 if it doesn't. It doesn't care if the value
+itself is true or false, only that the key has been set:
 
-=item * Returns a value
+=begin PIR_FRAGMENT
 
-C<.yield> can return a value N<or many values, or no values> to the caller.
-It is basically the same as a C<.return> in this regard.
+  new $P0, "Hash"
+  set $P0["key"], 0
+  exists $I0, $P0["key"] # does a value exist at "key"
+  print $I0             # prints 1
+  print "\n"
 
-=back
+=end PIR_FRAGMENT
 
-Here is a quick example of a simple coroutine:
+The C<delete>X<delete opcode (PIR)> opcode is also useful for working
+with hashes: it removes a key/value pair.
 
-  .sub MyCoro
-    .yield(1)
-    .yield(2)
-    .yield(3)
-    .return(4)
-  .end
+=head4 Iterators
 
-  .sub main :main
-    $I0 = MyCoro()    # 1
-    $I0 = MyCoro()    # 2
-    $I0 = MyCoro()    # 3
-    $I0 = MyCoro()    # 4
-    $I0 = MyCoro()    # 1
-    $I0 = MyCoro()    # 2
-    $I0 = MyCoro()    # 3
-    $I0 = MyCoro()    # 4
-    $I0 = MyCoro()    # 1
-    $I0 = MyCoro()    # 2
-    $I0 = MyCoro()    # 3
-    $I0 = MyCoro()    # 4
-  .end
+Z<CHP-9-SECT-3.1.3>
 
-This is obviously a contrived example, but it demonstrates how the coroutine
-stores it's state. The coroutine stores it's state when we reach a C<.yield>
-directive, and when the coroutine is called again it picks up where it last
-left off. Coroutines also handle parameters in a way that might not be
-intuitive. Here's an example of this:
+Iterators extract values from an aggregate PMC one at a time and without
+extracting duplicates. Iterators are most useful in loops where an action
+needs to be performed on every element in an aggregate. You create an
+iterator by creating a new C<Iterator> PMC, and passing the aggregate PMC
+to C<new> as an additional parameter:
 
-  .sub StoredConstant
-    .param int x
-    .yield(x)
-    .yield(x)
-    .yield(x)
-  .end
+=begin PIR_FRAGMENT
 
-  .sub main :main
-    $I0 = StoredConstant(5)       # $I0 = 5
-    $I0 = StoredConstant(6)       # $I0 = 5
-    $I0 = StoredConstant(7)       # $I0 = 5
-    $I0 = StoredConstant(8)       # $I0 = 8
-  .end
+  new $P1, "Iterator", $P2
 
-Notice how even though we are calling the C<StoredConstant> coroutine with
-different arguments each time, the value of parameter C<x> doesn't change
-until the coroutine's state resets after the last C<.yield>. Remember that
-a continuation takes a snapshot of the current state, and the C<.yield>
-directive takes a continuation. The next time we call the coroutine, it
-invokes the continuation internally, and returns us to the exact same place in
-the exact same condition as we were when we called the C<.yield>. In order
-to reset the coroutine and enable it to take a new parameter, we must either
-execute a C<.return> directive or reach the end of the coroutine.
+=end PIR_FRAGMENT
 
-=head2 Multiple Dispatch
+Alternatively, you can use the C<iter> opcode to do the same thing:
 
-Multiple dispatch is when there are multiple subroutines in a single
-namespace with the same name. These functions must differ, however, in
-their parameter list, or "signature". All subs with the same name get
-put into a single PMC called a MultiSub. The MultiSub is like a list
-of subroutines. When the multisub is invoked, the MultiSub PMC object
-searches through the list of subroutines and searches for the one with
-the closest matching signature. The best match is the sub that gets
-invoked.
+=begin PIR_FRAGMENT
 
-=head3 Defining MultiSubs
+  iter $P1, $P2     # Same!
 
-MultiSubs are subroutines with the C<:multi> flag applied to them.
-MultiSubs (also called "Multis") must all differ from one another in
-the number and/or type of arguments passed to the function. Having
-two multisubs with the same function signature could result in a
-parsing error, or the later function could overwrite the former one
-in the multi.
+=end PIR_FRAGMENT
 
-Multisubs are defined like this:
+The include file F<iterator.pasm> defines some constants for working
+with iterators. The C<.ITERATE_FROM_START> and C<.ITERATE_FROM_END>
+constants are used to select whether an array iterator starts from the
+beginning or end of the array. Since Hash PMCs are unordered, these two
+constants do not have any affect on Hash iterators.
 
-  .sub 'MyMulti' :multi
-      # does whatever a MyMulti does
-  .end
+A value can be extracted from the iterator using the C<shift> opcode.
+Evaluating the iterator PMC as a boolean returns whether the iterator has
+reached the end of the aggregate or not.
 
-Multis belong to a specific namespace. Functions in different namespaces
-with the same name do not conflict with each other N<this is one of the
-reasons for having multisubs in the first place!>. It's only when
-multiple functions in a single namespace need to have the same name that
-a multi is used.
+=begin PIR_FRAGMENT
 
-Multisubs take a special designator called a I<multi signature>. The multi
-signature tells Parrot what particular combination of input parameters the
-multi accepts. Each multi will have a different signature, and Parrot will
-be able to dispatch to each one depending on the arguments passed. The
-multi signature is specified in the C<:multi> directive:
+  .include "iterator.pasm"
+      new $P2, "Array"
+      push $P2, "a"
+      push $P2, "b"
+      push $P2, "c"
+      new $P1, "Iterator", $P2
+      set $P1, .ITERATE_FROM_START
 
-  .sub 'Add' :multi(I, I)
-    .param int x
-    .param int y
-    .return(x + y)
+  iter_loop:
+      unless $P1, iter_end
+      shift $P5, $P1
+      print $P5                        # prints "a", "b", "c"
+      branch iter_loop
+  iter_end:
+      # ...
+
+=end PIR_FRAGMENT
+
+Hash iterators work similarly to array iterators, but they extract keys
+only. With the key, you can find it's value from the original hash PMC.
+With hashes it's only meaningful to iterate in one direction since they
+don't define any order for their keys.
+
+=begin PIR_FRAGMENT
+
+  .include "iterator.pasm"
+      new $P2, "Hash"
+      set $P2["a"], 10
+      set $P2["b"], 20
+      set $P2["c"], 30
+      new $P1, "Iterator", $P2
+      set $P1, .ITERATE_FROM_START_KEYS
+
+  iter_loop:
+      unless $P1, iter_end
+      shift $S5, $P1                    # one of the keys "a", "b", "c"
+      set $I9, $P2[$S5]
+      print $I9                        # prints e.g. 20, 10, 30
+      branch iter_loop
+  iter_end:
+      # ...
+
+=end PIR_FRAGMENT
+
+=head4 Data structures
+
+Z<CHP-9-SECT-3.1.4>
+
+X<PMCs (Polymorphic Containers);data structures>
+Arrays and hashes can hold any data type, including other aggregates.
+Accessing elements deep within nested data structures is a common
+operation, so PIR provides a way to do it in a single instruction.
+Complex keys specify a series of nested data structures, with each
+individual key separated by a semicolon:
+
+=begin PIR_FRAGMENT
+
+  new $P0, "Hash"
+  new $P1, "Array"
+  set $P1[2], 42
+  set $P0["answer"], $P1
+  set $I1, 2
+  set $I0, $P0["answer";$I1]        # $i = %hash{"answer"}[2]
+  print $I0
+  print "\n"
+
+=end PIR_FRAGMENT
+
+This example builds up a data structure of a hash containing an array.
+The complex key C<P0["answer";I1]> retrieves an element of the array
+within the hash. You can also set a value using a complex key:
+
+=begin PIR_FRAGMENT
+
+  set $P0["answer";0], 5   # %hash{"answer"}[0] = 5
+
+=end PIR_FRAGMENT
+
+The individual keys are integers or strings, or registers with integer
+or string values.
+
+=head3 PMC Assignment
+
+Z<CHP-9-SECT-3.2>
+
+We mentioned before that C<set> on two X<PMCs (Polymorphic
+Containers);assignment> PMCs simply aliases them both to the same object,
+and that C<clone> creates a complete duplicate object. But if you just
+want to assign the value of one PMC to another PMC, you need the
+C<assign>X<assign opcode (PIR)> opcode:
+
+=begin PIR_FRAGMENT
+
+  new $P0, "Int"
+  new $P1, "Int"
+  set $P0, 42
+  set $P2, $P0
+  assign $P1, $P0     # note: $P1 has to exist already
+  inc $P0
+  print $P0          # prints 43
+  print "\n"
+  print $P1          # prints 42
+  print "\n"
+  print $P2          # prints 43
+  print "\n"
+
+=end PIR_FRAGMENT
+
+This example creates two C<Int> PMCs: C<P0> and C<P1>. It gives
+C<P0> a value of 42. It then uses C<set> to give the same value to
+C<P2>, but uses C<assign> to give the value to C<P1>. When C<P0> is
+incremented, C<P2> also changes, but C<P1> doesn't. The destination
+register for C<assign> must have an existing object of the right type
+in it, since C<assign> doesn't create a new object (as with C<clone>)
+or reuse the source object (as with C<set>).
+
+=head3 Properties
+
+Z<CHP-9-SECT-3.3>
+
+X<PMCs (Polymorphic Containers);properties>
+PMCs can have additional values attached to them as "properties" of
+the PMC. What these properties do is entirely up to the language being
+implemented. Most usually properties are used to hold extra metadata about
+the PMC that is used by the high-level language (HLL).
+
+The C<setprop>X<setprop opcode (PIR)> opcode sets the value of a
+named property on a PMC. It takes three arguments: the PMC to be set
+with a property, the name of the property, and a PMC containing the
+value of the property. The C<getprop>X<getprop opcode (PIR)> opcode
+returns the value of a property. It also takes three arguments: the
+PMC to store the property's value, the name of the property, and the
+PMC from which the property value is to be retrieved. Internally a PMCs
+properties are stored in a Hash structure, where the name of the property
+is stored in a special properties Hash.
+
+=begin PIR_FRAGMENT
+
+  new $P0, "String"
+  set $P0, "Zaphod"
+  new $P1, "Int"
+  set $P1, 1
+  setprop $P0, "constant", $P1       # set a property on $P0
+  getprop $P3, "constant", $P0       # retrieve a property on $P0
+  print $P3                          # prints 1
+  print "\n"
+
+=end PIR_FRAGMENT
+
+This example creates a C<String> object in C<P0>, and a C<Int>
+object with the value 1 in C<P1>. C<setprop> sets a property named
+"constant" on the object in C<P0> and gives the property the value in
+C<P1>.N<The "constant" property is ignored by PIR, but may be significant
+to the HLL that set it.> C<getprop> retrieves the value of the property
+"constant" on C<P0> and stores it in C<P3>.
+
+Properties are kept in a separate hash for each PMC. Property values
+are always PMCs, but only references to the actual PMCs. Trying to
+fetch the value of a property that doesn't exist returns a
+C<Undef>.
+
+C<delprop>X<delprop opcode (PIR)> deletes a property from a PMC.
+
+=begin PIR_FRAGMENT
+
+  delprop $P1, "constant"  # delete property
+
+=end PIR_FRAGMENT
+
+You can also return a complete hash of all properties on a PMC with
+C<prophash>X<prophash opcode (PIR)>.
+
+=begin PIR_FRAGMENT
+
+  prophash $P0, $P1         # set $P0 to the property hash of $P1
+
+=end PIR_FRAGMENT
+
+
+=head2 VTABLE Interfaces
+
+Internally, all operations on PMCs are performed by calling various VTABLE
+interfaces.
+
+=head3 Type Conversion
+
+The C<=> operator is very powerful.  Its simplest form stores a value into one
+of the Parrot registers. It can assign a string value to a C<string> register,
+an integer value to an C<int> register, a floating point value into a C<number>
+register, etc. However, the C<=> operator can assign I<any> type of value into
+I<any> type of register; Parrot will handle the conversion for you
+automatically:
+
+=begin PIR_FRAGMENT
+
+  $I0 = 5     # Integer. 5
+  $S0 = $I0   # Stringify. "5"
+  $N0 = $S0   # Numify. 5.0
+  $I0 = $N0   # Intify. 5
+
+=end PIR_FRAGMENT
+
+Notice that conversions between the numeric formats and strings only makes
+sense when the value to convert is a number.
+
+=begin PIR_FRAGMENT
+
+  $S0 = "parrot"
+  $I0 = $S0        # 0
+
+=end PIR_FRAGMENT
+
+An earlier example showed a string literal assigned to a PMC register of type
+C<String>. This works for all the primitive types and their autoboxed PMC
+equivalents:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'Integer'
+  $P0 = 5
+  $S0 = $P0      # Stringify. "5"
+  $N0 = $P0      # Numify. 5.0
+  $I0 = $P0      # Unbox. $I0 = 5
+
+  $P1 = new 'String'
+  $P1 = "5 birds"
+  $S1 = $P1      # Unbox. $S1 = "5 birds"
+  $I1 = $P1      # Intify. 5
+  $N1 = $P1      # Numify. 5.0
+
+  $P2 = new 'Number'
+  $P2 = 3.14
+  $S2 = $P2      # Stringify. "3.14"
+  $I2 = $P2      # Intify. 3
+  $N2 = $P2      # Unbox. $N2 = 3.14
+
+=end PIR_FRAGMENT
+
+=head2 Control Structures
+
+Z<CHP-3-SECT-5>
+
+X<PIR (Parrot intermediate representation);control flow>
+X<control flow;in PIR>
+
+Control flow in PIR occurs entirely with conditional and unconditional branches
+to labels. This may seem simplistic and primitive, but here PIR shows its roots
+as a thin overlay on the assembly language of a virtual processor.  PIR does
+not support high-level looping structures such as C<while> or C<for> loops. PIR
+has some support for basic C<if> branching constructs, but does not support
+more complicated C<if>/C<then>/C<else> branch structures.  
+
+The control structures of high-level languages hew tightly to the semantics of
+those languages; Parrot provides the minimal feature set necessary to implement
+any semantic of an HLL without dictating how that HLL may implement its
+features.  Language agnosticism is an important design goal in Parrot, and
+creates a very flexible and powerful development environment for language
+developers.
+
+X<goto instruction (PIR)>
+The most basic branching instruction is the unconditional branch, C<goto>:
+
+=begin PIR
+
+  .sub 'main'
+      goto L1
+      print "never printed"
+
+  L1:
+      print "after branch"
   .end
 
-  .sub 'Add' :multi(N, N)
-    .param num x
-    .param num y
-    .return(x + y)
+=end PIR
+
+The first C<print> statement never runs because the C<goto> always skips over it
+to the label C<L1>.
+
+The conditional branches combine C<if> or C<unless> with C<goto>.
+
+=begin PIR
+
+  .sub 'main'
+      $I0 = 42
+      if $I0 goto L1
+      say "never printed"
+  L1:
+      say "after branch"
   .end
 
-  .sub Start :main
-    $I0 = Add(1, 2)      # 3
-    $N0 = Add(3.14, 2.0) # 5.14
-    $S0 = Add("a", "b")  # ERROR! No (S, S) variant!
+=end PIR
+
+X<if (conditional);instruction (PIR)> X<unless (conditional);instruction (PIR)>
+In this example, the C<goto> branches to the label C<L1> only if the value
+stored in C<$I0> is true. The C<unless> statement is similar, but it branches
+when the tested value is false.  You can use PMC and STRING registers with
+C<if> and C<unless>.  The op will call the C<get_bool> vtable entry on any PMC
+so used and will convert the STRING to a boolean value.  An undefined value, 0,
+or an empty string are all false values. All other values are true.
+
+The comparison operators (C<E<lt>>, C<E<lt>=>, C<==>, C<!=>, C<E<gt>>,
+C<E<gt>=>) can combine with C<if ...  goto>. These branch when the
+comparison is true:
+
+=begin PIR
+
+  .sub 'main'
+      $I0 = 42
+      $I1 = 43
+      if $I0 < $I1 goto L1
+      say "never printed"
+  L1:
+      say "after branch"
+  .end
+
+=end PIR
+
+This example compares C<$I0> to C<$I1> and branches to the label C<L1> if
+C<$I0> is less than C<$I1>. The C<if $I0 E<lt> $I1 goto L1> statement
+translates directly to the C<lt> branch operation.
+
+Chapter 11's "PIR Instructions" section summarizes the other comparison
+operators.
+
+X<loops;PIR>
+X<PIR (Parrot intermediate representation);loop constructs>
+PIR has no special loop constructs. A combination of conditional and
+unconditional branches handle iteration:
+
+=begin PIR
+
+  .sub 'main'
+      $I0 = 1               # product
+      $I1 = 5               # counter
+
+  REDO:                     # start of loop
+      $I0 = $I0 * $I1
+      dec $I1
+      if $I1 > 0 goto REDO  # end of loop
+
+      say $I0
+  .end
+
+=end PIR
+
+X<do-while style loop;(PIR)>
+This example calculates the factorial C<5!>. Each time through the loop it
+multiplies C<$I0> by the current value of the counter C<$I1>, decrements the
+counter, and branches to the start of the loop.  The loop ends when C<$I1>
+counts down to 0. This is a I<do while>-style loop with the condition test at
+the end, so the code always runs the first time through.
+
+X<while-style loop (PIR)>
+For a I<while>-style loop with the condition test at the start, use a
+conditional branch with an unconditional branch:
+
+=begin PIR
+
+  .sub 'main'
+      $I0 = 1               # product
+      $I1 = 5               # counter
+
+  REDO:                     # start of loop
+      if $I1 <= 0 goto LAST
+      $I0 = $I0 * $I1
+      dec $I1
+      goto REDO
+  LAST:                     # end of loop
+
+      say $I0
+  .end
+
+=end PIR
+
+This example tests the counter C<$I1> at the start of the loop. At the
+end of the loop, it unconditionally branches back to the start of the
+loop and tests the condition again. The loop ends when the counter
+C<$I1> reaches 0 and the C<if> branches to the C<LAST> label. If the
+counter isn't a positive number before the loop, the loop never
+executes.
+
+You can build any high-level flow control construct from conditional and
+unconditional branches; the lowest level of computer hardware works this way.
+All modern programming languages use branching constructs to implement their
+most complex flow control devices.
+
+
+Branch instructions transfer control to a relative offset from the
+current instruction. The rightmost argument to every branch opcode is
+a label, which the assembler converts to the integer value of the
+offset. You can also branch on a literal integer value, but there's
+rarely any need to do so. The simplest branch instruction is
+C<branch>:
+
+=begin PIR_FRAGMENT
+
+    branch L1                # branch 4
+    print "skipped\n"
+  L1:
+    print "after branch\n"
+
+=end PIR_FRAGMENT
+
+This example unconditionally branches to the location of the label
+C<L1>, skipping over the first C<print> statement.
+
+Jump instructions transfer control to an absolute address. The C<jump>
+opcode doesn't calculate an address from a label, so it's used
+together with C<set_addr>:
+
+=begin PIR_FRAGMENT
+
+    set_addr $I0, L1
+    jump $I0
+    print "skipped\n"
+    end
+  L1:
+    print "after jump\n"
+
+=end PIR_FRAGMENT
+
+The C<set_addr>X<set_addr opcode (PIR)> opcode takes a label or an
+integer offset and returns an absolute address.
+
+You've probably noticed the C<end>X<end opcode (PIR)> opcode as the
+last statement in many examples above. This terminates the execution
+of the current run loop. Terminating the main bytecode segment (the
+first run loop) stops the interpreter. Without the C<end> statement,
+execution just falls off the end of the bytecode segment, with a good
+chance of crashing the interpreter.
+
+=head3 Conditional Branches
+
+Z<CHP-9-SECT-4.1>
+
+X<PIR (Parrot assembly language);conditional branches>
+X<conditional branches in PIR>
+Unconditional jumps and branches aren't really enough for flow
+control. What you need to implement the control structures of
+high-level languages is the ability to select different actions based
+on a set of conditions. PIR has opcodes that conditionally branch
+based on the truth of a single value or the comparison of two values.
+The following example has C<if>X<if (conditional);opcode (PIR)> and
+C<unless>X<unless (conditional);opcode (PIR)> conditional branches:
+
+=begin PIR_FRAGMENT
+
+    set $I0, 0
+    if $I0, TRUE
+    unless $I0, FALSE
+    print "skipped\n"
+    end
+  TRUE:
+    print "shouldn't happen\n"
+    end
+  FALSE:
+    print "the value was false\n"
+
+=end PIR_FRAGMENT
+
+C<if> branches if its first argument is a true value, and C<unless>
+branches if its first argument is a false value. In this case, the
+C<if> doesn't branch because C<I0> is false, but the C<unless> does
+branch.
+The comparison branching opcodes compare two values and branch if the
+stated relation holds true. These are
+C<eq>X<eq (equal);opcode (PIR)> (branch when equal),
+C<ne>X<ne (not equal);opcode (PIR)> (when not equal),
+C<lt>X<lt (less than);opcode (PIR)> (when less than),
+C<gt>X<gt (greater than);opcode (PIR)> (when greater than),
+C<le>X<le (less than or equal);opcode (PIR)> (when less than or
+equal), and C<ge>X<ge (greater than or equal);opcode (PIR)> (when
+greater than or equal). The two compared arguments must be the same
+register type:
+
+=begin PIR_FRAGMENT
+
+    set $I0, 4
+    set $I1, 4
+    eq $I0, $I1, EQUAL
+    print "skipped\n"
+    end
+  EQUAL:
+    print "the two values are equal\n"
+
+=end PIR_FRAGMENT
+
+This compares two integers, C<I0> and C<I1>, and branches if they're
+equal. Strings of different character sets or encodings are converted
+to Unicode before they're compared. PMCs have a C<cmp> vtable method.
+This gets called on the left argument to perform the comparison of the
+two objects.
+
+The comparison opcodes don't specify if a numeric or string comparison
+is intended. The type of the register selects for integers, floats,
+and strings. With PMCs, the vtable method C<cmp> or C<is_equal> of the
+first argument is responsible for comparing the PMC meaningfully with
+the other operand. If you need to force a numeric or string comparison
+on two PMCs, use the alternate comparison opcodes that end in the
+C<_num> and C<_str> suffixes.
+
+=begin PIR_FRAGMENT
+
+  eq_str $P0, $P1, label     # always a string compare
+  gt_num $P0, $P1, label     # always numerically
+
+=end PIR_FRAGMENT
+
+Finally, the C<eq_addr> opcode branches if two PMCs or strings are
+actually the same object (have the same address):
+
+=begin PIR_FRAGMENT
+
+  eq_addr $P0, $P1, same_pmcs_found
+
+=end PIR_FRAGMENT
+
+=head3 Iteration
+
+Z<CHP-9-SECT-4.2>
+
+X<iteration;in PIR>
+X<PIR (Parrot assembly language);iteration>
+PIR doesn't define high-level loop constructs. These are built up
+from a combination of conditional and unconditional branches. A
+I<do-while>X<do-while style loop;(PIR)> style loop can be constructed
+with a single conditional branch:
+
+=begin PIR_FRAGMENT
+
+    set $I0, 0
+    set $I1, 10
+  REDO:
+    inc $I0
+    print $I0
+    print "\n"
+    lt $I0, $I1, REDO
+
+=end PIR_FRAGMENT
+
+This example prints out the numbers 1 to 10. The first time through,
+it executes all statements up to the C<lt> statement.  If the
+condition evaluates as true (C<I0> is less than C<I1>) it branches to
+the C<REDO> label and runs the three statements in the loop body
+again. The loop ends when the condition evaluates as false.
+
+Conditional and unconditional branches can build up quite complex
+looping constructs, as follows:
+
+=begin PIR_FRAGMENT
+
+    # loop ($i=1; $i<=10; $i++) {
+    #    print "$i\n";
+    # }
+  loop_init:
+    set $I0, 1
+    branch loop_test
+  loop_body:
+    print $I0
+    print "\n"
+    branch loop_continue
+  loop_test:
+    le $I0, 10, loop_body
+    branch out
+  loop_continue:
+    inc $I0
+    branch loop_test
+  out:
+    # ... 
+
+=end PIR_FRAGMENT
+
+X<loops;PIR>
+X<PIR (Parrot assembly language);loops>
+This example emulates a X<counter-controlled loop> counter-controlled
+loop like Perl 6's C<loop> keyword or C's C<for>. The first time
+through the loop it sets the initial value of the counter in
+C<loop_init>, tests that the loop condition is met in C<loop_test>,
+and then executes the body of the loop in C<loop_body>. If the test
+fails on the first iteration, the loop body will never execute. The
+end of C<loop_body> branches to C<loop_continue>, which increments the
+counter and then goes to C<loop_test> again. The loop ends when the
+condition fails, and it branches to C<out>. The example is more
+complex than it needs to be just to count to 10, but it nicely shows
+the major components of a
+loop.
+
+=head2 Macros
+
+=for author
+
+Needs supplementing; needs moving.
+
+=end for
+
+=head2 Subroutines
+
+X<PIR (Parrot intermediate representation);subroutine> X<subroutine (PIR)>
+Subroutines in PIR are roughly equivalent to the subroutines or methods of a
+high-level language.  All code in a PIR source file must occur within a
+subroutine.  The simplest syntax for a PIR subroutine starts with the C<.sub>
+directive and ends with the C<.end> directiveN<The name C<main> is only a
+convention.>:
+
+=begin PIR
+
+  .sub 'main'
+      say "Hello, Polly."
+  .end
+
+=end PIR
+
+This example defines a subroutine named C<main> that prints a string C<"Hello,
+Polly.">. Parrot will normally execute the first subroutine it encounters in
+the first file it runs, but you can flag any subroutine as the first one to
+execute with the C<:main> marker:
+
+=begin PIR
+
+  .sub 'first'
+      say "Polly want a cracker?"
+  .end
+
+  .sub 'second' :main
+      say "Hello, Polly."
+  .end
+
+=end PIR
+
+This code prints out "Hello, Polly." but not "Polly want a cracker?".  Though
+the C<first> function appears first in the source code, C<second> has the
+C<:main> flag and gets called.  C<first> is never called.  Revising that
+program produces different results:
+
+=begin PIR
+
+  .sub 'first' :main
+      say "Polly want a cracker?"
+  .end
+
+  .sub 'second'
+      say "Hello, Polly."
+  .end
+
+=end PIR
+
+The output now is "Polly want a cracker?". Execution in PIR starts at the
+C<:main> function and continues until that function ends.  To perform other
+operations, you must call other functions explicitly.  Chapter 4 describes
+subroutines and their uses.
+
+
+X<PIR (Parrot intermediate representation);subroutines>
+X<subroutines;in PIR>
+The most basic building block of code reuse in PIR is the subroutine. A large
+program may perform a calculation like "the factorial of a number" several
+times.  Subroutines abstract this behavior into a single, named, stand-alone
+unit. PIR is a subroutine-based language in that all code in PIR must exist in
+a subroutine. Execution starts in the C<:main> subroutine, which itself can
+call other subroutines.  Subroutines can fit together into more elaborate
+chunks of code reusability such as methods and objects.
+
+Parrot supports multiple high-level languages.  Each language uses a different
+syntax for defining and calling subroutines. The goal of PIR is not to be a
+high-level language in itself, but to provide the basic tools that other
+languages can use to implement them. PIR's subroutine syntax may seem very
+primitive for this reason.
+
+=head3 Parrot Calling Conventions
+
+Z<CHP-4-SECT-1>
+
+X<PIR (Parrot intermediate representation);subroutines;Parrot calling conventions>
+X<subroutines;Parrot calling conventions;in PIR>
+
+The C<.sub> directive defines globally accessible subroutine
+objects.
+
+Subroutine objects of all kinds can be called with the
+C<invoke>X<invoke opcode (PIR)> opcode. There is also an C<invoke>
+C<PR<x>> instruction for calling objects held in a different register.
+
+The C<invokecc>X<invokecc opcode (PIR)> opcode is like C<invoke>, but it
+also creates and stores a new return continuation. When the
+called subroutine invokes this return continuation, it returns control
+to the instruction after the function call. This kind of call is known
+as Continuation Passing Style (CPS).
+X<CPS (Continuation Passing Style)>
+X<Continuation Passing Style (CPS)>
+
+The way that Parrot calls a subroutine -- passing arguments, altering control
+flow, and returning results -- is the "Parrot Calling Conventions" (PCC).
+Parrot generally hides the details of PCC from the programmer.  PIR has several
+constructs to gloss over these details, and the average programmer will not
+need to worry about them.  PCC uses the Continuation Passing Style
+X<Continuation Passing Style (CPS)>X<CPS (Continuation Passing Style)> (CPS) to
+pass control to subroutines and back again. Again, the details are irrelevant
+for most uses, but the power is available to anyone who wants to take advantage
+of it.
+
+=head3 Subroutine Calls
+
+X<PIR (Parrot intermediate representation);subroutine calls>
+PIR's simplest subroutine call syntax looks much like a subroutine
+call from a high-level language. This example calls the subroutine
+C<fact> with two arguments and assigns the result to C<$I0>:
+
+  $I0 = 'fact'(count, product)
+
+This simple statement hides much complexity. It generates a subroutine PMC
+object, creates a continuation PMC object to represent the control flow up to
+this point, passes the arguments, looks up the subroutine by name (and by
+signature, if necessary)), calls the subroutine, and assigns the results of the
+call to the appropriate integer register. This is all in addition to the
+computation the subroutine itself performs.
+
+The single line subroutine call is incredibly convenient, but it isn't always
+flexible enough. PIR also has a more verbose call syntax that is still more
+convenient than manual calls. This example looks up the subroutine C<fact> out
+in the global symbol table and calls it:
+
+  find_global $P1, "fact"
+
+  .begin_call
+    .arg count
+    .arg product
+    .call $P1
+    .result $I0
+  .end_call
+
+X<.arg directive>
+X<.result directive>
+The whole chunk of code from C<.begin_call> to C<.end_call> acts as a single
+unit. The C<.arg> directive sets up and passes arguments to the call. The
+C<.call> directive calls the subroutine and identifies the point at which to
+return control flow after the subroutine has completed. The C<.result>
+directive retrieves returned values from the call.
+
+=head3 Subroutine Declarations
+
+X<.param directive> In addition to syntax for subroutine calls, PIR provides
+syntax for subroutine definitions: the C<.sub> and C<.end> directives shown in
+earlier examples.  The C<.param> directive defines input parameters and creates
+local named variables for them (similar to C<.local>):
+
+  .param int c
+
+X<.return directive>
+The C<.return> directive allows the subroutine to return control flow
+to the calling subroutine, and optionally returns result output values.
+
+Here's a complete code example that implements the factorial algorithm.  The
+subroutine C<fact> is a separate subroutine, assembled and processed after the
+C<main> function.  Parrot resolves global symbols like the C<fact> label
+between different units.
+
+=begin PIR
+
+  # factorial.pir
+  .sub 'main' :main
+     .local int count
+     .local int product
+     count   = 5
+     product = 1
+
+     $I0 = 'fact'(count, product)
+
+     say $I0
+  .end
+
+  .sub 'fact'
+     .param int c
+     .param int p
+
+  loop:
+     if c <= 1 goto fin
+     p = c * p
+     dec c
+     branch loop
+  fin:
+     .return (p)
+  .end
+
+=end PIR
+
+This example defines two local named variables, C<count> and C<product>, and
+assigns them the values 1 and 5. It calls the C<fact> subroutine with both
+variables as arguments.  The C<fact> subroutine uses C<.param> to retrieve
+these parameters and C<.return> to return the result.  The final printed result
+is 120.
+
+As usual, execution of the program starts at the C<:main> subroutine.
+
+=head3 Parameters and Arguments
+
+=head4 Named Parameters
+
+=for author
+
+We have to get our terms straight here.  Which are "arguments" (passed in) and
+which are "parameters" (processed from within).
+
+=end for
+
+X<positional arguments>
+X<named arguments>
+Parameters passed only by their order are I<positional arguments>. The only
+differentiator between positional arguments is their positions in the function
+call.  Putting positional arguments in a different order will produce different
+effects, or may cause errors. Parrot also supports I<named parameters>. Instead
+of passing parameters by their position in the string, parameters are passed by
+name and can be in any order.  Here's an example:
+
+=begin PIR
+
+ .sub 'MySub'
+    .param string yrs :named("age")
+    .param string call :named("name")
+    $S0 = "Hello " . call
+    $S1 = "You are " . yrs
+    $S1 = $S1 . " years old"
+    say $S0
+    say $S1
+ .end
+
+ .sub 'main' :main
+    'MySub'("age" => 42, "name" => "Bob")
+ .end
+
+=end PIR
+
+You can also pass these pairs in the opposite order:
+
+=begin PIR
+
+ .sub 'main' :main
+    'MySub'("name" => "Bob", "age" => 42)    # Same!
+ .end
+
+=end PIR
+
+Named arguments can be a big help because you don't have to worry about the
+exact order of variables, especially as argument lists get very long.
+
+=head4 Optional Parameters
+
+X<optional arguments>
+Some functions have arguments with appropriate default values, so that callers
+don't always have to pass them.  Parrot provides a mechanism to identify
+optional argument.  Parrot also provides a flag value to determine if the
+caller has passed in an optional argument.
+
+Optional parameters appear in PIR as if they're actually I<two> parameters:
+the value and its flag:
+
+  .param string name     :optional
+  .param int    has_name :opt_flag
+
+The C<:optional> flag specifies that the given parameter is optional.  The
+C<:opt_flag> specifies an integer which parameter contains a boolean flag; this
+flag is true if the value was passed, and false otherwise. To provide a default
+value for an optional parameter, you can write:
+
+    .param string name     :optional
+    .param int    has_name :opt_flag
+
+    if has_name goto we_have_a_name
+    name = "Default value"
+  we_have_a_name:
+
+Optional parameters can be positional or named parameters. When using them with
+positional parameters, they must appear at the end of the list of positional
+parameters. Also, the C<:opt_flag> parameter must always appear directly after
+the C<:optional> parameter.
+
+  .sub 'Foo'
+    .param int optvalue :optional
+    .param int hasvalue :opt_flag
+    .param pmc notoptional          # WRONG!
+    ...
+
+  .sub 'Bar'
+     .param int hasvalue :opt_flag
+     .param int optvalue :optional  # WRONG!
+     ...
+
+  .sub 'Baz'
+    .param int optvalue :optional
+    .param pmc notoptional
+    .param int hasvalue :opt_flag   # WRONG!
+    ...
+
+You may mix optional parameters with named parameters:
+
+  .sub 'MySub'
+    .param int value     :named("answer") :optional
+    .param int has_value :opt_flag
+    ...
+
+You can call this function in two ways:
+
+  'MySub'("answer" => 42)  # with a value
+  'MySub'()                # without
+
+=head4 Commandline Arguments
+
+Programs written in Parrot have access to arguments passed on the command
+line:
+
+=begin PIR
+
+  .sub 'MyMain' :main
+    .param pmc all_args :slurpy
+    # ...
+  .end
+
+=end PIR
+
+=for author
+
+Please verify and expand.
+
+=end for
+
+The C<all_args> PMC is a ResizableStringArray PMC, which means you can loop
+over the results, access them individually, or even modify them.
+
+=head3 Continuations
+
+X<continuations>
+
+A continuation is a subroutine that captures a complete copy of the
+caller's context. Invoking a
+continuation starts or restarts it at the entry point:
+
+=begin PIR_FRAGMENT_INVALID
+
+    new $P1, "Integer"
+    set $P1, 5
+
+    newsub $P0, 'Continuation', _con
+  _con:
+    print "in cont "
+    print $P1
+    print "\n"
+    dec $P1
+    unless $P1, done
+    invoke                        # $P0
+  done:
+    print "done\n"
+
+=end PIR_FRAGMENT_INVALID
+
+This prints:
+
+  in cont 5
+  in cont 4
+  in cont 3
+  in cont 2
+  in cont 1
+  done
+
+Continuations are a kind of subroutine that take a snapshots of control
+flow. They are frozen images of the current
+execution state of the VM. Once you have a continuation, you can invoke it to
+return to the point where the continuation was first created. It's like a
+magical timewarp that allows the developer to arbitrarily move control flow
+back to any previous point in the program.
+
+Continuations are like any other PMC; you can create one with the C<new> opcode:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'Continuation'
+
+=end PIR_FRAGMENT
+
+The new continuation starts off in an undefined state. If you attempt to invoke
+a new continuation without initializing it, Parrot will throw an exception.  To
+prepare the continuation for use, assign it a destination label with the
+C<set_addr> opcode:
+
+=begin PIR_FRAGMENT
+
+    $P0 = new 'Continuation'
+    set_addr $P0, my_label
+
+  my_label:
+    # ...
+
+=end PIR_FRAGMENT
+
+To jump to the continuation's stored label and return the context to the state
+it was in I<at the point of its creation>, invoke the continuation:
+
+=begin PIR_FRAGMENT_INVALID
+
+  invoke $P0  # Explicit using "invoke" opcode
+  $P0()       # Same, but nicer syntax
+
+=end PIR_FRAGMENT_INVALID
+
+Even though you can use the subroutine notation C<$P0()> to invoke the
+continuation, it doesn't make any sense to pass arguments or obtain return
+values:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'Continuation'
+  set_addr $P0, my_label
+
+  $P0(1, 2)      # WRONG!
+
+  $P1 = $P0()    # WRONG!
+
+=end PIR_FRAGMENT
+
+
+=head4 Continuation Passing Style
+
+X<continuation passing style>
+X<CPS>
+
+Parrot uses continuations internally for control flow. When Parrot
+invokes a function, it creates a continuation representing the
+current point in the program.  It passes this continuation as an invisible
+parameter to the function call.  When that function returns, it invokes the
+continuation -- in effect, it performs a goto to the point of creation of that
+continuation.  If you have a continuation, you can invoke it to return to its
+point of creation any time you want.
+
+This type of flow control -- invoking continuations instead of performing bare
+jumps -- is X<Continuation Passing Style;CPS> Continuation Passing Style (CPS).
+
+
+
+=head4 Tailcalls
+
+In many cases, a subroutine will set up and call another subroutine, and then
+return the result of the second call directly. This is a X<tailcall> tailcall,
+and is an important opportunity for optimization.  Here's a contrived example
+in pseudocode:
+
+  call add_two(5)
+
+  subroutine add_two(value)
+    value = add_one(value)
+    return add_one(value)
+
+In this example, the subroutine C<add_two> makes two calls to c<add_one>. The
+second call to C<add_one> is the return value. C<add_one> gets called; its
+result gets returned to the caller of C<add_two>.  Nothing in C<add_two> uses
+that return value directly.
+
+A simple optimization is available for this type of code.  The second call to
+C<add_one> can return to the same place that C<add_two> returns; therefore,
+it's perfectly safe and correct to use the same return continuation that
+C<add_two> uses. The two subroutine calls can share a return continuation,
+instead of having to create a new continuation for each call.
+
+X<.tailcall directive>
+
+PIR provides the C<.tailcall> directive to identify similar situations.  Use it
+in place of the C<.return> directive. C<.tailcall> performs this optimization
+by reusing the return continuation of the parent function to make the tailcall:
+
+=begin PIR
+
+  .sub 'main' :main
+      .local int value
+      value = add_two(5)
+      say value
+  .end
+
+  .sub 'add_two'
+      .param int value
+      .local int val2
+      val2 = add_one(value)
+      .tailcall add_one(val2)
+  .end
+
+  .sub 'add_one'
+      .param int a
+      .local int b
+      b = a + 1
+      .return (b)
+  .end
+
+=end PIR
+
+This example above will print out the correct value "7".
+
+=head3 Native Call Interface
+
+Z<CHP-9-SECT-7.2>
+
+X<subroutines;calling conventions;NCI>
+A special version of the Parrot calling conventions are used by the
+X<NCI (Native Call Interface)> Native Call Interface (NCI) for calling
+subroutines with a known prototype in shared libraries. This is not
+really portable across all libraries, but it's worth a short example.
+This is a simplified version of the first test in F<t/pmc/nci.t>:
+
+=begin PIR_FRAGMENT
+
+    loadlib $P1, "libnci_test"      # get library object for a shared lib
+    print "loaded\n"
+    dlfunc $P0, $P1, "nci_dd", "dd" # obtain the function object
+    print "dlfunced\n"
+    set $I0, 1                      # prototype used - unchecked
+    set_args "0", 4.0               # set the argument
+    get_results "0", $N5            # prepare to store the return value
+    invokecc $P0                    # call nci_dd
+    ne $N5, 8.0, nok_1              # the test functions returns 2*arg
+    print "ok 1\n"
+    end
+    nok_1:
+    #...
+
+=end PIR_FRAGMENT
+
+This example shows two new instructions: C<loadlib> and C<dlfunc>. The
+C<loadlib>X<loadlib opcode (PIR)> opcode obtains a handle for a shared
+library. It searches for the shared library in the current directory,
+in F<runtime/parrot/dynext>, and in a few other configured
+directories. It also tries to load the provided filename unaltered and
+with appended extensions like C<.so> or C<.dll>. Which extensions it
+tries depends on the OS Parrot is running on.
+
+The C<dlfunc>X<dlfunc opcode (PIR)> opcode gets a function object from a
+previously loaded library (second argument) of a specified name (third
+argument) with a known function signature (fourth argument). The
+function signature is a string where the first character is the return
+value and the rest of the parameters are the function parameters. The
+characters used in X<NCI (Native Call Interface);function signatures>
+NCI function signatures are listed in Table 9-5.
+
+=begin table picture Function signature letters
+
+Z<CHP-9-TABLE-5>
+
+=headrow
+
+=row
+
+=cell Character
+
+=cell Register set
+
+=cell C type
+
+=bodyrows
+
+=row
+
+=cell C<v>
+
+=cell -
+
+=cell void (no return value)
+
+=row
+
+=cell C<c>
+
+=cell C<I>
+
+=cell char
+
+=row
+
+=cell C<s>
+
+=cell C<I>
+
+=cell short
+
+=row
+
+=cell C<i>
+
+=cell C<I>
+
+=cell int
+
+=row
+
+=cell C<l>
+
+=cell C<I>
+
+=cell long
+
+=row
+
+=cell C<f>
+
+=cell C<N>
+
+=cell float
+
+=row
+
+=cell C<d>
+
+=cell C<N>
+
+=cell double
+
+=row
+
+=cell C<t>
+
+=cell C<S>
+
+=cell char *
+
+=row
+
+=cell C<p>
+
+=cell C<P>
+
+=cell void * (or other pointer)
+
+=row
+
+=cell C<I>
+
+=cell -
+
+=cell Parrot_Interp *interpreter
+
+=row
+
+=cell C<C>
+
+=cell -
+
+=cell a callback function pointer
+
+=row
+
+=cell C<D>
+
+=cell -
+
+=cell a callback function pointer
+
+=row
+
+=cell C<Y>
+
+=cell C<P>
+
+=cell the subroutine C<C> or C<D> calls into
+
+=row
+
+=cell C<Z>
+
+=cell C<P>
+
+=cell the argument for C<Y>
+
+=end table
+
+For more information on callback functions, read the documentation in
+F<docs/pdds/pdd16_native_call.pod> and F<docs/pmc/struct.pod>.
+
+
+
+=head3 Coroutines
+
+X<PIR;Coroutines>
+X<Coroutines>
+
+As we mentioned in the previous chapter, coroutines are
+X<subroutines;coroutines> subroutines that
+can suspend themselves and return control to the caller--and then pick
+up where they left off the next time they're called, as if they never
+left.
+
+X<coroutines>
+In PIR, coroutines are subroutine-like objects:
+
+=begin PIR_FRAGMENT_INVALID
+
+  newsub P0, .Coroutine, _co_entry
+
+=end PIR_FRAGMENT_INVALID
+
+The C<Coroutine> object has its own user stack, register frame stacks,
+control stack, and pad stack. The pad stack is inherited from the
+caller. The coroutine's control stack has the caller's control stack
+prepended, but is still distinct. When the coroutine invokes itself,
+it returns to the caller and restores the caller's context (basically
+swapping all stacks). The next time the coroutine is invoked, it
+continues to execute from the point at which it previously returned:
+
+=begin PIR_FRAGMENT_INVALID
+
+    new_pad 0                # push a new lexical pad on stack
+    new P0, "Int"            # save one variable in it
+    set P0, 10
+    store_lex -1, "var", P0
+
+    newsub P0, .Coroutine, _cor
+                             # make a new coroutine object
+    saveall                  # preserve environment
+    invoke                   # invoke the coroutine
+    restoreall
+    print "back\n"
+    saveall
+    invoke                   # invoke coroutine again
+    restoreall
+    print "done\n"
+    pop_pad
+    end
+
+  _cor:
+    find_lex P1, "var"       # inherited pad from caller
+    print "in cor "
+    print P1
+    print "\n"
+    inc P1                   # var++
+    saveall
+    invoke                   # yield(  )
+    restoreall
+    print "again "
+    branch _cor              # next invocation of the coroutine
+
+=end PIR_FRAGMENT_INVALID
+
+This prints out the result:
+
+  in cor 10
+  back
+  again in cor 11
+  done
+
+X<invoke opcode (PIR);coroutines and>
+The C<invoke> inside the coroutine is commonly referred to as
+I<yield>. The coroutine never ends. When it reaches the bottom, it
+branches back up to C<_cor> and executes until it hits C<invoke>
+again.
+
+The interesting part about this example is that the coroutine yields
+in the same way that a subroutine is called. This means that the
+coroutine has to preserve its own register values. This example uses
+C<saveall> but it could have only stored the registers the coroutine
+actually used. Saving off the registers like this works because
+coroutines have their own register frame stacks.
+
+We've mentioned coroutines several times before, and we're finally going
+to explain what they are. Coroutines are similar to subroutines except
+that they have an internal notion of I<state> N<And the cool new name!>.
+Coroutines, in addition to performing a normal C<.return> to return
+control flow back to the caller and destroy the lexical environment of
+the subroutine, may also perform a C<.yield> operation. C<.yield> returns
+a value to the caller like C<.return> can, but it does not destroy the
+lexical state of the coroutine. The next time the coroutine is called, it
+continues execution from the point of the last C<.yield>, not at the
+beginning of the coroutine.
+
+In a Coroutine, when we continue from a C<.yield>, the entire lexical
+environment is the same as it was when C<.yield> was called. This
+means that the parameter values don't change, even if we call the
+coroutine with different arguments later.
+
+Coroutines are defined like any ordinary subroutine. They do not require
+any special flag or any special syntax to mark them as being a
+coroutine. However, what sets them apart is the use of the C<.yield>
+directive. C<.yield> plays several roles:
+
+=over 4
+
+=item * Identifies coroutines
+
+When Parrot sees a yield, it knows to create a Coroutine PMC object
+instead of a Sub PMC.
+
+=item * Creates a continuation
+
+Continuations, as we have already seen, allow us to continue
+execution at the point of the continuation later. It's like a snapshot of
+the current execution environment. C<.yield> creates a continuation in
+the coroutine and stores the continuation object in the coroutine object
+or later resuming from the point of the C<.yield>.
+
+=item * Returns a value
+
+C<.yield> can return a value N<or many values, or no values> to the caller.
+It is basically the same as a C<.return> in this regard.
+
+=back
+
+Here is a quick example of a simple coroutine:
+
+  .sub 'MyCoro'
+    .yield(1)
+    .yield(2)
+    .yield(3)
+    .return(4)
+  .end
+
+  .sub 'main' :main
+    $I0 = MyCoro()    # 1
+    $I0 = MyCoro()    # 2
+    $I0 = MyCoro()    # 3
+    $I0 = MyCoro()    # 4
+    $I0 = MyCoro()    # 1
+    $I0 = MyCoro()    # 2
+    $I0 = MyCoro()    # 3
+    $I0 = MyCoro()    # 4
+    $I0 = MyCoro()    # 1
+    $I0 = MyCoro()    # 2
+    $I0 = MyCoro()    # 3
+    $I0 = MyCoro()    # 4
+  .end
+
+This is obviously a contrived example, but it demonstrates how the coroutine
+stores it's state. The coroutine stores it's state when we reach a C<.yield>
+directive, and when the coroutine is called again it picks up where it last
+left off. Coroutines also handle parameters in a way that might not be
+intuitive. Here's an example of this:
+
+  .sub 'StoredConstant'
+    .param int x
+    .yield(x)
+    .yield(x)
+    .yield(x)
+  .end
+
+  .sub 'main' :main
+    $I0 = StoredConstant(5)       # $I0 = 5
+    $I0 = StoredConstant(6)       # $I0 = 5
+    $I0 = StoredConstant(7)       # $I0 = 5
+    $I0 = StoredConstant(8)       # $I0 = 8
+  .end
+
+Notice how even though we are calling the C<StoredConstant> coroutine with
+different arguments each time, the value of parameter C<x> doesn't change
+until the coroutine's state resets after the last C<.yield>. Remember that
+a continuation takes a snapshot of the current state, and the C<.yield>
+directive takes a continuation. The next time we call the coroutine, it
+invokes the continuation internally, and returns us to the exact same place in
+the exact same condition as we were when we called the C<.yield>. In order
+to reset the coroutine and enable it to take a new parameter, we must either
+execute a C<.return> directive or reach the end of the coroutine.
+
+=head3 Multiple Dispatch
+
+Multiple dispatch is when there are multiple subroutines in a single
+namespace with the same name. These functions must differ, however, in
+their parameter list, or "signature". All subs with the same name get
+put into a single PMC called a MultiSub. The MultiSub is like a list
+of subroutines. When the multisub is invoked, the MultiSub PMC object
+searches through the list of subroutines and searches for the one with
+the closest matching signature. The best match is the sub that gets
+invoked.
+
+MultiSubs are subroutines with the C<:multi> flag applied to them.
+MultiSubs (also called "Multis") must all differ from one another in
+the number and/or type of arguments passed to the function. Having
+two multisubs with the same function signature could result in a
+parsing error, or the later function could overwrite the former one
+in the multi.
+
+Multisubs are defined like this:
+
+  .sub 'MyMulti' :multi
+      # does whatever a MyMulti does
+  .end
+
+Multis belong to a specific namespace. Functions in different namespaces
+with the same name do not conflict with each other N<this is one of the
+reasons for having multisubs in the first place!>. It's only when
+multiple functions in a single namespace need to have the same name that
+a multi is used.
+
+Multisubs take a special designator called a I<multi signature>. The multi
+signature tells Parrot what particular combination of input parameters the
+multi accepts. Each multi will have a different signature, and Parrot will
+be able to dispatch to each one depending on the arguments passed. The
+multi signature is specified in the C<:multi> directive:
+
+  .sub 'Add' :multi(I, I)
+    .param int x
+    .param int y
+    .return(x + y)
+  .end
+
+  .sub 'Add' :multi(N, N)
+    .param num x
+    .param num y
+    .return(x + y)
+  .end
+
+  .sub 'Start' :main
+    $I0 = Add(1, 2)      # 3
+    $N0 = Add(3.14, 2.0) # 5.14
+    $S0 = Add("a", "b")  # ERROR! No (S, S) variant!
+  .end
+
+Multis can take I, N, S, and P types, but they can also use C<_> (underscore)
+to denote a wildcard, and a string that can be the name of a particular PMC
+type:
+
+  .sub 'Add' :multi(I, I)  # Two integers
+    ...
+
+  .sub 'Add' :multi(I, 'Float')  # An integer and Float PMC
+    ...
+
+                           # Two Integer PMCs
+  .sub 'Add' :multi('Integer', _)
+    ...
+
+When we call a multi PMC, Parrot will try to take the most specific
+best-match variant, and will fall back to more general variants if a perfect
+best-match cannot be found. So if we call C<'Add'(1, 2)>, Parrot will dispatch
+to the C<(I, I)> variant. If we call C<'Add'(1, "hi")>, Parrot will match the
+C<(I, _)> variant, since the string in the second argument doesn't match C<I>
+or C<'Float'>. Parrot can also choose to automatically promote one of the I,
+N, or S values to an Integer, Float, or String PMC.
+
+To make the decision about which multi variant to call, Parrot takes a
+I<Manhattan Distance> between the two. Parrot calculates the I<distance>
+between the multi signatures and the argument signature. Every difference
+counts as one step. A difference can be an autobox from a primitive type
+to a PMC, or the conversion from one primitive type to another, or the
+matching of an argument to a C<_> wildcard. After Parrot calculates the
+distance to each variant, it calls the function with the lowest distance.
+Notice that it's possible to define a variant that is impossible to call:
+for every potential combination of arguments there is a better match. This
+isn't necessarily a common occurrence, but it's something to watch out for
+in systems with a lot of multis and a limited number of data types in use.
+
+=head3 Sub PMCs
+
+Subroutines are a PMC type in Parrot. You can store them in PMC registers and
+manipulate them just as you do the other PMC types.  Look up a subroutine in
+the current namespace with the C<get_global> opcode:
+
+  $P0 = get_global "MySubName"
+
+To find a subroutine in a different namespace, first look up the appropriate
+the namespace PMC, then use that with C<get_global>:
+
+  $P0 = get_namespace "MyNamespace"
+  $P1 = get_global $P0, "MySubName"
+
+You can obviously invoke a Sub PMC:
+
+  $P0(1, 2, 3)
+
+You can get or even I<change> its name:
+
+  $S0 = $P0               # Get the current name
+  $P0 = "MyNewSubName"    # Set a new name
+
+You can get a hash of the complete metadata for the subroutine:
+
+  $P1 = inspect $P0
+
+The metadata fields in this hash are
+
+=over 4
+
+=item * pos_required
+
+The number of required positional parameters to the Sub
+
+=item * pos_optional
+
+The number of optional positional parameters to the Sub
+
+=item * named_required
+
+The number of required named parameters to the Sub
+
+=item * named_optional
+
+The number of optional named parameters to the Sub
+
+=item * pos_slurpy
+
+Returns true if the sub has a slurpy parameter to eat up extra positional args
+
+=item * named_slurpy
+
+Returns true if the sub has a slurpy parameter to eat up extra named args
+
+=back
+
+Instead of getting the whole inspection hash, you ask about individual pieces
+of metadata:
+
+  $I0 = inspect $P0, "pos_required"
+
+To discover to get the total number of defined parameters to the Sub, call the
+C<arity> method:
+
+  $I0 = $P0.'arity'()
+
+To fetch the namespace PMC that the Sub was defined into, call the
+C<get_namespace> method:
+
+  $P1 = $P0.'get_namespace'()
+
+=head3 Evaluating a Code String
+
+Z<CHP-9-SECT-7.6>
+
+X<code strings, evaluating>
+This isn't really a subroutine operation, but it does produce a code
+object that can be invoked. In this case, it's a X<bytecode segment
+object> bytecode segment object.
+
+The first step is to get an assembler or compiler for the target
+language:
+
+=begin PIR_FRAGMENT
+
+  compreg $P1, "PIR"
+
+=end PIR_FRAGMENT
+
+Within the Parrot interpreter there are currently three registered
+languages: C<PASM>, C<PIR>, and C<PASM1>. The first two are for parrot
+assembly language and parrot intermediate representation code. The third
+is for evaluating single statements in PASM. Parrot automatically adds
+an C<end> opcode at the end of C<PASM1> strings before they're
+compiled.
+
+This example places a bytecode segment object into the destination
+register C<P0> and then invokes it with C<invoke>:
+
+=begin PIR_FRAGMENT_INVALID
+
+  compreg P1, "PASM1"                # get compiler
+  set S1, "in eval\n"
+  compile P0, P1, "print S1"
+  invoke                             # eval code P0
+  print "back again\n"
+
+=end PIR_FRAGMENT_INVALID
+
+You can register a compiler or assembler for any language inside the
+Parrot core and use it to compile and invoke code from that language.
+These compilers may be written in PIR or reside in shared libraries.
+
+=begin PIR_FRAGMENT
+
+  compreg "MyLanguage", $P10
+
+=end PIR_FRAGMENT
+
+In this example the C<compreg> opcode registers the subroutine-like
+object C<P10> as a compiler for the language "MyLanguage". See
+F<examples/compilers> and F<examples/japh/japh16.pasm> for an external
+compiler in a shared library.
+
+
+
+=head2 Lexicals and Globals
+
+So far, we've been treating Parrot registers like the variables of a
+high-level language. This is fine, as far as it goes, but it isn't the
+full picture. The dynamic nature and introspective features of
+languages like Perl make it desirable to manipulate variables by name,
+instead of just by register or stack location. These languages also
+have global variables, which are visible throughout the entire
+program. Storing a global variable in a register would either tie up
+that register for the lifetime of the program or require some unwieldy way
+to shuffle the data into and out of registers.
+
+Parrot provides structures for storing both global and lexically
+scoped named variables. Lexical and global variables must be PMC
+values. PIR provides instructions for storing and retrieving
+variables from these structures so the PIR opcodes can operate on
+their values.
+
+=head3 Globals
+
+Z<CHP-9-SECT-6.1>
+
+X<PIR (Parrot assembly language);global variables>
+Global variables are stored in a C<Hash>, so every variable name
+must be unique.  PIR has two opcodes for globals, C<set_global> and
+C<get_global>:
+
+=begin PIR_FRAGMENT_INVALID
+
+  new P10, "Int"
+  set P10, 42
+  set_global "$foo", P10
+  # ...
+  get_global P0, "$foo"
+  print P0                        # prints 42
+
+=end PIR_FRAGMENT_INVALID
+
+The first two statements create a C<Int> in the PMC register
+C<P10> and give it the value 42. In the third statement,
+C<set_global> stores that PMC as the named global variable C<$foo>.
+At some later point in the program, C<get_global> retrieves the PMC
+from the global variable by name, and stores it in C<P0> so it can be
+printed.
+
+The C<set_global> opcode only stores a reference to the object. If
+we add an increment statement:
+
+=begin PIR_FRAGMENT
+
+  inc $P10
+
+=end PIR_FRAGMENT
+
+after the C<set_global> it increments the stored global, printing 43.
+If that's not what you want, you can C<clone> the PMC before you store
+it. Leaving the global variable as an alias does have advantages,
+though. If you retrieve a stored global into a register and modify it
+as follows:
+
+=begin PIR_FRAGMENT_INVALID
+
+  get_global P0, "varname"
+  inc P0
+
+=end PIR_FRAGMENT_INVALID
+
+the value of the stored global is directly modified, so you don't need
+to call C<set_global> again.
+
+The two-argument forms of C<set_global> and C<get_global> store or
+retrieve globals from the outermost namespace (what Perl users will
+know as the "main" namespace). A simple flat global namespace isn't
+enough for most languages, so Parrot also needs to support
+hierarchical namespaces for separating packages (classes and modules
+in Perl 6). Use C<set_rootglobal> and
+C<get_root_global> add an argument to select a nested namespace:
+
+=begin PIR_FRAGMENT_INVALID
+
+  set_root_global ["Foo"], "var", P0 # store P0 as var in the Foo namespace
+  get_root_global P1, ["Foo"], "var"  # get Foo::var
+
+=end PIR_FRAGMENT_INVALID
+
+Eventually the global opcodes will have variants that take a PMC to
+specify the namespace, but the design and implementation of these
+aren't finished yet.
+
+=head3 Lexicals
+
+X<PIR (Parrot assembly language);lexical variables>
+Lexical variables are stored in a lexical scratchpad. There's one pad
+for each lexical scope. Every pad has both a hash and an array, so
+elements can be stored either by name or by numeric index.
+
+=head4 Basic instructions
+
+Z<CHP-9-SECT-6.2.1>
+
+To store a lexical variable in the current scope pad, use C<store_lex>.
+Likewise, use C<find_lex> to retrieve a variable from the current pad.
+
+=begin PIR_FRAGMENT
+
+  new $P0, "Int"            # create a variable
+  set $P0, 10               # assign value to it
+  store_lex "foo", $P0      # store the var with the variable name "foo"
+  # ...
+  find_lex $P1, "foo"       # get the var "foo" into P1
+  print $P1
+  print "\n"                # prints 10
+
+=end PIR_FRAGMENT
+
+As we have seen above, we can declare a new subroutine to be a nested inner
+subroutine of an existing outer subroutine using the C<:outer> flag. The
+outer flag is used to specify the name of the outer subroutine. Where there
+may be multiple subroutines with the same name N<such is the case with
+multisubs, which we will discuss soon>, we can use the C<:subid> flag on the
+outer subroutine to give it a different--and unique--name that the lexical
+subroutines can reference in their C<:outer> declarations. Within lexical
+subroutines, the C<.lex> command defines a local variable that follows these
+scoping rules.
+
+=head3 LexPad and LexInfo PMCs
+
+Information about lexical variables in a subroutine is stored in two different
+types of PMCs: The LexPad PMC that we already mentioned briefly, and the
+LexInfo PMCs which we haven't. Neither of these PMC types are really usable
+from PIR code, but are instead used by Parrot internally to store information
+about lexical variables.
+
+C<LexInfo> PMCs are used to store information about lexical variables at
+compile time. This is read-only information that is generated during
+compilation to represent what is known about lexical variables. Not all
+subroutines get a LexInfo PMC by default, you need to indicate to Parrot
+somehow that you require a LexInfo PMC to be created. One way to do this is
+with the C<.lex> directive that we looked at above. Of course, the C<.lex>
+directive only works for languages where the names of lexical variables are
+all known at compile time. For languages where this information isn't known,
+the subroutine can be flagged with C<:lex> instead.
+
+C<LexPad> PMCs are used to store run-time information about lexical variables.
+This includes their current values and their type information. LexPad PMCs are
+created at runtime for subs that have a C<LexInfo> PMC already. These are
+created each time the subroutine is invoked, which allows for recursive
+subroutine calls without overwriting variable names.
+
+With a Subroutine PMC, you can get access to the associated LexInfo PMC by
+calling the C<'get_lexinfo'> method:
+
+  $P0 = find_global "MySubroutine"
+  $P1 = $P0.'get_lexinfo'()
+
+Once you have the LexInfo PMC, there are a limited number of operations that
+you can call with it:
+
+  $I0 = elements $P1    # Get the number of lexical variables from it
+  $P0 = $P1["name"]     # Get the entry for lexical variable "name"
+
+There really isn't much else useful to do with LexInfo PMCs, they're mostly
+used by Parrot internally and aren't helpful to the PIR programmer.
+
+There is no easy way to get a reference to the current LexPad PMC in a given
+subroutine, but like LexInfo PMCs that doesn't matter because they aren't
+useful from PIR anyway. Remember that subroutines themselves can be lexical
+and that therefore the lexical environment of a given variable can extend to
+multiple subroutines and therefore multiple LexPads. The opcodes C<find_lex>
+and C<store_lex> automatically search through nested LexPads recursively to
+find the proper environment information about the given variables.
+
+=head3 Lexical Subroutines
+
+X<Lexical Subroutines>
+
+Parrot offers support for lexical subroutines.  You can define a subroutine by
+name inside a larger subroutine, where the inner subroutine is only visible and
+callable from the outer. The inner subroutine inherits all the lexical
+variables from the outer subroutine, but can itself define its own lexical
+variables that the outer subroutine cannot access.   PIR lacks the concept of
+blocks or nested lexical scopes; this is how it performs the same function.
+
+If the subroutine is lexical, you can get its C<:outer> with the C<get_outer>
+method on the Sub PMC:
+
+  $P1 = $P0.'get_outer'()
+
+If there is no C<:outer> PMC, this returns a NULL PMC. Conversely, you can
+set the outer sub:
+
+  $P0.'set_outer'($P1)
+
+=head3 Scope and HLLs
+
+As mentioned previously, X<High Level Languages;HLL> High Level Languages such
+as Perl, Python, and Ruby allow nested scopes, or blocks within blocks that can
+have their own lexical variables.  Even this construct is common in the C
+programming language:
+
+  {
+      int x = 0;
+      int y = 1;
+      {
+          int z = 2;
+          /* x, y, and z are all visible here */
+      }
+
+      /* only x and y are visible here */
+  }
+
+In the inner block, all three varaibles are visible.  The variable C<z> is only
+visible inside that block. The outer block has no knowledge of C<z>.  A very
+direct, naI<iuml>ve translation of this code to PIR might be:
+
+  .param int x
+  .param int y
+  .param int z
+  x = 0
+  y = 1
+  z = 2
+  ...
+
+This PIR code is similar, but the handling of the variable C<z> is different:
+C<z> is visible throughout the entire current subroutine, where it is not
+visible throughout the entire C function. To help approximate this effect, PIR
+supplies lexical subroutines to create nested lexical scopes.
+
+=head3 PIR Scoping
+
+Only one PIR structure supports scoping like this: the subroutineN<... and
+objects that inherit from subroutines, such as methods, coroutines, and
+multisubs>. There are no blocks in PIR that have their own scope besides
+subroutines. Fortunately, we can use these lexical subroutines to simulate this
+behavior that HLLs require:
+
+=begin PIR
+
+  .sub 'MyOuter'
+      .local int x,y
+      .lex 'x', x
+      .lex 'y', y
+      'MyInner'()
+      # only x and y are visible here
+  .end
+
+  .sub 'MyInner' :outer('MyOuter')
+      .local int z
+      .lex 'z', z
+      #x, y, and z are all "visible" here
+  .end
+
+=end PIR
+
+In the example above we put the word C<"visible"> in quotes. This is because
+lexically-defined variables need to be accessed with the C<get_lex> and
+C<set_lex> opcodes. These two opcodes don't just access the value of a
+register, where the value is stored while it's being used, but they also make
+sure to interact with the C<LexPad> PMC that's storing the data. If the value
+isn't properly stored in the LexPad, then they won't be available in nested
+inner subroutines, or available from C<:outer> subroutines either.
+
+=head2 Namespaces
+
+X<Namespaces>
+X<.namespace>
+Namespaces provide a mechanism where names can be reused. This may not
+sound like much, but in large complicated systems, or systems with
+many included libraries, it can be very handy. Each namespace gets its
+own area for function names and global variables. This way you can have
+multiple functions named C<create> or C<new> or C<convert>, for
+instance, without having to use I<Multi-Method Dispatch> (MMD) which we
+will describe later. Namespaces are also vital for defining classes and their
+methods, which we already mentioned. We'll talk about all those uses here.
+
+Namespaces are specified with the C<.namespace []> directive. The brackets
+are not optional, but the keys inside them are. Here are some examples:
+
+  .namespace [ ]               # The root namespace
+  .namespace [ "Foo" ]         # The namespace "Foo"
+  .namespace [ "Foo" ; "Bar" ] # Namespace Foo::Bar
+  .namespace                   # WRONG! The [] are needed
+
+Using semicolons, namespaces can be nested to any arbitrary depth.
+Namespaces are special types of PMC, so we can access them and manipulate
+them just like other data objects. We can get the PMC for the root
+namespace using the C<get_root_namespace> opcode:
+
+  $P0 = get_root_namespace
+
+The current namespace, which might be different from the root namespace
+can be retrieved with the C<get_namespace> opcode:
+
+  $P0 = get_namespace             # get current namespace PMC
+  $P0 = get_namespace ["Foo"]     # get PMC for namespace "Foo"
+
+Namespaces are arranged into a large n-ary tree. There is the root namespace
+at the top of the tree, and in the root namespace are various special HLL
+namespaces. Each HLL compiler gets its own HLL namespace where it can store
+its data during compilation and runtime. Each HLL namespace may have a large
+hierarchy of other namespaces. We'll talk more about HLL namespaces and their
+significance in chapter 10.
+
+The root namespace is a busy place. Everybody could be lazy and use it to store
+all their subroutines and global variables, and then we would run into all
+sorts of collisions. One library would define a function "Foo", and then
+another library could try to create another subroutine with the same name.
+This is called I<namespace pollution>, because everybody is trying to put
+things into the root namespace, and those things are all unrelated to each
+other. Best practices requires that namespaces be used to hold private
+information away from public information, and to keep like things together.
+
+As an example, the namespace C<Integers> could be used to store subroutines
+that deal with integers. The namespace C<images> could be used to store
+subroutines that deal with creating and manipulating images. That way, when
+we have a subroutine that adds two numbers together, and a subroutine that
+performs additive image composition, we can name them both C<add> without any
+conflict or confusion. And within the C<image> namespace we could have sub
+namespaces for C<jpeg> and C<MRI> and C<schematics>, and each of these could
+have a C<add> method without getting into each other's way.
+
+The short version is this: use namespaces. There aren't any penalties to them,
+and they do a lot of work to keep things organized and separated.
+
+=head3 Namespace PMC
+
+The C<.namespace> directive that we've seen sets the current namespace. In
+PIR code, we have multiple ways to address a namespace:
+
+  # Get namespace "a/b/c" starting at the root namespace
+  $P0 = get_root_namespace ["a" ; "b" ; "c"]
+
+  # Get namespace "a/b/c" starting in the current HLL namespace.
+  $P0 = get_hll_namespace ["a" ; "b" ; "c"]
+  # Same
+  $P0 = get_root_namespace ["hll" ; "a" ; "b" ; "c"]
+
+  # Get namespace "a/b/c" starting in the current namespace
+  $P0 = get_namespace ["a" ; "b" ; "c"]
+
+Once we have a namespace PMC we can retrieve global variables and
+subroutine PMCs from it using the following functions:
+
+  $P1 = get_global $S0            # Get global in current namespace
+  $P1 = get_global ["Foo"], $S0   # Get global in namespace "Foo"
+  $P1 = get_global $P0, $S0       # Get global in $P0 namespace PMC
+
+=head3 Operations on the Namespace PMC
+
+We've seen above how to find a Namespace PMC. Once you have it, there are a
+few things you can do with it. You can find methods and variables that are
+stored in the namespace, or you can add new ones:
+
+  $P0 = get_namespace
+  $P0.'add_namespace'($P1)      # Add Namespace $P1 to $P0
+  $P1 = $P0.'find_namespace'("MyOtherNamespace")
+
+  # Find namespace "MyNamespace" in $P0, create it if it
+  #    doesn't exist
+  $P1 = $P0.'make_namespace'("MyNamespace")
+
+  $P0.'add_sub'("MySub", $P2)   # Add Sub PMC $P2 to the namespace
+  $P1 = $P0.'find_sub'("MySub") # Find it
+
+  $P0.'add_var'("MyVar", $P3)   # Add variable "MyVar" in $P3
+  $P1 = $P0.'find_var'("MyVar") # Find it
+
+  # Return the name of Namespace $P0 as a ResizableStringArray
+  $P3 = $P0.'get_name'()
+
+  # Find the parent namespace that contains this one:
+  $P5 = $P0.'get_parent'()
+
+  # Get the Class PMC associated with this namespace:
+  $P6 = $P0.'get_class'()
+
+There are a few other operations that can be done on Namespaces, but none
+as interesting as these. We'll talk about Namespaces throughout the rest
+of this chapter.
+
+
+=head2 Classes and Objects
+
+This section revolves around one complete example that defines a
+class, instantiates objects, and uses them. The whole example is
+included at the end of the section.
+
+=head3 Class declaration
+
+Z<CHP-9-SECT-12.1>
+
+X<classes;in PIR>
+The C<newclass>X<newclass opcode (PIR)> opcode defines a new class.
+It takes two arguments, the name of the class and the destination
+register for the class PMC. All classes (and objects) inherit from the
+C<ParrotClass> PMCX<ParrotClass PMC>, which is the core of the Parrot
+object system.
+
+=begin PIR_FRAGMENT
+
+    newclass $P1, "Foo"
+
+=end PIR_FRAGMENT
+
+To instantiate a new object of a particular class, you first look up
+the integer value for the class type with the C<find_type> opcode,
+then create an object of that type with the C<new> opcode:
+
+=begin PIR_FRAGMENT_INVALID
+
+    find_type I1, "Foo"
+    new P3I I1
+
+=end PIR_FRAGMENT_INVALID
+
+The C<new> opcode also checks to see if the class defines a
+method named "__init" and calls it if it exists.
+
+=head3 Attributes
+
+Z<CHP-9-SECT-12.2>
+
+X<attributes;in PIR>
+X<classes;attributes>
+The C<addattribute> opcode creates a slot in the class for an
+attribute (sometimes known as an I<instance variable>) and associates
+it with a name:
+
+=begin PIR_FRAGMENT
+
+    addattribute $P1, ".i"                # Foo.i
+
+=end PIR_FRAGMENT
+
+This chunk of code
+from the C<__init> method looks up the position of the first
+attribute, creates a C<Int> PMC, and stores it as the first
+attribute:
+
+=begin PIR_FRAGMENT_INVALID
+
+    classoffset $I0, $P2, "Foo"    # first "Foo" attribute of object P2
+    new $P6, "Int"                 # create storage for the attribute
+    setattribute $P2, $I0, $P6     # store the first attribute
+
+=end PIR_FRAGMENT_INVALID
+
+The C<classoffset> opcodeX<classoffset opcode (PIR)> takes a PMC
+containing an object and the name of its class, and returns an integer
+index for the position of the first attribute. The C<setattribute>
+opcode uses the integer index to store a PMC value in one of the
+object's attribute slots. This example initializes the first
+attribute. The second attribute would be at C<I0 + 1>, the third
+attribute at C<I0 + 2>, etc:
+
+=begin PIR_FRAGMENT_INVALID
+
+    inc $I0
+    setattribute $P2, $I0, $P7       # store next attribute
+    #...
+
+=end PIR_FRAGMENT_INVALID
+
+There is also support for named parameters with fully qualified
+parameter names (although this is a little bit slower than getting
+the class offset once and accessing several attributes by index):
+
+=begin PIR_FRAGMENT
+
+    new $P6, "Int"
+    setattribute $P2, "Foo\x0.i", $P6   # store the attribute
+
+=end PIR_FRAGMENT
+
+You use the same integer index to retrieve the value of an attribute.
+The C<getattribute>X<getattribute opcode (PIR)> opcode takes an object and
+an index as arguments and returns the attribute PMC at that position:
+
+=begin PIR_FRAGMENT_INVALID
+
+    classoffset $I0, $P2, "Foo"         # first "Foo" attribute of object P2
+    getattribute $P10, $P2, $I0         # indexed get of attribute
+
+=end PIR_FRAGMENT_INVALID
+
+or
+
+=begin PIR_FRAGMENT
+
+    getattribute $P10, $P2, "Foo\x0.i"  # named get
+
+=end PIR_FRAGMENT
+
+To set the value of an attribute PMC, first retrieve it with
+C<getattribute> and then assign to the returned PMC. Because PMC
+registers are only pointers to values, you don't need to store the PMC
+again after you modify its value:
+
+=begin PIR_FRAGMENT_INVALID
+
+    getattribute $P10, $P2, $I0
+    set $P10, $I5
+
+=end PIR_FRAGMENT_INVALID
+
+=head3 Methods
+
+Z<CHP-9-SECT-12.3>
+
+X<methods;in PIR>
+X<classes;methods>
+X<classes;namespaces>
+Methods in PIR are just subroutines installed in the namespace of the
+class. You define a method with the C<.pcc_sub> directive before the
+label:
+
+=begin PIR_INVALID_FRAGMENT
+
+  .pcc_sub _half:                 # I5 = self."_half"()
+    classoffset I0, P2, "Foo"
+    getattribute P10, P2, I0
+    set I5, P10                   # get value
+    div I5, 2
+    invoke P1
+
+=end PIR_INVALID_FRAGMENT
+
+This routine returns half of the value of the first attribute of the
+object. Method calls use the Parrot calling conventions so they always
+pass the I<invocant> object (often called I<self>) in C<P2>. Invoking
+the return continuation in C<P1> returns control to the caller.
+
+The C<.pcc_sub> directive automatically stores the subroutine as a
+global in the current namespace. The C<.namespace> directive sets the
+current namespace:
+
+=begin PIR
+
+  .namespace [ "Foo" ]
+
+=end PIR
+
+If the namespace is explicitly set to an empty string or key, then the
+subroutine is stored in the outermost namespace.
+
+The C<callmethodcc>X<callmethodcc opcode (PIR)> opcode makes a method
+call. It follows the Parrot calling conventions, so it expects to
+find the invocant object in C<P2>, the method object in C<P0>, etc. It
+adds one bit of magic, though. If you pass the name of the method in
+C<S0>, C<callmethodcc> looks up that method name in the invocant
+object and stores the method object in C<P0> for you:
+
+=begin PIR_FRAGMENT_INVALID
+
+    set $S0, "_half"            # set method name
+    set $P2, $P3                # the object
+    callmethodcc                # create return continuation, call
+    print $I5                   # result of method call
+    print "\n"
+
+=end PIR_FRAGMENT_INVALID
+
+The C<callmethodcc> opcode also generates a return continuation and
+stores it in C<P1>. The C<callmethod> opcode doesn't generate a return
+continuation, but is otherwise identical to C<callmethodcc>. Just like
+ordinary subroutine calls, you have to preserve and restore any
+registers you want to keep after a method call. Whether you store
+individual registers, register frames, or half register frames is up
+to you.
+
+=head4 Overriding vtable functions
+
+Z<CHP-9-SECT-12.3.1>
+
+Every object inherits a default set of I<vtable> functions from the
+C<ParrotObject> PMC, but you can also override them with your own
+methods. The vtable functions have predefined names that start with a
+double underscore "__". The following code defines a method named
+C<__init> in the C<Foo> class that initializes the first attribute of
+the object with an integer:
+
+=begin PIR_FRAGMENT_INVALID
+
+  .sub __init:
+    classoffset I0, P2, "Foo"     # lookup first attribute position
+    new P6, "Int"                 # create storage for the attribute
+    setattribute P2, I0, P6       # store the first attribute
+    invoke P1                     # return
+
+=end PIR_FRAGMENT_INVALID
+
+Ordinary methods have to be called explicitly, but the vtable
+functions are called implicitly in many different contexts. Parrot
+saves and restores registers for you in these calls. The C<__init>
+method is called whenever a new object is constructed:
+
+=begin PIR_FRAGMENT_INVALID
+
+    find_type I1, "Foo"
+    new P3, I1          # call __init if it exists
+
+=end PIR_FRAGMENT_INVALID
+
+A few other vtable functions in the complete code example for this
+section are C<__set_integer_native>, C<__add>, C<__get_integer>,
+C<__get_string>, and C<__increment>. The C<set> opcode calls Foo's
+C<__set_integer_native> vtable function when its destination register
+is a C<Foo> object and the source register is a native integer:
+
+=begin PIR_FRAGMENT
+
+    set $P3, 30          # call __set_integer_native method
+
+=end PIR_FRAGMENT
+
+The C<add> opcode calls Foo's C<__add> vtable function when it adds
+two C<Foo> objects:
+
+=begin PIR_FRAGMENT_INVALID
+
+    new $P4, $I1          # same with P4
+    set $P4, $12
+    new $P5, $I1          # create a new store for add
+
+    add $P5, $P3, $P4     # __add method
+
+=end PIR_FRAGMENT_INVALID
+
+The C<inc> opcode calls Foo's C<__increment> vtable function when it
+increments a C<Foo> object:
+
+=begin PIR_FRAGMENT
+
+    inc $P3              # __increment
+
+=end PIR_FRAGMENT
+
+Foo's C<__get_integer> and C<__get_string> vtable functions are called
+whenever an integer or string value is retrieved from a C<Foo> object:
+
+=begin PIR_FRAGMENT
+
+    set $I10, $P5         # __get_integer
+    #...
+    print $P5            # calls __get_string, prints 'fortytwo'
+
+=end PIR_FRAGMENT
+
+
+=head3 Inheritance
+
+Z<CHP-9-SECT-12.4>
+
+X<inheritance;in PIR>
+X<classes;inheritance>
+The C<subclass>X<subclass opcode (PIR)> opcode creates a new class that
+inherits methods and attributes from another class. It takes 3
+arguments: the destination register for the new class, a register
+containing the parent class, and the name of the new class:
+
+=begin PIR_FRAGMENT
+
+    subclass $P3, $P1, "Bar"
+
+=end PIR_FRAGMENT
+
+X<multiple inheritance; in PIR>
+For multiple inheritance, the C<addparent>X<addparent opcode (PIR)>
+opcode adds additional parents to a subclass.
+
+=begin PIR_FRAGMENT
+
+  newclass $P4, "Baz"
+  addparent $P3, $P4
+
+=end PIR_FRAGMENT
+
+To override an inherited method, define a method with the same name in
+the namespace of the subclass. The following code overrides Bar's
+C<__increment> method so it decrements the value instead of
+incrementing it:
+
+=begin PIR_FRAGMENT_INVALID
+
+  .namespace [ "Bar" ]
+
+  .sub __increment:
+    classoffset I0, P2, "Foo"     # get Foo's attribute slot offset
+    getattribute P10, P2, I0      # get the first Foo attribute
+    dec P10                       # the evil line
+    invoke P1
+
+=end PIR_FRAGMENT_INVALID
+
+Notice that the attribute inherited from C<Foo> can only be looked up
+with the C<Foo> class name, not the C<Bar> class name. This preserves
+the distinction between attributes that belong to the class and
+inherited attributes.
+
+Object creation for subclasses is the same as for ordinary classes:
+
+=begin PIR_FRAGMENT_INVALID
+
+    find_type $I1, "Bar"
+    new $P5, $I1
+
+=end PIR_FRAGMENT_INVALID
+
+Calls to inherited methods are just like calls to methods defined in
+the class:
+
+=begin PIR_FRAGMENT_INVALID
+
+    set $P5, 42                  # inherited __set_integer_native
+    inc $P5                      # overridden __increment
+    print $P5                    # prints 41 as Bar's __increment decrements
+    print "\n"
+
+    set $S0, "_half"             # set method name
+    set $P2, $P5                 # the object
+    callmethodcc                 # create return continuation, call
+    print $I5
+    print "\n"
+
+=end PIR_FRAGMENT_INVALID
+
+=head3 Additional Object Opcodes
+
+Z<CHP-9-SECT-12.5>
+
+The C<isa> and C<can> instructuions are also useful when working with
+objects. C<isa> checks whether an object belongs to or
+inherits from a particular class. C<can> checks whether
+an object has a particular method. Both return a true or false value.
+
+=begin PIR_FRAGMENT
+
+    $I0 = isa $P3, "Foo"         # 1
+    $I0 = isa $P3, "Bar"         # 1
+    $I0 = can $P3, "add"         # 1
+
+=end PIR_FRAGMENT
+
+
+It may seem more appropriate for a discussion of PIR's support for classes
+and objects to reside in its own chapter, instead of appearing in a generic
+chapter about PIR programming "basics". However, part of PIR's core
+functionality is its support for object-oriented programming. PIR doesn't
+use all the fancy syntax as other OO languages, and it doesn't even support
+all the features that most modern OO languages have. What PIR does have is
+support for some of the basic structures and abilities, the necessary subset
+to construct richer and higher-level object systems.
+
+
+=head3 Attributes
+
+Classes and subclasses can be given attributes N<in addition to methods,
+which we will talk about in the next chapter> which are named data fields.
+Attributes are created with the C<addattribute> opcode, and can be set
+and retrieved with the C<setattribute> and C<getattribute> opcodes
+respectively:
+
+  # Create the new class with two attributes
+  $P0 = newclass 'MyClass'
+  addattribute $P0, 'First'
+  addattribute $P0, 'Second'
+
+  # Create a new item of type MyClass
+  $P1 = new 'MyClass'
+
+  # Set values to the attributes
+  setattribute $P1, 'First', 'First Value'
+  setattribute $P1, 'Second', 'Second Value'
+
+  # Get the attribute values
+  $S0 = getattribute $P1, 'First'
+  $S1 = getattribute $P1, 'Second'
+
+Those values added as attributes don't need to be strings, even though
+both of the ones in the example are. They can be integers, numbers
+or PMCs too.
+
+=head3 Methods
+
+PIR provides syntax to simplify writing methods and method calls for
+object-oriented programming. We've seen some method calls in the examples
+above, especially when we were talking about the interfaces to certain PMC
+types. We've also seen a little bit of information about classes and objects
+in the previous chapter. PIR allows you to define your own classes, and with
+those classes you can define method interfaces to them. Method calls follow
+the same Parrot calling conventions that we have seen above, including all the
+various parameter configurations, lexical scoping, and other aspects we have
+already talked about.
+
+The second type of class can be defined in PIR at runtime. We saw some
+examples of this in the last chapter using the C<newclass> and C<subclass>
+opcodes. We also talked about class attribute values. Now, we're going to talk
+about associating subroutines with these classes, and they're called
+I<methods>. Methods are just like other normal subroutines with two major
+changes: they are marked with the C<:method> flag, and they exist in a
+I<namespace>. Before we can talk about methods, we need to discuss
+namespaces first.
+
+Z<CHP-4-SECT-2.2>
+
+Methods are just like subroutines, except
+they are invoked on a object PMC, and that PMC is passed as the c<self>
+parameter.
+
+The basic syntax for a method call is similar to the single line
+subroutine call above. It takes a variable for the invocant PMC and a
+string with the name of the method:
+
+  object."methodname"(arguments)
+
+Notice that the name of the method must be contained in quotes. If the
+name of the method is not contained in quotes, it's treated as a named
+variable that does. Here's an example:
+
+  .local string methname = "Foo"
+  object.methname()               # Same as object."Foo"()
+  object."Foo"()                  # Same
+
+The invocant can be a variable or register, and the method name can be
+a literal string, string variable, or method object PMC.
+
+=head3 Defining Methods
+
+Methods are defined like any other subroutine except with two major
+differences: They must be inside a namespace named after the class
+they are a part of, and they must use the C<:method> flag.
+
+  .namespace [ "MyClass"]
+
+  .sub "MyMethod" :method
+    ...
+
+Inside the method, the invocant object can be accessed using the C<self>
+keyword. C<self> isn't the only name you can call this value, however.
+You can also use the C<:invocant> flag to define a new name for the invocant
+object:
+
+(See TT #483)
+
+=begin PIR_INVALID
+
+  .sub "MyMethod" :method
+    $S0 = self                    # Already defined as "self"
+    say $S0
   .end
 
-Multis can take I, N, S, and P types, but they can also use C<_> (underscore)
-to denote a wildcard, and a string that can be the name of a particular PMC
-type:
+  .sub "MyMethod2" :method
+    .param pmc item :invocant     # "self" is now called "item"
+    $S0 = item
+    say $S0
+  .end
 
-  .sub 'Add' :multi(I, I)  # Two integers
-    ...
+=end PIR_INVALID
 
-  .sub 'Add' :multi(I, 'Float')  # An integer and Float PMC
-    ...
+This example defines two methods in the C<Foo> class. It calls one
+from the main body of the subroutine and the other from within the
+first method:
 
-                           # Two Integer PMCs
-  .sub 'Add' :multi('Integer', _)
-    ...
+=begin PIR
 
-When we call a multi PMC, Parrot will try to take the most specific
-best-match variant, and will fall back to more general variants if a perfect
-best-match cannot be found. So if we call C<'Add'(1, 2)>, Parrot will dispatch
-to the C<(I, I)> variant. If we call C<'Add'(1, "hi")>, Parrot will match the
-C<(I, _)> variant, since the string in the second argument doesn't match C<I>
-or C<'Float'>. Parrot can also choose to automatically promote one of the I,
-N, or S values to an Integer, Float, or String PMC.
+  .sub main
+    .local pmc class
+    .local pmc obj
+    newclass class, "Foo"       # create a new Foo class
+    new obj, "Foo"              # instantiate a Foo object
+    obj."meth"()                # call obj."meth" which is actually
+    print "done\n"              # in the "Foo" namespace
+  .end
 
-To make the decision about which multi variant to call, Parrot takes a
-I<Manhattan Distance> between the two. Parrot calculates the I<distance>
-between the multi signatures and the argument signature. Every difference
-counts as one step. A difference can be an autobox from a primitive type
-to a PMC, or the conversion from one primitive type to another, or the
-matching of an argument to a C<_> wildcard. After Parrot calculates the
-distance to each variant, it calls the function with the lowest distance.
-Notice that it's possible to define a variant that is impossible to call:
-for every potential combination of arguments there is a better match. This
-isn't necessarily a common occurrence, but it's something to watch out for
-in systems with a lot of multis and a limited number of data types in use.
+  .namespace [ "Foo" ]          # start namespace "Foo"
 
+  .sub meth :method             # define Foo::meth global
+     print "in meth\n"
+     $S0 = "other_meth"         # method names can be in a register too
+     self.$S0()                 # self is the invocant
+  .end
 
-=head2 Classes and Objects
+  .sub other_meth :method       # define another method
+     print "in other_meth\n"    # as above Parrot provides a return
+  .end                          # statement
 
-It may seem more appropriate for a discussion of PIR's support for classes
-and objects to reside in its own chapter, instead of appearing in a generic
-chapter about PIR programming "basics". However, part of PIR's core
-functionality is its support for object-oriented programming. PIR doesn't
-use all the fancy syntax as other OO languages, and it doesn't even support
-all the features that most modern OO languages have. What PIR does have is
-support for some of the basic structures and abilities, the necessary subset
-to construct richer and higher-level object systems.
+=end PIR
 
-=head2 PMCs as Classes
+Each method call looks up the method name in the object's class namespace.
+The C<.sub> directive automatically makes a symbol table entry for the
+subroutine in the current namespace.
 
-PMCs aren't exactly "classes" in the way that this term is normally used in
-object-oriented programming languages. They are polymorphic data items that
-can be one of a large variety of predefined types. As we have seen briefly,
-and as we will see in more depth later, PMCs have a standard interface called
-the VTABLE interface. VTABLEs are a standard list of functions that all PMCs
-implement N<or, PMCs can choose not to implement each interface explicitly and
-instead let Parrot call the default implementations>.
+When a C<.sub> is declared as a C<:method>, it automatically creates a
+local variable named C<self> and assigns it the object passed in
+C<P2>. You don't need to write C<.param pmc self> to get it, it comes
+free with the method.
 
-VTABLEs are very strict: There are a fixed number with fixed names and
-fixed argument lists. You can't just create any random VTABLE interface that
-you want to create, you can only make use of the ones that Parrot supplies
-and expects. To circumvent this limitation, PMCs may have METHODS in
-addition to VTABLEs. METHODs are arbitrary code functions that can be
-written in C, may have any name, and may implement any behavior.
+You can pass multiple arguments to a method and retrieve multiple
+return values just like a single line subroutine call:
 
-=head2 VTABLE Interfaces
+  (res1, res2) = obj."method"(arg1, arg2)
 
-Internally, all operations on PMCs are performed by calling various VTABLE
-interfaces.
 
-=head2 Class and Object PMCs
+=head3 Introspection
 
 The details about various PMC classes are managed by the Class PMC. Class PMCs
 contain information about the class, available methods, the inheritance
@@ -2015,46 +4321,137 @@
   $P0 = new 'MyArray'
   $P1 = new 'MyOtherArray'
 
-=head2 Attributes
 
-Classes and subclasses can be given attributes N<in addition to methods,
-which we will talk about in the next chapter> which are named data fields.
-Attributes are created with the C<addattribute> opcode, and can be set
-and retrieved with the C<setattribute> and C<getattribute> opcodes
-respectively:
 
-  # Create the new class with two attributes
-  $P0 = newclass 'MyClass'
-  addattribute $P0, 'First'
-  addattribute $P0, 'Second'
+=head3 Vtable Overrides
 
-  # Create a new item of type MyClass
-  $P1 = new 'MyClass'
+PMCs all subscribe to a common interface of functions called X<VTABLE>
+VTABLEs. Every PMC implements the same set of these interfaces, which
+perform very specific low-level tasks on the PMC. The term VTABLE was
+originally a shortened form of the name "virtual function table",
+although that name isn't used any more by the developers, or in any of
+the documentation. The virtual functions in the VTABLE, called X<VTABLE
+interfaces> VTABLE interfaces, are similar to ordinary functions and
+methods in many respects. VTABLE interfaces are occasionally called
+"VTABLE functions", or "VTABLE methods" or even "VTABLE entries" in
+casual conversation. A quick comparison shows that VTABLE interfaces
+are not really subroutines or methods in the way that those terms have
+been used throughout the rest of Parrot. Like methods on an object,
+VTABLE interfaces are defined for a specific class of PMC, and can be
+invoked on any member of that class. Likewise, in a VTABLE interface
+declaration, the C<self> keyword is used to describe the object that
+it is invoked upon. That's where the similarities end, however. Unlike
+ordinary subroutines or methods, VTABLE methods cannot be invoked
+directly, they are also not inherited through class hierarchies like
+how methods are. With all this terminology discussion out of the way,
+we can start talking about what VTABLES are and how they are used in
+Parrot.
 
-  # Set values to the attributes
-  setattribute $P1, 'First', 'First Value'
-  setattribute $P1, 'Second', 'Second Value'
+VTABLE interfaces are the primary way that data in the PMC is accessed
+and modified. VTABLES also provide a way to invoke the PMC if it's a
+subroutine or subroutine-like PMC. VTABLE interfaces are not called
+directly from PIR code, but are instead called internally by Parrot to
+implement specific opcodes and behaviors. For instance, the C<invoke>
+opcode calls the C<invoke> VTABLE interface of the subroutine PMC,
+while the C<inc> opcode on a PMC calls the C<increment> VTABLE
+interface on that PMC. What VTABLE interface overrides do, in essence,
+is to allow the programmer to change the very way that Parrot accesses
+PMC data in the most fundamental way, and changes the very way that the
+opcodes act on that data.
 
-  # Get the attribute values
-  $S0 = getattribute $P1, 'First'
-  $S1 = getattribute $P1, 'Second'
+PMCs, as we will look at more closely in later chapters, are typically
+implemented using X<PMC Script> PMC Script, a layer of syntax and macros
+over ordinary C code. A X<PMC Compiler> PMC compiler program converts the
+PMC files into C code for compilation as part of the ordinary build
+process. However, VTABLE interfaces can be written I<and overwritten> in
+PIR using the C<:vtable> flag on a subroutine declaration. This technique
+is used most commonly when subclassing an existing PMC class in PIR code
+to create a new data type with custom access methods.
 
-Those values added as attributes don't need to be strings, even though
-both of the ones in the example are. They can be integers, numbers
-or PMCs too.
+VTABLE interfaces are declared with the C<:vtable> flag:
 
-=head2 Input and Output
+  .sub 'set_integer' :vtable
+      #set the integer value of the PMC here
+  .end
 
-Like almost everything else in Parrot, input and output are handled by PMCs.
-Using the C<print> opcode or the C<say> opcode like we've already seen in
-some examples does this internally without your knowledge. However, we can
-do it explicitly too. First we'll talk about basic I/O, and then we will talk
-about using PMC-based filehandles for more advanced operations.
+in which case the subroutine must have the same name as the VTABLE
+interface it is intended to implement. VTABLE interfaces all have very
+specific names, and you can't override one with just any arbitrary name.
+However, if you would like to name the function something different but
+still use it as a VTABLE interface, you could add an additional name
+parameter to the flag:
+
+  .sub 'MySetInteger' :vtable('set_integer')
+      #set the integer value of the PMC here
+  .end
+
+VTABLE interfaces are often given the C<:method> flag also, so that they can
+be used directly in PIR code as methods, in addition to being used by Parrot
+as VTABLE interfaces. This means we can have the following:
+
+  .namespace [ "MyClass" ]
+
+  .sub 'ToString' :vtable('get_string') :method
+      $S0 = "hello!"
+      .return($S0)
+  .end
+
+  .namespace [ "OtherClass" ]
+
+  .local pmc myclass = new "MyClass"
+  say myclass                 # say converts to string internally
+  $S0 = myclass               # Convert to a string, store in $S0
+  $S0 = myclass.'ToString'()  # The same
+
+Inside a VTABLE interface definition, the C<self> local variable contains
+the PMC on which the VTABLE interface is invoked, just like in a method
+declaration.
+
+
+=head3 Roles
+
+As we've seen above and in the previous chapter, Class PMCs and NameSpace
+PMCs work to keep classes and methods together in a logical way. There is
+another factor to add to this mix: The Role PMC.
+
+Roles are like classes, but don't stand on their own. They represent
+collections of methods and VTABLES that can be added into an existing class.
+Adding a role to a class is called I<composing> that role, and any class
+that has been composed with a role C<does> that role.
+
+Roles are created as PMC and can be manipulated through opcodes and methods
+like other PMCs:
+
+  $P0 = new 'Role'
+  $P1 = get_global "MyRoleSub"
+  $P0.'add_method'("MyRoleSub", $P1)
+
+Once we've created a role and added methods to it, we can add that role to
+a class, or even to another role:
+
+  $P1 = new 'Role'
+  $P2 = new 'Class'
+  $P1.'add_role'($P0)
+  $P2.'add_role'($P0)
+  add_role $P2, $P0    # Same!
+
+Now that we have added the role, we can check whether we implement it:
+
+  $I0 = does $P2, $P0  # Yes
+
+We can get a list of roles from our Class PMC:
+
+  $P3 = $P2.'roles'()
+
+Roles are very useful for ensuring that related classes all implement a common
+interface.  
 
-=head2 Basic I/O Opcodes
 
-We've seen C<print> and C<say>. These are carry-over artifacts from Perl, when
-Parrot was simply the VM backend to the Perl 6 language. C<print> prints
+=head2 Filehandles
+
+Like almost everything else in Parrot, input and output are handled by PMCs.
+
+We've seen C<print> and C<say>. C<print> prints
 the given string argument, or the stringified form of the argument, if it's
 not a string, to standard output. C<say> does the same thing but also appends
 a trailing newline to it. Another opcode worth mentioning is the C<printerr>
@@ -2069,7 +4466,7 @@
 
 =begin PIR
 
-  .sub main
+  .sub 'main'
     loop_top:
       $S0 = read 10
       print $S0
@@ -2078,8 +4475,6 @@
 
 =end PIR
 
-=head2 Filehandles
-
 The ops we have seen so far are useful if all your I/O operations are limited
 to the standard streams. However, there are plenty of other places where
 you might want to get data from and send data to. Things like files, sockets,
@@ -2141,7 +4536,7 @@
 
 =begin PIR
 
-  .sub main
+  .sub 'main'
     $P0 = getstdout
     $P1 = open "myfile.txt", "r"
     loop_top:
@@ -2282,6 +4677,101 @@
 
 =head2 Exceptions
 
+=head2 Exceptions and Exception Handlers
+
+Z<CHP-9-SECT-8>
+
+X<exceptions>
+X<exception handlers>
+Exceptions provide a way of calling a piece of code outside the normal
+flow of control. They are mainly used for error reporting or cleanup
+tasks, but sometimes exceptions are just a funny way to branch from
+one code location to another one. The design and implementation of
+exceptions in Parrot isn't complete yet, but this section will give
+you an idea where we're headed.
+
+Exceptions are objects that hold all the information needed to handle
+the exception: the error message, the severity and type of the error,
+etc. The class of an exception object indicates the kind of exception
+it is.
+
+Exception handlers are derived from continuations. They are ordinary
+subroutines that follow the Parrot calling conventions, but are never
+explicitly called from within user code. User code pushes an exception
+handler onto the control stack with the C<set_eh>X<set_eh opcode (PIR)>
+opcode. The system calls the installed exception handler only when an
+exception is thrown (perhaps because of code that does division by
+zero or attempts to retrieve a global that wasn't stored.)
+
+=begin PIR_FRAGMENT_INVALID
+
+    newsub P20, .ExceptionHandler, _handler
+    set_eh P20                  # push handler on control stack
+    null P10                    # set register to null
+    get_global P10, "none"     # may throw exception
+    clear_eh                    # pop the handler off the stack
+    #...
+
+  _handler:                     # if not, execution continues here
+    is_null P10, not_found      # test P10
+    #...
+
+=end PIR_FRAGMENT_INVALID
+
+This example creates a new exception handler subroutine with the
+C<newsub> opcode and installs it on the control stack with the
+C<set_eh> opcode. It sets the C<P10> register to a null value (so it
+can be checked later) and attempts to retrieve the global variable
+named C<none>. If the global variable is found, the next statement
+(C<clear_eh>) pops the exception handler off the control stack and
+normal execution continues. If the C<get_global> call doesn't find
+C<none> it throws an exception by pushing an exception object onto the
+control stack. When Parrot sees that it has an exception, it pops it
+off the control stack and calls the exception handler C<_handler>.
+
+The first exception handler in the control stack sees every exception
+thrown. The handler has to examine the exception object and decide
+whether it can handle it (or discard it) or whether it should
+C<rethrow> the exception to pass it along to an exception handler
+deeper in the stack. The C<rethrow>X<rethrow opcode (PIR)> opcode is only
+valid in exception handlers. It pushes the exception object back onto
+the control stack so Parrot knows to search for the next exception
+handler in the stack. The process continues until some exception
+handler deals with the exception and returns normally, or until there
+are no more exception handlers on the control stack. When the system
+finds no installed exception handlers it defaults to a final action,
+which normally means it prints an appropriate message and terminates
+the program.
+
+When the system installs an exception handler, it creates a return
+continuation with a snapshot of the current interpreter context. If
+the exception handler just returns (that is, if the exception is
+cleanly caught) the return continuation restores the control stack
+back to its state when the exception handler was called, cleaning up
+the exception handler and any other changes that were made in the
+process of handling the exception.
+
+Exceptions thrown by standard Parrot opcodes (like the one thrown by
+C<get_global> above or by the C<throw> opcode) are always resumable,
+so when the exception handler function returns normally it continues
+execution at the opcode immediately after the one that threw the
+exception. Other exceptions at the run-loop level are also generally
+resumable.
+
+=begin PIR_FRAGMENT
+
+  new $P10, 'Exception'    # create new Exception object
+  set $P10, 'I die'        # set message attribute
+  throw $P10               # throw it
+
+=end PIR_FRAGMENT
+
+Exceptions are designed to work with the Parrot calling conventions.
+Since the return addresses of C<bsr> subroutine calls and exception
+handlers are both pushed onto the control stack, it's generally a bad
+idea to combine the two.
+
+
 Parrot includes a robust exception mechanism that is not only used internally
 to implement a variety of control flow constructs, but is also available for
 use directly from PIR code. Exceptions, in as few words as possible, are
@@ -2295,7 +4785,7 @@
 such as the location where the error was thrown (including complete
 backtraces), any annotation information from the file, and other data.
 
-=head2 Throwing Exceptions
+=head3 Throwing Exceptions
 
 Many exceptions are used internally in Parrot to indicate error conditions.
 Opcodes such as C<die> and C<warn> throw exceptions internally to do what they
@@ -2313,7 +4803,7 @@
 handler and continue execution there. If there are no handlers available,
 Parrot will exit.
 
-=head2 Exception Attributes
+=head3 Exception Attributes
 
 Since Exceptions are PMC objects, they can contain a number of useful data
 items. One such data item is the message:
@@ -2332,7 +4822,7 @@
 
   $P0["payload"] = $P2  # Any arbitrary PMC
 
-=head2 Exception Handlers
+=head3 Exception Handlers
 
 Exception handlers are labels in PIR code that can be jumped to when an
 exception is thrown. To list a label as an exception handler, the C<push_eh>
@@ -2374,13 +4864,13 @@
   my_handler:
     ...
 
-=head2 Rethrowing and Exception Propagation
+=head3 Rethrowing Exceptions
 
 Exception handlers are nested and are stored in a stack. This is because not
 all handlers are intended to handle all exceptions. If a handler cannot deal
-with a particular exception, it can C<rethrow> the exception to the next
-handler in the stack. Exceptions propagate through the handler stack until it
-reaches the default handler which causes Parrot to exit.
+with a particular exception, it can C<rethrow> the exception to the next outer handler
+handler. If none of the set handlers can handle the exception, the
+exception is a fatal error and Parrot will exit.
 
 =head2 Annotations
 
@@ -2431,6 +4921,331 @@
 C<'annotation'> which is the hash of annotations that were in effect at that
 point, and C<'sub'> which is the Sub PMC of that function.
 
+=head2 Events
+
+Z<CHP-9-SECT-9>
+
+An event is a notification that something has happened: a timer
+expired, an IO operation finished, a thread sent a message to
+another thread, or the user pressed C<Ctrl-C> to interrupt program
+execution.
+
+What all of these events have in common is that they arrive
+asynchronously. It's generally not safe to interrupt program flow at an
+arbitrary point and continue at a different position, so the event is
+placed in the
+interpreter's task queue. The run loops code regularly checks whether
+an event needs to be handled. Event handlers may be an internal piece
+of code or a user-defined event handler subroutine.
+
+Events are still experimental in Parrot, so the implementation and
+design is subject to change.
+
+=head3 Timers
+
+Z<CHP-9-SECT-9.1>
+
+C<Timer> objects are the replacement for Perl 5's C<alarm> handlers.
+They are also a significant improvement. Timers can fire once or
+repeatedly, and multiple timers can run independently. The precision
+of a timer is limited by the OS Parrot runs on, but it is always more
+fine-grained then a whole second. The final syntax isn't yet fixed, so
+please consult the documentation for examples.
+
+=head3 Signals
+
+Z<CHP-9-SECT-9.2>
+
+Signal handling is related to events. When Parrot gets a signal it
+needs to handle from the OS, it converts that signal into an event and
+broadcasts it to all running threads. Each thread independently
+decides if it's interested in this signal and, if so, how to respond to it.
+
+=begin PIR_FRAGMENT_INVALID
+
+    newsub P20, .ExceptionHandler, _handler
+    set_eh P20                  # establish signal handler
+    print "send SIGINT:\n"
+    sleep 2                     # press ^C after you saw start
+    print "no SIGINT\n"
+    end
+  _handler:
+    .include "signal.pasm"      # get signal definitions
+    print "caught "
+    set I0, P5["type"]         # if _type is negative, the ...
+    neg I0, I0                  # ... negated type is the signal
+    ne I0, .SIGINT, nok
+    print "SIGINT\n"
+  nok:
+    end
+
+=end PIR_FRAGMENT_INVALID
+
+This example creates a signal handler and pushes it on to the control
+stack. It then prompts the user to send a C<SIGINT> from the shell
+(this is usually C<Ctrl-C>, but it varies in different shells), and
+waits for 2 seconds. If the user doesn't send a SIGINT in 2 seconds
+the example just prints "no SIGINT" and ends. If the user does send a
+SIGINT, the signal handler catches it, prints out "caught SIGINT" and
+ends.N<Currently, only Linux installs a C<SIGINT> C<sigaction>
+handler, so this example won't work on other platforms.>
+
+=head2 Threads
+
+Z<CHP-9-SECT-10>
+
+Threads allow multiple pieces of code to run in parallel. This is
+useful when you have multiple physical CPUs to share the load of
+running individual threads. With a single processor, threads still
+provide the feeling of parallelism, but without any improvement in
+execution time. Even worse, sometimes using threads on a single
+processor will actually slow down your program.
+
+Still, many algorithms can be expressed more easily in terms of
+parallel running pieces of code and many applications profit from
+taking advantage of multiple CPUs. Threads can vastly simplify
+asynchronous programs like internet servers: a thread splits off,
+waits for some IO to happen, handles it, and relinquishes the
+processor again when it's done.
+
+Parrot compiles in thread support by default (at least, if the
+platform provides some kind of support for it). Unlike Perl 5,
+compiling with threading support doesn't impose any execution time
+penalty for a non-threaded program. Like exceptions and events,
+threads are still under development, so you can expect significant
+changes in the near future.
+
+As outlined in the previous chapter, Parrot implements three different
+threading models. (B<Note>:  As of version 1.0, the C<TQueue> PMC will be
+deprecated, rendering the following discussion obsolete.) The following
+example uses the third model, which takes advantage of shared data. It uses a
+C<TQueue> (thread-safe queue) object to synchronize the two parallel running
+threads. This is only a simple example to illustrate threads, not a typical
+usage of threads (no-one really wants to spawn two threads just to print out a
+simple string).
+
+=begin PIR_FRAGMENT_INVALID
+
+    get_global P5, "_th1"              # locate thread function
+    new P2, "ParrotThread"              # create a new thread
+    find_method P0, P2, "thread3"       # a shared thread's entry
+    new P7, "TQueue"                    # create a Queue object
+    new P8, "Int"                       # and a Int
+    push P7, P8                         # push the Int onto queue
+    new P6, "String"                    # create new string
+    set P6, "Js nte artHce\n"
+    set I3, 3                           # thread function gets 3 args
+    invoke                              # _th1.run(P5,P6,P7)
+    new P2, "ParrotThread"              # same for a second thread
+    get_global P5, "_th2"
+    set P6, "utaohrPro akr"             # set string to 2nd thread's
+    invoke                              # ... data, run 2nd thread too
+    end                                 # Parrot joins both
+
+  .pcc_sub _th1:                        # 1st thread function
+  w1: sleep 0.001                       # wait a bit and schedule
+    defined I1, P7                      # check if queue entry is ...
+    unless I1, w1                       # ... defined, yes: it's ours
+    set S5, P6                          # get string param
+    substr S0, S5, I0, 1                # extract next char
+    print S0                            # and print it
+    inc I0                              # increment char pointer
+    shift P8, P7                        # pull item off from queue
+    if S0, w1                           # then wait again, if todo
+    invoke P1                           # done with string
+
+  .pcc_sub _th2:                        # 2nd thread function
+  w2: sleep 0.001
+    defined I1, P7                      # if queue entry is defined
+    if I1, w2                           # then wait
+    set S5, P6
+    substr S0, S5, I0, 1                # if not print next char
+    print S0
+    inc I0
+    new P8, "Int"                       # and put a defined entry
+    push P7, P8                         # onto the queue so that
+    if S0, w2                           # the other thread will run
+    invoke P1                           # done with string
+
+=end PIR_FRAGMENT_INVALID
+
+This example creates a C<ParrotThread> object and calls its C<thread3>
+method, passing three arguments: a PMC for the C<_th1> subroutine in
+C<P5>, a string argument in C<P6>, and a C<TQueue> object in C<P7>
+containing a single integer. Remember from the earlier section
+"Parrot calling conventions" that registers 5-15
+hold the arguments for a subroutine or method call and C<I3> stores
+the number of arguments. The thread object is passed in C<P2>.
+
+This call to the C<thread3> method spawns a new thread to run the
+C<_th1> subroutine. The main body of the code then creates a second
+C<ParrotThread> object in C<P2>, stores a different subroutine in
+C<P5>, sets C<P6> to a new string value, and then calls the C<thread3>
+method again, passing it the same C<TQueue> object as the first
+thread. This method call spawns a second thread. The main body of code
+then ends, leaving the two threads to do the work.
+
+At this point the two threads have already started running. The first
+thread (C<_th1>) starts off by sleeping for a 1000th of a second. It
+then checks if the C<TQueue> object contains a value. Since it
+contains a value when the thread is first called, it goes ahead and
+runs the body of the subroutine. The first thing this does is shift
+the element off the C<TQueue>. It then pulls one character off a copy
+of the string parameter using C<substr>, prints the character,
+increments the current position (C<I0>) in the string, and loops back
+to the C<w1> label and sleeps. Since the queue doesn't have any
+elements now, the subroutine keeps sleeping.
+
+Meanwhile, the second thread (C<_th2>) also starts off by sleeping for
+a 1000th of a second. It checks if the shared C<TQueue> object
+contains a defined value but unlike the first thread it only continues
+sleeping if the queue does contain a value. Since the queue contains a
+value when the second thread is first called, the subroutine loops
+back to the C<w2> label and continues sleeping. It keeps sleeping
+until the first thread shifts the integer off the queue, then runs the
+body of the subroutine. The body pulls one character off a copy of the
+string parameter using C<substr>, prints the character, and increments
+the current position in the string. It then creates a new
+C<Int>, pushes it onto the shared queue, and loops back to the
+C<w2> label again to sleep. The queue has an element now, so the
+second thread keeps sleeping, but the first thread runs through its
+loop again.
+
+The two threads alternate like this, printing a character and marking
+the queue so the next thread can run, until there are no more
+characters in either string. At the end, each subroutine invokes the
+return continuation in C<P1> which terminates the thread. The
+interpreter waits for all threads to terminate in the cleanup phase
+after the C<end> in the main body of code.
+
+The final printed result (as you might have guessed) is:
+
+  Just another Parrot Hacker
+
+The syntax for threads isn't carved in stone and the implementation
+still isn't finished but as this example shows, threads are working
+now and already useful.
+
+Several methods are useful when working with threads. The C<join>
+method belongs to the C<ParrotThread> class. When it's called on a
+C<ParrotThread> object, the calling code waits until the thread
+terminates.
+
+=begin PIR_FRAGMENT_INVALID
+
+    new $P2, "ParrotThread"       # create a new thread
+    set $I5, $P2                  # get thread ID
+
+    find_method $P0, $P2, "join"  # get the join method...
+    invoke                        # ...and join (wait for) the thread
+    set $P16, $P5                 # the return result of the thread
+
+=end PIR_FRAGMENT_INVALID
+
+C<kill> and C<detach> are interpreter methods, so you have to grab the
+current interpreter object before you can look up the method object.
+
+=begin PIR_FRAGMENT_INVALID
+
+    set $I5, $P2                  # get thread ID of thread P2
+    getinterp $P3                 # get this interpreter object
+    find_method $P0, $P3, "kill"  # get kill method
+    invoke                        # kill thread with ID I5
+
+    find_method $P0, $P3, "detach"
+    invoke                      # detach thread with ID I5
+
+=end PIR_FRAGMENT_INVALID
+
+By the time you read this, some of these combinations of statements
+and much of the threading syntax above may be reduced to a simpler set
+of opcodes.
+
+=head2 Loading Bytecode
+
+Z<CHP-9-SECT-11>
+
+In addition to running Parrot bytecode on the command-line, you can
+also load pre-compiled bytecode directly into your PIR source file.
+The C<load_bytecode>X<load_bytecode opcode (PIR)> opcode takes a single
+argument: the name of the bytecode file to load. So, if you create a
+file named F<file.pasm> containing a single subroutine:
+
+=begin PIR_FRAGMENT_INVALID
+
+  # file.pasm
+  .sub _sub2:               # .sub stores a global sub
+     print "in sub2\n"
+     invoke P1
+
+=end PIR_FRAGMENT_INVALID
+
+and compile it to bytecode using the C<-o> command-line switch:
+
+  $ parrot -o file.pbc file.pasm
+
+You can then load the compiled bytecode into F<main.pasm> and directly
+call the subroutine defined in F<file.pasm>:
+
+=begin PIR_FRAGMENT_INVALID
+
+  # main.pir
+  main:
+    load_bytecode "file.pbc"    # compiled file.pasm
+    get_global $P0, "_sub2"
+    invokecc
+
+=end PIR_FRAGMENT_INVALID
+
+The C<load_bytecode> opcode also works with source files, as long as
+Parrot has a compiler registered for that type of file:
+
+=begin PIR_FRAGMENT_INVALID
+
+  # main2.pir
+  main:
+    load_bytecode "file.pasm"  # PIR source code
+    set_global $P0, "_sub2"
+    invokecc
+
+=end PIR_FRAGMENT_INVALID
+
+Subroutines marked with C<:load> run as soon as they're loaded (before
+C<load_bytecode> returns), rather than waiting to be called. A
+subroutine marked with C<:main> will always run first, no matter what
+name you give it or where you define it in the file.
+
+=begin PIR_FRAGMENT_INVALID
+
+  # file3.pir
+  .sub :load                    # mark the sub as to be run
+    print "file3\n"
+    invoke $P1                   # return
+
+  # main3.pasm
+  first:                        # first is never invoked
+    print "never\n"
+    invoke $P1
+
+  .sub :main                    # because _main is marked as the
+    print "main\n"              # MAIN entry of program execution
+    load_bytecode "file3.pasm"
+    print "back\n"
+
+=end PIR_FRAGMENT_INVALID
+
+This example uses both C<:load> and C<:main>. Because the C<main>
+subroutine is defined with C<:main> it will execute first even though
+another subroutine comes before it in the file. C<main> prints a
+line, loads the PIR source file, and then prints another line.
+Because C<_entry> in F<file3.pasm> is marked with C<:load> it runs
+before C<load_bytecode> returns, so the final output is:
+
+  main
+  file3
+  back
+
+
 =cut
 
 # Local variables:

Modified: branches/pmc_pct/docs/book/ch05_pge.pod
==============================================================================
--- branches/pmc_pct/docs/book/ch05_pge.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/book/ch05_pge.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -2,32 +2,30 @@
 
 =head1 Grammar Engine
 
-X<Parrot Grammar Engine> 
-X<PGE (Parrot Grammar Engine)> 
+X<Parrot Grammar Engine>
+X<PGE (Parrot Grammar Engine)>
 The Parrot Grammar Engine (PGE) is a parser generator, one of the key
-components of the Parrot Compiler Toolkit. It reads grammar files
-written in the PGE rules format, and generates parser modules for the
-syntax specified by those rules. PGE rules provide the full power of
-recursive descent parsing and operator precedence parsing, but are
-comfortably useful even if you don't know anything about parsing theory.
-In the usual case, all you'll ever need to know is that rules are
-patterns for matching text.
+components of the Parrot Compiler Toolkit. It reads grammar files written in
+the PGE rules format and generates parser modules.  PGE rules provide the full
+power of recursive descent parsing and operator precedence parsing, but are
+usable even if you don't know exactly what that means.  All you'll need to know
+to start is that rules are patterns for matching text.
 
 =head2 Grammars
 
 A grammar is a collection of rules, in much the same way that a class is a
-collection of methods.N<In fact, a grammar is just a special kind of class
-and a rule is just a special kind of method.> Each rule defines a pattern for
-matching one piece of text. The basic matching syntax for rules is likely to
-be somewhat familiar to anyone who has worked with regular expressions.
+collection of methods.N<A grammar is a special kind of class and a rule is a
+special kind of method.> Each rule defines a pattern for matching one unit of
+text. The basic matching syntax for rules is familiar to anyone who has worked
+with regular expressions:
 
   rule id { \d+ }
 
-Larger rules are composed from smaller rules:
+Smaller rules can combine into larger rules:
 
   rule record { <id> <name> <phone> }
 
-And a grammar holds a group of rules that work together:
+A grammar contains a group of rules that work together:
 
   grammar Contacts;
 
@@ -41,56 +39,67 @@
 
 =head3 Rules and Tokens
 
-There are two different kinds of rules, each declared with a different keyword:
-C<rule> or C<token>. A C<rule> does smart whitespace matching between the
-various pieces of the pattern. So, the C<record> rule above would match
-"6355 John" or "6355      John" but not "6355John".
-
-A C<token> only matches whitespace if you specifically request it. To get the
-same effect with a token, you'd have to add a C<\s> pattern to the rule:
+X<rule>
+X<token>
+There are two different kinds of rules: C<rule> or C<token>. A C<rule> performs
+smart whitespace matching between the various pieces of the pattern. The
+C<record> rule given previously would match "6355 John" or "6355      John" but
+not "6355John".
+
+A C<token> matches whitespace only if you specifically request it. To get the
+same effect with a token, add the C<\s> (match a space character) and C<+>
+(match the preceding atom -- the space character, in this case -- one or more
+times) pattern to the rule:
 
   token record { <id> \s+ <name> }
 
 =head3 The Start Rule
 
-A recursive descent parser is a top-down parser. This means it starts at the
-highest-level rule and works its way down through individual rules to match
-an entire string or file. In PGE, this top-level rule is called C<TOP> by
-convention.N<In "real" Perl 6, the top-level rule can be called anything.
-However, some of the PCT compiler tools expect it to be called C<TOP>.
-Compilers written with PCT should just use the name C<TOP> for all top-level
-tokens.>
+X<top>
+X<top-down parser>
+A recursive descent parser is a top-down parser. It starts at the highest-level
+rule and works its way down through individual rules to match an entire string
+or file. PGE convention calls this top-level rule C<TOP>N<Perl 6 allows any
+name for the top-level rule, but PCT expects a rule called C<TOP>.>.
 
   rule TOP { <record> }
 
 This rule matches a single record in a string or file. Once the parser has
-matched the entire string or file passed to the start rule, the parse is
-considered successful and a raw parse tree is returned.
+succeeded in matching the entire string or file passed to the start rule, it
+returns a parse tree.
 
 =head3 Testing a Grammar
 
-You might want to try out the examples in this chapter as you read along.
-To compile the following simple example, save it to a file called
-F<Contacts.pg>:
+Save this example to a file called F<Contacts.pg>:
 
   grammar Contacts is PGE::Grammar;
+
   rule  TOP    { <record> }
   rule  record { <id> <name> }
   token name   { 'John' | 'Bob ' | 'Fred' }
   token id     { \d+ }
 
-Then compile the grammar with the following command:
+Then compile the grammar:
+
+  $ B<parrot Perl6Grammar.pbc --output=Contacts.pir Contacts.pg>
+
+=for author
+
+Assume an installed Parrot for all examples?  Anyone working from the source
+tree should be able to mangle paths appropriately.
 
-  $ parrot Perl6Grammar.pbc --output=Contacts.pir Contacts.pg
+=end for
 
 The path to F<parrot> and to the F<Perl6Grammar.pbc> file will vary on
 different systems. If you compiled Parrot from source, it will be:
 
-  $ ./parrot runtime/parrot/library/PGE/Perl6Grammar.pbc \
-        --output=Contacts.pir Contacts.pg
+  $ B<./parrot runtime/parrot/library/PGE/Perl6Grammar.pbc \>
+        B<--output=Contacts.pir Contacts.pg>
 
-Next, create a small PIR script to run your grammar. You can save it as
-F<grammar_test.pir>.
+Next, create a small PIR script to run your grammar. Save it as
+F<grammar_test.pir>:
+
+=begin PIR
 
   .sub main :main
       load_bytecode 'PGE.pbc'        # load some required modules
@@ -100,18 +109,21 @@
       load_bytecode 'Contacts.pir'   # load your grammar
 
       .local string source
-      .local pmc top, grammar, match
+      source  = "3 John"
 
-      source = "3 John"
-      top = get_hll_global ['Contacts'], 'TOP'
+      .local pmc top, grammar, match
+      top     = get_hll_global ['Contacts'], 'TOP'
       grammar = get_class 'Contacts'
-      match = top(source, 'grammar' => grammar)
+      match   = top(source, 'grammar' => grammar)
+
       _dumper(match, "match")
   .end
 
-Now, you can run the test script with this command:
+=end PIR
 
-  $ parrot grammar_test.pir
+Run the test script:
+
+  $ B<parrot grammar_test.pir>
 
 It will print out a text representation of the raw parse tree stored in the
 C<match> variable:
@@ -123,52 +135,48 @@
       }
   }
 
-Each rule in the grammar corresponds to a node in the tree. This output shows
-that the top-level match variable contains one child named "record", that
-"record" contains two children named "id" and "name", and that "id" contains
-the number 3, and "name" contains the string "John". Exactly what we would
-expect from our simple grammar.
+Each node in the tree corresponds to a rule in the grammar.  The top-level
+match variable contains one child named C<record>, which contains two children
+named C<id> and C<name>.  C<id> contains the number 3, and C<name> contains the
+string "John". This is exactly what the simple grammar should have matched.
 
 =head2 Rule Syntax
 
-Every language has a set of basic components (words or parts of words)
-and syntax conventions for combining them. The "words" in rules are
-literal characters or symbols, some X<metacharacters> metacharacters
-(or metasymbols),  and X<rules;escape sequences>X<escape sequences,
-rules> escape sequences, while the combining syntax includes other
-metacharacters, X<quantifiers, rules> X<rules;quantifiers> quantifiers,
-bracketing characters, and assertions.
+Every language has a set of basic components (words or parts of words) and
+syntax conventions for combining them. The "words" in rules are literal
+characters or symbols, some X<metacharacters> metacharacters (or metasymbols),
+and X<rules;escape sequences>X<escape sequences, rules> escape sequences, while
+the combining syntax includes other metacharacters, X<quantifiers, rules>
+X<rules;quantifiers> quantifiers, bracketing characters, and assertions.
 
 =head3 Metacharacters
 
-The C<.> matches any single character, even a newline character. The C<^> and
-C<$> metacharacters are zero-width matches on the beginning and end of a
-string. They each have doubled alternates C<^^> and C<$$> that match at the
-beginning and end of every line within a string.
-
-The C<|>, C<&>, C<\>, C<#>, and C<:=> metacharacters are all syntax
-structure elements. The C<|> is an alternation between two options. The
-C<&> matches two patterns simultaneously (the patterns must be the same
-length). The C<\> turns literal characters into metacharacters (the
-escape sequences). The C<#> marks a comment to the end of the line. You can
-start a comment at any point on any line in a rule. The C<:=> binds a
-hypothetical variable to the result of a subrule or grouped pattern.
-Hypotheticals are covered in L<Hypothetical Variables> later in this chapter.
-
-The metacharacters C<()>, C<[]>, C<{}> and C<E<lt>E<gt>> are bracketing
-pairs. The pairs always have to be balanced within the rule, unless they
-are literal characters (escaped with a C<\>). The C<()> and C<[]> pairs
-group patterns to match as a single atom. They're often used to
-capture a result, mark the boundaries of an alternation, or mark a group
-of patterns with a quantifier. Parentheses C<()> are
-capturing and square brackets C<[]> are non-capturing. The C<{}>
-brackets define a section of code (a closure) within a rule. These
-closures are always a successful zero-width match. The C<E<lt>...E<gt>> brackets
-mark assertions, which handle a variety of constructs including
-character classes and user-defined quantifiers. Assertions are covered
-in L<Assertions> later in this chapter.
+The C<.> metacharacter matches any single character, even a newline character.
+The C<^> and C<$> metacharacters are zero-width matches which represent the
+beginning and end of a string. They each have doubled alternates C<^^> and
+C<$$> that match at the beginning and end of every (newline-delimited) line
+within a string.
+
+The C<|>, C<&>, C<\>, C<#>, and C<:=> metacharacters are all syntax structure
+elements. C<|> alternates between two options. C<&> matches two patterns
+simultaneously (the patterns must be the same length). C<\> turns literal
+characters into metacharacters (producing escape sequences). C<#> starts a
+comment which proceeds until the end of the line. You can start a comment at
+any point on any line in a rule. C<:=> binds a hypothetical variable to the
+result of a subrule or grouped pattern (see L<Hypothetical Variables>).
+
+The metacharacters C<()>, C<[]>, C<{}> and C<E<lt>E<gt>> are bracketing pairs.
+Bracketing pairs must always be balanced within the rule; to use a literal
+character, escape it with a C<\>.  The C<()> and C<[]> pairs group patterns as
+a single atom. They often capture a result, mark the boundaries of an
+alternation, or mark a group of patterns with a quantifier. Parentheses C<()>
+capture, but square brackets C<[]> do not. The C<{}> brackets define a section
+of code (a closure) within a rule. These closures are always a successful
+zero-width match. The C<E<lt>...E<gt>> brackets mark assertions, which handle a
+variety of constructs including character classes and user-defined quantifiers
+(see L<Assertions>).
 
-Table 7-2 summarizes the basic set of metacharacters.
+Table 7-2 summarizes the basic metacharacters.
 
 =begin table picture Metacharacters
 
@@ -209,14 +217,14 @@
 
 =cell C<^^>
 
-=cell Match the beginning of a line.
+=cell Match the beginning of a line within the string.
 X<^ (caret);^^ beginning of line (rules)>
 
 =row
 
 =cell C<$$>
 
-=cell Match the end of a line.
+=cell Match the end of a line within the string.
 X<$ (dollar sign);$$ end of line (rules)>
 
 =row
@@ -279,7 +287,6 @@
 
 =end table
 
-
 =head3 Escape Sequences
 
 Z<CHP-7-SECT-2.2>
@@ -287,19 +294,21 @@
 X<escape sequences, rules>
 X<rules;escape sequences>
 X<\ (backslash);\ escape sequences (rules)>
-The escape sequences are literal characters acting as metacharacters,
-marked with the C<\> escape. Some escape sequences represent single
-characters that are difficult to represent literally, like C<\t> for
-tab, or C<\x[...]> for a character specified by a hexadecimal number.
-Some represent limited character classes, like C<\d> for digits or C<\w>
-for word characters. Some represent zero-width positions in a match,
-like C<\b> for a word boundary. With all the escape sequences that use
-brackets, C<()>, C<{}>, and C<E<lt>E<gt>> work in place of C<[]>.
+
+Escape sequences are literal characters acting as metacharacters.  A preceding
+backslash (C<\>) identifies them as escapes. Some escape sequences represent
+single characters that are difficult to represent literally, such as C<\t> for
+tab, or C<\x[...]> to specify a character by its hexadecimal number.  Some
+represent limited character classes, such as C<\d> for digits or C<\w> for word
+characters. Some represent zero-width positions in a match, such as C<\b> for a
+word boundary.
 
 X<variable interpolation in rules>
 X<rules;variable interpolation>
-Note that since an ordinary variable now interpolates as a literal
-string by default, the C<\Q> escape sequence is rarely needed.
+If you've used Perl 5 regexps, you may remember the C<\Q> escape sequence which
+treats everything until the following C<\E> sequence as literal text,
+containing no escape sequences.  Because ordinary variables now interpolate as
+literal strings by default, the C<\Q> escape sequence is rarely needed.
 
 A<CHP-7-TABLE-3>Table 7-3 shows the escape sequences for rules.
 
@@ -477,7 +486,8 @@
 
 =cell C<\w>
 
-=cell Match a word character (Unicode alphanumeric plus "_").
+=cell Match a word character (Unicode alphanumeric characters plus the
+underscore C<_>).
 
 =row
 
@@ -505,21 +515,21 @@
 Z<CHP-7-SECT-2.3>
 
 Quantifiers specify the number of times an atom (a single character,
-metacharacter, escape sequence, grouped pattern, assertion, etc) will
-match.
+metacharacter, escape sequence, grouped pattern, assertion, etc) will match.
 
 X<. (dot);.. (range);quantifier (rules)>
 X<. (dot);... (infinite range);quantifier (rules)>
-The numeric quantifiers use assertion syntax. A single number
-(C<E<lt>3E<gt>>) requires exactly that many matches. A numeric range
-quantifier (C<E<lt>3C<..>5E<gt>>) succeeds if the number of matches is
-between the minimum and maximum numbers. A range with three trailing
-dots (C<E<lt>2...E<gt>>) is shorthand for C<E<lt>R<n>..InfE<gt>> and
-matches as many times as possible.
-
-Each quantifier has a minimal alternate form, marked with a trailing
-C<?>, that matches the shortest possible sequence first.
-
+The numeric quantifiers use assertion syntax. A single number (C<E<lt>3E<gt>>)
+requires exactly that many matches. A numeric range quantifier
+(C<E<lt>3C<..>5E<gt>>) succeeds if the number of matches is between the minimum
+and maximum numbers, inclusive. A range with three trailing dots
+(C<E<lt>2...E<gt>>) is shorthand for C<E<lt>R<n>..InfE<gt>>; it matches as many
+times as possible.
+
+Each quantifier has a minimal alternate form -- marked with a trailing C<?> --
+which matches the shortest possible sequence first.  That is, given the string
+C<aaaaaa>, C<aE<lt>3C<..>5E<gt>> will match C<aaaaa> and C<aE<lt>3C<..>5E<gt>?>
+will match C<aaa>.
 
 A<CHP-7-TABLE-4>Table 7-4 shows the built-in
 X<quantifiers, rules> X<rules;quantifiers> quantifiers.
@@ -590,54 +600,53 @@
 
 =end table
 
-
 =head3 Assertions
 
 Z<CHP-7-SECT-2.4>
 
 X<assertions, rules>
 X<rules;assertions>
-In general, an assertion simply states that some condition or state is
-true and the match fails when that assertion is false. Many different
-constructs with many different purposes use assertion syntax.
+An assertion states that some condition or state is true. The match fails when
+that assertion is false.
 
 X<variable interpolation in rules>
 X<rules;variable interpolation>
+
 Assertions match named and anonymous rules, arrays or hashes containing
-anonymous rules, and subroutines or closures that return anonymous
-rules. You have to enclose a variable in assertion delimiters to get it
-to interpolate as an anonymous rule or rules. A bare scalar in a pattern
+anonymous rules, and subroutines or closures that return anonymous rules.
+
+To interpolate a variable in assertion rules, enclose it in assertion
+delimiters.
+A bare scalar in a pattern
 interpolates as a literal string, while a scalar variable in assertion
 brackets interpolates as an anonymous rule. A bare array in a pattern
 matches as a series of alternate literal strings, while an array in
 assertion brackets interpolates as a series of alternate anonymous
-rules. In the simplest case, a bare hash in a pattern matches a word
-(C<\w+>) and tries to find that word as one of its keys.N<The effect is
-much as if it matched the keys as a series of alternates, but you're
-guaranteed to match the longest possible key, instead of just the first
-one it hits in random order.>, while a hash in assertion brackets does
-the same, but then also matches the associated value as an anonymous
-rule.
+rules.
+
+A bare hash in a pattern matches a word (C<\w+>) if and only if that word is
+one of its keysN<The effect is similar to matching the keys as a series of
+alternates, but it prefers to match the longest possible key, instead of the
+first potential match.>, while a hash in assertion brackets also matches the
+associated value as an anonymous rule.
 
 X<fail keyword>
-A bare closure in a pattern always matches (unless it calls C<fail>),
-but a closure in assertion brackets C<E<lt>{...}E<gt>> must return an
-anonymous rule, which is immediately matched.
-
-An assertion with parentheses C<E<lt>(...)E<gt>> is similar to a bare
-closure in a pattern in that it allows you to include straight Perl code
-within a rule. The difference is that C<E<lt>(...)E<gt>> evaluates the
-return value of the closure in boolean context. The match succeeds if
-the return value is true and fails if the return value is false.
-
-Assertions match character classes, both named and enumerated. A named
-rule character class is often more accurate than an enumerated character
-class. For example, C<E<lt>[a-zA-Z]E<gt>> is commonly used to match
-alphabetic characters, but generally what's really needed is the
-built-in rule C<E<lt>alphaE<gt>> which matches the full set of Unicode
-alphabetic characters.
+A bare closure in a pattern always matches (unless it calls C<fail>), but a
+closure in assertion brackets C<E<lt>{...}E<gt>> must return an anonymous rule
+to match.
+
+An assertion with parentheses C<E<lt>(...)E<gt>> resembles a bare closure in a
+pattern in that it allows you to include Perl code within a rule.
+C<E<lt>(...)E<gt>> evaluates the return value of the closure in boolean
+context. The match succeeds or fails based on that return value.
+
+Assertions match character classes, both named and enumerated. A named rule
+character class is often more accurate than an enumerated character class. The
+common C<E<lt>[a-zA-Z]E<gt>> idiom matches ASCII alphabetic characters, but the
+more comprehensive built-in rule C<E<lt>alphaE<gt>> matches the full set of
+Unicode alphabetic characters.
 
-A<CHP-7-TABLE-5>Table 7-5 shows the syntax for assertions.
+A<CHP-7-TABLE-5>Table 7-5 shows the syntax of assertions.
 
 =begin table picture Assertions
 
@@ -718,8 +727,7 @@
 
 =cell C<E<lt>%hashE<gt>>
 
-=cell Match a key from the hash, then its value (which is an anonymous
-rule).
+=cell Match a key from the hash, then its value (as an anonymous rule).
 
 =row
 
@@ -741,73 +749,65 @@
 
 =end table
 
-
 =head3 Modifiers
 
 Z<CHP-7-SECT-2.5>
 
 X<modifiers>
 X<: (colon);: modifier delimiter in rules>
-Modifiers alter the meaning of the pattern syntax. The standard
-position for modifiers is at the beginning of the rule, right after
-the C<m>, C<s>, or C<rx>, or after the name in a named rule. Modifiers
-cannot attach to the outside of a bare C</.../>. For example:
+Modifiers alter the meaning of a pattern. The standard position for modifiers
+is at the beginning of the rule, right after the C<m>, C<s>, or C<rx>, or after
+the name in a named rule. Modifiers cannot attach to the outside of a bare
+C</.../>. For example:
 
   m:i/marvin/ # case insensitive
   rule names :i { marvin | ford | arthur }
 
-The single-character modifiers can be grouped, but the others must be
-separated by a colon:
+You may group single-character modifiers, but you must separate longer
+modifiers by colons:
 
   m:wig/ zaphod /                        # OK
   m:words:ignorecase:globally / zaphod / # OK
   m:wordsignorecaseglobally / zaphod /   # Not OK
 
-Most of the modifiers can also go inside the rule, attached to the
-rule delimiters or to grouping delimiters. Internal modifiers are
-lexically scoped to their enclosing delimiters, so you get a temporary
-alteration of the pattern:
+Most modifiers can also appear inside the rule when attached to rule or
+grouping delimiters. Internal modifiers are lexically scoped to their enclosing
+delimiters, so can alter subpatterns:
 
   m/:w I saw [:i zaphod] / # only 'zaphod' is case insensitive
 
-The repetition modifiers (C<:R<N>x>, C<:R<N>th>, C<:once>,
-C<:globally>, and C<:exhaustive>) and the continue modifier (C<:cont>)
-can't be lexically scoped, because they alter the return value of the
-entire rule.
-
-The C<:R<N>x> modifier matches the rule a counted number of times. If
-the modifier expects more matches than the string has, the match fails.
-It has an alternate form C<:x(R<N>)> that can take a variable in place
-of the number.
-
-The C<:once> modifier on a rule only allows it to match once. The rule
-will not match again until the you call the C<.reset> method on the rule
-object.
-
-The C<:globally> modifier matches as many times as possible. The
-C<:exhaustive> modifier also matches as many times as possible, but in
-as many different ways as possible.
-
-The C<:R<N>th> modifier preserves one result from a particular counted
-match. If the rule matches fewer times than the modifier expects, the
-match fails. It has several alternate forms. One form--C<:th(R<N>)>--can
-take a variable in place of the number. The other forms--C<:R<N>st>,
-C<:R<N>nd>, and C<:R<N>rd>--are for cases where it's more natural to
-write C<:1st>, C<:2nd>, C<:3rd> than it is to write C<:1th>, C<:2th>,
-C<:3th>. Either way is valid, so pick the one that's most comfortable
-for you.
-
-By default, rules ignore literal whitespace within the pattern.  The
-C<:w> modifier makes rules sensitive to literal whitespace, but in an
-intelligent way. Any cluster of literal whitespace acts like an explicit
-C<\s+> when it separates two identifiers and C<\s*> everywhere else.
-
-There are no modifiers to alter whether the matched string is treated as
-a single line or multiple lines. That's why the "beginning of string"
-and "end of string" metasymbols have "beginning of line" and "end of
-line" counterparts.
+The repetition modifiers (C<:R<N>x>, C<:R<N>th>, C<:once>, C<:globally>, and
+C<:exhaustive>) and the continue modifier (C<:cont>) alter the return value of
+the rule as a whole, so you cannot use them lexically inside a rule.
+
+The C<:R<N>x> modifier matches the rule a specific number of times. If the
+modifier expects more matches than the string has, the match fails.  Its
+alternate form (C<:x(R<N>)>) can take a variable in place of the number.
+
+The C<:once> modifier on a rule only allows it to match once. The rule will not
+match again until the you call the C<.reset> method on the rule object.
+
+The C<:globally> modifier matches as many times as possible. The C<:exhaustive>
+modifier also matches as many times as possible, in as many different ways as
+possible.
+
+The C<:R<N>th> modifier preserves one result from a particular counted match.
+If the rule matches fewer times than the modifier expects, the match fails. It
+has several alternate forms. One form, C<:th(R<N>)>, takes a variable in place
+of the number. The other forms -- C<:R<N>st>, C<:R<N>nd>, and C<:R<N>rd> --
+allow you to write more naturally C<:1st>, C<:2nd>, C<:3rd>.  The other way is
+valid as well; choose whichever is most comfortable.
+
+By default, rules ignore literal whitespace within the pattern.  The C<:w>
+modifier makes rules sensitive to literal whitespace, but in an intelligent
+way. Any cluster of literal whitespace acts like an explicit C<\s+> when it
+separates two identifiers and C<\s*> everywhere else.
+
+I<No> modifiers exist to treat the matched string as a single line or multiple
+lines.  Instead, use the "beginning of string" and "end of string" or
+"beginning of line" and "end of line" metacharacters.
 
-A<CHP-7-TABLE-6>Table 7-6 shows the current list of modifiers.
+A<CHP-7-TABLE-6>Table 7-6 lists the available modifiers.
 
 =begin table picture Modifiers
 
@@ -888,7 +888,7 @@
 
 =cell C<:once>
 
-=cell Only match the pattern once.
+=cell Match the pattern once and only once.
 
 =row
 
@@ -896,8 +896,8 @@
 
 =cell C<:globally>
 
-=cell Match the pattern as many times as possible, but only possibilities
-that don't overlap.
+=cell Match the pattern as many times as possible without overlapping
+possibilities.
 
 =row
 
@@ -905,7 +905,7 @@
 
 =cell C<:exhaustive>
 
-=cell Match every possible occurrence of a pattern, even overlapping
+=cell Match every possible occurrence of a pattern, including overlapping
 possibilities.
 
 =row
@@ -950,94 +950,93 @@
 
 =end table
 
-
 =head3 Built-in Rules
 
 Z<CHP-7-SECT-3>
 
 X<rules;built-in>
-A number of named rules are provided by default, including a complete
-set of X<POSIX-style classes> POSIX-style classes, and X<Unicode
-property classes> Unicode property classes. The list isn't fully
-defined yet, but A<CHP-7-TABLE-7>Table 7-7 shows a few you're
-likely to see.
-
-The C<E<lt>nullE<gt>> rule matches a zero-width string (so it's always
-true) and C<E<lt>priorE<gt>> matches whatever the most recent successful
-rule matched. These replace the two behaviors of 
-X</ (slash);// invalid null pattern>
-X<invalid null pattern //> the Perl 5 null pattern C<//>,
-which is no longer valid syntax for rules. 
+PGE provides several named rules, including a complete set of X<POSIX-style
+classes> POSIX-style classes, and X<Unicode property classes> Unicode property
+classes. The list isn't fully defined yet, but A<CHP-7-TABLE-7>Table 7-7 shows
+a few you're likely to see.
+
+The C<E<lt>nullE<gt>> rule matches a zero-width string (it always matches) and
+C<E<lt>priorE<gt>> matches whatever the most recent successful rule matched.
+These replace the two behaviors of X</ (slash);// invalid null pattern>
+X<invalid null pattern //> the Perl 5 null pattern C<//>, which is no longer
+valid syntax for rules.
 
 =begin table picture Built-in rules
 
 Z<CHP-7-TABLE-7>
 
-=headrow 
+=headrow
 
-=row 
+=row
 
 =cell Rule
 
 =cell Meaning
 
-=bodyrows 
+=bodyrows
 
-=row 
+=row
 
 =cell C<E<lt>alphaE<gt>>
 
 =cell Match a Unicode alphabetic character.
 
-=row 
+=row
 
 =cell C<E<lt>digitE<gt>>
 
 =cell Match a Unicode digit.
 
-=row 
+=row
 
 =cell C<E<lt>spE<gt>>
 
 =cell Match a single space character (the same as C<\s>).
 
-=row 
+=row
 
 =cell C<E<lt>wsE<gt>>
 
 =cell Match any whitespace (the same as C<\s+>).
 
-=row 
+=row
 
 =cell C<E<lt>nullE<gt>>
 
 =cell Match the null string.
 
-=row 
+=row
 
 =cell C<E<lt>priorE<gt>>
 
 =cell Match the same thing as the previous match.
 
-=row 
+=row
 
 =cell C<E<lt>before ...E<gt>>
 
-=cell Zero-width lookahead. Assert that you're I<before> a pattern.
+=cell Zero-width lookahead. Assert that the current position I<precedes> a
+pattern.
 
-=row 
+=row
 
 =cell C<E<lt>after ...E<gt>>
 
-=cell Zero-width lookbehind. Assert that you're I<after> a pattern.
+=cell Zero-width lookbehind. Assert that the current position I<follows> a
+pattern.
 
-=row 
+=row
 
 =cell C<E<lt>prop ...E<gt>>
 
 =cell Match any character with the named property.
 
-=row 
+=row
 
 =cell C<E<lt>replace(...)E<gt>>
 
@@ -1046,122 +1045,129 @@
 
 =end table
 
-
 =head3 Backtracking Control
 
 Z<CHP-7-SECT-4>
 
 X<backtracking controls>
-X<fail keyword> 
-Backtracking is triggered whenever part of the pattern fails to match.
-You can also explicitly trigger backtracking by calling the C<fail>
-function within a closure. A<CHP-7-TABLE-8>Table 7-8 shows some
-metacharacters and built-in rules relevant to backtracking.
+X<fail keyword>
+Whenever part of the pattern fails to match, PGE performs backtracking --
+backing up to the previous point at which the match could succeed and trying
+again.  You can explicitly trigger backtracking by calling the C<fail> function
+within a closure. A<CHP-7-TABLE-8>Table 7-8 displays metacharacters and
+built-in rules relevant to backtracking.
+
+=for author
+
+This could use an example.
+
+=end for
 
 =begin table picture Backtracking controls
 
 Z<CHP-7-TABLE-8>
 
-=headrow 
+=headrow
 
-=row 
+=row
 
 =cell Operator
 
 =cell Meaning
 
-=bodyrows 
+=bodyrows
 
-=row 
+=row
 
 =cell C<:>
 
-=cell Don't retry the previous atom, fail to the next
-earlier atom.
+=cell Don't retry the previous atom.  Instead, fail to the next earlier atom.
 X<: (colon);: fail to atom before last (rules)>
 X<backtracking controls;: fail to atom before last>
 
-=row 
+=row
 
 =cell C<::>
 
-=cell Don't backtrack over this point, fail out of the closest
+=cell Don't backtrack over this point. Instead fail out of the closest
 enclosing group (C<(...)>, C<[...]>, or the rule delimiters).
 X<: (colon);:: fail out of group (rules)>
 X<backtracking controls;: fail out of group>
 
-=row 
+=row
 
 =cell C<:::>
 
-=cell Don't backtrack over this point, fail out of the
-current rule or subrule.
+=cell Don't backtrack over this point.  Instead, fail out of the current rule
+or subrule.
 X<: (colon);::: fail out of rule (rules)>
 X<backtracking controls;: fail out of rule>
 
-=row 
+=row
 
 =cell C<E<lt>commitE<gt>>
 
-=cell Don't backtrack over this point, fail out of the
-entire match (even from within a subrule).
+=cell Don't backtrack over this point. Instead, fail out of the entire match
+(even from within a subrule).
 
-=row 
+=row
 
 =cell C<E<lt>cutE<gt>>
 
-=cell Like C<E<lt>commitE<gt>>, but also cuts the string matched. The
-current matching position at this point becomes the new beginning of
-the string.
+=cell Like C<E<lt>commitE<gt>>, but also cuts the string matched. The current
+matching position at this point becomes the new beginning of the string.
 
 =end table
 
-
 =head3 Calling Actions
 
-Once the parser has matched the entire input N<a
-source code file, or a line of input at the terminal in interactive
-mode> the parse is considered successful and the generated AST is
-delivered to the code generator for conversion into PIR.
+Once the parser has matched the entire input N<a source code file, or a line of
+input at the terminal in interactive mode> the parse has succeeded.  The
+generated AST is now available to the code generator for conversion into PIR.
+
+=for author
+
+Please review.  The forward declaration is awkward here, but a little bit of
+explanation might ameliorate this.
+
+=end for
 
+This AST gets built up by actions -- code snippets attached to rules and
+tokens.  To call an action, insert the C<{*}> token into the rule. When PGE
+encounters C<{*}>, it will call the associated action method with the current
+match object as an argument.
 
-We haven't covered actions yet, but it's still important now to talk
-about how we will call them when we are ready. We call an action
-by inserting the C<{*}> token into the rule. When the C<{*}> rule is
-encountered, PGE calls the associated action method with the current
-match object as an argument. Let's take our C<persons_name> rule
-from above, and sprinkle liberally with action calls:
+The best way to demonstrate this is by example.  Sprinkle the C<persons_name>
+rule liberally with action calls:
 
  rule persons_name {
     {*} <first_name> {*} <last_name> {*}
  }
 
-The first call to the action method contains an empty match object
-because the parser hasn't had a chance to match anything yet. The
-second call contains only the first name of the match. The third and
-final call contains both the matched first and last name. Notice that
-if the match fails halfway through, we still call the actions where
-we succeeded, but do not call the actions after the failure. So, if
-we try to match the string "Leia", the action is called before the
-name and after the first name. When the rule tries to match the last
-name, it fails because no last name is provided, and the third action
-method call is never made.
+The first call to the action method contains an empty match object because the
+parser hasn't matched anything yet.  The second call contains only the first
+name of the match. The third and final call contains both the matched first and
+last name.
+
+If the match fails halfway through, PGE will still call the actions that have
+succeeded; it will not call the actions after the failure.  If you try to match
+the string "Leia", PGE will call the first two action methods.  When the rule
+tries to match the last name, it fails, and PGE will not call the third action
+method.
 
 =head3 Alternations and Keys
 
-In addition to sub-rules, groups, and quantifiers, we also are able to
-take alternations between options that are either-or. The vertical bar
-token "|" can be used to distinguish between options where only one
-may match, Here's an example:
+In addition to sub-rules, groups, and quantifiers, you can also express
+either-or alternations between options. The vertical bar token (C<|>)
+distinguishes between options where only one may match:
 
  rule hero {
     ['Luke' | 'Leia'] 'Skywalker'
  }
 
-This rule will match either "Luke Skywalker" or "Leia Skywalker" but
-won't match "Luke Leia Skywalker" N<or anything else, for that matter>.
-With things like alternations, if we want to call an action method it's
-helpful to distinguish which combination we matched:
+This rule will match either "Luke Skywalker" or "Leia Skywalker" but won't
+match "Luke Leia Skywalker"N<nor anything else.>.  Given alternations and
+action methods, it's often important to distinguish which alternation matched:
 
  rule hero {
     [
@@ -1171,19 +1177,15 @@
     'Skywalker'
  }
 
-This is the same rule, except now it passes two arguments to its
-action method: the match object and the name of the person who
-got matched.
+This is the same rule, except now it passes two arguments to its action method:
+the match object and the name of the person who matched.
 
 =head3 Warning: Left Recursion
 
-Getting into all the nitty-gritty theory behind parsers is well beyond
-the scope of this book. However, there is one potential pitfall that
-developers should be made aware of that is not immediately obvious.
-Like functions in ordinary procedural or functional languages, the
-methods in the PGE parser grammar can call themselves recursively.
-Consider the following rules derived in part from the grammar for the
-C programming language:
+If you've worked with parsers before, you may have seen this coming.  If not,
+don't fear.  Like functions in ordinary procedural or functional languages, the
+methods in the PGE parser grammar can call themselves recursively.  Consider
+some rules derived in part from the grammar for the C programming language:
 
  rule if_statement {
     'if' <condition> '{' <statement>* '}' <else_block>?
@@ -1197,49 +1199,47 @@
     'else' '{' <statements>* '}'
  }
 
-Notice that an C<if_statement> can contain a list of C<statement>s, and
-that each statement may itself be an C<if_statement>? This is called
-I<recursion> X<Recursion>, and is part of where the "Recursive Descent"
-algorithm gets its name from.
-
-Now, let's look at a more direct example of a comma-separated list of
-integer digits to form an array. We can define this recursively as
-follows:
+An C<if_statement> can contain a list of C<statement>s, and that each statement
+may itself be an C<if_statement>.  This is I<recursion> X<Recursion>; it's one
+of the reasons PGE is a "Recursive descent" parser.
+
+Consider the more direct example of a comma-separated list of integer digits
+which form a list.  A recursive definition might be:
 
  rule list {
      <list> ',' <digit> | <digit>
  }
 
-The intention is that if there is only one digit, we match the second
-option in the alternation, and if there are more digits we can match
-them recursively in the first alternation. However, take a close look
-at the insidious result. The recursive descent parser enters the C<list>
-rule. It's first option is to enter the list rule again, so it does.
-Recursive descent is a depth-first algorithm, and it will continue to
-descent down a particular path until it finds a successful match or a
-match failure. In this case, it matches C<list> and then it matches
-C<list> again, then it matches C<list> again, and so on and so forth.
-What we have created is an infinite loop pattern called I<left recursion>.
-
-Left recursion is caused when the left-most item of the left-most
-alternation is a recursion. The rule above can be easily resolved
-by writing:
+If there is only one digit, the second option in the alternation matches.  If
+there are multiple digits, recursion will match them through the first
+alternation.
+
+That's the intention.  The results are insidious.
+
+The recursive descent parser enters the C<list> rule. Its first option is to
+enter the list rule again, so it does.  Recursive descent is a X<depth-first
+algorithm> depth-first algorithm; PGE will continue to descend down a
+particular path until it finds a successful match or a match failure. In this
+case, it matches C<list>, then it matches C<list> again, then it matches
+C<list> again, and so on.  This rule forms an infinite loop -- a pattern called
+X<left recursion> I<left recursion>.  The problem is that the left-most item of
+the left-most alternation is itself a recursion.
+
+The rule above does not recurse infinitely when rewritten as:
 
  rule list {
     <digit> | <list> ',' <digit>
  }
 
-Or even
+... or even:
 
  rule list {
     <digit> ',' <list> | <digit>
  }
 
-Both of these two options make sure the left-most item in our rule is not
-a recursion, therefore preventing left recursion.
+Both options ensure that the left-most item in the rule is recursive.
 
-Here is a more tricky example where the left recursion is hidden from
-view:
+Left recursion may be trickier.  It's not immediately obvious in this grammar:
 
  rule term {
     <expression> '*' <term> | <digit>
@@ -1249,84 +1249,85 @@
     <term> '+' <expression> | <term>
  }
 
-This is a very limited subset of mathematical equations that we might like
-to write, and even in this small subset we have this same problem: To
-match a C<term>, the parser first tries to match an C<expression>, which
-in turn matches a C<term> and then an C<expression> ...
-
-Left recursion is not the only problem you can run into with a recursive
-descent grammar, but it's one that's likely going to come up relatively
-often for new language designers, and one that is not always likely to
-generate useful error messages.
+Even this common, limited subset of mathematical equations has the same
+problem.  To match a C<term>, the parser first tries to match an C<expression>,
+which in turn matches a C<term> and then an C<expression> ....
+
+Again, the solution is simple.  Rewrite at least one of the rules so that the
+first condition it tries to match is not itself a recursive situation.
 
 =head3 Operator Precedence Parser
 
-Places where there are lots of little tokens in a statement, and where
-there are lots of possible options that a top-down parser will have to
-attempt can become relatively inefficient using PCT's recursive descent
-parser. Specifically, mathematical expressions are very open-ended and
-have forms that are difficult to anticipate. Consider the expression:
+Recursive descent parsing can be inefficient where statements have lots of
+little tokens and many possible options to match.  For example, mathematical
+expressions are very open-ended, with many valid forms which are difficult to
+anticipate.  Consider the expression:
 
  a + b * c + d
 
-The recursive descent parser is going to have to recognize through
-significant trial and error how this statement should be parsed. For tasks
-like this, recursive descent parsers are not ideal, although a type of
-bottom-up parser called an I<operator precedence>
-X<Parser, Operator precedence> parser is. Operator precedence parsers
-work similarly to more versatile bottom-up parsers such as Lex or Yacc, but
-are optimized for use with expressions and equations. The "things" in an
-equation are split into two subtypes: I<terms> and I<operators>. Operators
-themselves are split into a number of types including prefix (C<-a>),
-postfix (C<i++>), infix (C<x + y>), circumfix (C<[z]>), postcircumfix
-(C<a[b]>), and list (C<1, 2, 3>). Each operator gets its own precedence
-number that specifies how closely it binds to the terms. In the example above,
-the expression is parsed
+A recursive descent parser will undergo significant trial and error to parse
+this statement.  Recursive descent parsing is not ideal for these situations.
+Instead, a type of bottom-up parser called an I<operator precedence> X<Parser,
+Operator precedence> parser is much better.
+
+=for author
+
+Is this a categorization of all opps or just PGE's opp?
+
+=end for
+
+Operator precedence parsers work similarly to more versatile bottom-up parsers
+such as Lex or Yacc, but are optimized for use with expressions and equations.
+Equations have two subtypes, I<terms> and I<operators>. Operators themselves
+have several subtypes, including prefix (C<-a>), postfix (C<i++>), infix (C<x +
+y>), circumfix (C<[z]>), postcircumfix (C<a[b]>), and list (C<1, 2, 3>). Each
+operator gets its own precedence number that specifies how closely it binds to
+the terms. The previous example should parse as:
 
  a + (b * c) + d
 
-This is because the C<*> operator has a higher precedence and therefore binds
-more tightly then the C<+> operator.
+... because the C<*> operator has a higher precedence -- binding more tightly
+to its terms -- than the C<+> operator.
 
-To switch from the top-down recursive descent parser to the bottom-up
-operator precedence parser, a rule must be defined that is an C<optable>
-X<Parser, optable>:
+Within a grammar, switch from the top-down recursive descent parser to the
+bottom-up operator precedence parser with an C<optable> X<Parser, optable>
+rule:
 
  rule expression is optable { ... }
 
-The C<...> ellipses aren't an editorial shortcut, it's the Perl 6 operator
-that is used to define a function signature. The C<...> indicates that
-this is just a signature and that the actual guts of it will be filled in
-somewhere else. In this case, that "somewhere else" is in the definition of
-the optable role.
+The C<...> ellipsis isn't an editorial shortcut, it's the Perl 6 operator to to
+define a function signature. The C<...> indicates that this is just a
+signature; the actual implementation is elsewhere.  In this case, that location
+in the definition of the optable.
 
 =head3 Protofunction Definitions
 
-Protofunctions are used to define operators in the optable in the same way that
-rules and tokens are used throughout the rest of the grammar. A proto is a way
-of saying that the rule is overridable dynamically, and that it might be defined
-somewhere else. In this case, PCT takes information from the proto declaration
-and fills in the details for us. On another note, this also means that the HLL
-itself can modify its own grammar at run time, by overriding the proto
-definitions for its operator table. Some languages call this process "operator
-overloading".
+X<Protofunctions>
+
+Protofunctions define operators in the optable in the same way that rules and
+tokens make up the grammar. A proto declares a rule, defined elsewhere, which
+other code may override dynamically.  In this case, PCT takes information from
+the proto declaration and fills in the details. The "dynamic overriding"
+implies that a high-level language itself itself can modify its own grammar at
+run time, by overriding the proto definitions for its operator table. Some
+languages call this process X<operator overloading> I<operator overloading>.
 
-A proto is defined like this, taking some of our grammar rules above:
+A proto definition resembles:
 
  'proto' <proto_name> [ 'is' <property> ] '{' '...' '}'
 
-The name of the operator, listed as C<< <proto_name> >> above, contains both a
-location part and an identifier part. The location is one of the places where
-the operator can be located, such as infix, postfix, prefix, circumfix, and
-postcircumfix. The name of the operator is the symbol used for the operator in
-any of the quotes that Perl 6 understands:
+The name of the operator, noted as C<< <proto_name> >>, contains both a
+location part and an identifier part. The location is the type of the operator,
+such as infix, postfix, prefix, circumfix, and postcircumfix. The name of the
+operator is the symbol used for the operator in any of the quotes that Perl 6
+understands:
 
  proto infix:<+>                  # a + b
  proto postfix:'--'               # i--
  proto circumfix:«<>»             # <x>
 
-The C<is> X<Parser, is> keyword defines a property of the rule. Some examples of
-this are:
+The C<is> X<Parser, is> keyword defines a property of the rule. Examples
+include:
 
  is precedence(1)     # Specifies an exact precedence
  is equiv('+')        # Has the same precedence as the "+" operator
@@ -1338,13 +1339,21 @@
  is parsed(&myRule)   # The token is parsed and identified using the rule
                       # "myRule" from the top-down parser
 
-Protofunction definitions are function signatures which can be overridden via
-multimethod dispatch. This means functions can be written I<with the same name>
-as the rule to implement the behavior of the operator:
+=for author
+
+Please review.
+
+=end for
+
+Protofunction definitions are function signatures; you can override them with
+multimethod dispatch. This means that you can write functions I<with the same
+name> as the rule to implement the behavior of the operator.  Here's a proto:
 
  rule infix:"+" { ... }
 
-And in a PIR file for built-in functions:
+... and its corresponding PIR rule:
+
+=begin PIR
 
  .sub 'infix:+'
     .param pmc a
@@ -1354,37 +1363,39 @@
     .return(c)
  .end
 
-The question to ask then is "Why have an C<is subname()> property, if all
-operators can be defined as subroutines?" The answer is that using the
-C<is subname()> property allows PCT to call a subroutine of a different
-name then the operator. This is a good idea if there is already a built-in
-function in the language that duplicates the functionality of the operator.
-There is no sense duplicating functionality, is there?
+=end PIR
+
+You may ask "Why have an C<is subname()> property, if you can define all
+operators as subroutines?" Using the C<is subname()> property allows PCT to
+call a subroutine of a different name then the operator.  This is a good idea
+if there is already a built-in function in the language that duplicates the
+functionality of the operator.  There is no sense in duplicating behavior.
 
 The great thing about protos being overloadable is that you can specify
 different functions to call with different signatures:
 
+=begin PIR
+
  .sub 'infix:+' :multi('Integer', 'Integer')
-    ...
+    #...
  .end
 
  .sub 'infix:+' :multi('CLispRatio', 'Number')
-    ...
+    #...
  .end
 
  .sub 'infix:+' :multi('Perl6Double', 'PythonInteger')
-    ...
+    #...
  .end
 
-This list can be a bit intimidating, and it's hard to imagine that it would
-be necessary to write up a new function to handle addition between
-every conceivable pair of operands. Fortunately for us all, this isn't the
-case because all these data types have those VTABLE interfaces that we can
-use. For most data types Parrot already has basic arithmetic operations
-built in, and it's only necessary to override for those data types with
-special needs. This example was only a demonstration of the flexibility
-of the method.
+=end PIR
 
+This list can be a bit intimidating, and it's hard to imagine that it would be
+necessary to write up a new function to handle addition between every
+conceivable pair of operands. Fortunately, this is rarely the case in Parrot,
+because all these data types support common the VTABLE interface. For most data
+types Parrot already has basic arithmetic operations built in, and it's only
+necessary to override for those data types with special needs.
 
 =head3 Hypothetical Variables
 
@@ -1393,75 +1404,87 @@
 X<variables;hypothetical>
 X<hypothetical variables>
 X<rules;captures>
-Hypothetical variables are a powerful way of building up data structures
-from within a match. Ordinary captures with C<()> store the result of
-the captures in C<$1>, C<$2>, etc. The values stored in these variables
-will be kept if the match is successful, but thrown away if the match
-fails (hence the term "hypothetical"). The numbered capture variables
-are accessible outside the match, but only within the immediate
+Hypothetical variables are a powerful way of building up data structures from
+within a match. Ordinary captures with C<()> store the result of the captures
+in C<$1>, C<$2>, etc. PGE stores values in these variables if the match is
+successful, but throws them away if the match fails.  The numbered capture
+variables are accessible outside the match, but only within the immediate
 surrounding lexical scope:
 
   "Zaphod Beeblebrox" ~~ m:w/ (\w+) (\w+) /;
-  
+
   print $1; # prints Zaphod
 
-You can also capture into any user-defined variable with the binding
-operator C<:=>. These variables must already be defined in the lexical
-scope surrounding the rule:
+You can also capture into any user-defined variable with the binding operator
+C<:=> -- I<if> you have declared these variables in a lexical scope enclosing
+the rule:
 
   my $person;
   "Zaphod's just this guy." ~~ / ^ $person := (\w+) /;
   print $person; # prints Zaphod
 
-Repeated matches can be captured into an array:
+You may capture repeated matches into an array:
 
   my @words;
   "feefifofum" ~~ / @words := (f<-[f]>+)* /;
   # @words contains ("fee", "fi", "fo", "fum")
 
-Pairs of repeated matches can be captured into a hash:
+You may capture pairs of repeated matches into a hash:
 
   my %customers;
   $records ~~ m:w/ %customers := [ E<lt>idE<gt> = E<lt>nameE<gt> \n]* /;
 
-If you don't need the captured value outside the rule, use a C<$?>
-variable instead. These are only directly accessible within the rule:
+If you don't need the captured value outside the rule, use a C<$?> variable
+instead. These are only directly accessible within the rule:
 
   "Zaphod saw Zaphod" ~~ m:w/ $?name := (\w+) \w+ $?name/;
 
-A match of a named rule stores the result in a C<$?> variable with the
-same name as the rule. These variables are also accessible only within
-the rule:
+A match of a named rule stores the result in a C<$?> variable with the same
+name as the rule. These variables are also accessible only within the rule:
 
   "Zaphod saw Zaphod" ~~ m:w/ E<lt>nameE<gt> \w+ $?name /;
 
+=for author
+
+This next paragraph feels out of place; is there more?
 
-When a rule matches a sequence of input tokens, an associated method
-in NQP is called to convert that match into an AST node. This node
-is then inserted into the I<parse tree>.
+=end for
+
+When a rule matches a sequence of input tokens, PCT calls an associated method
+within NQP to convert that match into an AST node, which it inserts into the
+I<parse tree>.
 
 =head3 Basic Rules
 
-Let's start off with a simple rule:
+Consider the simple example rule:
 
  rule persons_name {
     <first_name> <last_name>
  }
 
-We also define the two name tokens as:
+... and two example tokens:
 
  token first_name { <alpha>+ }
- token last_name { <alpha>+ }
+ token last_name  { <alpha>+ }
+
+The special token C<< <alpha> >> is a built-in construct that only accepts
+upper case and lower case letters. The C<+> after the C<< <alpha> >> tag is a
+short way of saying "one or more". The rule will match names like C<Darth
+Vader>N<It also matches many strings that I<aren't> real names>, but won't
+match something like C<C 3P0>.
+
+This rule I<will> match C<Jar Jar Binks>, but not as you might expect: way you
+would expect: It would match the first "Jar" as C<< <first_name> >>, the second
+"Jar" as C<< <last_name> >>, and ignore "Binks"N<You should ignore the whole
+thing.>.
+
+=for author
+
+The rest seems vestigial.  An example like this should precede the rest of the
+chapter.  There are forward references, but it's a decent overview for people
+who haven't used similar systems before -- if you avoid going out in the weeds.
 
-The special token C<< <alpha> >> is a built-in construct that only
-accepts upper case and lower case letters. The "+" after the
-C<< <alpha> >> tag is a short way of saying "one or more". Our rule
-C<persons_name> would match something like C<Darth Vader> N<Actually,
-it matches a lot of things that aren't people's names>but wouldn't
-match something like C<C 3P0>. Notice that the rule above would match
-C<Jar Jar Binks>, but not the way you would expect: It would match the
-first "Jar" as C<< <first_name> >> and the second "Jar" as
-C<< <last_name> >> and wouldn't match "Binks" at all.
+=end for
 
 this example shows another new construct, the square brackets. Square
 brackets are ways to group things together. The star at the end means

Modified: branches/pmc_pct/docs/book/ch06_nqp.pod
==============================================================================
--- branches/pmc_pct/docs/book/ch06_nqp.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/book/ch06_nqp.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -67,12 +67,16 @@
 
 Which calls the PIR function:
 
+=begin PIR
+
  .namespace []
  .sub 'create_new_array'
      .param pmc elems :slurpy
      .return(elems)
  .end
 
+=end PIR
+
 Remember how we said NQP was a bare-bones subset of Perl 6? It really doesn't
 have a lot of features that programmers might expect. In this chapter we will
 talk about some of the features and capabilities that it does have.

Modified: branches/pmc_pct/docs/book/ch09_pasm.pod
==============================================================================
--- branches/pmc_pct/docs/book/ch09_pasm.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/book/ch09_pasm.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -6,57 +6,34 @@
 
 X<Parrot Assembly Language;;(see PASM)>
 X<PASM (Parrot assembly language)>
-We've seen some of the common ways for programming Parrot in earlier
-chapters: PIR is the intermediate language that's used most often for
-implementing routines in Parrot, NQP is used for writing grammar actions
-for high-level language compilers, PGE is used for specifying grammar
-rules, and various high-level languages that target Parrot are used for
-most other programming tasks. These options, though many and versatile,
-are not the only ways to interface with Parrot.
-
-In regular assemblers, assembly language mnemonics share a one-to-one
-correspondence with the underlying machine code words that they
-represent. A simple assembler (and, for that matter, a simple disassembler)
-could be implemented as a mere lookup table. PIR does not have this kind
-of direct correspondance to PBC. A number of PIR features, especially the
-various directives, typically translate into a number of individual
-operations. Register names, such as C<$P7> don't indicate the actual
-storage location of the register in PIR either. The register allocator
-will intelligently move and rearrange registers to conserve memory, so
-the numbers you use to specify registers in PIR will be mapped to
-different numbers when compiled into PBC.
-
-Because PIR and PBC can't be directly translated to one another, and
-because it can be difficult to disassemble low-level PBC back into the
-higher-level composite statements of PIR, especially after optimization,
-another tool is needed. That tool is PASM.
-
-PASM, the Parrot Assembly Language, is the lowest-level interface to
-Parrot. PASM instruction mnemonics do share a one-to-one correspondence
-to the underlying PBC opcodes, and for this reason is used by the Parrot
-disassembler instead of PIR. PASM is missing some of the features of
-PIR: Most directives, symbolic operators, C<if> and C<unless> compound
-statements, automatic register allocation, and a few other bits of
-syntactic sugar are missing from PASM. Because of these omissions, it is
-strongly recommended that most developers do not use PASM to write any
-large amount of code. Use PIR if you need to, or a higher-level language
-if you can.
-
-=head2 PASM Files
-
-X<.pasm files>
-The Parrot compilers, IMCC and PIRC, differentiate between PIR and PASM
-code files based on the file extension. A file with a F<.pasm> extension
-is treated as pure PASM code by Parrot, as is any file run with the C<-a>
-command-line option.
-
-Early in the Parrot project's history, PIR was treated as a pure superset
-of PASM. All PASM was valid PIR, but PIR added a few extra features that
-the programmers found to be nice. However, this situation has changed and
-PIR is no longer a strict superset of PASM. For this reason, PASM and
-PIR code need to be kept in files with separate extensions. As we mentioned
-before, C<.pasm> files are always treated as containing only PASM, while
-C<.pir> files are used for PIR code, by convention.
+PIR is the intermediate language that's used most often for implementing
+libraries in Parrot, NQP is used for writing grammar actions for
+high-level language compilers, PGE is used for specifying grammar rules,
+and various high-level languages that target Parrot are used for most
+other programming tasks. These options, though many and versatile, are
+not the only ways to interface with Parrot.
+
+Like PIR, Parrot Assembly Language (PASM) is a low-level language native
+to the virtual machine. PASM is a pure assembly language, with none of
+the syntactic sugar that makes PIR friendly for library development.
+
+Its primary purpose is to act as a plain English reprepresention of the
+bytecode format. In regular assemblers, assembly language mnemonics
+share a one-to-one correspondence with the underlying machine code words
+that they represent. A simple assembler (and, for that matter, a simple
+disassembler) could be implemented as a mere lookup table.  PASM
+instructions share a one-to-one correspondence to the underlying
+bytecode instructions, and for this reason PASM is used by the Parrot
+disassembler instead of PIR.
+
+PASM is used as a debugging tool more often than it is used to write
+extensive libraries of code. PIR or a higher-level language are
+recommended for most development tasks.
+
+X<.pasm extension>
+PASM files use the F<.pasm> file extension. Parrot also has a C<-a>
+command-line option to tell it to treat a file as PASM code even if it
+doesn't have a F<.pasm> extension.
 
 =head2 Basics
 
@@ -89,3286 +66,13 @@
 
 =end PASM
 
-X<PASM (Parrot assembly language);labels>
-A label names a line of code so other instructions can refer to it.
-Label names consist of letters, numbers, and underscores, exactly the
-same syntax as is used for labels in PIR. Simple labels are often all
-capital letters to make them stand out from the rest of the source code
-more clearly. This is just a common convention and is not a rule. A label
-can be in front of a line of code, or it can be on it's own line. Keeping
-labels separate is usually recommended for readability, but again this is
-just a suggestion and not a rule.
 
-=begin PASM
-
-  LABEL:
-      print "Norwegian Blue\n"
-
-=end PASM
-
-=begin PASM
-
-  LABEL: print "Norwegian Blue\n"
-
-=end PASM
-
-X<PASM (Parrot assembly language);comments>
-POD (plain old documentation) is also allowed in PASM like it is in PIR.
-An equals sign in the first column marks the start of a POD block, and
-a C<=cut> marker signals the end of a POD block.
-
-=begin PASM
-
-  =head2
-
-  This is POD documentation, and is treated like a
-  comment. The PASM interpreter ignores this.
-
-  =cut
-
-  end
-
-=end PASM
-
-Besides POD, there are also ordinary 1-line comments using the # sign,
-which is the same in PIR:
-
-=begin PASM
-
-  LABEL:                        # This is a comment
-    print "Norwegian Blue\n"    # Print a color name
-
-=end PASM
-
-=head3 Constants
-
-Z<CHP-9-SECT-2.1>
-
-X<PASM (Parrot assembly language);constants>
-We've already seen constants in PIR, and for the most part the syntax
-is the same in PASM. We will give a brief refresher here, but see the
-chapter on PIR for a more in-depth discussion of constants and datatypes.
-
-Integer constants in Parrot are signed integers.N<The sizes of integers
-and all other data values like floats are defined when Parrot is
-configured and built. Integers are typically 32 bits wide on 32-bit
-computers (a range of -2G<31> to +2G<31>-1) and twice that size on
-64-bit processors.> Decimal integer constants can have a positive (C<+>) or
-negative (C<->) sign in front. Binary integers are preceded by C<0b>
-or C<0B>, and hexadecimal integers are preceded by C<0x> or C<0X>:
-
-=begin PASM
-
-  print 42         # Decimalinteger constant
-  print +144       # integer constant
-  print 0x2A       # hexadecimal integer
-  print 0b1101     # binary integer
-
-=end PASM
-
-Floating-point constants can also be positive or negative. Scientific
-notation provides an exponent, marked with C<e> or C<E> (the sign of
-the exponent is optional):
-
-=begin PASM
-
-  print 3.14159    # floating point constant
-  print 1.e6       # scientific notation
-  print -1.23e+45
-
-=end PASM
-
-String constants are wrapped in single or double quotation marks.
-Quotation marks inside the string must be escaped by a backslash.
-Other special characters also have escape sequences. These are the
-same as for Perl 5's C<qq()> operator: C<\t> (tab), C<\n> (newline),
-C<\r> (return), C<\f> (form feed), C<\\> (literal slash), C<\">
-(literal double quote), etc.
-
-=begin PASM
-
-  print "string\n"    # string constant with escaped newline
-  print "\\"          # a literal backslash
-  print 'a\n'         # three chars: 'a', a backslash, and a 'n'
-
-=end PASM
-
-=head3 Working with Registers
-
-Z<CHP-9-SECT-2.2>
-
-X<PASM (Parrot assembly language);registers>
-X<registers;Parrot;;(see PASM, registers)>
-Parrot is a register-based virtual machine. It has 4 typed register
-sets: integers, floating-point numbers, strings, and polymorphic container
-objects called PMCs. Register names consist of a capital letter indicating
-the register set type and the number of the register. Register numbers are
-non-negative (zero and positive numbers), and do not have a pre-defined
-upper limit N<At least not a restrictive limit. Parrot registers are stored
-internally as an array. More registers means a larger allocated array, which
-can bring penalties on some systems>. For example:
-
-  I0   integer register #0
-  N11  number or floating point register #11
-  S2   string register #2
-  P33  PMC register #33
-
-We see the immediate difference here that PASM registers do not have the
-C<$> dollar sign in front of them like PIR registers do. The syntactical
-difference indicates that there is an underlying semantic difference:
-In PIR, register numbers are just suggestions and registers are automatically
-allocated; In PASM, register numbers are literal offsets into the register
-array, and registers are not automatically managed. Let's take a look at a
-simple PIR function:
-
-=begin PIR
-
-  .sub 'foo'
-      $I33 = 1
-  .end
-
-=end PIR
-
-This function allocates only one register. The register allocator counts that
-there is only one register needed, and converts C<$I33> to C<I0> internally.
-Now, let's look at a similar PASM subroutine:
-
-=begin PASM
-
-  foo:
-      set I33, 1
-  end
-
-=end PASM
-
-This function, which looks to perform the same simple operation actually is
-a little different. This small snippet of code actually allocates 33
-registers, even though only one of them is needed N<The number 33 here was not
-a random choice. To save on initial allocations Parrot automatically allocates
-space for 32 registers of each type in each context. This might not always be
-the case, but for now it is.>. In PASM mode it's up to the programmer to keep
-track of memory usage and not allocate more registers then are needed.
-
-=head4 Register assignment
-
-Z<CHP-9-SECT-2.2.1>
-
-X<PASM (Parrot assembly language);registers;assignment>
-The most basic operation on registers is assignment using the C<set>
-opcode:
-
-=begin PASM
-
-  set I0, 42        # set integer register #0 to the integer value 42
-  set N3, 3.14159   # set number register #3 to an approximation of pi
-  set I1, I0        # set register I1 to what I0 contains
-  set I2, N3        # truncate the floating point number to an integer
-
-=end PASM
-
-In PIR code the set opcode is represented by the C<=> symbol to perform the
-assignment. The C<exchange> opcode swaps the contents of two registers of the
-same type:
-
-=begin PASM
-
-  exchange I1, I0   # set register I1 to what I0 contains
-                    # and set register I0 to what I1 contains
-
-=end PASM
-
-PMC registers contain references to PMC structures internally. So, the set
-opcode doesn't copy the entire PMC, it only copies the reference to the
-PMC data. Here's an example that shows a side effect of this operation:
-
-=begin PASM
-
-  new P0, "String"
-  set P0, "Ford"
-  set P1, P0
-  set P1, "Zaphod"
-  print P0                # prints "Zaphod"
-  print P1                # prints "Zaphod"
-  end
-
-=end PASM
-
-In this example, both C<P0> and C<P1> are both references to the same
-internal data structure, so when we set C<P1> to the string literal
-C<"Zaphod">, it overwrites the previous value C<"Ford">. Now, both C<P0>
-and C<P1> point to the String PMC C<"Zaphod">, even though it appears that
-we only set one of those two registers to that value.
-
-Strings in Parrot are also stored as references to internal data structures
-like PMCs. However, strings use Copy-On-Write (COW) optimizations. When we
-call C<set S1, S0> we copy the pointer only, so both registers point to the
-same string memory. We don't actually make a copy of the string until one of
-two registers is modified. Here's the same example using string registers
-instead of PMC registers, which demonstrate how strings use COW:
-
-=begin PASM
-
-  set S0, "Ford"
-  set S1, S0
-  set S1, "Zaphod"
-  print S0                # prints "Ford"
-  print S1                # prints "Zaphod"
-  end
-
-=end PASM
-
-Here, we can clearly see the opposite result from how PMCs were handled in
-the previous example. Modifying one of the two registers causes a new string
-to be created, preserving the old value in C<S0> and assigning the new value
-to the new string in C<S1>. The benefits here are that we don't have to worry
-about stray references causing side effects in our code, and we don't waste
-time copying a string until it's actually time to make a copy. Some
-developers have suggested that PMCs should also use COW semantics to help
-optimize copy operations in PMCs too. However, the PMC system in Parrot isn't
-yet mature enough to support these kinds of semantics. One day in the future,
-Parrot might change this, but it hasn't changed yet.
-
-=head4 PMC object types
-
-Z<CHP-9-SECT-2.2.2>
-
-X<PMCs (Polymorphic Containers);object types>
-Every PMC has a distinct type that determines its behavior through the
-vtable interface. In the chapter on PIR, we've seen a number of these vtable
-functions already, and seen how they implement the behaviors found inside
-the various opcodes. The vtable interface is standard, and all PMCs implement
-the exact same set of vtables. We've seen some of the vtables and their uses,
-and more of them will be discussed in this chapter and later in the various
-reference chapters.
-
-The C<typeof> opcode can be used to determine the type of a PMC. When
-the source argument is a PMC and the destination is a string register,
-C<typeof> returns the name of the type:
-
-=begin PASM
-
-  new P0, "String"
-  typeof S0, P0               # S0 is "String"
-  print S0
-  print "\n"
-  end
-
-=end PASM
-
-Using C<typeof> with a PMC output parameter instead, it returns the Class
-PMC for that type.
-
-=head4 Autoboxing
-
-Z<CHP-9-SECT-2.2.3>
-
-X<Autoboxing>
-As we've seen in the previous chapters about PIR, we can convert between
-primitive string, integer, and number types and PMCs. PIR used the C<=>
-operator to make these conversions. PASM uses the C<set> opcode to do the
-same thing. C<set> will perform the type conversions for us automatically,
-in a process called I<autoboxing>.
-
-Assigning a primitive data type to a PMC of a String, Integer, or Float type
-converts that PMC to the new type. So, assigning a string to a Number PMC
-converts it into a String PMC. Assigning an integer value converts it to a
-C<Integer>, and assigning C<undef> converts it to an C<Undef> PMC:
-
-=begin PASM
-
-  new P0, "String"
-  set P0, "Ford\n"
-  print P0           # prints "Ford\n"
-  set P0, 42
-  print P0           # prints 42
-  print "\n"
-  typeof S0, P0
-  print S0           # prints "Integer"
-  print "\n"
-  end
-
-=end PASM
-
-C<P0> starts as a C<String>, but when C<set> assigns it an integer
-value 42 (replacing the old string value C<"Ford">), it changes type
-to C<Integer>. This behavior only works for the wrapper PMC types for the
-primitive values string, int, and num. Other PMC classes will have different
-behaviors when you try to assign a primitive value to them.
-
-We can also use the C<box> opcode to explicitly convert an integer, a float,
-or a string into an appropriate PMC type.
-
-=begin PASM
-
-  box P0, 3
-  typeof S0, P0         # P0 is an "Integer"
-  box P1, "hello"
-  typeof S0, P1         # P1 is a "String"
-  box P2, 3.14
-  typeof S0, P2         # P2 is a "Number"
-
-=end PASM
-
-=head3 Math Operations
-
-Z<CHP-9-SECT-2.3>
-
-X<PASM (Parrot assembly language);math operations>
-PASM has a full set of math instructions. These work with integers,
-floating-point numbers, and PMCs that implement the vtable methods of
-a numeric object. Most of the major math opcodes have two- and
-three-argument forms:
-
-=begin PASM
-
-  add I10, I11, I2        # I10 = I11 + I2
-  add I0, I1              # I0 += I1
-  add I0, I0, I1          # Same!
-
-=end PASM
-
-The three-argument form of C<add>X<add opcode (PASM)> stores the sum
-of the last two registers in the first register. The two-argument form
-adds the first register to the second and stores the result back in
-the first register.
-
-The source arguments can be Parrot registers or constants, but they
-must be compatible with the type of the destination register.
-Generally, "compatible" means that the source and destination have to
-be the same type, but there are a few exceptions:
-
-=begin PASM
-
-  sub P0, P1, 2          # P0 = P1 - 2
-  sub P0, P1, 1.5        # P0 = P1 - 1.5
-
-=end PASM
-
-If the destination register is an integer register, like C<I0>, the
-other arguments must be integer registers or integer constants. A
-floating-point destination, like C<N0>, usually requires
-floating-point arguments, but many math opcodes also allow the final
-argument to be an integer. Opcodes with a PMC destination register may
-take an integer, floating-point, or PMC final argument:
-
-=begin PASM
-
-  mul P0, P1             # P0 *= P1
-  mul P0, I1
-  mul P0, N1
-  mul P0, P1, P2         # P0 = P1 * P2
-  mul P0, P1, I2
-  mul P0, P1, N2
-
-=end PASM
-
-X<PMCs (Polymorphic Containers);operations on>
-Operations on a PMC are implemented by the vtable method of the destination
-(in the two-argument form) or the left source argument (in the three argument
-form). The result of an operation is entirely determined by the behavior of
-the PMCs vtable. For some types of PMC the results may be very idiosyncratic
-and not intuitive, so it's important to familiarize yourself with the behavior
-of the particular PMC before you start performing a lot of operations on it.
-
-We won't list every math opcode here, but we'll list some of the most common
-ones. You can get a complete list in "PASM Opcodes" in Chapter 11.
-
-=head4 Unary math opcodes
-
-Z<CHP-9-SECT-2.3.1>
-
-The unary opcodes have either a destination argument and a source
-argument, or a single argument as destination and source. Some of the
-most common unary math opcodes are C<inc> (increment), C<dec>
-(decrement), C<abs> (absolute value), C<neg> (negate), and C<fact>
-(factorial):
-
-=begin PASM
-
-  abs N0, -5.0  # the absolute value of -5.0 is 5.0
-  fact I1, 5    # the factorial of 5 is 120
-  inc I1        # 120 incremented by 1 is 121
-
-=end PASM
-
-=head4 Binary math opcodes
-
-Z<CHP-9-SECT-2.3.2>
-
-X<PASM (Parrot assembly language);math operations;binary>
-Binary opcodes have two source arguments and a destination argument, and we
-saw examples of these types above. As we mentioned before, most binary math
-opcodes have a two-argument form in which the first argument is both a source
-and the destination. Parrot provides C<add>X<add opcode (PASM)> (addition),
-C<sub>X<sub opcode (PASM)> (subtraction), C<mul>X<mul opcode (PASM)>
-(multiplication), C<div>X<div opcode (PASM)> (division), and C<pow>X<pow
-opcode (PASM)> (exponent) opcodes, as well as two different modulus
-operations. C<mod>X<mod opcode (PASM)> is Parrot's implementation of modulus,
-and C<cmod>X<cmod opcode (PASM)> performs an operation equivalent the C<%>
-operator from the C programming language. It also provides C<gcd>X<gcd opcode
-(PASM)> (greatest common divisor) and C<lcm>X<lcm opcode (PASM)> (least common
-multiple).
-
-=begin PASM
-
-  div I0, 12, 5   # I0 = 12 / 5
-  mod I0, 12, 5   # I0 = 12 % 5
-
-=end PASM
-
-=head4 Floating-point operations
-
-Z<CHP-9-SECT-2.3.3>
-
-X<PASM (Parrot assembly language);math operations;floating-point>
-Although most of the math operations work with both floating-point numbers
-and integers, a few require floating-point destination registers. Among these
-are C<ln> (natural log), C<log2> (log base 2), C<log10> (log base 10), and
-C<exp> (I<e>G<x>), as well as a full set of trigonometric opcodes such as
-C<sin> (sine), C<cos> (cosine), C<tan> (tangent), C<sec> (secant), C<cosh>
-(hyperbolic cosine), C<tanh> (hyperbolic tangent), C<sech> (hyperbolic secant),
-C<asin> (arc sine), C<acos> (arc cosine), C<atan> (arc tangent), C<asec> (arc
-secant), C<exsec> (exsecant), C<hav> (haversine), and C<vers> (versine). All
-angle arguments for the X<trigonometric functions (PASM)> trigonometric
-functions are in radians:
-
-=begin PASM
-
-  sin N1, N0
-  exp N1, 2
-
-=end PASM
-
-The majority of the floating-point operations have a single source argument
-and a single destination argument. Even though the destination must be a
-floating-point register, the source can be either an integer or floating-point
-number.
-
-The C<atan>X<atan opcode (PASM)> opcode also has a three-argument variant that
-implements C's C<atan2()>:
-
-=begin PASM
-
-  atan N0, 1, 1
-
-=end PASM
-
-=head3 Working with Strings
-
-Z<CHP-9-SECT-2.4>
-
-X<PASM (Parrot assembly language);string operations>
-String operations work with string registers and with PMCs that implement a
-string class. String operations on PMC registers require all their string
-arguments to be String PMCs.
-
-=head4 Concatenating strings
-
-Z<CHP-9-SECT-2.4.1>
-
-X<PASM (Parrot assembly language);string operations;concatenation>
-Use the C<concat>X<concat opcode (PASM)> opcode to concatenate
-strings. With string register or string constant arguments, C<concat>
-has both a two-argument and a three-argument form. The first argument
-is a source and a destination in the two-argument form:
-
-=begin PASM
-
-  set S0, "ab"
-  concat S0, "cd"     # S0 has "cd" appended
-  print S0            # prints "abcd"
-  print "\n"
-
-  concat S1, S0, "xy" # S1 is the string S0 with "xy" appended
-  print S1            # prints "abcdxy"
-  print "\n"
-  end
-
-=end PASM
-
-The first C<concat> concatenates the string "cd" onto the string "ab" in
-C<S0>. It generates a new string "abcd" and changes C<S0> to point to the
-new string. The second C<concat> concatenates "xy" onto the string "abcd"
-in C<S0> and stores the new string in C<S1>.
-
-X<PMCs (Polymorphic Containers);concatenation>
-For PMC registers, C<concat> has only a three-argument form with
-separate registers for source and destination:
-
-=begin PASM
-
-  new P0, "String"
-  new P1, "String"
-  new P2, "String"
-  set P0, "ab"
-  set P1, "cd"
-  concat P2, P0, P1
-  print P2            # prints abcd
-  print "\n"
-  end
-
-=end PASM
-
-Here, C<concat> concatenates the strings in C<P0> and C<P1> and stores
-the result in C<P2>.
-
-=head4 Repeating strings
-
-Z<CHP-9-SECT-2.4.2>
-
-X<PASM (Parrot assembly language);string operations;repeating strings>
-The C<repeat>X<repeat opcode (PASM)> opcode repeats a string a certain
-number of times:
-
-=begin PASM
-
-  set S0, "x"
-  repeat S1, S0, 5  # S1 = S0 x 5
-  print S1          # prints "xxxxx"
-  print "\n"
-  end
-
-=end PASM
-
-In this example, C<repeat> generates a new string with "x" repeated
-five times and stores a pointer to it in C<S1>.
-
-=head4 Length of a string
-
-Z<CHP-9-SECT-2.4.3>
-
-X<PASM (Parrot assembly language);string operations;length>
-The C<length>X<length opcode (PASM)> opcode returns the length of a
-string in characters. This won't be the same as the length in bytes
-for multibyte encoded strings:
-
-=begin PASM
-
-  set S0, "abcd"
-  length I0, S0                # the length is 4
-  print I0
-  print "\n"
-  end
-
-=end PASM
-
-C<length> doesn't have an equivalent for PMC strings.
-
-=head4 Substrings
-
-Z<CHP-9-SECT-2.4.4>
-
-X<PASM (Parrot assembly language);string operations;substrings>
-The simplest version of the C<substr>X<substr opcode (PASM)> opcode
-takes four arguments: a destination register, a string, an offset
-position, and a length. It returns a substring of the original string,
-starting from the offset position (0 is the first character) and
-spanning the length:
-
-=begin PASM
-
-  substr S0, "abcde", 1, 2        # S0 is "bc"
-
-=end PASM
-
-This example extracts a two-character string from "abcde" at a
-one-character offset from the beginning of the string (starting with
-the second character). It generates a new string, "bc", in the
-destination register C<S0>.
-
-When the offset position is negative, it counts backward from the end
-of the string. So an offset of -1 starts at the last character of the
-string.
-
-C<substr> also has a five-argument form, where the fifth argument is a
-string to replace the substring. This modifies the second argument and
-returns the removed substring in the destination register.
-
-=begin PASM
-
-  set S1, "abcde"
-  substr S0, S1, 1, 2, "XYZ"
-  print S0                        # prints "bc"
-  print "\n"
-  print S1                        # prints "aXYZde"
-  print "\n"
-  end
-
-=end PASM
-
-This replaces the substring "bc" in C<S1> with the string "XYZ", and
-returns "bc" in C<S0>.
-
-When the offset position in a replacing C<substr> is one character
-beyond the original string length, C<substr> appends the replacement
-string just like the C<concat> opcode. If the replacement string is an
-empty string, the characters are just removed from the original
-string.
-
-When you don't need to capture the replaced string, there's an
-optimized version of C<substr> that just does a replace without
-returning the removed substring.
-
-=begin PASM
-
-  set S1, "abcde"
-  substr S1, 1, 2, "XYZ"
-  print S1                        # prints "aXYZde"
-  print "\n"
-  end
-
-=end PASM
-
-The PMC versions of C<substr> are not yet implemented.
-
-=head4 Chopping strings
-
-Z<CHP-9-SECT-2.4.5>
-
-X<PASM (Parrot assembly language);string operations;chopping strings>
-The C<chopn>X<chopn opcode (PASM)> opcode removes characters from the
-end of a string. It takes two arguments: the string to modify and the
-count of characters to remove.
-
-=begin PASM
-
-  set S0, "abcde"
-  chopn S0, 2
-  print S0         # prints "abc"
-  print "\n"
-  end
-
-=end PASM
-
-This example removes two characters from the end of C<S0>. If the
-count is negative, that many characters are kept in the string:
-
-=begin PASM
-
-  set S0, "abcde"
-  chopn S0, -2
-  print S0         # prints "ab"
-  print "\n"
-  end
-
-=end PASM
-
-This keeps the first two characters in C<S0> and removes the rest.
-C<chopn> also has a three-argument version that stores the chopped
-string in a separate destination register, leaving the original string
-untouched:
-
-=begin PASM
-
-  set S0, "abcde"
-  chopn S1, S0, 1
-  print S1         # prints "abcd"
-  print "\n"
-  end
-
-=end PASM
-
-=head4 Copying and Cloning
-
-Z<CHP-9-SECT-2.4.6>
-
-X<PASM (Parrot assembly language);string operations;copying> The C<clone>
-X<clone opcode (PASM)> opcode makes a deep copy of a string or PMC. Earlier
-in this chapter we saw that PMC and String values used with the C<set> opcode
-didn't create a copy of the underlying data structure, it only created
-a copy of the reference to that structure. With strings, this doesn't cause
-a problem because strings use Copy On Write (COW) semantics to automatically
-create a copy of the string when one reference is modified. However, as we
-saw, PMCs don't have this same behavior and so making a change to one PMC
-reference would modify the data that all the other references to that same
-PMC pointed to.
-
-Instead of just copying the pointer like C<set> would do, we can use the
-C<clone> opcode to create a I<deep copy> of the PMC, not just a I<shallow
-copy> of the reference.
-
-=begin PASM
-
-  new P0, "String"
-  set P0, "Ford"
-  clone P1, P0
-  set P0, "Zaphod"
-  print P0        # prints "Zaphod"
-  print P1        # prints "Ford"
-  end
-
-=end PASM
-
-This example creates an identical, independent clone of the PMC in
-C<P0> and puts a pointer to it in C<P1>. Later changes to C<P0> have
-no effect on the PMC referenced in C<P1>.
-
-With simple strings, the copes created by C<clone> are COW exactly the same
-as the copy created by C<set>, so there is no difference between these two
-opcodes for strings. By convention, C<set> is used with strings more often
-then C<clone>, but there is no rule about this.
-
-=head4 Converting characters
-
-Z<CHP-9-SECT-2.4.7>
-
-X<PASM (Parrot assembly language);string operations;converting strings>
-The C<chr>X<chr opcode (PASM)> opcode takes an integer value and returns the
-corresponding character in the ASCII character set as a one-character string,
-while the C<ord>X<ord opcode (PASM)> opcode takes a single character string
-and returns the integer value of the character at the first position in the
-string. Notice that the integer value of the character will differ depending
-on the current encoding of the string:
-
-=begin PASM
-
-  chr S0, 65                # S0 is "A"
-  ord I0, S0                # I0 is 65, if S0 is ASCII or UTF-8
-
-=end PASM
-
-C<ord> has a three-argument variant that takes a character offset to select
-a single character from a multicharacter string. The offset must be within
-the length of the string:
-
-=begin PASM
-
-  ord I0, "ABC", 2        # I0 is 67
-
-=end PASM
-
-A negative offset counts backward from the end of the string, so -1 is
-the last character.
-
-=begin PASM
-
-  ord I0, "ABC", -1        # I0 is 67
-
-=end PASM
-
-=head4 Formatting strings
-
-Z<CHP-9-SECT-2.4.8>
-
-X<PASM (Parrot assembly language);string operations;formatting strings>
-The C<sprintf>X<sprintf opcode (PASM)> opcode generates a formatted string
-from a series of values. It takes three arguments: the destination register,
-a string specifying the format, and an ordered aggregate PMC (like an
-C<Array> PMC) containing the values to be formatted. The format string and
-the destination register can be either strings or PMCs:
-
-=begin PASM
-
-  sprintf S0, S1, P2
-  sprintf P0, P1, P2
-
-=end PASM
-
-The format string is similar to the one for C's C<sprintf> function,
-but with some extensions for Parrot data types. Each format field in
-the string starts with a C<%>
-X<% (percent sign);% format strings for sprintf opcode (PASM)> and
-ends with a character specifying the output format. The output format
-characters are listed in Table 9-1.
-
-=begin table picture Format characters
-
-Z<CHP-9-TABLE-1>
-
-=headrow
-
-=row
-
-=cell Format
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<%c>
-
-=cell A single character.
-
-=row
-
-=cell C<%d>
-
-=cell A decimal integer.
-
-=row
-
-=cell C<%i>
-
-=cell A decimal integer.
-
-=row
-
-=cell C<%u>
-
-=cell An unsigned integer.
-
-=row
-
-=cell C<%o>
-
-=cell An octal integer.
-
-=row
-
-=cell C<%x>
-
-=cell A hex integer, preceded by 0x when # is specified.
-
-=row
-
-=cell C<%X>
-
-=cell A hex integer with a capital X (when # is specified).
-
-=row
-
-=cell C<%b>
-
-=cell A binary integer, preceded by 0b when # is specified.
-
-=row
-
-=cell C<%B>
-
-=cell A binary integer with a capital B (when # is specified).
-
-=row
-
-=cell C<%p>
-
-=cell A pointer address in hex.
-
-=row
-
-=cell C<%f>
-
-=cell A floating-point number.
-
-=row
-
-=cell C<%e>
-
-=cell A floating-point number in scientific notation (displayed with a
-lowercase "e").
-
-=row
-
-=cell C<%E>
-
-=cell The same as C<%e>, but displayed with an uppercase E.
-
-=row
-
-=cell C<%g>
-
-=cell The same as either C<%e> or C<%f>, whichever fits best.
-
-=row
-
-=cell C<%G>
-
-=cell The same as C<%g>, but displayed with an uppercase E.
-
-=row
-
-=cell C<%s>
-
-=cell A string.
-
-=end table
-
-Each format field can be specified with several options: R<flags>,
-R<width>, R<precision>, and R<size>. The format flags are listed in
-Table 9-2.
-
-=begin table picture Format flags
-
-Z<CHP-9-TABLE-2>
-
-=headrow
-
-=row
-
-=cell Flag
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell 0
-
-=cell Pad with zeros.
-
-=row
-
-=cell E<lt>spaceE<gt>
-
-=cell Pad with spaces.
-
-=row
-
-=cell C<+>
-
-=cell Prefix numbers with a sign.
-
-=row
-
-=cell C<->
-
-=cell Align left.
-
-=row
-
-=cell C<#>
-
-=cell Prefix a leading 0 for octal, 0x for hex, or force a decimal point.
-
-=end table
-
-The R<width> is a number defining the minimum width of the output from
-a field. The R<precision> is the maximum width for strings or
-integers, and the number of decimal places for floating-point fields.
-If either R<width> or R<precision> is an asterisk (C<*>), it takes its
-value from the next argument in the PMC.
-
-The R<size> modifier defines the type of the argument the field takes.
-The flags are listed in Table 9-3.
-
-=begin table picture Size flags
-
-Z<CHP-9-TABLE-3>
-
-=headrow
-
-=row
-
-=cell Character
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<h>
-
-=cell short integer or single-precision float
-
-=row
-
-=cell C<l>
-
-=cell long
-
-=row
-
-=cell C<H>
-
-=cell huge value (long long or long double)
-
-=row
-
-=cell C<v>
-
-=cell Parrot INTVAL or FLOATVAL
-
-=row
-
-=cell C<O>
-
-=cell opcode_t pointer
-
-=row
-
-=cell C<P>
-
-=cell C<PMC>
-
-=row
-
-=cell C<S>
-
-=cell String
-
-=end table
-
-The values in the aggregate PMC must have a type compatible with the
-specified R<size>.
-
-Here's a short illustration of string formats:
-
-=begin PASM
-
-  new P2, "Array"
-  new P0, "Int"
-  set P0, 42
-  push P2, P0
-  new P1, "Num"
-  set P1, 10
-  push P2, P1
-  sprintf S0, "int %#Px num %+2.3Pf\n", P2
-  print S0     # prints "int 0x2a num +10.000"
-  print "\n"
-  end
-
-=end PASM
-
-The first eight lines create a C<Array> with two elements: a
-C<Int> and a C<Num>. The format string of the C<sprintf> has
-two format fields. The first, C<%#Px>, takes a PMC argument from the
-aggregate (C<P>) and formats it as a hexadecimal integer (C<x>), with
-a leading 0x (C<#>). The second format field, C<%+2.3Pf>, takes a PMC
-argument (C<P>) and formats it as a floating-point number (C<f>), with
-a minimum of two whole digits and a maximum of three decimal places
-(C<2.3>) and a leading sign (C<+>).
-
-The test files F<t/op/string.t> and F<t/src/sprintf.t> have many more
-examples of format strings.
-
-=head4 Testing for substrings
-
-Z<CHP-9-SECT-2.4.9>
-
-X<PASM (Parrot assembly language);string operations;testing for substrings>
-The C<index>X<index opcode (PASM)> opcode searches for a substring
-within a string. If it finds the substring, it returns the position
-where the substring was found as a character offset from the beginning
-of the string. If it fails to find the substring, it returns -1:
-
-=begin PASM
-
-  index I0, "Beeblebrox", "eb"
-  print I0                       # prints 2
-  print "\n"
-  index I0, "Beeblebrox", "Ford"
-  print I0                       # prints -1
-  print "\n"
-  end
-
-=end PASM
-
-C<index> also has a four-argument version, where the fourth argument
-defines an offset position for starting the search:
-
-=begin PASM
-
-  index I0, "Beeblebrox", "eb", 3
-  print I0                         # prints 5
-  print "\n"
-  end
-
-=end PASM
-
-This finds the second "eb" in "Beeblebrox" instead of the first,
-because the search skips the first three characters in the
-string.
-
-=head4 Joining strings
-
-The C<join> opcode joins the elements of an array PMC into a single
-string. The second argument separates the individual elements of the
-PMC in the final string result.
-
-=begin PASM
-
-  new P0, "Array"
-  push P0, "hi"
-  push P0, 0
-  push P0, 1
-  push P0, 0
-  push P0, "parrot"
-  join S0, "__", P0
-  print S0              # prints "hi__0__1__0__parrot"
-  end
-
-=end PASM
-
-This example builds a C<Array> in C<P0> with the values C<"hi">,
-C<0>, C<1>, C<0>, and C<"parrot">. It then joins those values (separated
-by the string C<"__">) into a single string, and stores it in C<S0>.
-
-=head4 Splitting strings
-
-Splitting a string yields a new array containing the resulting
-substrings of the original string.
-
-=begin PASM
-
-  split P0, "", "abc"
-  set P1, P0[0]
-  print P1              # 'a'
-  set P1, P0[2]
-  print P1              # 'c'
-  end
-
-=end PASM
-
-This example splits the string "abc" into individual characters and
-stores them in an array in C<P0>. It then prints out the first and
-third elements of the array. For now, the split pattern (the second
-argument to the opcode) is ignored except for a test to make sure that
-its length is zero.
-
-=head3 Logical and Bitwise Operations
-
-Z<CHP-9-SECT-2.6>
-
-X<PASM (Parrot assembly language);bitwise operations>
-X<PASM (Parrot assembly language);logical operations>
-The X<logical opcodes> logical opcodes evaluate the truth of their
-arguments. They're often used to make decisions on control flow.
-Logical operations are implemented for integers and PMCs. Numeric
-values are false if they're 0, and true otherwise. Strings are false
-if they're the empty string or a single character "0", and true
-otherwise. PMCs are true when their
-C<get_bool>X<get_bool vtable method (PASM)> vtable method returns a
-nonzero value.
-
-The C<and>X<and opcode (PASM)> opcode returns the second argument if
-it's false and the third argument otherwise:
-
-=begin PASM
-
-  and I0, 0, 1  # returns 0
-  and I0, 1, 2  # returns 2
-
-=end PASM
-
-The C<or>X<or opcode (PASM)> opcode returns the second argument if
-it's true and the third argument otherwise:
-
-=begin PASM
-
-  or I0, 1, 0  # returns 1
-  or I0, 0, 2  # returns 2
-
-  or P0, P1, P2
-
-=end PASM
-
-Both C<and> and C<or> are short-circuiting. If they can determine what
-value to return from the second argument, they'll never evaluate the
-third.  This is significant only for PMCs, as they might have side
-effects on evaluation.
-
-The C<xor>X<xor opcode (PASM)> opcode returns the second argument if
-it is the only true value, returns the third argument if it is the
-only true value, and returns false if both values are true or both are
-false:
-
-=begin PASM
-
-  xor I0, 1, 0  # returns 1
-  xor I0, 0, 1  # returns 1
-  xor I0, 1, 1  # returns 0
-  xor I0, 0, 0  # returns 0
-
-=end PASM
-
-The C<not>X<not opcode (PASM)> opcode returns a true value when the
-second argument is false, and a false value if the second argument is
-true:
-
-=begin PASM
-
-  not I0, I1
-  not P0, P1
-
-=end PASM
-
-The X<bitwise;opcodes (PASM)> bitwise opcodes operate on their values
-a single bit at a time. C<band>X<band opcode (PASM)>,
-C<bor>X<bor opcode (PASM)>, and C<bxor>X<bxor opcode (PASM)> return a
-value that is the logical AND, OR, or XOR of each bit in the source
-arguments. They each take a destination register and two source
-registers. They also have two-argument forms where the destination is
-also a source.  C<bnot>X<bnot opcode (PASM)> is the logical NOT of
-each bit in a single source argument.
-
-=begin PASM
-
-  bnot I0, I1
-  band P0, P1
-  bor I0, I1, I2
-  bxor P0, P1, I2
-
-=end PASM
-
-X<bitwise;string opcodes>
-The bitwise opcodes also have string variants for AND, OR, and XOR:
-C<bors>X<bors opcode (PASM)>, C<bands>X<bands opcode (PASM)>, and
-C<bxors>X<bxors opcode (PASM)>. These take string register or PMC
-string source arguments and perform the logical operation on each byte
-of the strings to produce the final string.
-
-=begin PASM
-
-  bors S0, S1
-  bands P0, P1
-  bors S0, S1, S2
-  bxors P0, P1, S2
-
-=end PASM
-
-The bitwise string opcodes only have meaningful results when they're
-used with simple ASCII strings because the bitwise operation is done
-per byte.
-
-The logical and arithmetic shift operations shift their values by a
-specified number of bits:
-
-=begin PASM
-
-  shl  I0, I1, I2        # shift I1 left by count I2 giving I0
-  shr  I0, I1, I2        # arithmetic shift right
-  lsr  P0, P1, P2        # logical shift right
-
-=end PASM
-
-=head2 Working with PMCs
-
-Z<CHP-9-SECT-3>
-
-In most of the examples we've shown so far, X<PMCs (Polymorphic
-Containers);working with> PMCs just duplicate the functionality of integers,
-numbers, and strings. They wouldn't be terribly useful if that's all they did,
-though. PMCs offer several advanced features that we will look at in the next
-few sections.
-
-=head3 Aggregates
-
-Z<CHP-9-SECT-3.1>
-
-PMCs can define complex types that hold multiple values. These are
-commonly called "X<PMCs (Polymorphic Containers);aggregate>
-X<aggregate PMCs> aggregates." The most important feature added for
-aggregates is keyed access. Elements within an aggregate PMC can be
-stored and retrieved by a numeric or string key. PASM also offers a
-full set of operations for manipulating aggregate data types.
-
-Two of the most basic aggregate types are arrays and hashes. The primary
-difference between these two is that arrays are indexed using integer keys,
-and hashes are indexed with string keys. The term "hash" in this context is
-derived from the data type in Perl 5 of the same name. Other programming
-languages might refer to the same concept using different terms such as
-"dictionary" or "hash table" or "associative array".
-
-Arrays and hashes are not the only types of aggregates available, although
-they are the most simple demonstrations of using integer and strings as
-keys in an aggregate, respectively.
-
-=head4 Arrays
-
-Z<CHP-9-SECT-3.1.1>
-
-X<PMCs (Polymorphic Containers);arrays>
-The C<Array>X<Array PMC> PMC is an ordered aggregate with zero-based integer
-keys. The syntax for X<keyed access to PMCs> keyed access to a PMC puts the
-key in square brackets after the register name:
-
-=begin PASM
-
-  new P0, "Array"     # obtain a new array object
-  set P0, 2           # set its length
-  set P0[0], 10       # set first element to 10
-  set P0[1], I31      # set second element to I31
-  set I0, P0[0]       # get the first element
-  set I1, P0          # get array length
-
-=end PASM
-
-A key on the destination register of a C<set> operation sets a value
-for that key in the aggregate. A key on the source register of a
-C<set> returns the value for that key. If you set C<P0> without a key,
-you set the length of the array, not one of its values.N<C<Array>
-is an autoextending array, so you never need to set its length. Other
-array types may require the length to be set explicitly.> And if you
-assign the C<Array> to an integer, you get the length of the
-array.
-
-We mention "other array types" above, not as a vague suggestion that there may
-be other types of arrays eventually, but as an indication that we actually
-have several types of array PMCs in Parrot's core. Parrot comes with
-C<FixedPMCArray>, C<ResizablePMCArray>, C<FixedIntegerArray>,
-C<ResizableIntegerArray>, C<FixedFloatArray>, C<ResizableFloatArray>,
-C<FixedStringArray>, C<ResizableStringArray>, C<FixedBooleanArray>,
-and C<ResizableBooleanArray> types. These various types of arrays use
-various packing methods to create higher memory efficiency for their contents
-then using a single generic array type would be able to. The trade-off for
-higher memory efficiency is that these array PMCs can only hold a single type
-of data.
-
-The array PMC types that start with "Fixed" have a fixed size and do not
-automatically extend themselves if you attempt to add data to a higher index
-then the array contains. The "Resizable" variants will automatically extend
-themselves as more data are added, but the cost is in algorithmic complexity
-of checking array bounds and reallocating array memory.
-
-To retrieve the number of items currently in an array, you can use the
-C<elements> opcode.
-
-=begin PASM
-
-  set P0, 100         # allocate store for 100 elements
-  set I0, P0          # obtain current allocation size
-  elements I0, P0     # get element count
-
-=end PASM
-
-Some other useful instructions for working with arrays are C<push>,
-C<pop>, C<shift>, and C<unshift> (you'll find them in
-"PASM Opcodes" in Chapter 11).
-
-=head4 Hashes
-
-Z<CHP-9-SECT-3.1.2>
-
-X<PMCs (Polymorphic Containers);hashes>
-The C<Hash>X<Hash PMC> PMC is an unordered aggregate which uses string keys
-to identify elements within it.
-
-=begin PASM
-
-  new P1, "Hash"      # generate a new hash object
-  set P1["key"], 10   # set key and value
-  set I0, P1["key"]   # obtain value for key
-  set I1, P1          # number of entries in hash
-
-=end PASM
-
-The C<exists>X<exists opcode (PASM)> opcode tests whether a keyed
-value exists in an aggregate. It returns 1 if it finds the key in the
-aggregate, and returns 0 if it doesn't. It doesn't care if the value
-itself is true or false, only that the key has been set:
-
-=begin PASM
-
-  new P0, "Hash"
-  set P0["key"], 0
-  exists I0, P0["key"] # does a value exist at "key"
-  print I0             # prints 1
-  print "\n"
-  end
-
-=end PASM
-
-The C<delete>X<delete opcode (PASM)> opcode is also useful for working
-with hashes: it removes a key/value pair.
-
-=head4 Iterators
-
-Z<CHP-9-SECT-3.1.3>
-
-Iterators extract values from an aggregate PMC one at a time and without
-extracting duplicates. Iterators are most useful in loops where an action
-needs to be performed on every element in an aggregate. You create an
-iterator by creating a new C<Iterator> PMC, and passing the aggregate PMC
-to C<new> as an additional parameter:
-
-=begin PASM
-
-  new P1, "Iterator", P2
-
-=end PASM
-
-Alternatively, you can use the C<iter> opcode to do the same thing:
-
-=begin PASM
-
-  iter P1, P2     # Same!
-
-=end PASM
-
-The include file F<iterator.pasm> defines some constants for working
-with iterators. The C<.ITERATE_FROM_START> and C<.ITERATE_FROM_END>
-constants are used to select whether an array iterator starts from the
-beginning or end of the array. Since Hash PMCs are unordered, these two
-constants do not have any affect on Hash iterators.
-
-A value can be extracted from the iterator using the C<shift> opcode.
-Evaluating the iterator PMC as a boolean returns whether the iterator has
-reached the end of the aggregate or not.
-
-=begin PASM
-
-  .include "iterator.pasm"
-      new P2, "Array"
-      push P2, "a"
-      push P2, "b"
-      push P2, "c"
-      new P1, "Iterator", P2
-      set P1, .ITERATE_FROM_START
-
-  iter_loop:
-      unless P1, iter_end
-      shift P5, P1
-      print P5                        # prints "a", "b", "c"
-      branch iter_loop
-  iter_end:
-      end
-
-=end PASM
-
-Hash iterators work similarly to array iterators, but they extract keys
-only. With the key, you can find it's value from the original hash PMC.
-With hashes it's only meaningful to iterate in one direction since they
-don't define any order for their keys.
-
-=begin PASM
-
-  .include "iterator.pasm"
-      new P2, "Hash"
-      set P2["a"], 10
-      set P2["b"], 20
-      set P2["c"], 30
-      new P1, "Iterator", P2
-      set P1, .ITERATE_FROM_START_KEYS
-
-  iter_loop:
-      unless P1, iter_end
-      shift S5, P1                    # one of the keys "a", "b", "c"
-      set I9, P2[S5]
-      print I9                        # prints e.g. 20, 10, 30
-      branch iter_loop
-  iter_end:
-      end
-
-=end PASM
-
-=head4 Data structures
-
-Z<CHP-9-SECT-3.1.4>
-
-X<PMCs (Polymorphic Containers);data structures>
-Arrays and hashes can hold any data type, including other aggregates.
-Accessing elements deep within nested data structures is a common
-operation, so PASM provides a way to do it in a single instruction.
-Complex keys specify a series of nested data structures, with each
-individual key separated by a semicolon:
-
-=begin PASM
-
-  new P0, "Hash"
-  new P1, "Array"
-  set P1[2], 42
-  set P0["answer"], P1
-  set I1, 2
-  set I0, P0["answer";I1]        # $i = %hash{"answer"}[2]
-  print I0
-  print "\n"
-  end
-
-=end PASM
-
-This example builds up a data structure of a hash containing an array.
-The complex key C<P0["answer";I1]> retrieves an element of the array
-within the hash. You can also set a value using a complex key:
-
-=begin PASM
-
-  set P0["answer";0], 5   # %hash{"answer"}[0] = 5
-
-=end PASM
-
-The individual keys are integers or strings, or registers with integer
-or string values.
-
-=head3 PMC Assignment
-
-Z<CHP-9-SECT-3.2>
-
-We mentioned before that C<set> on two X<PMCs (Polymorphic
-Containers);assignment> PMCs simply aliases them both to the same object,
-and that C<clone> creates a complete duplicate object. But if you just
-want to assign the value of one PMC to another PMC, you need the
-C<assign>X<assign opcode (PASM)> opcode:
-
-=begin PASM
-
-  new P0, "Int"
-  new P1, "Int"
-  set P0, 42
-  set P2, P0
-  assign P1, P0     # note: P1 has to exist already
-  inc P0
-  print P0          # prints 43
-  print "\n"
-  print P1          # prints 42
-  print "\n"
-  print P2          # prints 43
-  print "\n"
-  end
-
-=end PASM
-
-This example creates two C<Int> PMCs: C<P0> and C<P1>. It gives
-C<P0> a value of 42. It then uses C<set> to give the same value to
-C<P2>, but uses C<assign> to give the value to C<P1>. When C<P0> is
-incremented, C<P2> also changes, but C<P1> doesn't. The destination
-register for C<assign> must have an existing object of the right type
-in it, since C<assign> doesn't create a new object (as with C<clone>)
-or reuse the source object (as with C<set>).
-
-=head3 Properties
-
-Z<CHP-9-SECT-3.3>
-
-X<PMCs (Polymorphic Containers);properties>
-PMCs can have additional values attached to them as "properties" of
-the PMC. What these properties do is entirely up to the language being
-implemented. Most usually properties are used to hold extra metadata about
-the PMC that is used by the high-level language (HLL).
-
-The C<setprop>X<setprop opcode (PASM)> opcode sets the value of a
-named property on a PMC. It takes three arguments: the PMC to be set
-with a property, the name of the property, and a PMC containing the
-value of the property. The C<getprop>X<getprop opcode (PASM)> opcode
-returns the value of a property. It also takes three arguments: the
-PMC to store the property's value, the name of the property, and the
-PMC from which the property value is to be retrieved. Internally a PMCs
-properties are stored in a Hash structure, where the name of the property
-is stored in a special properties Hash.
-
-=begin PASM
-
-  new P0, "String"
-  set P0, "Zaphod"
-  new P1, "Int"
-  set P1, 1
-  setprop P0, "constant", P1        # set a property on P0
-  getprop P3, "constant", P0        # retrieve a property on P0
-  print P3                          # prints 1
-  print "\n"
-  end
-
-=end PASM
-
-This example creates a C<String> object in C<P0>, and a C<Int>
-object with the value 1 in C<P1>. C<setprop> sets a property named
-"constant" on the object in C<P0> and gives the property the value in
-C<P1>.N<The "constant" property is ignored by PASM, but may be significant
-to the HLL that set it.> C<getprop> retrieves the value of the property
-"constant" on C<P0> and stores it in C<P3>.
-
-Properties are kept in a separate hash for each PMC. Property values
-are always PMCs, but only references to the actual PMCs. Trying to
-fetch the value of a property that doesn't exist returns a
-C<Undef>.
-
-C<delprop>X<delprop opcode (PASM)> deletes a property from a PMC.
-
-=begin PASM
-
-  delprop P1, "constant"  # delete property
-
-=end PASM
-
-You can also return a complete hash of all properties on a PMC with
-C<prophash>X<prophash opcode (PASM)>.
-
-=begin PASM
-
-  prophash P0, P1         # set P0 to the property hash of P1
-
-=end PASM
-
-=head2 Flow Control
-
-Z<CHP-9-SECT-4>
-
-X<PASM (Parrot assembly language);flow control>
-Although it has many advanced features, at heart PASM is an assembly
-language. All flow control in PASM--as in most assembly languages--is
-done with branches and jumps.
-
-Branch instructions transfer control to a relative offset from the
-current instruction. The rightmost argument to every branch opcode is
-a label, which the assembler converts to the integer value of the
-offset. You can also branch on a literal integer value, but there's
-rarely any need to do so. The simplest branch instruction is
-C<branch>:
-
-=begin PASM
-
-    branch L1                # branch 4
-    print "skipped\n"
-  L1:
-    print "after branch\n"
-    end
-
-=end PASM
-
-This example unconditionally branches to the location of the label
-C<L1>, skipping over the first C<print> statement.
-
-Jump instructions transfer control to an absolute address. The C<jump>
-opcode doesn't calculate an address from a label, so it's used
-together with C<set_addr>:
-
-=begin PASM
-
-    set_addr I0, L1
-    jump I0
-    print "skipped\n"
-    end
-  L1:
-    print "after jump\n"
-    end
-
-=end PASM
-
-The C<set_addr>X<set_addr opcode (PASM)> opcode takes a label or an
-integer offset and returns an absolute address.
-
-You've probably noticed the C<end>X<end opcode (PASM)> opcode as the
-last statement in many examples above. This terminates the execution
-of the current run loop. Terminating the main bytecode segment (the
-first run loop) stops the interpreter. Without the C<end> statement,
-execution just falls off the end of the bytecode segment, with a good
-chance of crashing the interpreter.
-
-=head3 Conditional Branches
-
-Z<CHP-9-SECT-4.1>
-
-X<PASM (Parrot assembly language);conditional branches>
-X<conditional branches in PASM>
-Unconditional jumps and branches aren't really enough for flow
-control. What you need to implement the control structures of
-high-level languages is the ability to select different actions based
-on a set of conditions. PASM has opcodes that conditionally branch
-based on the truth of a single value or the comparison of two values.
-The following example has C<if>X<if (conditional);opcode (PASM)> and
-C<unless>X<unless (conditional);opcode (PASM)> conditional branches:
-
-=begin PASM
-
-    set I0, 0
-    if I0, TRUE
-    unless I0, FALSE
-    print "skipped\n"
-    end
-  TRUE:
-    print "shouldn't happen\n"
-    end
-  FALSE:
-    print "the value was false\n"
-    end
-
-=end PASM
-
-C<if> branches if its first argument is a true value, and C<unless>
-branches if its first argument is a false value. In this case, the
-C<if> doesn't branch because C<I0> is false, but the C<unless> does
-branch.
-The comparison branching opcodes compare two values and branch if the
-stated relation holds true. These are
-C<eq>X<eq (equal);opcode (PASM)> (branch when equal),
-C<ne>X<ne (not equal);opcode (PASM)> (when not equal),
-C<lt>X<lt (less than);opcode (PASM)> (when less than),
-C<gt>X<gt (greater than);opcode (PASM)> (when greater than),
-C<le>X<le (less than or equal);opcode (PASM)> (when less than or
-equal), and C<ge>X<ge (greater than or equal);opcode (PASM)> (when
-greater than or equal). The two compared arguments must be the same
-register type:
-
-=begin PASM
-
-    set I0, 4
-    set I1, 4
-    eq I0, I1, EQUAL
-    print "skipped\n"
-    end
-  EQUAL:
-    print "the two values are equal\n"
-    end
-
-=end PASM
-
-This compares two integers, C<I0> and C<I1>, and branches if they're
-equal. Strings of different character sets or encodings are converted
-to Unicode before they're compared. PMCs have a C<cmp> vtable method.
-This gets called on the left argument to perform the comparison of the
-two objects.
-
-The comparison opcodes don't specify if a numeric or string comparison
-is intended. The type of the register selects for integers, floats,
-and strings. With PMCs, the vtable method C<cmp> or C<is_equal> of the
-first argument is responsible for comparing the PMC meaningfully with
-the other operand. If you need to force a numeric or string comparison
-on two PMCs, use the alternate comparison opcodes that end in the
-C<_num> and C<_str> suffixes.
-
-=begin PASM
-
-  eq_str P0, P1, label     # always a string compare
-  gt_num P0, P1, label     # always numerically
-
-=end PASM
-
-Finally, the C<eq_addr> opcode branches if two PMCs or strings are
-actually the same object (have the same address):
-
-=begin PASM
-
-  eq_addr P0, P1, same_pmcs_found
-
-=end PASM
-
-=head3 Iteration
-
-Z<CHP-9-SECT-4.2>
-
-X<iteration;in PASM>
-X<PASM (Parrot assembly language);iteration>
-PASM doesn't define high-level loop constructs. These are built up
-from a combination of conditional and unconditional branches. A
-I<do-while>X<do-while style loop;(PASM)> style loop can be constructed
-with a single conditional branch:
-
-=begin PASM
-
-    set I0, 0
-    set I1, 10
-  REDO:
-    inc I0
-    print I0
-    print "\n"
-    lt I0, I1, REDO
-    end
-
-=end PASM
-
-This example prints out the numbers 1 to 10. The first time through,
-it executes all statements up to the C<lt> statement.  If the
-condition evaluates as true (C<I0> is less than C<I1>) it branches to
-the C<REDO> label and runs the three statements in the loop body
-again. The loop ends when the condition evaluates as false.
-
-Conditional and unconditional branches can build up quite complex
-looping constructs, as follows:
-
-=begin PASM
-
-    # loop ($i=1; $i<=10; $i++) {
-    #    print "$i\n";
-    # }
-  loop_init:
-    set I0, 1
-    branch loop_test
-  loop_body:
-    print I0
-    print "\n"
-    branch loop_continue
-  loop_test:
-    le I0, 10, loop_body
-    branch out
-  loop_continue:
-    inc I0
-    branch loop_test
-  out:
-    end
-
-=end PASM
-
-X<loops;PASM>
-X<PASM (Parrot assembly language);loops>
-This example emulates a X<counter-controlled loop> counter-controlled
-loop like Perl 6's C<loop> keyword or C's C<for>. The first time
-through the loop it sets the initial value of the counter in
-C<loop_init>, tests that the loop condition is met in C<loop_test>,
-and then executes the body of the loop in C<loop_body>. If the test
-fails on the first iteration, the loop body will never execute. The
-end of C<loop_body> branches to C<loop_continue>, which increments the
-counter and then goes to C<loop_test> again. The loop ends when the
-condition fails, and it branches to C<out>. The example is more
-complex than it needs to be just to count to 10, but it nicely shows
-the major components of a
-loop.
-
-=head2 Lexicals and Globals
-
-Z<CHP-9-SECT-6>
-
-So far, we've been treating Parrot registers like the variables of a
-high-level language. This is fine, as far as it goes, but it isn't the
-full picture. The dynamic nature and introspective features of
-languages like Perl make it desirable to manipulate variables by name,
-instead of just by register or stack location. These languages also
-have global variables, which are visible throughout the entire
-program. Storing a global variable in a register would either tie up
-that register for the lifetime of the program or require some unwieldy way
-to shuffle the data into and out of registers.
-
-Parrot provides structures for storing both global and lexically
-scoped named variables. Lexical and global variables must be PMC
-values. PASM provides instructions for storing and retrieving
-variables from these structures so the PASM opcodes can operate on
-their values.
-
-=head3 Globals
-
-Z<CHP-9-SECT-6.1>
-
-X<PASM (Parrot assembly language);global variables>
-Global variables are stored in a C<Hash>, so every variable name
-must be unique.  PASM has two opcodes for globals, C<set_global> and
-C<get_global>:
-
-=begin PASM
-
-  new P10, "Int"
-  set P10, 42
-  set_global "$foo", P10
-  # ...
-  get_global P0, "$foo"
-  print P0                        # prints 42
-  end
-
-=end PASM
-
-The first two statements create a C<Int> in the PMC register
-C<P10> and give it the value 42. In the third statement,
-C<set_global> stores that PMC as the named global variable C<$foo>.
-At some later point in the program, C<get_global> retrieves the PMC
-from the global variable by name, and stores it in C<P0> so it can be
-printed.
-
-The C<set_global> opcode only stores a reference to the object. If
-we add an increment statement:
-
-=begin PASM
-
-  inc P10
-
-=end PASM
-
-after the C<set_global> it increments the stored global, printing 43.
-If that's not what you want, you can C<clone> the PMC before you store
-it. Leaving the global variable as an alias does have advantages,
-though. If you retrieve a stored global into a register and modify it
-as follows:
-
-=begin PASM
-
-  get_global P0, "varname"
-  inc P0
-
-=end PASM
-
-the value of the stored global is directly modified, so you don't need
-to call C<set_global> again.
-
-The two-argument forms of C<set_global> and C<get_global> store or
-retrieve globals from the outermost namespace (what Perl users will
-know as the "main" namespace). A simple flat global namespace isn't
-enough for most languages, so Parrot also needs to support
-hierarchical namespaces for separating packages (classes and modules
-in Perl 6). Use C<set_rootglobal> and
-C<get_root_global> add an argument to select a nested namespace:
-
-=begin PASM
-
-  set_root_global ["Foo"], "var", P0 # store P0 as var in the Foo namespace
-  get_root_global P1, ["Foo"], "var"  # get Foo::var
-
-=end PASM
-
-Eventually the global opcodes will have variants that take a PMC to
-specify the namespace, but the design and implementation of these
-aren't finished yet.
-
-=head3 Lexicals
-
-Z<CHP-9-SECT-6.2>
-
-X<PASM (Parrot assembly language);lexical variables>
-Lexical variables are stored in a lexical scratchpad. There's one pad
-for each lexical scope. Every pad has both a hash and an array, so
-elements can be stored either by name or by numeric index.
-
-=head4 Basic instructions
-
-Z<CHP-9-SECT-6.2.1>
-
-To store a lexical variable in the current scope pad, use C<store_lex>.
-Likewise, use C<find_lex> to retrieve a variable from the current pad.
-
-=begin PASM
-
-  new P0, "Int"            # create a variable
-  set P0, 10               # assign value to it
-  store_lex "foo", P0      # store the var with the variable name "foo"
-  # ...
-  find_lex P1, "foo"       # get the var "foo" into P1
-  print P1
-  print "\n"               # prints 10
-  end
-
-=end PASM
-
-=head2 Subroutines
-
-Z<CHP-9-SECT-7>
-
-X<subroutines>
-Subroutines and methods are the basic building blocks of larger
-programs. At the heart of every subroutine call are two fundamental
-actions: it has to store the current location so it can come back to
-it, and it has to transfer control to the subroutine. The
-C<bsr>X<bsr opcode (PASM)> opcode does both. It pushes the address of the
-next instruction onto the control stack, and then branches to a label
-that marks the subroutine:
-
-=begin PASM
-
-    print "in main\n"
-    bsr _sub
-    print "and back\n"
-    end
-  _sub:
-    print "in sub\n"
-    ret
-
-=end PASM
-
-At the end of the subroutine, the C<ret> instruction pops a location
-back off the control stack and goes there, returning control to the
-caller. The C<jsr>X<jsr opcode (PASM)> opcode pushes the current location
-onto the call stack and jumps to a subroutine. Just like the C<jump>
-opcode, it takes an absolute address in an integer register, so the
-address has to be calculated first with the C<set_addr>X<set_addr
-opcode (PASM)> opcode:
-
-=begin PASM
-
-    print "in main\n"
-    set_addr I0, _sub
-    jsr I0
-    print "and back\n"
-    end
-  _sub:
-    print "in sub\n"
-    ret
-
-=end PASM
-
-=head3 Calling Conventions
-
-Z<CHP-9-SECT-7.1>
-
-X<registers;usage for subroutine calls>
-X<subroutines;register usage>
-X<subroutines;calling conventions>
-A C<bsr> or C<jsr> is fine for a simple subroutine call, but few
-subroutines are quite that simple. Who is responsible for saving and
-restoring the registers, however, so that they don't get overwritten when
-we perform a c<bsr> or C<jsr>? How are arguments passed? Where are the
-subroutine's return values stored? A number of different answers are
-possible. You've seen how many ways Parrot has of storing values. The
-critical point is that the caller and the called subroutine have to
-agree on all the answers.
-
-=head4 Parrot calling conventions
-
-Z<CHP-9-SECT-7.1.2>
-
-Internal subroutines can use whatever calling convention serves them
-best. Externally visible subroutines and methods need stricter rules.
-Since these routines may be called as part of an included library or
-module and even from a different high level language, it's important
-to have a consistent interface.
-
-The C<.sub> directive defines globally accessible subroutine
-objects.
-
-Subroutine objects of all kinds can be called with the
-C<invoke>X<invoke opcode (PASM)> opcode. There is also an C<invoke>
-C<PR<x>> instruction for calling objects held in a different register.
-
-The C<invokecc>X<invokecc opcode (PASM)> opcode is like C<invoke>, but it
-also creates and stores a new return continuation. When the
-called subroutine invokes this return continuation, it returns control
-to the instruction after the function call. This kind of call is known
-as Continuation Passing Style (CPS).
-X<CPS (Continuation Passing Style)>
-X<Continuation Passing Style (CPS)>
-
-=head3 Native Call Interface
-
-Z<CHP-9-SECT-7.2>
-
-X<subroutines;calling conventions;NCI>
-A special version of the Parrot calling conventions are used by the
-X<NCI (Native Call Interface)> Native Call Interface (NCI) for calling
-subroutines with a known prototype in shared libraries. This is not
-really portable across all libraries, but it's worth a short example.
-This is a simplified version of the first test in F<t/pmc/nci.t>:
-
-=begin PASM
-
-    loadlib P1, "libnci_test"     # get library object for a shared lib
-    print "loaded\n"
-    dlfunc P0, P1, "nci_dd", "dd" # obtain the function object
-    print "dlfunced\n"
-    set I0, 1                     # prototype used - unchecked
-    set_args "0", 4.0             # set the argument
-    get_results "0", N5           # prepare to store the return value
-    invokecc P0                   # call nci_dd
-    ne N5, 8.0, nok_1             # the test functions returns 2*arg
-    print "ok 1\n"
-    end
-    nok_1:
-    #...
-
-=end PASM
-
-This example shows two new instructions: C<loadlib> and C<dlfunc>. The
-C<loadlib>X<loadlib opcode (PASM)> opcode obtains a handle for a shared
-library. It searches for the shared library in the current directory,
-in F<runtime/parrot/dynext>, and in a few other configured
-directories. It also tries to load the provided filename unaltered and
-with appended extensions like C<.so> or C<.dll>. Which extensions it
-tries depends on the OS Parrot is running on.
-
-The C<dlfunc>X<dlfunc opcode (PASM)> opcode gets a function object from a
-previously loaded library (second argument) of a specified name (third
-argument) with a known function signature (fourth argument). The
-function signature is a string where the first character is the return
-value and the rest of the parameters are the function parameters. The
-characters used in X<NCI (Native Call Interface);function signatures>
-NCI function signatures are listed in Table 9-5.
-
-=begin table picture Function signature letters
-
-Z<CHP-9-TABLE-5>
-
-=headrow
-
-=row
-
-=cell Character
-
-=cell Register set
-
-=cell C type
-
-=bodyrows
-
-=row
-
-=cell C<v>
-
-=cell -
-
-=cell void (no return value)
-
-=row
-
-=cell C<c>
-
-=cell C<I>
-
-=cell char
-
-=row
-
-=cell C<s>
-
-=cell C<I>
-
-=cell short
-
-=row
-
-=cell C<i>
-
-=cell C<I>
-
-=cell int
-
-=row
-
-=cell C<l>
-
-=cell C<I>
-
-=cell long
-
-=row
-
-=cell C<f>
-
-=cell C<N>
-
-=cell float
-
-=row
-
-=cell C<d>
-
-=cell C<N>
-
-=cell double
-
-=row
-
-=cell C<t>
-
-=cell C<S>
-
-=cell char *
-
-=row
-
-=cell C<p>
-
-=cell C<P>
-
-=cell void * (or other pointer)
-
-=row
-
-=cell C<I>
-
-=cell -
-
-=cell Parrot_Interp *interpreter
-
-=row
-
-=cell C<C>
-
-=cell -
-
-=cell a callback function pointer
-
-=row
-
-=cell C<D>
-
-=cell -
-
-=cell a callback function pointer
-
-=row
-
-=cell C<Y>
-
-=cell C<P>
-
-=cell the subroutine C<C> or C<D> calls into
-
-=row
-
-=cell C<Z>
-
-=cell C<P>
-
-=cell the argument for C<Y>
-
-=end table
-
-For more information on callback functions, read the documentation in
-F<docs/pdds/pdd16_native_call.pod> and F<docs/pmc/struct.pod>.
-
-=head3 Coroutines
-
-Z<CHP-9-SECT-7.4>
-
-As we mentioned in the previous chapter, coroutines are
-X<subroutines;coroutines> subroutines that
-can suspend themselves and return control to the caller--and then pick
-up where they left off the next time they're called, as if they never
-left.
-
-X<coroutines>
-In PASM, coroutines are subroutine-like objects:
-
-=begin PASM
-
-  newsub P0, .Coroutine, _co_entry
-
-=end PASM
-
-The C<Coroutine> object has its own user stack, register frame stacks,
-control stack, and pad stack. The pad stack is inherited from the
-caller. The coroutine's control stack has the caller's control stack
-prepended, but is still distinct. When the coroutine invokes itself,
-it returns to the caller and restores the caller's context (basically
-swapping all stacks). The next time the coroutine is invoked, it
-continues to execute from the point at which it previously returned:
-
-=begin PASM
-
-    new_pad 0                # push a new lexical pad on stack
-    new P0, "Int"            # save one variable in it
-    set P0, 10
-    store_lex -1, "var", P0
-
-    newsub P0, .Coroutine, _cor
-                             # make a new coroutine object
-    saveall                  # preserve environment
-    invoke                   # invoke the coroutine
-    restoreall
-    print "back\n"
-    saveall
-    invoke                   # invoke coroutine again
-    restoreall
-    print "done\n"
-    pop_pad
-    end
-
-  _cor:
-    find_lex P1, "var"       # inherited pad from caller
-    print "in cor "
-    print P1
-    print "\n"
-    inc P1                   # var++
-    saveall
-    invoke                   # yield(  )
-    restoreall
-    print "again "
-    branch _cor              # next invocation of the coroutine
-
-=end PASM
-
-This prints out the result:
-
-  in cor 10
-  back
-  again in cor 11
-  done
-
-X<invoke opcode (PASM);coroutines and>
-The C<invoke> inside the coroutine is commonly referred to as
-I<yield>. The coroutine never ends. When it reaches the bottom, it
-branches back up to C<_cor> and executes until it hits C<invoke>
-again.
-
-The interesting part about this example is that the coroutine yields
-in the same way that a subroutine is called. This means that the
-coroutine has to preserve its own register values. This example uses
-C<saveall> but it could have only stored the registers the coroutine
-actually used. Saving off the registers like this works because
-coroutines have their own register frame stacks.
-
-=head3 Continuations
-
-Z<CHP-9-SECT-7.5>
-
-X<continuations>
-X<subroutines;continuations>
-A continuation is a subroutine that gets a complete copy of the
-caller's context, including its own copy of the call stack. Invoking a
-continuation starts or restarts it at the entry point:
-
-=begin PASM
-
-    new P1, "Int"
-    set P1, 5
-
-    newsub P0, .Continuation, _con
-  _con:
-    print "in cont "
-    print P1
-    print "\n"
-    dec P1
-    unless P1, done
-    invoke                        # P0
-  done:
-    print "done\n"
-    end
-
-=end PASM
-
-This prints:
-
-  in cont 5
-  in cont 4
-  in cont 3
-  in cont 2
-  in cont 1
-  done
-
-=head3 Evaluating a Code String
-
-Z<CHP-9-SECT-7.6>
-
-X<code strings, evaluating>
-This isn't really a subroutine operation, but it does produce a code
-object that can be invoked. In this case, it's a X<bytecode segment
-object> bytecode segment object.
-
-The first step is to get an assembler or compiler for the target
-language:
-
-=begin PASM
-
-  compreg P1, "PASM"
-
-=end PASM
-
-Within the Parrot interpreter there are currently three registered
-languages: C<PASM>, C<PIR>, and C<PASM1>. The first two are for parrot
-assembly language and parrot intermediate representation code. The third
-is for evaluating single statements in PASM. Parrot automatically adds
-an C<end> opcode at the end of C<PASM1> strings before they're
-compiled.
-
-This example places a bytecode segment object into the destination
-register C<P0> and then invokes it with C<invoke>:
-
-=begin PASM
-
-  compreg P1, "PASM1"                # get compiler
-  set S1, "in eval\n"
-  compile P0, P1, "print S1"
-  invoke                             # eval code P0
-  print "back again\n"
-  end
-
-=end PASM
-
-You can register a compiler or assembler for any language inside the
-Parrot core and use it to compile and invoke code from that language.
-These compilers may be written in PASM or reside in shared libraries.
-
-=begin PASM
-
-  compreg "MyLanguage", P10
-
-=end PASM
-
-In this example the C<compreg> opcode registers the subroutine-like
-object C<P10> as a compiler for the language "MyLanguage". See
-F<examples/compilers> and F<examples/japh/japh16.pasm> for an external
-compiler in a shared library.
-
-=head2 Exceptions and Exception Handlers
-
-Z<CHP-9-SECT-8>
-
-X<exceptions>
-X<exception handlers>
-Exceptions provide a way of calling a piece of code outside the normal
-flow of control. They are mainly used for error reporting or cleanup
-tasks, but sometimes exceptions are just a funny way to branch from
-one code location to another one. The design and implementation of
-exceptions in Parrot isn't complete yet, but this section will give
-you an idea where we're headed.
-
-Exceptions are objects that hold all the information needed to handle
-the exception: the error message, the severity and type of the error,
-etc. The class of an exception object indicates the kind of exception
-it is.
-
-Exception handlers are derived from continuations. They are ordinary
-subroutines that follow the Parrot calling conventions, but are never
-explicitly called from within user code. User code pushes an exception
-handler onto the control stack with the C<set_eh>X<set_eh opcode (PASM)>
-opcode. The system calls the installed exception handler only when an
-exception is thrown (perhaps because of code that does division by
-zero or attempts to retrieve a global that wasn't stored.)
-
-=begin PASM
-
-    newsub P20, .ExceptionHandler, _handler
-    set_eh P20                  # push handler on control stack
-    null P10                    # set register to null
-    get_global P10, "none"     # may throw exception
-    clear_eh                    # pop the handler off the stack
-    #...
-
-  _handler:                     # if not, execution continues here
-    is_null P10, not_found      # test P10
-    #...
-
-=end PASM
-
-This example creates a new exception handler subroutine with the
-C<newsub> opcode and installs it on the control stack with the
-C<set_eh> opcode. It sets the C<P10> register to a null value (so it
-can be checked later) and attempts to retrieve the global variable
-named C<none>. If the global variable is found, the next statement
-(C<clear_eh>) pops the exception handler off the control stack and
-normal execution continues. If the C<get_global> call doesn't find
-C<none> it throws an exception by pushing an exception object onto the
-control stack. When Parrot sees that it has an exception, it pops it
-off the control stack and calls the exception handler C<_handler>.
-
-The first exception handler in the control stack sees every exception
-thrown. The handler has to examine the exception object and decide
-whether it can handle it (or discard it) or whether it should
-C<rethrow> the exception to pass it along to an exception handler
-deeper in the stack. The C<rethrow>X<rethrow opcode (PASM)> opcode is only
-valid in exception handlers. It pushes the exception object back onto
-the control stack so Parrot knows to search for the next exception
-handler in the stack. The process continues until some exception
-handler deals with the exception and returns normally, or until there
-are no more exception handlers on the control stack. When the system
-finds no installed exception handlers it defaults to a final action,
-which normally means it prints an appropriate message and terminates
-the program.
-
-When the system installs an exception handler, it creates a return
-continuation with a snapshot of the current interpreter context. If
-the exception handler just returns (that is, if the exception is
-cleanly caught) the return continuation restores the control stack
-back to its state when the exception handler was called, cleaning up
-the exception handler and any other changes that were made in the
-process of handling the exception.
-
-Exceptions thrown by standard Parrot opcodes (like the one thrown by
-C<get_global> above or by the C<throw> opcode) are always resumable,
-so when the exception handler function returns normally it continues
-execution at the opcode immediately after the one that threw the
-exception. Other exceptions at the run-loop level are also generally
-resumable.
-
-=begin PASM
-
-  new P10, 'Exception'    # create new Exception object
-  set P10, 'I die'        # set message attribute
-  throw P10               # throw it
-
-=end PASM
-
-Exceptions are designed to work with the Parrot calling conventions.
-Since the return addresses of C<bsr> subroutine calls and exception
-handlers are both pushed onto the control stack, it's generally a bad
-idea to combine the two.
-
-=head2 Events
-
-Z<CHP-9-SECT-9>
-
-An event is a notification that something has happened: a timer
-expired, an IO operation finished, a thread sent a message to
-another thread, or the user pressed C<Ctrl-C> to interrupt program
-execution.
-
-What all of these events have in common is that they arrive
-asynchronously. It's generally not safe to interrupt program flow at an
-arbitrary point and continue at a different position, so the event is
-placed in the
-interpreter's task queue. The run loops code regularly checks whether
-an event needs to be handled. Event handlers may be an internal piece
-of code or a user-defined event handler subroutine.
-
-Events are still experimental in Parrot, so the implementation and
-design is subject to change.
-
-=head3 Timers
-
-Z<CHP-9-SECT-9.1>
-
-C<Timer> objects are the replacement for Perl 5's C<alarm> handlers.
-They are also a significant improvement. Timers can fire once or
-repeatedly, and multiple timers can run independently. The precision
-of a timer is limited by the OS Parrot runs on, but it is always more
-fine-grained then a whole second. The final syntax isn't yet fixed, so
-please consult the documentation for examples.
-
-=head3 Signals
-
-Z<CHP-9-SECT-9.2>
-
-Signal handling is related to events. When Parrot gets a signal it
-needs to handle from the OS, it converts that signal into an event and
-broadcasts it to all running threads. Each thread independently
-decides if it's interested in this signal and, if so, how to respond to it.
-
-=begin PASM
-
-    newsub P20, .ExceptionHandler, _handler
-    set_eh P20                  # establish signal handler
-    print "send SIGINT:\n"
-    sleep 2                     # press ^C after you saw start
-    print "no SIGINT\n"
-    end
-  _handler:
-    .include "signal.pasm"      # get signal definitions
-    print "caught "
-    set I0, P5["type"]         # if _type is negative, the ...
-    neg I0, I0                  # ... negated type is the signal
-    ne I0, .SIGINT, nok
-    print "SIGINT\n"
-  nok:
-    end
-
-=end PASM
-
-This example creates a signal handler and pushes it on to the control
-stack. It then prompts the user to send a C<SIGINT> from the shell
-(this is usually C<Ctrl-C>, but it varies in different shells), and
-waits for 2 seconds. If the user doesn't send a SIGINT in 2 seconds
-the example just prints "no SIGINT" and ends. If the user does send a
-SIGINT, the signal handler catches it, prints out "caught SIGINT" and
-ends.N<Currently, only Linux installs a C<SIGINT> C<sigaction>
-handler, so this example won't work on other platforms.>
-
-=head2 Threads
-
-Z<CHP-9-SECT-10>
-
-Threads allow multiple pieces of code to run in parallel. This is
-useful when you have multiple physical CPUs to share the load of
-running individual threads. With a single processor, threads still
-provide the feeling of parallelism, but without any improvement in
-execution time. Even worse, sometimes using threads on a single
-processor will actually slow down your program.
-
-Still, many algorithms can be expressed more easily in terms of
-parallel running pieces of code and many applications profit from
-taking advantage of multiple CPUs. Threads can vastly simplify
-asynchronous programs like internet servers: a thread splits off,
-waits for some IO to happen, handles it, and relinquishes the
-processor again when it's done.
-
-Parrot compiles in thread support by default (at least, if the
-platform provides some kind of support for it). Unlike Perl 5,
-compiling with threading support doesn't impose any execution time
-penalty for a non-threaded program. Like exceptions and events,
-threads are still under development, so you can expect significant
-changes in the near future.
-
-As outlined in the previous chapter, Parrot implements three different
-threading models. (B<Note>:  As of version 1.0, the C<TQueue> PMC will be
-deprecated, rendering the following discussion obsolete.) The following
-example uses the third model, which takes advantage of shared data. It uses a
-C<TQueue> (thread-safe queue) object to synchronize the two parallel running
-threads. This is only a simple example to illustrate threads, not a typical
-usage of threads (no-one really wants to spawn two threads just to print out a
-simple string).
-
-=begin PASM
-
-    get_global P5, "_th1"              # locate thread function
-    new P2, "ParrotThread"              # create a new thread
-    find_method P0, P2, "thread3"       # a shared thread's entry
-    new P7, "TQueue"                    # create a Queue object
-    new P8, "Int"                       # and a Int
-    push P7, P8                         # push the Int onto queue
-    new P6, "String"                    # create new string
-    set P6, "Js nte artHce\n"
-    set I3, 3                           # thread function gets 3 args
-    invoke                              # _th1.run(P5,P6,P7)
-    new P2, "ParrotThread"              # same for a second thread
-    get_global P5, "_th2"
-    set P6, "utaohrPro akr"             # set string to 2nd thread's
-    invoke                              # ... data, run 2nd thread too
-    end                                 # Parrot joins both
-
-  .pcc_sub _th1:                        # 1st thread function
-  w1: sleep 0.001                       # wait a bit and schedule
-    defined I1, P7                      # check if queue entry is ...
-    unless I1, w1                       # ... defined, yes: it's ours
-    set S5, P6                          # get string param
-    substr S0, S5, I0, 1                # extract next char
-    print S0                            # and print it
-    inc I0                              # increment char pointer
-    shift P8, P7                        # pull item off from queue
-    if S0, w1                           # then wait again, if todo
-    invoke P1                           # done with string
-
-  .pcc_sub _th2:                        # 2nd thread function
-  w2: sleep 0.001
-    defined I1, P7                      # if queue entry is defined
-    if I1, w2                           # then wait
-    set S5, P6
-    substr S0, S5, I0, 1                # if not print next char
-    print S0
-    inc I0
-    new P8, "Int"                       # and put a defined entry
-    push P7, P8                         # onto the queue so that
-    if S0, w2                           # the other thread will run
-    invoke P1                           # done with string
-
-=end PASM
-
-This example creates a C<ParrotThread> object and calls its C<thread3>
-method, passing three arguments: a PMC for the C<_th1> subroutine in
-C<P5>, a string argument in C<P6>, and a C<TQueue> object in C<P7>
-containing a single integer. Remember from the earlier section
-"Parrot calling conventions" that registers 5-15
-hold the arguments for a subroutine or method call and C<I3> stores
-the number of arguments. The thread object is passed in C<P2>.
-
-This call to the C<thread3> method spawns a new thread to run the
-C<_th1> subroutine. The main body of the code then creates a second
-C<ParrotThread> object in C<P2>, stores a different subroutine in
-C<P5>, sets C<P6> to a new string value, and then calls the C<thread3>
-method again, passing it the same C<TQueue> object as the first
-thread. This method call spawns a second thread. The main body of code
-then ends, leaving the two threads to do the work.
-
-At this point the two threads have already started running. The first
-thread (C<_th1>) starts off by sleeping for a 1000th of a second. It
-then checks if the C<TQueue> object contains a value. Since it
-contains a value when the thread is first called, it goes ahead and
-runs the body of the subroutine. The first thing this does is shift
-the element off the C<TQueue>. It then pulls one character off a copy
-of the string parameter using C<substr>, prints the character,
-increments the current position (C<I0>) in the string, and loops back
-to the C<w1> label and sleeps. Since the queue doesn't have any
-elements now, the subroutine keeps sleeping.
-
-Meanwhile, the second thread (C<_th2>) also starts off by sleeping for
-a 1000th of a second. It checks if the shared C<TQueue> object
-contains a defined value but unlike the first thread it only continues
-sleeping if the queue does contain a value. Since the queue contains a
-value when the second thread is first called, the subroutine loops
-back to the C<w2> label and continues sleeping. It keeps sleeping
-until the first thread shifts the integer off the queue, then runs the
-body of the subroutine. The body pulls one character off a copy of the
-string parameter using C<substr>, prints the character, and increments
-the current position in the string. It then creates a new
-C<Int>, pushes it onto the shared queue, and loops back to the
-C<w2> label again to sleep. The queue has an element now, so the
-second thread keeps sleeping, but the first thread runs through its
-loop again.
-
-The two threads alternate like this, printing a character and marking
-the queue so the next thread can run, until there are no more
-characters in either string. At the end, each subroutine invokes the
-return continuation in C<P1> which terminates the thread. The
-interpreter waits for all threads to terminate in the cleanup phase
-after the C<end> in the main body of code.
-
-The final printed result (as you might have guessed) is:
-
-  Just another Parrot Hacker
-
-The syntax for threads isn't carved in stone and the implementation
-still isn't finished but as this example shows, threads are working
-now and already useful.
-
-Several methods are useful when working with threads. The C<join>
-method belongs to the C<ParrotThread> class. When it's called on a
-C<ParrotThread> object, the calling code waits until the thread
-terminates.
-
-=begin PASM
-
-    new P2, "ParrotThread"      # create a new thread
-    set I5, P2                  # get thread ID
-
-    find_method P0, P2, "join"  # get the join method...
-    invoke                      # ...and join (wait for) the thread
-    set P16, P5                 # the return result of the thread
-
-=end PASM
-
-C<kill> and C<detach> are interpreter methods, so you have to grab the
-current interpreter object before you can look up the method object.
-
-=begin PASM
-
-    set I5, P2                  # get thread ID of thread P2
-    getinterp P3                # get this interpreter object
-    find_method P0, P3, "kill"  # get kill method
-    invoke                      # kill thread with ID I5
-
-    find_method P0, P3, "detach"
-    invoke                      # detach thread with ID I5
-
-=end PASM
-
-By the time you read this, some of these combinations of statements
-and much of the threading syntax above may be reduced to a simpler set
-of opcodes.
-
-=head2 Loading Bytecode
-
-Z<CHP-9-SECT-11>
-
-In addition to running Parrot bytecode on the command-line, you can
-also load pre-compiled bytecode directly into your PASM source file.
-The C<load_bytecode>X<load_bytecode opcode (PASM)> opcode takes a single
-argument: the name of the bytecode file to load. So, if you create a
-file named F<file.pasm> containing a single subroutine:
-
-=begin PASM
-
-  # file.pasm
-  .sub _sub2:               # .sub stores a global sub
-     print "in sub2\n"
-     invoke P1
-
-=end PASM
-
-and compile it to bytecode using the C<-o> command-line switch:
-
-  $ parrot -o file.pbc file.pasm
-
-You can then load the compiled bytecode into F<main.pasm> and directly
-call the subroutine defined in F<file.pasm>:
-
-=begin PASM
-
-  # main.pasm
-  main:
-    load_bytecode "file.pbc"    # compiled file.pasm
-    get_global P0, "_sub2"
-    invokecc
-    end
-
-=end PASM
-
-The C<load_bytecode> opcode also works with source files, as long as
-Parrot has a compiler registered for that type of file:
-
-=begin PASM
-
-  # main2.pasm
-  main:
-    load_bytecode "file.pasm"  # PASM source code
-    set_global P0, "_sub2"
-    invokecc
-    end
-
-=end PASM
-
-Subroutines marked with C<:load> run as soon as they're loaded (before
-C<load_bytecode> returns), rather than waiting to be called. A
-subroutine marked with C<:main> will always run first, no matter what
-name you give it or where you define it in the file.
-
-=begin PASM
-
-  # file3.pasm
-  .sub :load                    # mark the sub as to be run
-    print "file3\n"
-    invoke P1                   # return
-
-  # main3.pasm
-  first:                        # first is never invoked
-    print "never\n"
-    invoke P1
-
-  .sub :main                    # because _main is marked as the
-    print "main\n"              # MAIN entry of program execution
-    load_bytecode "file3.pasm"
-    print "back\n"
-    end
-
-=end PASM
-
-This example uses both C<:load> and C<:main>. Because the C<main>
-subroutine is defined with C<:main> it will execute first even though
-another subroutine comes before it in the file. C<main> prints a
-line, loads the PASM source file, and then prints another line.
-Because C<_entry> in F<file3.pasm> is marked with C<:load> it runs
-before C<load_bytecode> returns, so the final output is:
-
-  main
-  file3
-  back
-
-=head2 Classes and Objects
-
-Z<CHP-9-SECT-12>
-
-This section revolves around one complete example that defines a
-class, instantiates objects, and uses them. The whole example is
-included at the end of the section.
-
-=head3 Class declaration
-
-Z<CHP-9-SECT-12.1>
-
-X<classes;in PASM>
-The C<newclass>X<newclass opcode (PASM)> opcode defines a new class.
-It takes two arguments, the name of the class and the destination
-register for the class PMC. All classes (and objects) inherit from the
-C<ParrotClass> PMCX<ParrotClass PMC>, which is the core of the Parrot
-object system.
-
-=begin PASM
-
-    newclass P1, "Foo"
-
-=end PASM
-
-To instantiate a new object of a particular class, you first look up
-the integer value for the class type with the C<find_type> opcode,
-then create an object of that type with the C<new> opcode:
-
-=begin PASM
-
-    find_type I1, "Foo"
-    new P3I I1
-
-=end PASM
-
-The C<new> opcode also checks to see if the class defines a
-method named "__init" and calls it if it exists.
-
-=head3 Attributes
-
-Z<CHP-9-SECT-12.2>
-
-X<attributes;in PASM>
-X<classes;attributes>
-The C<addattribute> opcode creates a slot in the class for an
-attribute (sometimes known as an I<instance variable>) and associates
-it with a name:
-
-=begin PASM
-
-    addattribute P1, ".i"                # Foo.i
-
-=end PASM
-
-This chunk of code
-from the C<__init> method looks up the position of the first
-attribute, creates a C<Int> PMC, and stores it as the first
-attribute:
-
-=begin PASM
-
-    classoffset I0, P2, "Foo"     # first "Foo" attribute of object P2
-    new P6, "Int"                 # create storage for the attribute
-    setattribute P2, I0, P6       # store the first attribute
-
-=end PASM
-
-The C<classoffset> opcodeX<classoffset opcode (PASM)> takes a PMC
-containing an object and the name of its class, and returns an integer
-index for the position of the first attribute. The C<setattribute>
-opcode uses the integer index to store a PMC value in one of the
-object's attribute slots. This example initializes the first
-attribute. The second attribute would be at C<I0 + 1>, the third
-attribute at C<I0 + 2>, etc:
-
-=begin PASM
-
-    inc I0
-    setattribute P2, I0, P7       # store next attribute
-    #...
-
-=end PASM
-
-There is also support for named parameters with fully qualified
-parameter names (although this is a little bit slower than getting
-the class offset once and accessing several attributes by index):
 
-=begin PASM
-
-    new P6, "Int"
-    setattribute P2, "Foo\x0.i", P6   # store the attribute
-
-=end PASM
-
-You use the same integer index to retrieve the value of an attribute.
-The C<getattribute>X<getattribute opcode (PASM)> opcode takes an object and
-an index as arguments and returns the attribute PMC at that position:
-
-=begin PASM
-
-    classoffset I0, P2, "Foo"         # first "Foo" attribute of object P2
-    getattribute P10, P2, I0          # indexed get of attribute
-
-=end PASM
-
-or
-
-=begin PASM
-
-    getattribute P10, P2, "Foo\x0.i"  # named get
-
-=end PASM
-
-To set the value of an attribute PMC, first retrieve it with
-C<getattribute> and then assign to the returned PMC. Because PMC
-registers are only pointers to values, you don't need to store the PMC
-again after you modify its value:
-
-=begin PASM
-
-    getattribute P10, P2, I0
-    set P10, I5
-
-=end PASM
-
-=head3 Methods
-
-Z<CHP-9-SECT-12.3>
-
-X<methods;in PASM>
-X<classes;methods>
-X<classes;namespaces>
-Methods in PASM are just subroutines installed in the namespace of the
-class. You define a method with the C<.pcc_sub> directive before the
-label:
-
-=begin PASM
-
-  .pcc_sub _half:                 # I5 = self."_half"()
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set I5, P10                   # get value
-    div I5, 2
-    invoke P1
-
-=end PASM
-
-This routine returns half of the value of the first attribute of the
-object. Method calls use the Parrot calling conventions so they always
-pass the I<invocant> object (often called I<self>) in C<P2>. Invoking
-the return continuation in C<P1> returns control to the caller.
-
-The C<.pcc_sub> directive automatically stores the subroutine as a
-global in the current namespace. The C<.namespace> directive sets the
-current namespace:
-
-=begin PASM
-
-  .namespace [ "Foo" ]
-
-=end PASM
-
-If the namespace is explicitly set to an empty string or key, then the
-subroutine is stored in the outermost namespace.
-
-The C<callmethodcc>X<callmethodcc opcode (PASM)> opcode makes a method
-call. It follows the Parrot calling conventions, so it expects to
-find the invocant object in C<P2>, the method object in C<P0>, etc. It
-adds one bit of magic, though. If you pass the name of the method in
-C<S0>, C<callmethodcc> looks up that method name in the invocant
-object and stores the method object in C<P0> for you:
-
-=begin PASM
-
-    set S0, "_half"             # set method name
-    set P2, P3                  # the object
-    callmethodcc                # create return continuation, call
-    print I5                    # result of method call
-    print "\n"
-
-=end PASM
-
-The C<callmethodcc> opcode also generates a return continuation and
-stores it in C<P1>. The C<callmethod> opcode doesn't generate a return
-continuation, but is otherwise identical to C<callmethodcc>. Just like
-ordinary subroutine calls, you have to preserve and restore any
-registers you want to keep after a method call. Whether you store
-individual registers, register frames, or half register frames is up
-to you.
-
-=head4 Overriding vtable functions
-
-Z<CHP-9-SECT-12.3.1>
-
-Every object inherits a default set of I<vtable> functions from the
-C<ParrotObject> PMC, but you can also override them with your own
-methods. The vtable functions have predefined names that start with a
-double underscore "__". The following code defines a method named
-C<__init> in the C<Foo> class that initializes the first attribute of
-the object with an integer:
-
-=begin PASM
-
-  .sub __init:
-    classoffset I0, P2, "Foo"     # lookup first attribute position
-    new P6, "Int"                 # create storage for the attribute
-    setattribute P2, I0, P6       # store the first attribute
-    invoke P1                     # return
-
-=end PASM
-
-Ordinary methods have to be called explicitly, but the vtable
-functions are called implicitly in many different contexts. Parrot
-saves and restores registers for you in these calls. The C<__init>
-method is called whenever a new object is constructed:
-
-=begin PASM
-
-    find_type I1, "Foo"
-    new P3, I1          # call __init if it exists
-
-=end PASM
-
-A few other vtable functions in the complete code example for this
-section are C<__set_integer_native>, C<__add>, C<__get_integer>,
-C<__get_string>, and C<__increment>. The C<set> opcode calls Foo's
-C<__set_integer_native> vtable function when its destination register
-is a C<Foo> object and the source register is a native integer:
-
-=begin PASM
-
-    set P3, 30          # call __set_integer_native method
-
-=end PASM
-
-The C<add> opcode calls Foo's C<__add> vtable function when it adds
-two C<Foo> objects:
-
-=begin PASM
 
-    new P4, I1          # same with P4
-    set P4, 12
-    new P5, I1          # create a new store for add
 
-    add P5, P3, P4      # __add method
 
-=end PASM
-
-The C<inc> opcode calls Foo's C<__increment> vtable function when it
-increments a C<Foo> object:
-
-=begin PASM
-
-    inc P3              # __increment
-
-=end PASM
-
-Foo's C<__get_integer> and C<__get_string> vtable functions are called
-whenever an integer or string value is retrieved from a C<Foo> object:
-
-=begin PASM
-
-    set I10, P5         # __get_integer
-    #...
-    print P5            # calls __get_string, prints 'fortytwo'
-
-=end PASM
-
-
-=head3 Inheritance
-
-Z<CHP-9-SECT-12.4>
-
-X<inheritance;in PASM>
-X<classes;inheritance>
-The C<subclass>X<subclass opcode (PASM)> opcode creates a new class that
-inherits methods and attributes from another class. It takes 3
-arguments: the destination register for the new class, a register
-containing the parent class, and the name of the new class:
-
-=begin PASM
-
-    subclass P3, P1, "Bar"
-
-=end PASM
-
-X<multiple inheritance; in PASM>
-For multiple inheritance, the C<addparent>X<addparent opcode (PASM)>
-opcode adds additional parents to a subclass.
-
-=begin PASM
-
-  newclass P4, "Baz"
-  addparent P3, P4
-
-=end PASM
-
-To override an inherited method, define a method with the same name in
-the namespace of the subclass. The following code overrides Bar's
-C<__increment> method so it decrements the value instead of
-incrementing it:
-
-=begin PASM
-
-  .namespace [ "Bar" ]
-
-  .sub __increment:
-    classoffset I0, P2, "Foo"     # get Foo's attribute slot offset
-    getattribute P10, P2, I0      # get the first Foo attribute
-    dec P10                       # the evil line
-    invoke P1
-
-=end PASM
-
-Notice that the attribute inherited from C<Foo> can only be looked up
-with the C<Foo> class name, not the C<Bar> class name. This preserves
-the distinction between attributes that belong to the class and
-inherited attributes.
-
-Object creation for subclasses is the same as for ordinary classes:
-
-=begin PASM
-
-    find_type I1, "Bar"
-    new P5, I1
-
-=end PASM
-
-Calls to inherited methods are just like calls to methods defined in
-the class:
-
-=begin PASM
-
-    set P5, 42                  # inherited __set_integer_native
-    inc P5                      # overridden __increment
-    print P5                    # prints 41 as Bar's __increment decrements
-    print "\n"
-
-    set S0, "_half"             # set method name
-    set P2, P5                  # the object
-    callmethodcc                # create return continuation, call
-    print I5
-    print "\n"
-
-=end PASM
-
-=head3 Additional Object Opcodes
-
-Z<CHP-9-SECT-12.5>
-
-The C<isa> and C<can> opcodes are also useful when working with
-objects. C<isa>X<isa opcode (PASM)> checks whether an object belongs to or
-inherits from a particular class. C<can>X<can opcode (PASM)> checks whether
-an object has a particular method. Both return a true or false value.
-
-=begin PASM
-
-    isa I0, P3, "Foo"           # 1
-    isa I0, P3, "Bar"           # 1
-    can I0, P3, "__add"         # 1
-
-=end PASM
-
-=head3 Complete Example
-
-Z<CHP-9-SECT-12.6>
-
-=begin PASM
-
-    newclass P1, "Foo"
-    addattribute P1, "$.i"                # Foo.i
-
-    find_type I1, "Foo"
-    new P3, I1          # call __init if it exists
-    set P3, 30          # call __set_integer_native method
-
-    new P4, I1          # same with P4
-    set P4, 12
-    new P5, I1          # create a new LHS for add
-
-    add P5, P3, P4      # __add method
-    set I10, P5         # __get_integer
-    print I10
-    print "\n"
-    print P5            # calls __get_string prints 'fortytwo'
-    print "\n"
-
-    inc P3              # __increment
-    add P5, P3, P4
-    print P5            # calls __get_string prints '43'
-    print "\n"
-
-    subclass P3, P1, "Bar"
-
-    find_type I1, "Bar"
-    new P3, I1
-
-    set P3, 100
-    new P4, I1
-    set P4, 200
-    new P5, I1
-
-    add P5, P3, P4
-    print P5                    # prints 300
-    print "\n"
-
-    set P5, 42
-    print P5                    # prints 'fortytwo'
-    print "\n"
-
-    inc P5
-    print P5                    # prints 41 as Bar's
-    print "\n"                  # __increment decrements
-
-    set S0, "_half"             # set method name
-    set P2, P3                  # the object
-    callmethodcc                # create return continuation, call
-    print I5                    # prints 50
-    print "\n"
-
-    end
-
-  .namespace [ "Foo" ]
-
-  .sub __init:
-    classoffset I0, P2, "Foo"     # lookup first attribute position
-    new P6, "Int"                 # create a store for the attribute
-    setattribute P2, I0, P6       # store the first attribute
-    invoke P1                     # return
-
-  .sub __set_integer_native:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set P10, I5                   # assign passed in value
-    invoke P1
-
-  .sub __get_integer:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set I5, P10                   # return value
-    invoke P1
-
-  .sub __get_string:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set I5, P10
-    set S5, P10                   # get stringified value
-    ne I5, 42, ok
-    set S5, "fortytwo"            # or return modified one
-  ok:
-    invoke P1
-
-  .sub __increment:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0      # as with all aggregates, this
-    inc P10                       # has reference semantics - no
-    invoke P1                     # setattribute needed
-
-  .sub __add:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0      # object
-    getattribute P11, P5, I0      # argument
-    getattribute P12, P6, I0      # destination
-    add P12, P10, P11
-    invoke P1
-
-  .sub _half:                 # I5 = _half(self)
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set I5, P10                   # get value
-    div I5, 2
-    invoke P1
-
-
-  .namespace [ "Bar" ]
-
-  .sub __increment:
-    classoffset I0, P2, "Foo"     # get Foo's attribute slot offset
-    getattribute P10, P2, I0      # get the first Foo attribute
-    dec P10                       # the evil line
-    invoke P1
-
-=end PASM
 
-This example prints out:
 
-  42
-  fortytwo
-  43
-  300
-  fortytwo
-  41
-  50
 
 =cut
 

Modified: branches/pmc_pct/docs/book/draft/chXX_hlls.pod
==============================================================================
--- branches/pmc_pct/docs/book/draft/chXX_hlls.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/book/draft/chXX_hlls.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -64,8 +64,12 @@
 will have a common form. If a compiler object is in register C<$P0>, it can
 be stored using the following C<compreg> syntax:
 
+=begin PIR_FRAGMENT
+
   compreg 'MyCompiler', $P0
 
+=end PIR_FRAGMENT
+
 There are two built-in compiler objects: One for PIR and one for PASM. These
 two don't need to be stored first, they can simply be retrieved and used.
 The PIR and PASM compiler objects are Sub PMCs that take a single string
@@ -81,15 +85,23 @@
 importance to many modern dynamic languages.  Here's an example using
 the PIR compiler:
 
+=begin PIR_FRAGMENT
+
+  .local string code
+  code = "..."
   $P0 = compreg 'PIR'      # Get the compiler object
   $P1 = $P0(code)          # Compile the string variable "code"
 
+=end PIR_FRAGMENT
+
 The returned value from invoking the compiler object is an array of PMCs
 that contains the various executable subroutines from the compiled source.
 Here's a more verbose example of this:
 
+=begin PIR_FRAGMENT
+
   $P0 = compreg 'PIR'
-  $S0 = << "END_OF_CODE"
+  $S0 = <<"END_OF_CODE"
 
     .sub 'hello'
        say 'hello world!'
@@ -99,7 +111,7 @@
        say 'goodbye world!'
     .end
 
-  END_OF_CODE
+END_OF_CODE
 
   $P1 = $P0($S0)
   $P2 = $P1[0]      # The sub "hello"
@@ -108,8 +120,12 @@
   $P2()             # "hello world!"
   $P3()             # "goodbye world!"
 
+=end PIR_FRAGMENT
+
 Here's an example of a Read-Eval-Print-Loop (REPL) in PIR:
 
+=begin PIR
+
   .sub main
     $P0 = getstdin
     $P1 = compreg 'PIR'
@@ -124,6 +140,8 @@
       goto loop_top
   .end
 
+=end PIR
+
 The exact list of HLL packages installed on your system may vary. Some
 language compiler packages will exist as part of the Parrot source code
 repository, but many will be developed and maintained separately. In any
@@ -149,20 +167,28 @@
 instead of using the normal built-in types. Mappings can be created with the
 C<"hll_map"> method of the interpreter PMC.
 
+=begin PIR_FRAGMENT
+
   $P0 = newclass "MyNewClass"         # New type
-  $P1 = getclass "ResizablePMCArray"  # Built-in type
+  $P1 = get_class "ResizablePMCArray"  # Built-in type
   $P2 = getinterp
   $P2.'hll_map'($P1, $P0)
 
+=end PIR_FRAGMENT
+
 With the mapping in place, anywhere that Parrot would have used a
 ResizablePMCArray it now uses a MyNewClass object instead. Here's one example
 of this:
 
+=begin PIR
+
   .sub 'MyTestSub'
       .param pmc arglist :slurpy   # A MyNewClass array of args
       .return(arglist)
   .end
 
+=end PIR
+
 =head2 Interoperability Guidelines
 
 =head3 Libraries and APIs

Modified: branches/pmc_pct/docs/dev/pmc_freeze.pod
==============================================================================
--- branches/pmc_pct/docs/dev/pmc_freeze.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/dev/pmc_freeze.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -58,7 +58,7 @@
 
 =item mark
 
-Mark all objects as being live by calling B<pobject_lives> called from GC.
+Mark all objects as being live by calling B<Parrot_gc_mark_PObj_alive> called from GC.
 While the functionality is the same, it will not be implemented on top of this
 general scheme for performance reasons. This leads to some code duplication,
 but GC is run permanently and deserves all the speed it can get.

Modified: branches/pmc_pct/docs/embed.pod
==============================================================================
--- branches/pmc_pct/docs/embed.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/embed.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -386,7 +386,7 @@
 
 Returns the class corresponding to the supplied namespace.
 
-=item C<Parrot_PMC Parrot_Class_instantiate(PARROT_INTERP, Parrot_PMC the_class Parrot_PMC arg)>
+=item C<Parrot_PMC VTABLE_instantiate(PARROT_INTERP, Parrot_PMC the_class Parrot_PMC arg)>
 
 Instantiates a new object of class C<the_class>, which can be obtained from
 C<Parrot_oo_get_class()>.  Passes an optional PMC argument C<arg> to the

Modified: branches/pmc_pct/docs/pdds/pdd09_gc.pod
==============================================================================
--- branches/pmc_pct/docs/pdds/pdd09_gc.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/pdds/pdd09_gc.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -380,8 +380,8 @@
 For a concurrent collector, calls to this function may activate a concurrent
 collection thread or, if such a thread is already running, do nothing at all.
 
-The C<do_gc_mark> function is called from the C<Parrot_do_gc_run> function,
-and should not usually be called directly.
+The C<do_gc_mark> function is called from the C<Parrot_gc_mark_and_sweep>
+function, and should not usually be called directly.
 
 C<flags> is one of:
 
@@ -570,9 +570,9 @@
 =item PObj_custom_mark_FLAG
 
 The C<mark> vtable slot will be called during the GC mark phase. The mark
-function must call C<pobject_lives> for all non-NULL objects (Buffers and
-PMCs) that PMC refers to. This flag is typically tested and the custom mark
-VTABLE method called from C<src/gc/api.c:mark_special>.
+function must call C<Parrot_gc_mark_PObj_alive> for all non-NULL objects
+(Buffers and PMCs) that PMC refers to. This flag is typically tested and the
+custom mark VTABLE method called from C<src/gc/api.c:mark_special>.
 
 =item PObj_external_FLAG
 

Modified: branches/pmc_pct/docs/pmc.pod
==============================================================================
--- branches/pmc_pct/docs/pmc.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/pmc.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -87,7 +87,7 @@
 =head1 PMCs and GC
 
 The GC system doesn't make any assumptions about your PMC's layout. Whenever a
-PMC is found in the root set, B<pobject_lives()> is called with that PMC.  The
+PMC is found in the root set, B<Parrot_gc_mark_PObj_alive()> is called with that PMC.  The
 PMC is responsible to mark all contained or referenced active Parrot objects
 (Buffers, STRINGs or other PMCs) when its C<mark()> VTABLE function is called.
 
@@ -107,7 +107,7 @@
 
 If your PMC contains any other B<PObj>s (STRINGs, PMCs, etc), your PMC must
 implement the B<mark()> VTABLE function and set this flag.  The B<mark()>
-VTABLE function must call B<pobject_lives()> on all B<PObj>s which your PMC
+VTABLE function must call B<Parrot_gc_mark_PObj_alive()> on all B<PObj>s which your PMC
 contains.
 
 =item PObj_active_destroy_FLAG

Modified: branches/pmc_pct/docs/project/release_manager_guide.pod
==============================================================================
--- branches/pmc_pct/docs/project/release_manager_guide.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/project/release_manager_guide.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -15,8 +15,10 @@
 they've committed to accomplish in time for the release.
 
 A couple of weeks in advance: Ask people to run C<make fulltest> and
-report (and hopefully fix!) any problems they find. Also check in with
+report (and hopefully fix!) any problems they find. Check in with
 language project leads for release blockers, to allow time to fix them.
+Also ask people to review the tickets targeted for the upcoming release
+L<https://trac.parrot.org/parrot/roadmap>.
 
 A couple of days in advance: announce the new release to
 parrot-dev at lists.parrot.org and to the IRC channel #parrot. Ask whether

Modified: branches/pmc_pct/docs/user/pir/exceptions.pod
==============================================================================
--- branches/pmc_pct/docs/user/pir/exceptions.pod	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/docs/user/pir/exceptions.pod	Fri May 15 21:49:40 2009	(r38803)
@@ -10,8 +10,8 @@
 including two pasm files that define constants for exception type and
 severity.
 
-    .include 'include/except_types.pasm'
-    .include 'include/except_severity.pasm'
+    .include 'except_types.pasm'
+    .include 'except_severity.pasm'
 
 You create exceptions just like you create any other object, with
 C<new>.
@@ -38,8 +38,8 @@
 
 =head3 Throw Example
 
-    .include 'include/except_types.pasm'
-    .include 'include/except_severity.pasm'
+    .include 'except_types.pasm'
+    .include 'except_severity.pasm'
     .local pmc ex
     ex = new 'Exception'
     ex = "Everything is horrible, dood."
@@ -90,7 +90,7 @@
 
 =begin PIR
 
-    .include 'include/except_severity.pasm'
+    .include 'except_severity.pasm'
 
     .sub 'dostuff'
         .local pmc eh

Modified: branches/pmc_pct/examples/library/ncurses_life.pir
==============================================================================
--- branches/pmc_pct/examples/library/ncurses_life.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/library/ncurses_life.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -59,7 +59,7 @@
 .sub _MAIN :main
     .param pmc argv
     # the command line
-    load_bytecode "library/ncurses.pasm"
+    load_bytecode 'ncurses.pbc'
 
     # should autogenerate these
     .globalconst int KEY_DOWN = 258

Modified: branches/pmc_pct/examples/opengl/shapes.pir
==============================================================================
--- branches/pmc_pct/examples/opengl/shapes.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/opengl/shapes.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -68,8 +68,8 @@
     .param string window_title
 
     # Load OpenGL libary and a helper library for calling glutInit
-    load_bytecode 'library/OpenGL.pbc'
-    load_bytecode 'library/NCI/call_toolkit_init.pbc'
+    load_bytecode 'OpenGL.pbc'
+    load_bytecode 'NCI/call_toolkit_init.pbc'
 
     # Import all OpenGL/GLU/GLUT functions
     .local pmc import_gl

Modified: branches/pmc_pct/examples/opengl/static-triangle.pir
==============================================================================
--- branches/pmc_pct/examples/opengl/static-triangle.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/opengl/static-triangle.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -29,8 +29,8 @@
     .param pmc argv
 
     # Load OpenGL libary and a helper library for calling glutInit
-    load_bytecode 'library/OpenGL.pbc'
-    load_bytecode 'library/NCI/call_toolkit_init.pbc'
+    load_bytecode 'OpenGL.pbc'
+    load_bytecode 'NCI/call_toolkit_init.pbc'
 
     # Import all OpenGL/GLU/GLUT functions
     .local pmc import_gl

Modified: branches/pmc_pct/examples/opengl/triangle.pir
==============================================================================
--- branches/pmc_pct/examples/opengl/triangle.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/opengl/triangle.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -32,8 +32,8 @@
     .param pmc argv
 
     # Load OpenGL libary and a helper library for calling glutInit
-    load_bytecode 'library/OpenGL.pbc'
-    load_bytecode 'library/NCI/call_toolkit_init.pbc'
+    load_bytecode 'OpenGL.pbc'
+    load_bytecode 'NCI/call_toolkit_init.pbc'
 
     # Import all OpenGL/GLU/GLUT functions
     .local pmc import_gl

Modified: branches/pmc_pct/examples/pir/sudoku.pir
==============================================================================
--- branches/pmc_pct/examples/pir/sudoku.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/pir/sudoku.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2149,7 +2149,7 @@
 
 .sub nc_start
     .local pmc stdscr
-    load_bytecode "library/ncurses.pasm"
+    load_bytecode 'ncurses.pbc'
     stdscr = _init_curses()
     .return(stdscr)
 .end

Modified: branches/pmc_pct/examples/streams/Bytes.pir
==============================================================================
--- branches/pmc_pct/examples/streams/Bytes.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/Bytes.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -16,15 +16,15 @@
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "library/Stream/Sub.pir"
-    load_bytecode "library/Stream/Replay.pir"
+    load_bytecode 'Stream/Sub.pbc'
+    load_bytecode 'Stream/Replay.pbc'
 
-    $P0 = new "Stream::Sub"
+    $P0 = new ['Stream'; 'Sub']
     # set the stream's source sub
     .const 'Sub' temp = "_hello"
     assign $P0, $P1
 
-    stream = new "Stream::Replay"
+    stream = new ['Stream'; 'Replay']
     assign stream, $P0
 
     $S0 = stream."read_bytes"( 3 )
@@ -83,7 +83,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/Combiner.pir
==============================================================================
--- branches/pmc_pct/examples/streams/Combiner.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/Combiner.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -31,23 +31,23 @@
     .local pmc text
     .local pmc combined
 
-    load_bytecode "library/Stream/Base.pbc"
-    load_bytecode "library/Stream/Combiner.pbc"
-    load_bytecode "library/Stream/Sub.pbc"
+    load_bytecode 'Stream/Base.pbc'
+    load_bytecode 'Stream/Combiner.pbc'
+    load_bytecode 'Stream/Sub.pbc'
 
     # create the counter stream
-    counter = new "Stream::Sub"
+    counter = new ['Stream'; 'Sub']
     .const 'Sub' temp = "_counter"
     assign counter, temp
 
     # create the text stream
-    text = new "Stream::Sub"
+    text = new ['Stream'; 'Sub']
     # set its source
     .const 'Sub' temp = "_text"
     assign text, temp
 
     # create a combiner stream
-    combined = new "Stream::Combiner"
+    combined = new ['Stream'; 'Combiner']
     # add the streams
     assign combined, counter
     assign combined, text
@@ -133,7 +133,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/Coroutine.pir
==============================================================================
--- branches/pmc_pct/examples/streams/Coroutine.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/Coroutine.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -26,11 +26,11 @@
     .local pmc stream
     .local pmc temp
 
-    load_bytecode "library/Stream/Base.pbc"
-    load_bytecode "library/Stream/Coroutine.pbc"
+    load_bytecode "Stream/Base.pbc"
+    load_bytecode "Stream/Coroutine.pbc"
 
     # create the coroutine stream
-    stream = new "Stream::Coroutine"
+    stream = new ['Stream'; 'Coroutine']
 
     # set the stream's source coroutine
     # A .Sub is a coroutine when there is a yield?
@@ -84,7 +84,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/FileLines.pir
==============================================================================
--- branches/pmc_pct/examples/streams/FileLines.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/FileLines.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -38,26 +38,26 @@
     name = argv[1]
 NO_NAME:
 
-    load_bytecode "library/Stream/ParrotIO.pir"
-    load_bytecode "library/Stream/Lines.pir"
-    load_bytecode "library/Stream/Sub.pir"
-    load_bytecode "library/Stream/Combiner.pir"
+    load_bytecode 'Stream/ParrotIO.pbc'
+    load_bytecode 'Stream/Lines.pbc'
+    load_bytecode 'Stream/Sub.pbc'
+    load_bytecode 'Stream/Combiner.pbc'
 
     # create a file stream
-    file = new "Stream::ParrotIO"
+    file = new ['Stream'; 'ParrotIO']
     file."open"( name, 'r' )
 
     # process it one line per read
-    lines = new "Stream::Lines"
+    lines = new ['Stream'; 'Lines']
     assign lines, file
 
     # endless counter
-    counter = new "Stream::Sub"
+    counter = new ['Stream'; 'Sub']
     .const 'Sub' temp = "_counter"
     assign counter, temp
 
     # combine the counter and the file's lines
-    combiner = new "Stream::Combiner"
+    combiner = new ['Stream'; 'Combiner']
     assign combiner, counter
     assign combiner, lines
 
@@ -101,7 +101,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/Filter.pir
==============================================================================
--- branches/pmc_pct/examples/streams/Filter.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/Filter.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -23,17 +23,17 @@
     .local pmc stream
     .local pmc filter
 
-    load_bytecode "Stream/Sub.pir"
-    load_bytecode "Stream/Filter.pir"
+    load_bytecode 'Stream/Sub.pbc'
+    load_bytecode 'Stream/Filter.pbc'
 
     # create the counter stream
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
     # assign its source
     .const 'Sub' temp = "_counter"
     assign stream, temp
 
     # create the filter stream
-    filter = new "Stream::Filter"
+    filter = new ['Stream'; 'Filter']
     # assign its source
     assign filter, stream
     # set the filter sub
@@ -109,7 +109,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/Include.pir
==============================================================================
--- branches/pmc_pct/examples/streams/Include.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/Include.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -17,9 +17,9 @@
 .sub _main
     .local pmc stream
 
-    load_bytecode "Stream/Sub.pir"
+    load_bytecode 'Stream/Sub.pbc'
 
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
 
     # set the stream's source sub
     .const 'Sub' temp = "_counter"
@@ -56,7 +56,7 @@
     if i != 4 goto SKIP
     .local pmc temp
 
-    temp = new "Stream::Sub"
+    temp = new ['Stream'; 'Sub']
 
     .const 'Sub' func = "_included"
     assign temp, func
@@ -85,7 +85,7 @@
     self."write"( "hello" )
 
     # create another stream
-    temp = new "Stream::Sub"
+    temp = new ['Stream'; 'Sub']
     .const 'Sub' func = "_counter2"
     assign temp, func
 
@@ -127,7 +127,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/Lines.pir
==============================================================================
--- branches/pmc_pct/examples/streams/Lines.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/Lines.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -18,17 +18,17 @@
     .local pmc stream
     .local pmc lines
 
-    load_bytecode "Stream/Sub.pir"
-    load_bytecode "Stream/Lines.pir"
+    load_bytecode 'Stream/Sub.pbc'
+    load_bytecode 'Stream/Lines.pbc'
 
     # create a text stream
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
     # set the source
     .const 'Sub' temp = "_text"
     assign stream, temp
 
     # create a lines stream
-    lines = new "Stream::Lines"
+    lines = new ['Stream'; 'Lines']
     # set the source
     assign lines, stream
 
@@ -63,7 +63,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/ParrotIO.pir
==============================================================================
--- branches/pmc_pct/examples/streams/ParrotIO.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/ParrotIO.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -19,10 +19,10 @@
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "library/Stream/ParrotIO.pir"
+    load_bytecode 'Stream/ParrotIO.pbc'
 
     # create the ParrotIO stream
-    stream = new "Stream::ParrotIO"
+    stream = new ['Stream'; 'ParrotIO']
 
     # open this file
     stream."open"( "examples/streams/ParrotIO.pir", 'r' )
@@ -44,7 +44,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/Replay.pir
==============================================================================
--- branches/pmc_pct/examples/streams/Replay.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/Replay.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -4,10 +4,10 @@
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "library/Stream/Writer.pir"
-    load_bytecode "library/Stream/Replay.pir"
+    load_bytecode 'Stream/Writer.pbc'
+    load_bytecode 'Stream/Replay.pbc'
 
-    stream = new "Stream::Writer"
+    stream = new ['Stream'; 'Writer']
     $P0 = get_global "_reader"
     assign stream, $P0
 
@@ -28,7 +28,7 @@
     .local pmc stream3
     .local string str
 
-    stream1 = new "Stream::Replay"
+    stream1 = new ['Stream'; 'Replay']
     assign stream1, self
 
     print "reader start\n"

Modified: branches/pmc_pct/examples/streams/SubCounter.pir
==============================================================================
--- branches/pmc_pct/examples/streams/SubCounter.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/SubCounter.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -17,10 +17,10 @@
 .sub _main
     .local pmc stream
 
-    load_bytecode "library/Stream/Base.pbc"
-    load_bytecode "library/Stream/Sub.pbc"
+    load_bytecode 'Stream/Base.pbc'
+    load_bytecode 'Stream/Sub.pbc'
 
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
 
     # set the stream's source sub
     .const 'Sub' temp = "_counter"
@@ -68,7 +68,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/SubHello.pir
==============================================================================
--- branches/pmc_pct/examples/streams/SubHello.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/SubHello.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -17,9 +17,9 @@
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "Stream/Sub.pir"
+    load_bytecode 'Stream/Sub.pbc'
 
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
 
     # set the stream's source sub
     .const 'Sub' temp = "_hello"
@@ -56,7 +56,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/streams/Writer.pir
==============================================================================
--- branches/pmc_pct/examples/streams/Writer.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/streams/Writer.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -17,9 +17,9 @@
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "library/Stream/Writer.pir"
+    load_bytecode 'Stream/Writer.pbc'
 
-    stream = new "Stream::Writer"
+    stream = new ['Stream'; 'Writer']
 
     # set the stream's source sub
     .const 'Sub' temp = "_reader"
@@ -60,7 +60,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/examples/tutorial/90_writing_tests.pir
==============================================================================
--- branches/pmc_pct/examples/tutorial/90_writing_tests.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/examples/tutorial/90_writing_tests.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -12,7 +12,7 @@
 =cut
 
 .sub _main :main
-    load_bytecode 'library/Test/More.pbc'
+    load_bytecode 'Test/More.pbc'
 
     .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace

Modified: branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/Embed.pm
==============================================================================
--- branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/Embed.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/Embed.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 package Parrot::Embed;
-
+# Copyright (C) 2006-2009, Parrot Foundation.
 # $Id$
 
 use strict;
@@ -48,13 +48,6 @@
 Please report any bugs or feature requests to the Parrot Porters mailing list.
 Someday there may be a CPAN version of this code.  Who knows?
 
-=head1 COPYRIGHT & LICENSE
-
-Copyright (C) 2006-2008, Parrot Foundation / chromatic.
-
-This program is free software; you can redistribute it and/or modify it
-under the same terms as Parrot itself.
-
 =cut
 
 # Local Variables:

Modified: branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/Interpreter.pm
==============================================================================
--- branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/Interpreter.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/Interpreter.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 package Parrot::Interpreter;
-
+# Copyright (C) 2006-2009, Parrot Foundation.
 # $Id$
 
 use strict;
@@ -120,13 +120,6 @@
 Please report any bugs or feature requests to the Parrot Porters mailing list.
 Someday there may be a CPAN version of this code.  Who knows?
 
-=head1 COPYRIGHT & LICENSE
-
-Copyright (C) 2006-2008, Parrot Foundation / chromatic.
-
-This program is free software; you can redistribute it and/or modify it
-under the same terms as Parrot itself.
-
 =cut
 
 # Local Variables:

Modified: branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/PMC.pm
==============================================================================
--- branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/PMC.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/ext/Parrot-Embed/lib/Parrot/PMC.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 package Parrot::PMC;
-
+# Copyright (C) 2006-2009, Parrot Foundation.
 # $Id$
 
 use strict;
@@ -84,13 +84,6 @@
 Please report any bugs or feature requests to the Parrot Porters mailing list.
 Someday there may be a CPAN version of this code.  Who knows?
 
-=head1 COPYRIGHT & LICENSE
-
-Copyright (C) 2006-2008, Parrot Foundation / chromatic.
-
-This program is free software; you can redistribute it and/or modify it
-under the same terms as Parrot itself.
-
 =cut
 
 # Local Variables:

Modified: branches/pmc_pct/include/parrot/exceptions.h
==============================================================================
--- branches/pmc_pct/include/parrot/exceptions.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/exceptions.h	Fri May 15 21:49:40 2009	(r38803)
@@ -283,15 +283,14 @@
 #  define PARROT_ASSERT(x) (x) ? ((void)0) : Parrot_confess(#x, __FILE__, __LINE__)
 #  define PARROT_ASSERT_ARG(x) ((x) ? (0) : (Parrot_confess(#x, __FILE__, __LINE__), 0))
 
-#  ifdef _MSC_VER
-#    define ASSERT_ARGS(a)
-#  else
+#  ifdef __GNUC__
 #    define ASSERT_ARGS(a) ASSERT_ARGS_ ## a ;
-#  endif /* _MSC_VER */
+#  else
+#    define ASSERT_ARGS(a)
+#  endif /* __GNUC__ */
 
 #endif /* NDEBUG */
 
-
 #endif /* PARROT_EXCEPTIONS_H_GUARD */
 
 /*

Modified: branches/pmc_pct/include/parrot/gc_api.h
==============================================================================
--- branches/pmc_pct/include/parrot/gc_api.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/gc_api.h	Fri May 15 21:49:40 2009	(r38803)
@@ -15,36 +15,117 @@
  * Please note: these objects might be bogus */
 #define GC_VERBOSE 0
 
-#include "parrot/gc_mark_sweep.h"
 #include "parrot/parrot.h"
 
-/* Macros for recursively blocking and unblocking GC mark */
-#define Parrot_block_GC_mark(interp) \
-        { \
-            (interp)->arena_base->gc_mark_block_level++; \
-            Parrot_shared_gc_block(interp); \
-        }
-
-#define Parrot_unblock_GC_mark(interp) \
-        if ((interp)->arena_base->gc_mark_block_level) { \
-            (interp)->arena_base->gc_mark_block_level--; \
-            Parrot_shared_gc_unblock(interp); \
-        }
-
-/* Macros for recursively blocking and unblocking GC sweep */
-#define Parrot_block_GC_sweep(interp) \
-        (interp)->arena_base->gc_sweep_block_level++
-
-#define Parrot_unblock_GC_sweep(interp) \
-        if ((interp)->arena_base->gc_sweep_block_level) \
-            (interp)->arena_base->gc_sweep_block_level--
-
-/* Macros for testing if the GC mark and sweep are blocked */
-#define Parrot_is_blocked_GC_mark(interp) \
-        ((interp)->arena_base->gc_mark_block_level)
+/*
+ * we need an alignment that is the same as malloc(3) have for
+ * allocating Buffer items like FLOATVAL (double)
+ * This should be either a config hint or tested
+ */
+#ifdef MALLOC_ALIGNMENT
+#  define BUFFER_ALIGNMENT MALLOC_ALIGNMENT
+#else
+/* or (2 * sizeof (size_t)) */
+#  define BUFFER_ALIGNMENT 8
+#endif
+
+#define BUFFER_ALIGN_1 (BUFFER_ALIGNMENT - 1)
+#define BUFFER_ALIGN_MASK ~BUFFER_ALIGN_1
+
+#define WORD_ALIGN_1 (sizeof (void *) - 1)
+#define WORD_ALIGN_MASK ~WORD_ALIGN_1
+
+/* pool iteration */
+typedef enum {
+    POOL_PMC    = 0x01,
+    POOL_BUFFER = 0x02,
+    POOL_CONST  = 0x04,
+    POOL_ALL    = 0x07
+} pool_iter_enum;
+
+struct Small_Object_Pool;
+struct Small_Object_Arena;
+struct Arenas;
+
+typedef int (*pool_iter_fn)(PARROT_INTERP, struct Small_Object_Pool *, int, void*);
+
+typedef struct Memory_Block {
+    size_t free;
+    size_t size;
+    struct Memory_Block *prev;
+    struct Memory_Block *next;
+    char *start;
+    char *top;
+} Memory_Block;
+
+typedef struct Memory_Pool {
+    Memory_Block *top_block;
+    void (*compact)(PARROT_INTERP, struct Memory_Pool *);
+    size_t minimum_block_size;
+    size_t total_allocated; /* total bytes allocated to this pool */
+    size_t guaranteed_reclaimable;     /* bytes that can definitely be reclaimed*/
+    size_t possibly_reclaimable;     /* bytes that can possibly be reclaimed
+                                      * (above plus COW-freed bytes) */
+    FLOATVAL reclaim_factor; /* minimum percentage we will reclaim */
+} Memory_Pool;
+
+typedef enum {
+    GC_TRACE_FULL,
+    GC_TRACE_ROOT_ONLY,
+    GC_TRACE_SYSTEM_ONLY
+} Parrot_gc_trace_type;
+
+typedef void (*add_free_object_fn_type)(PARROT_INTERP, struct Small_Object_Pool *, void *);
+typedef void * (*get_free_object_fn_type)(PARROT_INTERP, struct Small_Object_Pool *);
+typedef void (*alloc_objects_fn_type)(PARROT_INTERP, struct Small_Object_Pool *);
+typedef void (*gc_object_fn_type)(PARROT_INTERP, struct Small_Object_Pool *, PObj *);
+
+/*
+ * macros used in arena scan code to convert from object pointers
+ * to arena pointers ...
+ */
+
+#if PARROT_GC_GMS
+#  define GC_HEADER_SIZE (sizeof (Gc_gms_hdr))
+#  define PObj_to_ARENA(o) PObj_to_GMSH(o)
+#  define ARENA_to_PObj(p) GMSH_to_PObj((Gc_gms_hdr*)(p))
+#else
+#  define GC_HEADER_SIZE 0
+#  define PObj_to_ARENA(o) (o)
+#  define ARENA_to_PObj(p) (p)
+#endif
 
-#define Parrot_is_blocked_GC_sweep(interp) \
-        ((interp)->arena_base->gc_sweep_block_level)
+/* &gen_from_enum(interpinfo.pasm) prefix(INTERPINFO_) */
+
+typedef enum {
+    TOTAL_MEM_ALLOC = 1,
+    GC_MARK_RUNS,
+    GC_COLLECT_RUNS,
+    ACTIVE_PMCS,
+    ACTIVE_BUFFERS,
+    TOTAL_PMCS,
+    TOTAL_BUFFERS,
+    HEADER_ALLOCS_SINCE_COLLECT,
+    MEM_ALLOCS_SINCE_COLLECT,
+    TOTAL_COPIED,
+    IMPATIENT_PMCS,
+    GC_LAZY_MARK_RUNS,
+    EXTENDED_PMCS,
+    CURRENT_RUNCORE,
+
+    /* interpinfo_p constants */
+    CURRENT_SUB,
+    CURRENT_CONT,
+    CURRENT_OBJECT,
+    CURRENT_LEXPAD,
+
+    /* interpinfo_s constants */
+    EXECUTABLE_FULLNAME,
+    EXECUTABLE_BASENAME,
+    RUNTIME_PREFIX
+} Interpinfo_enum;
+
+/* &end_gen */
 
 #define GC_trace_stack_FLAG    (UINTVAL)(1 << 0)   /* trace system areas and stack */
 #define GC_trace_normal        (UINTVAL)(1 << 0)   /* the same */
@@ -55,195 +136,330 @@
 /* HEADERIZER BEGIN: src/gc/api.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-void add_pmc_ext(PARROT_INTERP, ARGMOD(PMC *pmc))
+PARROT_EXPORT
+void Parrot_block_GC_mark(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void Parrot_block_GC_sweep(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void Parrot_gc_mark_PObj_alive(PARROT_INTERP, ARGMOD(PObj *obj))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*obj);
+
+PARROT_EXPORT
+unsigned int Parrot_is_blocked_GC_mark(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+unsigned int Parrot_is_blocked_GC_sweep(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void Parrot_unblock_GC_mark(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void Parrot_unblock_GC_sweep(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+int Parrot_gc_active_pmcs(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+int Parrot_gc_active_sized_buffers(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_add_pmc_ext(PARROT_INTERP, ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pmc);
 
-void add_pmc_sync(PARROT_INTERP, ARGMOD(PMC *pmc))
+void Parrot_gc_add_pmc_sync(PARROT_INTERP, ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pmc);
 
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-Buffer * new_buffer_header(PARROT_INTERP)
+void Parrot_gc_allocate_buffer_storage_aligned(PARROT_INTERP,
+    ARGOUT(Buffer *buffer),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*buffer);
+
+void Parrot_gc_allocate_string_storage(PARROT_INTERP,
+    ARGOUT(STRING *str),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*str);
+
+void Parrot_gc_cleanup_next_for_GC(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_compact_memory_pool(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_completely_unblock(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+size_t Parrot_gc_count_collect_runs(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+size_t Parrot_gc_count_lazy_mark_runs(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+size_t Parrot_gc_count_mark_runs(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_destroy_header_pools(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_destroy_memory_pools(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+UINTVAL Parrot_gc_extended_pmcs(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_finalize(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_free_bufferlike_header(PARROT_INTERP,
+    ARGMOD(PObj *obj),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*obj);
+
+void Parrot_gc_free_pmc_ext(PARROT_INTERP, ARGMOD(PMC *p))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*p);
+
+void Parrot_gc_free_pmc_header(PARROT_INTERP, ARGMOD(PMC *pmc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*pmc);
+
+void Parrot_gc_free_string_header(PARROT_INTERP, ARGMOD(STRING *s))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*s);
+
+int Parrot_gc_get_pmc_index(PARROT_INTERP, ARGIN(PMC* pmc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+size_t Parrot_gc_headers_alloc_since_last_collect(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+UINTVAL Parrot_gc_impatient_pmcs(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+void Parrot_gc_initialize(PARROT_INTERP, ARGIN(void *stacktop))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+void Parrot_gc_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
+        __attribute__nonnull__(1);
+
+size_t Parrot_gc_mem_alloc_since_last_collect(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_merge_header_pools(
+    ARGMOD(Interp *dest_interp),
+    ARGIN(Interp *source_interp))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*dest_interp);
+
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-void * new_bufferlike_header(PARROT_INTERP, size_t size)
+void * Parrot_gc_new_bufferlike_header(PARROT_INTERP, size_t size)
         __attribute__nonnull__(1);
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-PMC * new_pmc_header(PARROT_INTERP, UINTVAL flags)
+PMC * Parrot_gc_new_pmc_header(PARROT_INTERP, UINTVAL flags)
         __attribute__nonnull__(1);
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-STRING * new_string_header(PARROT_INTERP, UINTVAL flags)
+STRING * Parrot_gc_new_string_header(PARROT_INTERP, UINTVAL flags)
         __attribute__nonnull__(1);
 
-void Parrot_do_gc_run(PARROT_INTERP, UINTVAL flags)
-        __attribute__nonnull__(1);
-
-void Parrot_gc_free_buffer(SHIM_INTERP,
-    ARGMOD(Small_Object_Pool *pool),
-    ARGMOD(PObj *b))
+void Parrot_gc_pmc_needs_early_collection(PARROT_INTERP, ARGMOD(PMC *pmc))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*pool)
-        FUNC_MODIFIES(*b);
+        FUNC_MODIFIES(*pmc);
 
-void Parrot_gc_free_buffer_malloc(SHIM_INTERP,
-    SHIM(Small_Object_Pool *pool),
-    ARGMOD(PObj *b))
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*b);
+PARROT_WARN_UNUSED_RESULT
+int Parrot_gc_ptr_in_memory_pool(PARROT_INTERP, ARGIN(void *bufstart))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
 
-void Parrot_gc_free_pmc(PARROT_INTERP,
-    SHIM(Small_Object_Pool *pool),
-    ARGMOD(PObj *p))
+int Parrot_gc_ptr_is_pmc(PARROT_INTERP, ARGIN(void *ptr))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*p);
+        __attribute__nonnull__(2);
 
-void Parrot_gc_free_pmc_ext(PARROT_INTERP, ARGMOD(PMC *p))
+void Parrot_gc_reallocate_buffer_storage(PARROT_INTERP,
+    ARGMOD(Buffer *buffer),
+    size_t newsize)
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        FUNC_MODIFIES(*p);
+        FUNC_MODIFIES(*buffer);
 
-void Parrot_gc_free_sysmem(SHIM_INTERP,
-    SHIM(Small_Object_Pool *pool),
-    ARGMOD(PObj *b))
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*b);
+void Parrot_gc_reallocate_string_storage(PARROT_INTERP,
+    ARGMOD(STRING *str),
+    size_t newsize)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*str);
 
-void Parrot_gc_ms_run_init(PARROT_INTERP)
+UINTVAL Parrot_gc_total_copied(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-void Parrot_gc_profile_end(PARROT_INTERP, int what)
+size_t Parrot_gc_total_memory_allocated(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-void Parrot_gc_profile_start(PARROT_INTERP)
+int Parrot_gc_total_pmcs(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-#define ASSERT_ARGS_add_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+int Parrot_gc_total_sized_buffers(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+#define ASSERT_ARGS_Parrot_block_GC_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_block_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_mark_PObj_alive __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(obj)
+#define ASSERT_ARGS_Parrot_is_blocked_GC_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_is_blocked_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_unblock_GC_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_unblock_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_active_pmcs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_active_sized_buffers \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_add_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
-#define ASSERT_ARGS_add_pmc_sync __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_add_pmc_sync __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
-#define ASSERT_ARGS_new_buffer_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_allocate_buffer_storage_aligned \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(buffer)
+#define ASSERT_ARGS_Parrot_gc_allocate_string_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(str)
+#define ASSERT_ARGS_Parrot_gc_cleanup_next_for_GC __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_new_bufferlike_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_compact_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_new_pmc_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_completely_unblock __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_new_string_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_count_collect_runs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_do_gc_run __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_count_lazy_mark_runs \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_gc_free_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(pool) \
-    || PARROT_ASSERT_ARG(b)
-#define ASSERT_ARGS_Parrot_gc_free_buffer_malloc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(b)
-#define ASSERT_ARGS_Parrot_gc_free_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_count_mark_runs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_destroy_header_pools \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_destroy_memory_pools \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_extended_pmcs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_finalize __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_free_bufferlike_header \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(p)
+    || PARROT_ASSERT_ARG(obj)
 #define ASSERT_ARGS_Parrot_gc_free_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(p)
-#define ASSERT_ARGS_Parrot_gc_free_sysmem __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(b)
-#define ASSERT_ARGS_Parrot_gc_ms_run_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_free_pmc_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmc)
+#define ASSERT_ARGS_Parrot_gc_free_string_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(s)
+#define ASSERT_ARGS_Parrot_gc_get_pmc_index __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmc)
+#define ASSERT_ARGS_Parrot_gc_headers_alloc_since_last_collect \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_gc_profile_end __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_impatient_pmcs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_gc_profile_start __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_initialize __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(stacktop)
+#define ASSERT_ARGS_Parrot_gc_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: src/gc/api.c */
-
-/* GC subsystem init functions */
-/* HEADERIZER BEGIN: src/gc/generational_ms.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-
-PARROT_EXPORT
-void Parrot_gc_gms_init(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_EXPORT
-void parrot_gc_gms_pobject_lives(PARROT_INTERP, ARGMOD(PObj *obj))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*obj);
-
-void parrot_gc_gms_wb(PARROT_INTERP,
-    ARGIN(PMC *agg),
-    ARGIN(void *old),
-    ARGIN(void *_new))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4);
-
-void parrot_gc_gms_wb_key(PARROT_INTERP,
-    ARGIN(PMC *agg),
-    ARGIN(void *old),
-    ARGIN(void *old_key),
-    ARGIN(void *_new),
-    ARGIN(void *new_key))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        __attribute__nonnull__(5)
-        __attribute__nonnull__(6);
-
-#define ASSERT_ARGS_Parrot_gc_gms_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_mem_alloc_since_last_collect \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_merge_header_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(dest_interp) \
+    || PARROT_ASSERT_ARG(source_interp)
+#define ASSERT_ARGS_Parrot_gc_new_bufferlike_header \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_parrot_gc_gms_pobject_lives __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_Parrot_gc_new_pmc_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_new_string_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_pmc_needs_early_collection \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(obj)
-#define ASSERT_ARGS_parrot_gc_gms_wb __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+    || PARROT_ASSERT_ARG(pmc)
+#define ASSERT_ARGS_Parrot_gc_ptr_in_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(agg) \
-    || PARROT_ASSERT_ARG(old) \
-    || PARROT_ASSERT_ARG(_new)
-#define ASSERT_ARGS_parrot_gc_gms_wb_key __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(agg) \
-    || PARROT_ASSERT_ARG(old) \
-    || PARROT_ASSERT_ARG(old_key) \
-    || PARROT_ASSERT_ARG(_new) \
-    || PARROT_ASSERT_ARG(new_key)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: src/gc/generational_ms.c */
-
-/* HEADERIZER BEGIN: src/gc/incremental_ms.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-
-void Parrot_gc_ims_init(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-void Parrot_gc_ims_wb(PARROT_INTERP, ARGMOD(PMC *agg), ARGMOD(PMC *_new))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*agg)
-        FUNC_MODIFIES(*_new);
-
-#define ASSERT_ARGS_Parrot_gc_ims_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_gc_ims_wb __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+    || PARROT_ASSERT_ARG(bufstart)
+#define ASSERT_ARGS_Parrot_gc_ptr_is_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(agg) \
-    || PARROT_ASSERT_ARG(_new)
+    || PARROT_ASSERT_ARG(ptr)
+#define ASSERT_ARGS_Parrot_gc_reallocate_buffer_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(buffer)
+#define ASSERT_ARGS_Parrot_gc_reallocate_string_storage \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(str)
+#define ASSERT_ARGS_Parrot_gc_total_copied __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_total_memory_allocated \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_total_pmcs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_total_sized_buffers __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: src/gc/incremental_ms.c */
+/* HEADERIZER END: src/gc/api.c */
+
+/* DEPRECATED. pobject_lives is being renamed to Parrot_gc_mark_PObj_alive.
+   this macro is provided for compatibility until version 1.4 or later when
+   it can be removed per the deprecation policy. See TT #664 for details */
+#define pobject_lives Parrot_gc_mark_PObj_alive
 
 /* write barrier */
 #if PARROT_GC_MS

Deleted: branches/pmc_pct/include/parrot/gc_mark_sweep.h
==============================================================================
--- branches/pmc_pct/include/parrot/gc_mark_sweep.h	Fri May 15 21:49:40 2009	(r38802)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,269 +0,0 @@
-/*
- * $Id$
- * Copyright (C) 2002-2008, Parrot Foundation.
- */
-
-#ifndef PARROT_GC_MARK_SWEEP_H_GUARD
-#define PARROT_GC_MARK_SWEEP_H_GUARD
-
-#  include "parrot/parrot.h"
-
-typedef struct Small_Object_Arena {
-    size_t                     used;
-    size_t                     total_objects;
-    struct Small_Object_Arena *prev;
-    struct Small_Object_Arena *next;
-    void                      *start_objects;
-} Small_Object_Arena;
-
-struct Small_Object_Pool;
-
-typedef enum {
-    GC_TRACE_FULL,
-    GC_TRACE_ROOT_ONLY,
-    GC_TRACE_SYSTEM_ONLY
-} Parrot_gc_trace_type;
-
-typedef void (*add_free_object_fn_type)(PARROT_INTERP, struct Small_Object_Pool *, void *);
-typedef void * (*get_free_object_fn_type)(PARROT_INTERP, struct Small_Object_Pool *);
-typedef void (*alloc_objects_fn_type)(PARROT_INTERP, struct Small_Object_Pool *);
-typedef void (*gc_object_fn_type)(PARROT_INTERP, struct Small_Object_Pool *, PObj *);
-
-#if PARROT_GC_GMS
-/*
- * all objects have this header in front of the actual
- * object pointer. The prev/next pointers chain all existing
- * objects for one pool (sizeclass) together.
- *
- * XXX this could lead to unaligned FLOATVALs in the adjacent PMC
- *     if that's true either insert a dummy or reorder PMC members
- *     ??? How is that possible?
- */
-typedef struct _gc_gms_hdr {
-    struct _gc_gms_hdr *prev;
-    struct _gc_gms_hdr *next;
-    struct _gc_gms_gen *gen;
-    void *gc_dummy_align;       /* see above */
-} Gc_gms_hdr;
-
-#  define PObj_to_GMSH(o) (((Gc_gms_hdr*)(o))-1)
-#  define GMSH_to_PObj(p) ((PObj*) ((p)+1))
-
-/* the structure uses 2 ptrs itself */
-#  define GC_GMS_STORE_SIZE (64-2)
-
-typedef struct _gc_gms_hdr_store {
-    struct _gc_gms_hdr_store *next;
-    Gc_gms_hdr **ptr;                           /* insert location */
-    Gc_gms_hdr * (store[GC_GMS_STORE_SIZE]);    /* array of hdr pointers */
-} Gc_gms_hdr_store;
-
-typedef struct _gc_gms_hdr_list {
-    Gc_gms_hdr_store *first;
-    Gc_gms_hdr_store *last;
-} Gc_gms_hdr_list;
-
-
-/*
- * all objects belong to one generation
- */
-typedef struct _gc_gms_gen {
-    UINTVAL gen_no;                     /* generation number */
-    UINTVAL timely_destruct_obj_sofar;  /* sum up to this generation */
-    UINTVAL black_color;                /* live color of this generation */
-    struct _gc_gms_hdr *first;          /* first header in this generation */
-    struct _gc_gms_hdr *last;           /* last header in this generation */
-    struct _gc_gms_hdr *fin;            /* need destruction/finalization */
-    struct Small_Object_Pool *pool;     /* where this generation belongs to */
-    Gc_gms_hdr_list igp;                /* IGPs for this generation */
-    UINTVAL n_possibly_dead;            /* overwritten count */
-    UINTVAL n_objects;                  /* live objects count */
-    struct _gc_gms_gen *prev;
-    struct _gc_gms_gen *next;
-} Gc_gms_gen;
-
-#endif /* PARROT_GC_GMS */
-
-/* Tracked resource pool */
-typedef struct Small_Object_Pool {
-    Small_Object_Arena *last_Arena;
-    /* Size in bytes of an individual pool item. This size may include
-     * a GC-system specific GC header.
-     * See the macros below.
-     */
-    size_t object_size;
-    size_t objects_per_alloc;
-    size_t total_objects;
-    size_t num_free_objects;    /* number of resources in the free pool */
-    int skip;
-    size_t replenish_level;
-    void *free_list;
-    /* adds a free object to the pool's free list  */
-    add_free_object_fn_type     add_free_object;
-    get_free_object_fn_type     get_free_object;
-    alloc_objects_fn_type       alloc_objects;
-    alloc_objects_fn_type       more_objects;
-    gc_object_fn_type           gc_object;
-    /* gets and removes a free object from the pool's free list */
-    /* allocates more objects */
-    struct Memory_Pool *mem_pool;
-    size_t start_arena_memory;
-    size_t end_arena_memory;
-    const char *name;
-#if PARROT_GC_GMS
-    struct _gc_gms_hdr marker;          /* limit of list */
-    struct _gc_gms_hdr *black;          /* alive */
-    struct _gc_gms_hdr *black_fin;      /* alive, needs destruction */
-    struct _gc_gms_hdr *gray;           /* to be scanned */
-    struct _gc_gms_hdr *white;          /* unprocessed */
-    struct _gc_gms_hdr *white_fin;      /* unprocesse, needs destruction */
-
-    struct _gc_gms_gen *first_gen;      /* linked list of generations */
-    struct _gc_gms_gen *last_gen;
-
-#endif
-} Small_Object_Pool;
-
-/*
- * macros used in arena scan code to convert from object pointers
- * to arena pointers ...
- */
-
-#if PARROT_GC_GMS
-#  define GC_HEADER_SIZE (sizeof (Gc_gms_hdr))
-#  define PObj_to_ARENA(o) PObj_to_GMSH(o)
-#  define ARENA_to_PObj(p) GMSH_to_PObj((Gc_gms_hdr*)(p))
-#else
-#  define GC_HEADER_SIZE 0
-#  define PObj_to_ARENA(o) (o)
-#  define ARENA_to_PObj(p) (p)
-#endif
-
-
-/* HEADERIZER BEGIN: src/gc/mark_sweep.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-
-PARROT_EXPORT
-void pobject_lives(PARROT_INTERP, ARGMOD(PObj *obj))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*obj);
-
-PARROT_WARN_UNUSED_RESULT
-INTVAL contained_in_pool(
-    ARGIN(const Small_Object_Pool *pool),
-    ARGIN(const void *ptr))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-void gc_pmc_ext_pool_init(ARGMOD(Small_Object_Pool *pool))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*pool);
-
-PARROT_MALLOC
-PARROT_CANNOT_RETURN_NULL
-Small_Object_Pool * new_small_object_pool(
-    size_t object_size,
-    size_t objects_per_alloc);
-
-void Parrot_add_to_free_list(PARROT_INTERP,
-    ARGMOD(Small_Object_Pool *pool),
-    ARGMOD(Small_Object_Arena *arena))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*pool)
-        FUNC_MODIFIES(*arena);
-
-void Parrot_append_arena_in_pool(PARROT_INTERP,
-    ARGMOD(Small_Object_Pool *pool),
-    ARGMOD(Small_Object_Arena *new_arena),
-    size_t size)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*pool)
-        FUNC_MODIFIES(*new_arena);
-
-void Parrot_gc_clear_live_bits(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-void Parrot_gc_ms_init(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-void Parrot_gc_ms_run(PARROT_INTERP, UINTVAL flags)
-        __attribute__nonnull__(1);
-
-void Parrot_gc_sweep(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*pool);
-
-int Parrot_gc_trace_children(PARROT_INTERP, size_t how_many)
-        __attribute__nonnull__(1);
-
-int Parrot_gc_trace_root(PARROT_INTERP, Parrot_gc_trace_type trace)
-        __attribute__nonnull__(1);
-
-int Parrot_is_const_pmc(PARROT_INTERP, ARGIN(const PMC *pmc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-void Parrot_small_object_pool_merge(PARROT_INTERP,
-    ARGMOD(Small_Object_Pool *dest),
-    ARGMOD(Small_Object_Pool *source))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*dest)
-        FUNC_MODIFIES(*source);
-
-#define ASSERT_ARGS_pobject_lives __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(obj)
-#define ASSERT_ARGS_contained_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(pool) \
-    || PARROT_ASSERT_ARG(ptr)
-#define ASSERT_ARGS_gc_pmc_ext_pool_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(pool)
-#define ASSERT_ARGS_new_small_object_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
-#define ASSERT_ARGS_Parrot_add_to_free_list __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pool) \
-    || PARROT_ASSERT_ARG(arena)
-#define ASSERT_ARGS_Parrot_append_arena_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pool) \
-    || PARROT_ASSERT_ARG(new_arena)
-#define ASSERT_ARGS_Parrot_gc_clear_live_bits __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_gc_ms_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_gc_ms_run __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_gc_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pool)
-#define ASSERT_ARGS_Parrot_gc_trace_children __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_gc_trace_root __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_is_const_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pmc)
-#define ASSERT_ARGS_Parrot_small_object_pool_merge \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(dest) \
-    || PARROT_ASSERT_ARG(source)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: src/gc/mark_sweep.c */
-
-#endif /* PARROT_GC_MARK_SWEEP_H_GUARD */
-
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */

Deleted: branches/pmc_pct/include/parrot/gc_pools.h
==============================================================================
--- branches/pmc_pct/include/parrot/gc_pools.h	Fri May 15 21:49:40 2009	(r38802)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,179 +0,0 @@
-/* gc_pools.h
- *  Copyright (C) 2001-2009, Parrot Foundation.
- *  SVN Info
- *     $Id$
- *  Overview:
- *     Handles pool management for GC.
- *  Data Structure and Algorithms:
- *  History:
- *  Notes:
- *  References:
- */
-
-#ifndef PARROT_GC_POOLS_H_GUARD
-#define PARROT_GC_POOLS_H_GUARD
-
-#include "parrot/parrot.h"
-
-/*
- * we need an alignment that is the same as malloc(3) have for
- * allocating Buffer items like FLOATVAL (double)
- * This should be either a config hint or tested
- */
-#ifdef MALLOC_ALIGNMENT
-#  define BUFFER_ALIGNMENT MALLOC_ALIGNMENT
-#else
-/* or (2 * sizeof (size_t)) */
-#  define BUFFER_ALIGNMENT 8
-#endif
-
-#define BUFFER_ALIGN_1 (BUFFER_ALIGNMENT - 1)
-#define BUFFER_ALIGN_MASK ~BUFFER_ALIGN_1
-
-#define WORD_ALIGN_1 (sizeof (void *) - 1)
-#define WORD_ALIGN_MASK ~WORD_ALIGN_1
-
-/* pool iteration */
-typedef enum {
-    POOL_PMC    = 0x01,
-    POOL_BUFFER = 0x02,
-    POOL_CONST  = 0x04,
-    POOL_ALL    = 0x07
-} pool_iter_enum;
-
-typedef int (*pool_iter_fn)(PARROT_INTERP, struct Small_Object_Pool *, int, void*);
-
-
-/* HEADERIZER BEGIN: src/gc/pools.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-Small_Object_Pool * get_bufferlike_pool(PARROT_INTERP, size_t buffer_size)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-void * get_free_buffer(PARROT_INTERP, ARGIN(Small_Object_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-size_t get_max_buffer_address(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-size_t get_max_pmc_address(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-size_t get_min_buffer_address(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-size_t get_min_pmc_address(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-int is_buffer_ptr(PARROT_INTERP, ARGIN(const void *ptr))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-int is_pmc_ptr(PARROT_INTERP, ARGIN(const void *ptr))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-Small_Object_Pool * new_buffer_pool(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-Small_Object_Pool * new_bufferlike_pool(PARROT_INTERP,
-    size_t actual_buffer_size)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-Small_Object_Pool * new_pmc_pool(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-Small_Object_Pool * new_string_pool(PARROT_INTERP, INTVAL constant)
-        __attribute__nonnull__(1);
-
-void Parrot_destroy_header_pools(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_IGNORABLE_RESULT
-int /*@alt void@*/
-Parrot_forall_header_pools(PARROT_INTERP,
-    int flag,
-    ARGIN_NULLOK(void *arg),
-    NOTNULL(pool_iter_fn func))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(4);
-
-void Parrot_initialize_header_pools(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-void Parrot_merge_header_pools(
-    ARGMOD(Interp *dest_interp),
-    ARGIN(Interp *source_interp))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*dest_interp);
-
-#define ASSERT_ARGS_get_bufferlike_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_get_free_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pool)
-#define ASSERT_ARGS_get_max_buffer_address __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_get_max_pmc_address __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_get_min_buffer_address __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_get_min_pmc_address __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_is_buffer_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(ptr)
-#define ASSERT_ARGS_is_pmc_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(ptr)
-#define ASSERT_ARGS_new_buffer_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_new_bufferlike_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_new_pmc_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_new_string_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_destroy_header_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_forall_header_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(func)
-#define ASSERT_ARGS_Parrot_initialize_header_pools \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_merge_header_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(dest_interp) \
-    || PARROT_ASSERT_ARG(source_interp)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: src/gc/pools.c */
-
-
-#endif /* PARROT_GC_POOLS_H_GUARD */
-
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */

Modified: branches/pmc_pct/include/parrot/hash.h
==============================================================================
--- branches/pmc_pct/include/parrot/hash.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/hash.h	Fri May 15 21:49:40 2009	(r38803)
@@ -81,8 +81,7 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_EXPORT
-void parrot_dump_hash(SHIM_INTERP, ARGIN(const Hash *hash))
-        __attribute__nonnull__(2);
+void parrot_dump_hash(SHIM_INTERP, SHIM(const Hash *hash));
 
 PARROT_EXPORT
 void parrot_hash_clone(PARROT_INTERP,
@@ -160,8 +159,7 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
-INTVAL parrot_hash_size(PARROT_INTERP, ARGIN(const Hash *hash))
-        __attribute__nonnull__(1)
+INTVAL parrot_hash_size(SHIM_INTERP, ARGIN(const Hash *hash))
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
@@ -242,8 +240,7 @@
         __attribute__nonnull__(4)
         __attribute__nonnull__(5);
 
-#define ASSERT_ARGS_parrot_dump_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(hash)
+#define ASSERT_ARGS_parrot_dump_hash __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_parrot_hash_clone __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(hash) \
@@ -275,8 +272,7 @@
     || PARROT_ASSERT_ARG(hash) \
     || PARROT_ASSERT_ARG(key)
 #define ASSERT_ARGS_parrot_hash_size __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(hash)
+       PARROT_ASSERT_ARG(hash)
 #define ASSERT_ARGS_parrot_hash_visit __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(hash) \

Modified: branches/pmc_pct/include/parrot/interpreter.h
==============================================================================
--- branches/pmc_pct/include/parrot/interpreter.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/interpreter.h	Fri May 15 21:49:40 2009	(r38803)
@@ -580,6 +580,7 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 INTVAL interpinfo(PARROT_INTERP, INTVAL what)
         __attribute__nonnull__(1);
 

Modified: branches/pmc_pct/include/parrot/io.h
==============================================================================
--- branches/pmc_pct/include/parrot/io.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/io.h	Fri May 15 21:49:40 2009	(r38803)
@@ -184,7 +184,9 @@
         FUNC_MODIFIES(*pmc);
 
 PARROT_EXPORT
-INTVAL Parrot_io_fprintf(PARROT_INTERP,
+PARROT_IGNORABLE_RESULT
+INTVAL /*@alt void@*/
+Parrot_io_fprintf(PARROT_INTERP,
     ARGMOD(PMC *pmc),
     ARGIN(const char *s),
     ...)
@@ -201,6 +203,7 @@
         FUNC_MODIFIES(*pmc);
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 INTVAL Parrot_io_is_closed(PARROT_INTERP, ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -214,6 +217,7 @@
         FUNC_MODIFIES(*pmc);
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 PIOOFF_T Parrot_io_make_offset(INTVAL offset);
 
 PARROT_EXPORT
@@ -233,6 +237,7 @@
         __attribute__nonnull__(3);
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 INTVAL Parrot_io_peek(PARROT_INTERP,
     ARGMOD(PMC *pmc),
     ARGOUT(STRING **buffer))
@@ -243,7 +248,11 @@
         FUNC_MODIFIES(*buffer);
 
 PARROT_EXPORT
-INTVAL Parrot_io_printf(PARROT_INTERP, ARGIN(const char *s), ...)
+PARROT_IGNORABLE_RESULT
+INTVAL /*@alt void@*/
+Parrot_io_printf(PARROT_INTERP,
+    ARGIN(const char *s),
+    ...)
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -296,6 +305,7 @@
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 PMC * Parrot_io_stdhandle(PARROT_INTERP,
     INTVAL fileno,
@@ -332,7 +342,10 @@
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*pmc);
 
+PARROT_WARN_UNUSED_RESULT
 PIOOFF_T Parrot_io_make_offset32(INTVAL hi, INTVAL lo);
+
+PARROT_WARN_UNUSED_RESULT
 PIOOFF_T Parrot_io_make_offset_pmc(PARROT_INTERP, ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)

Modified: branches/pmc_pct/include/parrot/memory.h
==============================================================================
--- branches/pmc_pct/include/parrot/memory.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/memory.h	Fri May 15 21:49:40 2009	(r38803)
@@ -111,10 +111,6 @@
     int line)
         __attribute__nonnull__(4);
 
-void mem_setup_allocator(PARROT_INTERP, ARGIN(void *stacktop))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
 #define ASSERT_ARGS_mem_sys_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_mem_sys_allocate_zeroed __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_mem_sys_free __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
@@ -130,9 +126,6 @@
        PARROT_ASSERT_ARG(file)
 #define ASSERT_ARGS_mem__internal_realloc_zeroed __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(file)
-#define ASSERT_ARGS_mem_setup_allocator __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(stacktop)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/gc/memory.c */
 

Modified: branches/pmc_pct/include/parrot/misc.h
==============================================================================
--- branches/pmc_pct/include/parrot/misc.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/misc.h	Fri May 15 21:49:40 2009	(r38803)
@@ -268,12 +268,12 @@
 
     typedef struct sprintf_obj SPRINTF_OBJ;
 
-    typedef STRING *(*sprintf_getchar_t) (PARROT_INTERP, INTVAL, SPRINTF_OBJ *);
-    typedef HUGEINTVAL(*sprintf_getint_t) (PARROT_INTERP, INTVAL, SPRINTF_OBJ *);
-    typedef UHUGEINTVAL(*sprintf_getuint_t) (PARROT_INTERP, INTVAL, SPRINTF_OBJ *);
-    typedef HUGEFLOATVAL(*sprintf_getfloat_t) (PARROT_INTERP, INTVAL, SPRINTF_OBJ *);
-    typedef STRING *(*sprintf_getstring_t) (PARROT_INTERP, INTVAL, SPRINTF_OBJ *);
-    typedef void *(*sprintf_getptr_t) (PARROT_INTERP, INTVAL, SPRINTF_OBJ *);
+    typedef STRING *(*sprintf_getchar_t)       (PARROT_INTERP, INTVAL, ARGIN(SPRINTF_OBJ *));
+    typedef HUGEINTVAL(*sprintf_getint_t)      (PARROT_INTERP, INTVAL, ARGIN(SPRINTF_OBJ *));
+    typedef UHUGEINTVAL(*sprintf_getuint_t)    (PARROT_INTERP, INTVAL, ARGIN(SPRINTF_OBJ *));
+    typedef HUGEFLOATVAL(*sprintf_getfloat_t)  (PARROT_INTERP, INTVAL, ARGIN(SPRINTF_OBJ *));
+    typedef STRING *(*sprintf_getstring_t)     (PARROT_INTERP, INTVAL, ARGIN(SPRINTF_OBJ *));
+    typedef void *(*sprintf_getptr_t)          (PARROT_INTERP, INTVAL, ARGIN(SPRINTF_OBJ *));
 
     struct sprintf_obj {
         void *data;

Modified: branches/pmc_pct/include/parrot/multidispatch.h
==============================================================================
--- branches/pmc_pct/include/parrot/multidispatch.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/multidispatch.h	Fri May 15 21:49:40 2009	(r38803)
@@ -51,6 +51,7 @@
         STRING *multi_name;
         STRING *short_sig;
         STRING *full_sig;
+        STRING *ns_name;
         funcptr_t func_ptr;
 } multi_func_list;
 

Modified: branches/pmc_pct/include/parrot/packfile.h
==============================================================================
--- branches/pmc_pct/include/parrot/packfile.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/packfile.h	Fri May 15 21:49:40 2009	(r38803)
@@ -464,7 +464,7 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
-INTVAL PackFile_add_segment(SHIM_INTERP,
+void PackFile_add_segment(SHIM_INTERP,
     ARGMOD(PackFile_Directory *dir),
     ARGIN(PackFile_Segment *seg))
         __attribute__nonnull__(2)
@@ -483,21 +483,18 @@
         FUNC_MODIFIES(*self);
 
 PARROT_EXPORT
-void PackFile_Annotations_add_group(PARROT_INTERP,
+void PackFile_Annotations_add_group(SHIM_INTERP,
     ARGMOD(PackFile_Annotations *self),
     opcode_t offset)
-        __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*self);
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
-PackFile_Segment * PackFile_Annotations_new(PARROT_INTERP,
-    ARGIN(struct PackFile *pf),
+PackFile_Segment * PackFile_Annotations_new(SHIM_INTERP,
+    SHIM(struct PackFile *pf),
     SHIM(const char *name),
-    NULLOK(int add))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+    NULLOK(int add));
 
 PARROT_EXPORT
 void PackFile_Constant_destroy(SHIM_INTERP,
@@ -619,7 +616,7 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
-INTVAL PackFile_funcs_register(SHIM_INTERP,
+void PackFile_funcs_register(SHIM_INTERP,
     ARGOUT(PackFile *pf),
     UINTVAL type,
     const PackFile_funcs funcs)
@@ -815,6 +812,7 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 opcode_t * PackFile_Annotations_pack(PARROT_INTERP,
     ARGIN(PackFile_Segment *seg),
@@ -824,9 +822,9 @@
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*cursor);
 
-size_t PackFile_Annotations_packed_size(PARROT_INTERP,
+PARROT_WARN_UNUSED_RESULT
+size_t PackFile_Annotations_packed_size(SHIM_INTERP,
     ARGIN(PackFile_Segment *seg))
-        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
@@ -853,11 +851,8 @@
     || PARROT_ASSERT_ARG(self)
 #define ASSERT_ARGS_PackFile_Annotations_add_group \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(self)
-#define ASSERT_ARGS_PackFile_Annotations_new __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pf)
+       PARROT_ASSERT_ARG(self)
+#define ASSERT_ARGS_PackFile_Annotations_new __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_PackFile_Constant_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_PackFile_Constant_new __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_PackFile_Constant_pack_size __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -984,8 +979,7 @@
     || PARROT_ASSERT_ARG(cursor)
 #define ASSERT_ARGS_PackFile_Annotations_packed_size \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(seg)
+       PARROT_ASSERT_ARG(seg)
 #define ASSERT_ARGS_PackFile_Annotations_unpack __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(seg) \

Modified: branches/pmc_pct/include/parrot/parrot.h
==============================================================================
--- branches/pmc_pct/include/parrot/parrot.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/parrot.h	Fri May 15 21:49:40 2009	(r38803)
@@ -283,9 +283,6 @@
 #include "parrot/pmc.h"
 #include "parrot/events.h"
 #include "parrot/gc_api.h"
-#include "parrot/gc_mark_sweep.h"
-#include "parrot/gc_pools.h"
-#include "parrot/resources.h"
 #include "parrot/string_funcs.h"
 #include "parrot/misc.h"
 #include "parrot/sub.h"

Deleted: branches/pmc_pct/include/parrot/resources.h
==============================================================================
--- branches/pmc_pct/include/parrot/resources.h	Fri May 15 21:49:40 2009	(r38802)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,224 +0,0 @@
-/* resources.h
- *  Copyright (C) 2001-2007, Parrot Foundation.
- *  SVN Info
- *     $Id$
- *  Overview:
- *     Defines the resource allocation API
- *  Data Structure and Algorithms:
- *  History:
- *  Notes:
- *  References:
- */
-
-#ifndef PARROT_RESOURCES_H_GUARD
-#define PARROT_RESOURCES_H_GUARD
-
-#include "parrot/parrot.h"
-
-typedef struct Memory_Block {
-    size_t free;
-    size_t size;
-    struct Memory_Block *prev;
-    struct Memory_Block *next;
-    char *start;
-    char *top;
-} Memory_Block;
-
-typedef struct Memory_Pool {
-    Memory_Block *top_block;
-    void (*compact)(PARROT_INTERP, struct Memory_Pool *);
-    size_t minimum_block_size;
-    size_t total_allocated; /* total bytes allocated to this pool */
-    size_t guaranteed_reclaimable;     /* bytes that can definitely be reclaimed*/
-    size_t possibly_reclaimable;     /* bytes that can possibly be reclaimed
-                                      * (above plus COW-freed bytes) */
-    FLOATVAL reclaim_factor; /* minimum percentage we will reclaim */
-} Memory_Pool;
-
-
-/* HEADERIZER BEGIN: src/gc/resources.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-
-void Parrot_allocate(PARROT_INTERP, ARGOUT(Buffer *buffer), size_t size)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*buffer);
-
-void Parrot_allocate_aligned(PARROT_INTERP,
-    ARGOUT(Buffer *buffer),
-    size_t size)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*buffer);
-
-void Parrot_allocate_string(PARROT_INTERP, ARGOUT(STRING *str), size_t size)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*str);
-
-void Parrot_destroy_memory_pools(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-void Parrot_go_collect(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-int Parrot_in_memory_pool(PARROT_INTERP, ARGIN(void *bufstart))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-void Parrot_initialize_memory_pools(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-void Parrot_merge_memory_pools(
-    ARGIN(Interp *dest_interp),
-    ARGIN(Interp *source_interp))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-void Parrot_reallocate(PARROT_INTERP,
-    ARGMOD(Buffer *buffer),
-    size_t newsize)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*buffer);
-
-void Parrot_reallocate_string(PARROT_INTERP,
-    ARGMOD(STRING *str),
-    size_t newsize)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*str);
-
-#define ASSERT_ARGS_Parrot_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(buffer)
-#define ASSERT_ARGS_Parrot_allocate_aligned __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(buffer)
-#define ASSERT_ARGS_Parrot_allocate_string __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(str)
-#define ASSERT_ARGS_Parrot_destroy_memory_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_go_collect __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_in_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(bufstart)
-#define ASSERT_ARGS_Parrot_initialize_memory_pools \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_merge_memory_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(dest_interp) \
-    || PARROT_ASSERT_ARG(source_interp)
-#define ASSERT_ARGS_Parrot_reallocate __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(buffer)
-#define ASSERT_ARGS_Parrot_reallocate_string __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(str)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: src/gc/resources.c */
-
-typedef struct Arenas {
-    Memory_Pool *memory_pool;
-    Memory_Pool *constant_string_pool;
-    struct Small_Object_Pool *string_header_pool;
-    struct Small_Object_Pool *pmc_pool;
-    struct Small_Object_Pool *pmc_ext_pool;
-    struct Small_Object_Pool *constant_pmc_pool;
-    struct Small_Object_Pool *buffer_header_pool;
-    struct Small_Object_Pool *constant_string_header_pool;
-    struct Small_Object_Pool **sized_header_pools;
-    size_t num_sized;
-    /*
-     * function slots that each subsystem must provide
-     */
-    void (*do_gc_mark)(PARROT_INTERP, UINTVAL flags);
-    void (*finalize_gc_system) (PARROT_INTERP);
-    void (*init_pool)(PARROT_INTERP, struct Small_Object_Pool *);
-    /*
-     * statistics for GC
-     */
-    size_t  gc_mark_runs;       /* Number of times we've done a mark run*/
-    size_t  gc_lazy_mark_runs;  /* Number of successful lazy mark runs */
-    size_t  gc_collect_runs;    /* Number of times we've done a memory
-                                   compaction */
-    size_t  mem_allocs_since_last_collect;      /* The number of memory
-                                                 * allocations from the
-                                                 * system since the last
-                                                 * compaction run */
-    size_t  header_allocs_since_last_collect;   /* The number of header
-                                                 * blocks allocated from
-                                                 * the system since the last
-                                                 * GC run */
-    size_t  memory_allocated;     /* The total amount of
-                                   * allocatable memory
-                                   * allocated. Doesn't count
-                                   * memory for headers or
-                                   * internal structures or
-                                   * anything */
-    UINTVAL memory_collected;     /* Total amount of memory copied
-                                     during collection */
-    UINTVAL num_early_gc_PMCs;    /* how many PMCs want immediate destruction */
-    UINTVAL num_early_PMCs_seen;  /* how many such PMCs has GC seen */
-    UINTVAL num_extended_PMCs;    /* active PMCs having pmc_ext */
-    PMC* gc_mark_start;           /* first PMC marked during a GC run */
-    PMC* gc_mark_ptr;             /* last PMC marked during a GC run */
-    PMC* gc_trace_ptr;            /* last PMC trace_children was called on */
-    int lazy_gc;                  /* flag that indicates whether we should stop
-                                     when we've seen all impatient PMCs */
-    /*
-     * GC blocking
-     */
-    UINTVAL gc_mark_block_level;  /* How many outstanding GC block
-                                     requests are there? */
-    UINTVAL gc_sweep_block_level; /* How many outstanding GC block
-                                     requests are there? */
-    /*
-     * private data for the GC subsystem
-     */
-    void *  gc_private;           /* gc subsystem data */
-} Arenas;
-
-/* &gen_from_enum(interpinfo.pasm) prefix(INTERPINFO_) */
-
-typedef enum {
-    TOTAL_MEM_ALLOC = 1,
-    GC_MARK_RUNS,
-    GC_COLLECT_RUNS,
-    ACTIVE_PMCS,
-    ACTIVE_BUFFERS,
-    TOTAL_PMCS,
-    TOTAL_BUFFERS,
-    HEADER_ALLOCS_SINCE_COLLECT,
-    MEM_ALLOCS_SINCE_COLLECT,
-    TOTAL_COPIED,
-    IMPATIENT_PMCS,
-    GC_LAZY_MARK_RUNS,
-    EXTENDED_PMCS,
-    CURRENT_RUNCORE,
-
-    /* interpinfo_p constants */
-    CURRENT_SUB,
-    CURRENT_CONT,
-    CURRENT_OBJECT,
-    CURRENT_LEXPAD,
-
-    /* interpinfo_s constants */
-    EXECUTABLE_FULLNAME,
-    EXECUTABLE_BASENAME,
-    RUNTIME_PREFIX
-} Interpinfo_enum;
-
-/* &end_gen */
-
-#endif /* PARROT_RESOURCES_H_GUARD */
-
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */

Modified: branches/pmc_pct/include/parrot/stacks.h
==============================================================================
--- branches/pmc_pct/include/parrot/stacks.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/include/parrot/stacks.h	Fri May 15 21:49:40 2009	(r38803)
@@ -21,15 +21,12 @@
 typedef struct Stack_Entry {
     UnionVal entry;
     Stack_entry_type  entry_type;
-    void (*cleanup)(PARROT_INTERP, struct Stack_Entry *);
+    void (*cleanup)(PARROT_INTERP, ARGIN(struct Stack_Entry *));
 } Stack_Entry_t;
 
-struct Small_Object_Pool; /* forward decl */
-
 typedef struct Stack_Chunk {
     UnionVal            cache;
     Parrot_UInt         flags;
-    struct Small_Object_Pool  *pool;
     const char         *name;
     struct Stack_Chunk *prev;
     Parrot_UInt         refcount;

Modified: branches/pmc_pct/lib/Parrot/Docs/File.pm
==============================================================================
--- branches/pmc_pct/lib/Parrot/Docs/File.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/lib/Parrot/Docs/File.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -409,8 +409,6 @@
             $desc =~ s/\s+$//os;
 
             # Remove any POD.
-            # RT#43683 - Decide whether we want to do this or convert
-            # to HTML in the documentation item.
             $desc =~ s/[CFL]<([^>]+)>/$1/osg;
 
             return $desc;

Modified: branches/pmc_pct/lib/Parrot/Docs/POD2HTML.pm
==============================================================================
--- branches/pmc_pct/lib/Parrot/Docs/POD2HTML.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/lib/Parrot/Docs/POD2HTML.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -45,7 +45,12 @@
 sub new {
     my $new = shift->SUPER::new(@_);
 
-    $new->accept_targets('PIR', 'PASM');
+    $new->accept_targets(qw(
+        PIR PASM PIR_FRAGMENT
+        PIR_INVALID PIR_TODO
+        PASM_INVALID PASM_TODO
+        PIR_FRAGMENT_INVALID
+    ));
     delete(@{$new->{'Tagmap'}}{'Data','/Data'});
 
     return $new;
@@ -348,7 +353,7 @@
     my $token = shift;
     my $target = $token->attr("target");
 
-    if ($target eq "PIR" || $target eq "PASM") {
+    if ($target =~ m/^(PIR|PASM)/) {
         print { $self->{'output_fh'} } '<pre>';
         $self->{IN_CODE_BLOCK} = 1;
     }

Modified: branches/pmc_pct/lib/Parrot/Pmc2c/PMC/RO.pm
==============================================================================
--- branches/pmc_pct/lib/Parrot/Pmc2c/PMC/RO.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/lib/Parrot/Pmc2c/PMC/RO.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -64,77 +64,44 @@
     }
 
     foreach my $vt_method ( @{ $self->vtable->methods } ) {
-        my $vt_method_name = $vt_method->name;
-        if ( $vt_method_name eq 'find_method' ) {
-            my $ro_method = Parrot::Pmc2c::Method->new(
-                {
-                    name        => $vt_method_name,
-                    parent_name => $parent->name,
-                    return_type => $vt_method->return_type,
-                    parameters  => $vt_method->parameters,
-                    type        => Parrot::Pmc2c::Method::VTABLE,
-                }
-            );
-            my $find_method_parent;
-            if ( $parent->implements_vtable($vt_method_name) ) {
-                $find_method_parent = $parent->name;
-            }
-            else {
-                $find_method_parent = $parent->{super}{$vt_method_name};
+        my $name = $vt_method->name;
+
+        # Generate ro variant only iff we override method constantness with ":write"
+        next unless $parent->{has_method}{$name}
+                    && $parent->vtable_method_does_write($name)
+                    && !$parent->vtable->attrs($name)->{write};
+
+        # All parameters passed in are shims, because we're
+        # creating an exception-thrower.
+        my @parameters = split( /\s*,\s*/, $vt_method->parameters );
+        @parameters = map { "SHIM($_)" } @parameters;
+
+        my $ro_method = Parrot::Pmc2c::Method->new(
+            {
+                name        => $name,
+                parent_name => $parent->name,
+                return_type => $vt_method->return_type,
+                parameters  => join( ', ', @parameters ),
+                type        => Parrot::Pmc2c::Method::VTABLE,
+                pmc_unused  => 1,
             }
-            # We can't use enum_class_Foo there. $parent can be non-core PMC.
-            my $real_findmethod = 'interp->vtables[pmc_type(interp, Parrot_str_new_constant(interp, "' . $find_method_parent . '"))]->find_method';
-            my $body            = <<"EOC";
-    PMC *const method = $real_findmethod(interp, pmc, method_name);
-    if (!PMC_IS_NULL(VTABLE_getprop(interp, method, CONST_STRING_GEN(interp, "write"))))
-        return PMCNULL;
-    else
-        return method;
-EOC
-            $ro_method->body( Parrot::Pmc2c::Emitter->text($body) );
-            $self->add_method($ro_method);
-        }
-        elsif ( $parent->vtable_method_does_write($vt_method_name) ) {
-            # All parameters passed in are shims, because we're
-            # creating an exception-thrower.
-            my @parameters = split( /\s*,\s*/, $vt_method->parameters );
-            @parameters = map { "SHIM($_)" } @parameters;
-
-            my $ro_method = Parrot::Pmc2c::Method->new(
-                {
-                    name        => $vt_method_name,
-                    parent_name => $parent->name,
-                    return_type => $vt_method->return_type,
-                    parameters  => join( ', ', @parameters ),
-                    type        => Parrot::Pmc2c::Method::VTABLE,
-                    pmc_unused  => 1,
-                }
-            );
-            my $pmcname = $parent->name;
-            my $ret     = return_statement($ro_method);
-            my $body    = <<EOC;
-    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_WRITE_TO_CONSTCLASS,
-            "$vt_method_name() in read-only instance of $pmcname");
+        );
+        my $pmcname = $parent->name;
+        my $ret     = return_statement($ro_method);
+        my $body    = <<EOC;
+Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_WRITE_TO_CONSTCLASS,
+        "$name() in read-only instance of $pmcname");
 EOC
 
-            # don't return after a Parrot_ex_throw_from_c_args
-            $ro_method->body( Parrot::Pmc2c::Emitter->text($body) );
-            $self->add_method($ro_method);
-        }
-        else {
-            if ( $parent->implements_vtable($vt_method_name) ) {
-                my $parent_method = $parent->get_method($vt_method_name);
-                $self->{super}{$vt_method_name} = $parent_method->parent_name;
-            }
-            else {
-                $self->{super}{$vt_method_name} = $parent->{super}{$vt_method_name};
-            }
-        }
+        # don't return after a Parrot_ex_throw_from_c_args
+        $ro_method->body( Parrot::Pmc2c::Emitter->text($body) );
+        $self->add_method($ro_method);
     }
 
     return $self;
 }
 
+
 1;
 
 # Local Variables:

Modified: branches/pmc_pct/lib/Parrot/Pmc2c/PMC/default.pm
==============================================================================
--- branches/pmc_pct/lib/Parrot/Pmc2c/PMC/default.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/lib/Parrot/Pmc2c/PMC/default.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -26,27 +26,65 @@
     foreach my $method ( @{ $self->vtable->methods } ) {
         my $vt_method_name = $method->name;
         next unless $self->unimplemented_vtable($vt_method_name);
-        my $new_default_method = $method->clone(
-            {
-                parent_name => $self->name,
-                type        => Parrot::Pmc2c::Method::VTABLE,
-            }
-        );
-        my $ret = return_statement($method);
-
-        # take care to mark the parameters as unused
-        # to avoid compiler warnings
-        my $body;
-        foreach my $param (split /,\s*/, $method->parameters) {
-            $param =~ s/.*\b(\w+)/$1/;
-            $body .= "    UNUSED($param)\n";
+        $self->add_method($self->_generate_default_method($self, $method, 'cant_do_method'));
+    }
+    return 1;
+}
+
+sub gen_methods {
+    my ($self) = @_;
+
+    $self->SUPER::gen_methods;
+
+    # Generate RO variants.
+    my $ro = Parrot::Pmc2c::PMC::RO->new($self);
+    $ro->{emitter} = $self->{emitter};
+    foreach my $method ( @{ $self->vtable->methods } ) {
+        my $vt_method_name = $method->name;
+        if ($vt_method_name eq 'find_method') {
+            # Generate default_ro_find_method.
+            $self->{emitter}->emit(<<'EOC');
+static  PMC *
+Parrot_default_ro_find_method(PARROT_INTERP, PMC *pmc, STRING *method_name) {
+    /* Use non-readonly find_method. Current vtable is ro variant. So ro_variant contains non-ro variant */
+    PMC *const method = pmc->vtable->ro_variant_vtable->find_method(interp, pmc, method_name);
+    if (!PMC_IS_NULL(VTABLE_getprop(interp, method, CONST_STRING_GEN(interp, "write"))))
+        return PMCNULL;
+    else
+        return method;
+}
+EOC
+        }
+        if ( $self->vtable_method_does_write($vt_method_name) ) {
+            my $m = $self->_generate_default_method($ro, $method, 'cant_do_write_method');
+            $m->generate_body($ro);
         }
-        $body .= qq{    cant_do_method(interp, pmc, "$vt_method_name");\n};
+    }
+}
+
+sub _generate_default_method {
+    my ($self, $pmc, $method, $stub_func) = @_;
 
-        $new_default_method->body( Parrot::Pmc2c::Emitter->text($body));
-        $self->add_method($new_default_method);
+    my $clone = $method->clone(
+         {
+             parent_name => $self->name,
+             type        => Parrot::Pmc2c::Method::VTABLE,
+         }
+     );
+
+    # take care to mark the parameters as unused
+    # to avoid compiler warnings
+    my $body;
+    foreach my $param (split /,\s*/, $method->parameters) {
+        $param =~ s/.*\b(\w+)/$1/;
+        $body .= "    UNUSED($param)\n";
     }
-    return 1;
+    my $vt_method_name = $method->name;
+    $body .= qq{    $stub_func(interp, pmc, "$vt_method_name");\n};
+
+    $clone->body( Parrot::Pmc2c::Emitter->text($body));
+
+    $clone;
 }
 
 sub update_vtable_func {
@@ -74,6 +112,27 @@
 
 EOC
 
+    # Generate RO version of default VTABLE.
+    my $ro_vtable_decl = '';
+    foreach my $name ( @{ $self->vtable->names } ) {
+        if ($self->vtable_method_does_write($name) || ($name eq 'find_method')) {
+            $ro_vtable_decl .= "    vt->$name = Parrot_default_ro_${name};\n";
+        }
+    }
+
+    $cout .= <<"EOC";
+
+PARROT_EXPORT VTABLE* Parrot_default_ro_get_vtable(PARROT_INTERP) {
+
+    VTABLE * vt = Parrot_default_get_vtable(interp);
+
+$ro_vtable_decl
+
+    return vt;
+}
+
+EOC
+
     $cout;
 }
 

Modified: branches/pmc_pct/lib/Parrot/Pmc2c/PMCEmitter.pm
==============================================================================
--- branches/pmc_pct/lib/Parrot/Pmc2c/PMCEmitter.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/lib/Parrot/Pmc2c/PMCEmitter.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -404,10 +404,11 @@
 
     foreach my $method ( @{ $self->methods } ) {
         next unless $method->is_multi;
-        my $short_sig = $method->{MULTI_short_sig};
-        my $full_sig = $pmcname . "," . $method->{MULTI_full_sig};
+        my $short_sig    = $method->{MULTI_short_sig};
+        my $full_sig     = $pmcname . "," . $method->{MULTI_full_sig};
         my $functionname = 'Parrot_' . $pmcname . '_' . $method->name;
-        push @multi_names, [ $method->symbol, $short_sig, $full_sig, $functionname ];
+        push @multi_names, [ $method->symbol, $short_sig, $full_sig,
+                             $pmcname, $functionname ];
     }
     return ( \@multi_names );
 }
@@ -520,11 +521,14 @@
     my $cache         = {};
 
     for my $multi (@$multi_funcs) {
-        my ($name, $ssig, $fsig, $func) = @$multi;
-        my ($name_str, $ssig_str, $fsig_str)     =
-            map { gen_multi_name($_, $cache) } ($name, $ssig, $fsig);
-
-        for my $s ([$name, $name_str], [$ssig, $ssig_str], [$fsig,$fsig_str]) {
+        my ($name, $ssig, $fsig, $ns, $func) = @$multi;
+        my ($name_str, $ssig_str, $fsig_str, $ns_name)     =
+            map { gen_multi_name($_, $cache) } ($name, $ssig, $fsig, $ns);
+
+        for my $s ([$name, $name_str],
+                   [$ssig, $ssig_str],
+                   [$fsig, $fsig_str],
+                   [$ns,   $ns_name ]) {
             my ($raw_string, $name) = @$s;
             next if $strings_seen{$name}++;
             $multi_strings .=  "        STRING *$name = "
@@ -535,6 +539,7 @@
         { $name_str,
           $ssig_str,
           $fsig_str,
+          $ns_name,
           (funcptr_t) $func }
 END_MULTI_LIST
 
@@ -827,28 +832,29 @@
 
 EOC
 
-    my %extra_vt;
-    $extra_vt{ro} = $self->{ro} if $self->{ro};
-
-    for my $k (keys %extra_vt) {
-
-        my $vtable_updates = '';
-        foreach my $vt_method ( @{ $self->$k->vtable->names} ) {
-
-            next unless ($self->$k->implements_vtable($vt_method));
-
-            $vtable_updates .= "    vt->$vt_method = Parrot_${classname}_${k}_${vt_method};\n";
+    # Generate RO vtable for implemented non-updating methods
+    $vtable_updates = '';
+    foreach my $name ( @{ $self->vtable->names} ) {
+        next unless exists $self->{has_method}{$name};
+        if ($self->vtable_method_does_write($name)) {
+            # If we override constantness status of vtable
+            if (!$self->vtable->attrs($name)->{write}) {
+                $vtable_updates .= "    vt->$name = Parrot_${classname}_ro_${name};\n";
+            }
+        }
+        else {
+            $vtable_updates .= "    vt->$name = Parrot_${classname}_${name};\n";
         }
+    }
 
-        $cout .= <<"EOC";
+    $cout .= <<"EOC";
 
-PARROT_EXPORT VTABLE *Parrot_${classname}_${k}_update_vtable(VTABLE *vt) {
+PARROT_EXPORT VTABLE *Parrot_${classname}_ro_update_vtable(VTABLE *vt) {
 $vtable_updates
     return vt;
 }
 
 EOC
-    }
 
     $cout;
 }
@@ -885,31 +891,25 @@
 
 EOC
 
-    my %extra_vt;
-    $extra_vt{ro} = $self->{ro} if $self->{ro};
-
-    for my $k (keys %extra_vt) {
-        my $get_extra_vtable = '';
-        foreach my $parent_name ( reverse ($self->name, @{ $self->parents }) ) {
-            if ($parent_name eq 'default') {
-                $get_extra_vtable .= "    vt = Parrot_default_get_vtable(interp);\n";
-            }
-            else {
-                $get_extra_vtable .= "    Parrot_${parent_name}_update_vtable(vt);\n";
-                $get_extra_vtable .= "    Parrot_${parent_name}_${k}_update_vtable(vt);\n";
-            }
+    my $get_extra_vtable = '';
+    foreach my $parent_name ( reverse ($self->name, @{ $self->parents }) ) {
+        if ($parent_name eq 'default') {
+            $get_extra_vtable .= "    vt = Parrot_default_ro_get_vtable(interp);\n";
+        }
+        else {
+            $get_extra_vtable .= "    Parrot_${parent_name}_ro_update_vtable(vt);\n";
         }
+    }
 
-        $cout .= <<"EOC";
+    $cout .= <<"EOC";
 PARROT_EXPORT
-VTABLE* Parrot_${classname}_${k}_get_vtable(PARROT_INTERP) {
+VTABLE* Parrot_${classname}_ro_get_vtable(PARROT_INTERP) {
     VTABLE *vt;
 $get_extra_vtable
     return vt;
 }
 
 EOC
-    }
 
     $cout;
 }

Modified: branches/pmc_pct/lib/Parrot/Revision.pm
==============================================================================
--- branches/pmc_pct/lib/Parrot/Revision.pm	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/lib/Parrot/Revision.pm	Fri May 15 21:49:40 2009	(r38803)
@@ -91,6 +91,12 @@
             ($revision) = $line =~ /(\d+)/;
         }
     }
+    if( !$revision && (-d '.git') ) {
+        my $git_log = qx/git log -100 2>$nul/;
+        if(defined($git_log) && $git_log =~ /git-svn-id: \S+\@(\d+)\s/) {
+            $revision = $1;
+        }
+    }
     return $revision;
 }
 

Modified: branches/pmc_pct/ports/ubuntu/changelog
==============================================================================
--- branches/pmc_pct/ports/ubuntu/changelog	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/ports/ubuntu/changelog	Fri May 15 21:49:40 2009	(r38803)
@@ -1,27 +1,30 @@
-parrot (1.0.0-1ubuntu1~ppa8~intrepid1) intrepid; urgency=low
-  * New upstream release
-  * Bumped Standards-Version to 3.8.0
+parrot (1.0.0-1ubuntu1~ppa9~karmic1) karmic; urgency=low
+  * Resynchronize with Debian unstable.
 
- -- Allison Randal <allison at parrot.org>  Thu, 19 Mar 2009 01:56:39 -0700
+ -- Allison Randal <allison at parrot.org>  Sun, 10 May 2009 20:39:20 -0700
 
 parrot (1.0.0-1) unstable; urgency=low
   * New upstream release
   * debian/control.in:
     - Updated Description of all packages.
     - Bumped Standards-Version to 3.8.1
-  * debian/rules:
     - Add new packages parrot-minimal and parrot-devel
+  * debian/rules:
     - Integrate Ubuntu packaging changes to automatically generate
       debian/control.
     - Re-order dh_installdeb in binary-arch to run after dh_makeshlibs and
       shlibdeps so that the library gets installed properly (patch from David
       Nusinow)
-  * parrot.install.in, parrot-doc.install.in, libparrot-dev.install.in
-    - Added template files, replace parrot.install, parrot-doc.install, and
-      libparrot-dev.install
+    - Move manpage generation to new packages. Rename parrot-debugger.1 to
+      parrot_debugger.1 to match executable name. Generate parrot_config
+      manpage from .pir source files (patch from David Nusinow)
+  * parrot.install.in, parrot-doc.install.in, libparrot.install.in,
+    libparrot-dev.install.in
+    - Added template files, replace parrot.install, parrot-doc.install, 
+      libparrot.install, and libparrot-dev.install
   * parrot-minimal.install.in, parrot-devel.install.in
     - Added template files for new packages
-  * parrot-doc.docs
+  * parrot-doc.docs, libparrot-dev.dirs
     - Removed
   * libparrot.postinst
     - Added so ldconfig gets called properly by dh_makeshlibs (patch from
@@ -31,7 +34,7 @@
       distribution.
     - Removed copyright info for files no longer in distribution.
 
- -- Allison Randal <allison at parrot.org>  Wed, 18 Mar 2009 23:50:41 -0700
+ -- Allison Randal <allison at parrot.org>  Wed, 25 Mar 2009 00:45:40 -0500
 
 parrot (0.9.0-1ubuntu1) intrepid; urgency=low
 

Modified: branches/pmc_pct/ports/ubuntu/control.in
==============================================================================
--- branches/pmc_pct/ports/ubuntu/control.in	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/ports/ubuntu/control.in	Fri May 15 21:49:40 2009	(r38803)
@@ -1,14 +1,14 @@
 Source: parrot
-Section: universe/interpreters
+Section: interpreters
 Priority: optional
 Maintainer: Ubuntu MOTU Developers <ubuntu-motu at lists.ubuntu.com>
 XSBC-Original-Maintainer: Debian Parrot Maintainers <pkg-parrot-devel at lists.alioth.debian.org>
 Build-Depends: debhelper (>= 5.0.0), perl, perl-doc, libgdbm-dev, libreadline-dev
-Standards-Version: 3.8.0
+Standards-Version: 3.8.1
 
 Package: parrot
 Architecture: any
-Depends: parrot-minimal (= ${binary:Version})
+Depends: ${shlibs:Depends}, parrot-minimal (= ${binary:Version})
 Suggests: parrot-doc
 Provides: parrot-test, parrot-data-dumper
 Description: A virtual machine for dynamic languages
@@ -19,6 +19,8 @@
 Package: parrot-minimal
 Architecture: any
 Depends: ${shlibs:Depends}
+Conflicts: parrot ( << 1.0.0 )
+Replaces: parrot ( << 1.0.0 )
 Description: A minimal install of the Parrot VM
  This package contains the core Parrot virtual machine. It's all that you need
  to get up and running in the average use case, and is sufficient to run most
@@ -26,17 +28,15 @@
 
 Package: libparrot at SOVERSION@
 Architecture: any
-Section: universe/libs
+Section: libs
 Depends: ${shlibs:Depends}
-Provides: libparrot
-Conflicts: libparrot
 Description: Parrot shared library
  This package contains the Parrot shared library, used by the Parrot virtual
  machine and by programs that embed Parrot.
  
 Package: libparrot-dev
 Architecture: any
-Section: universe/devel
+Section: libdevel
 Depends: libparrot at SOVERSION@ (= ${binary:Version}), parrot
 Description: Parrot shared library development files
  This package contains header files and a static library, needed to develop
@@ -44,7 +44,7 @@
 
 Package: parrot-doc
 Architecture: all
-Section: universe/doc
+Section: doc
 Suggests: perl-doc
 Description: Parrot documentation
  Parrot manual pages and raw Pod documentation. If you are developing a
@@ -53,9 +53,11 @@
 
 Package: parrot-devel
 Architecture: any
-Section: universe/devel
-Depends: parrot, perl
+Section: devel
+Depends: ${shlibs:Depends}, parrot, libparrot-dev, perl
 Provides: parrot-pge, parrot-tge, parrot-pct, parrot-nqp
+Conflicts: parrot ( << 1.0.0 ), libparrot-dev ( << 1.0.0 )
+Replaces: parrot ( << 1.0.0 ), libparrot-dev ( << 1.0.0 )
 Description: Parrot development tools
  This package contains development tools for the Parrot virtual machine. It is
  essential for developing language implementations to run on Parrot, but not

Modified: branches/pmc_pct/runtime/parrot/library/Data/Dumper.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Data/Dumper.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Data/Dumper.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -9,7 +9,7 @@
     goto END
 
   load_library:
-        load_bytecode "Data/Dumper/Default.pir"
+        load_bytecode "Data/Dumper/Default.pbc"
         newclass $P0, "Data::Dumper"
 END:
     .return ()

Modified: branches/pmc_pct/runtime/parrot/library/Data/Dumper/Default.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Data/Dumper/Default.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Data/Dumper/Default.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -25,7 +25,7 @@
     goto END
 
   create_ddb:
-    load_bytecode "library/Data/Dumper/Base.pir"
+    load_bytecode 'Data/Dumper/Base.pbc'
     get_class $P0, "Data::Dumper::Base"
     subclass $P0, $P0, "Data::Dumper::Default"
 END:

Modified: branches/pmc_pct/runtime/parrot/library/Data/Replace.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Data/Replace.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Data/Replace.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -8,7 +8,7 @@
 
     ...
 
-    load_bytecode "library/Data/Replace.pir"
+    load_bytecode "Data/Replace.pbc"
 
     .local pmc replace
 

Modified: branches/pmc_pct/runtime/parrot/library/Digest/MD5.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Digest/MD5.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Digest/MD5.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -13,13 +13,13 @@
 
 =head1 SYNOPSIS
 
-  load_bytecode "Digest/MD5.pir"
+  load_bytecode "Digest/MD5.pbc"
   $P0 = _md5sum("foo")
   _md5_print($P0)
 
 or
 
-  load_bytecode "Digest/MD5.pir"
+  load_bytecode "Digest/MD5.pbc"
   $P0 = _md5sum("bar")
   $S0 = _md5_hex($P0)
 

Modified: branches/pmc_pct/runtime/parrot/library/Getopt/Obj.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Getopt/Obj.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Getopt/Obj.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -11,7 +11,7 @@
 
     .local string prog_name
     prog_name = shift argv
-    load_bytecode "Getopt/Obj.pir"
+    load_bytecode "Getopt/Obj.pbc"
     .local pmc getopts
     getopts = new "Getopt::Obj"
     getopts."notOptStop"(1)
@@ -352,7 +352,7 @@
     .return(return)
 .end
 
-=item C<__push_string(STRING format)>
+=item C<push_string(STRING format)>
 
 A vtable method, invoked by e.g. C<push getopts, "foo|f=s">.  The format is as such.
 

Modified: branches/pmc_pct/runtime/parrot/library/HTTP/Daemon.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/HTTP/Daemon.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/HTTP/Daemon.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -7,7 +7,7 @@
 
 =head1 SYNOPSIS
 
-  load_bytecode "HTTP/Daemon.pir"
+  load_bytecode "HTTP/Daemon.pbc"
   opts = new 'Hash'
   opts['LocalPort'] = 1234
   opts['LocalAddr'] = 'localhost'

Modified: branches/pmc_pct/runtime/parrot/library/Math/Rand.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Math/Rand.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Math/Rand.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -34,7 +34,7 @@
 
 =head1 USAGE
 
-    load_bytecode 'library/Math/Rand.pbc'
+    load_bytecode 'Math/Rand.pbc'
     .local pmc rand
     rand = get_global [ 'Math'; 'Rand' ], 'rand'
     .local pmc srand

Modified: branches/pmc_pct/runtime/parrot/library/NCI/call_toolkit_init.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/NCI/call_toolkit_init.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/NCI/call_toolkit_init.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -11,8 +11,8 @@
         .param pmc argv
 
         # Load this library and the NCI wrapper for the toolkit
-	load_bytecode 'library/NCI/call_toolkit_init.pbc'
-	load_bytecode 'library/FooTK.pbc'
+	load_bytecode 'NCI/call_toolkit_init.pbc'
+	load_bytecode 'FooTK.pbc'
 
 	# Find Subs for toolkit's init function, and this helper routine
         .local pmc fooInit, call_toolkit_init

Modified: branches/pmc_pct/runtime/parrot/library/OpenGL.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/OpenGL.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/OpenGL.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,8 @@
     .param pmc argv
 
     # Load OpenGL libary and a helper library for calling glutInit
-    load_bytecode 'library/OpenGL.pbc'
-    load_bytecode 'library/NCI/call_toolkit_init.pbc'
+    load_bytecode 'OpenGL.pbc'
+    load_bytecode 'NCI/call_toolkit_init.pbc'
 
     # Import all OpenGL/GLU/GLUT functions
     .local pmc import_gl
@@ -80,9 +80,6 @@
 
 .namespace ['OpenGL']
 
-.include 'library/OpenGL_funcs.pir'
-
-
 =item _opengl_init()
 
 At module load time, calls the other initialization routines in the proper
@@ -91,6 +88,7 @@
 =cut
 
 .sub _opengl_init :load
+    load_bytecode 'OpenGL_funcs.pbc'
     _load_opengl_libs()
     _wrap_all_opengl_entry_points()
 .end

Modified: branches/pmc_pct/runtime/parrot/library/PGE/Perl6Grammar.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/PGE/Perl6Grammar.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/PGE/Perl6Grammar.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -66,7 +66,7 @@
     .local pmc pgc
 
     pgc = compreg 'PGE::Perl6Grammar'
-    pgc.'command_line'(args, 'target'=>'PIR', 'combine'=>1)
+    pgc.'command_line'(args, 'target'=>'PIR', 'combine'=>1, 'transcode'=>'iso-8859-1')
     .return ()
 .end
 
@@ -101,7 +101,8 @@
       | '"' (<-["]>*:) '"'
       | '(' (<-[)]>*:) ')'
       | '<' (<-[>]>*:) '>'
-      | '«' (<-[»]>*:) '»'
+      | \xc2\xab (.*?) \xc2\xbb
+      | \xab (<-[\xbb]>*:) \xbb
       | (\S+)
       ]
       END_ARG_RULE

Modified: branches/pmc_pct/runtime/parrot/library/Parrot/Coroutine.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Parrot/Coroutine.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Parrot/Coroutine.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -9,7 +9,7 @@
 =head1 SYNOPSIS
 
     .sub onload :load
-        load_bytecode 'Parrot/Coroutine.pir'
+        load_bytecode 'Parrot/Coroutine.pbc'
     .end
 
     ## Recursive coroutine to enumerate tree elements.  Each element that is

Modified: branches/pmc_pct/runtime/parrot/library/Pg.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Pg.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Pg.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -44,7 +44,7 @@
 
 .sub __load :load
     .local pmc cl
-    load_bytecode "postgres.pir"         # TODO .pbc
+    load_bytecode 'postgres.pbc'
     cl = newclass 'Pg'       # Pg connection constructor
 
     # XXX the hasa 'con' is suboptimal

Modified: branches/pmc_pct/runtime/parrot/library/Stream/Base.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/Base.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/Base.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::Base - Stream library base class
+Stream;Base - Stream library base class
 
 =head1 VERSION
 
@@ -22,13 +22,13 @@
 
 =cut
 
-.namespace ["Stream::Base"]
+.namespace ['Stream'; 'Base']
 
 .sub onload :load :anon
-    $P0 = get_class 'Stream::Base'
+    $P0 = get_class ['Stream'; 'Base']
     unless null $P0 goto END
 
-    newclass $P0, "Stream::Base"
+    newclass $P0, ['Stream'; 'Base']
     addattribute $P0, 'source'
     addattribute $P0, 'includes'
     addattribute $P0, 'buffer'
@@ -39,7 +39,7 @@
     .local pmc close
 
     # call our own close
-    close = get_hll_global ['Stream::Base'], 'close'
+    close = get_hll_global ['Stream'; 'Base'], 'close'
     close(self)
 .end
 
@@ -134,7 +134,7 @@
 
     .return(ret)
 ERROR:
-    print "Stream::Base::source(): parameters passed\n"
+    print "Stream;Base.source(): parameters passed\n"
     end
 .end
 
@@ -348,7 +348,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Stream/Combiner.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/Combiner.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/Combiner.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::Combiner - combines different streams to a single stream.
+Stream;Combiner - combines different streams to a single stream.
 
 =head1 VERSION
 
@@ -29,13 +29,13 @@
     .local pmc base
     .local pmc comb
 
-    $P0 = get_class 'Stream::Combiner'
+    $P0 = get_class ['Stream'; 'Combiner']
     unless null $P0 goto END
 
-    load_bytecode "library/Stream/Base.pir"
+    load_bytecode 'Stream/Base.pbc'
 
-    get_class base, "Stream::Base"
-    subclass comb, base, "Stream::Combiner"
+    get_class base, ['Stream'; 'Base']
+    subclass comb, base, ['Stream'; 'Combiner']
 
     addattribute comb, "combiner"
 END:
@@ -52,7 +52,7 @@
 
 .include "iterator.pasm"
 
-.namespace ["Stream::Combiner"]
+.namespace ['Stream'; 'Combiner']
 
 .sub init :vtable :method
 
@@ -204,7 +204,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Stream/Coroutine.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/Coroutine.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/Coroutine.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::Base - Stream library base class
+Stream;Coroutine - Stream library coroutine class
 
 =head1 VERSION
 
@@ -27,17 +27,17 @@
     .local pmc coro
     .local int i
 
-    $P0 = get_class "Stream::Coroutine"
+    $P0 = get_class ['Stream'; 'Coroutine']
     unless null $P0 goto END
 
-    load_bytecode "library/Stream/Base.pir"
+    load_bytecode 'Stream/Base.pbc'
 
-    get_class base, "Stream::Base"
-    subclass coro, base, "Stream::Coroutine"
+    get_class base, ['Stream'; 'Base']
+    subclass coro, base, ['Stream'; 'Coroutine']
 END:
 .end
 
-.namespace ["Stream::Coroutine"]
+.namespace ['Stream'; 'Coroutine']
 
 =item source."rawRead"() (B<internal>)
 
@@ -70,7 +70,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Stream/Filter.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/Filter.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/Filter.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::Filter - filter and/or alter a stream
+Stream;Filter - filter and/or alter a stream
 
 =head1 VERSION
 
@@ -27,19 +27,19 @@
     .local pmc base
     .local pmc filter
 
-    $P0 = get_class 'Stream::Filter'
+    $P0 = get_class ['Stream'; 'Filter']
     unless null $P0 goto END
 
-    load_bytecode "library/Stream/Base.pir"
+    load_bytecode 'Stream/Base.pbc'
 
-    get_class base, "Stream::Base"
-    subclass filter, base, "Stream::Filter"
+    get_class base, ['Stream'; 'Base']
+    subclass filter, base, ['Stream'; 'Filter']
 
     addattribute filter, "filter"
 END:
 .end
 
-.namespace ["Stream::Filter"]
+.namespace ['Stream'; 'Filter']
 
 =item source."filter"( filter )
 
@@ -94,7 +94,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Stream/Lines.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/Lines.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/Lines.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::Lines - process a stream one line per read
+Stream;Lines - process a stream one line per read
 
 =head1 VERSION
 
@@ -27,19 +27,19 @@
     .local pmc base
     .local pmc lines
 
-    $P0 = get_class 'Stream::Lines'
+    $P0 = get_class ['Stream'; 'Lines']
     unless null $P0 goto END
 
-    load_bytecode "library/Stream/Base.pir"
+    load_bytecode 'Stream/Base.pbc'
 
-    get_class base, "Stream::Base"
-    subclass lines, base, "Stream::Lines"
+    get_class base, ['Stream'; 'Base']
+    subclass lines, base, ['Stream'; 'Lines']
 
     addattribute lines, "line_buffer"
 END:
 .end
 
-.namespace ["Stream::Lines"]
+.namespace ['Stream'; 'Lines']
 
 .sub init :vtable :method
     .local pmc temp
@@ -183,7 +183,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Stream/ParrotIO.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/ParrotIO.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/ParrotIO.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::ParrotIO - a ParrotIO PMC as source for a Stream
+Stream;ParrotIO - a ParrotIO PMC as source for a Stream
 
 =head1 VERSION
 
@@ -27,19 +27,19 @@
     .local pmc base
     .local pmc io
 
-    $P0 = get_class 'Stream::ParrotIO'
+    $P0 = get_class ['Stream'; 'ParrotIO']
     unless null $P0 goto END
 
-    load_bytecode "library/Stream/Base.pir"
+    load_bytecode 'Stream/Base.pbc'
 
-    get_class base, "Stream::Base"
-    subclass io, base, "Stream::ParrotIO"
+    get_class base, ['Stream'; 'Base']
+    subclass io, base, ['Stream'; 'ParrotIO']
 
     addattribute io, "blocksize"
 END:
 .end
 
-.namespace ["Stream::ParrotIO"]
+.namespace ['Stream'; 'ParrotIO']
 
 .sub init :vtable :method
     self."blockSize"( 50 )
@@ -119,7 +119,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Stream/Replay.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/Replay.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/Replay.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::Replay - replayable Stream
+Stream;Replay - replayable Stream
 
 =head1 VERSION
 
@@ -10,9 +10,9 @@
 
 =head1 SYNOPSIS
 
-    load_bytecode "library/Stream/Replay.pir"
+    load_bytecode 'Stream/Replay.pbc'
 
-    $P0 = new "Stream::Replay"
+    $P0 = new ['Stream'; 'Replay']
     assign $P0, other_stream
 
     # .. read from $P0 ..
@@ -34,22 +34,22 @@
 
 =cut
 
-.namespace ["Stream::Replay"]
+.namespace ['Stream'; 'Replay']
 
 .sub onload :load :anon
-    $P0 = get_class 'Stream::Replay'
+    $P0 = get_class ['Stream'; 'Replay']
     unless null $P0 goto END
 
-    load_bytecode "library/Stream/Base.pir"
+    load_bytecode 'Stream/Base.pbc'
 
-    # Stream::Replay
-    get_class $P0, "Stream::Base"
-    subclass $P0, $P0, "Stream::Replay"
+    # Stream;Replay
+    get_class $P0, ['Stream'; 'Base']
+    subclass $P0, $P0, ['Stream'; 'Replay']
     addattribute $P0, "replay_buffer"
     addattribute $P0, "pos"
 
-    # Stream::Replay::Buffer
-    newclass $P0, "Stream::Replay::Buffer"
+    # Stream;Replay;Buffer
+    newclass $P0, ['Stream'; 'Replay'; 'Buffer']
     addattribute $P0, "strings"
     addattribute $P0, "clones"
 END:
@@ -78,7 +78,7 @@
     .param pmc val
     .local pmc buffer
 
-    isa $I0, val, "Stream::Replay"
+    isa $I0, val, ['Stream'; 'Replay']
     unless $I0 goto NOTA
 
     # get the buffer
@@ -102,7 +102,7 @@
     val = val."source"()
     goto ASSIGN
 NOTA:
-    buffer = new "Stream::Replay::Buffer"
+    buffer = new ['Stream'; 'Replay'; 'Buffer']
     setattribute self, 'replay_buffer', buffer
 ASSIGN:
     self."setSource"( val )
@@ -142,7 +142,7 @@
     .local pmc ret
     .local pmc temp
 
-    ret = new "Stream::Replay"
+    ret = new ['Stream'; 'Replay']
 
     assign ret, self
 
@@ -155,7 +155,7 @@
 .end
 
 
-.namespace ["Stream::Replay::Buffer"]
+.namespace ['Stream'; 'Replay'; 'Buffer']
 
 .sub init :vtable :method
     .local pmc temp
@@ -251,7 +251,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Stream/Sub.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/Sub.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/Sub.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::Sub - a PIR sub as source for a Stream
+Stream;Sub - a PIR sub as source for a Stream
 
 =head1 VERSION
 
@@ -11,7 +11,7 @@
 =head1 SYNOPSIS
 
     # create the stream
-    new stream, "Stream::Sub"
+    new stream, ['Stream'; Sub']
 
     # set the source sub
     .const 'Sub' temp = "_test"
@@ -25,7 +25,7 @@
 
 =head1 DESCRIPTION
 
-Like every stream, Stream::Sub as has a C<read> method.
+Like every stream, Stream;Sub as has a C<read> method.
 The benefit is that this stream also has a C<write> method, though it
 can not be called from arbitrary locations.
 
@@ -58,19 +58,19 @@
     .local pmc base
     .local pmc sub
 
-    $P0 = get_class "Stream::Sub"
+    $P0 = get_class ['Stream'; 'Sub']
     unless null $P0 goto END
 
-    load_bytecode "library/Stream/Base.pir"
+    load_bytecode 'Stream/Base.pbc'
 
-    get_class base, "Stream::Base"
-    subclass sub, base, "Stream::Sub"
+    get_class base, ['Stream'; 'Base']
+    subclass sub, base, ['Stream'; 'Sub']
 
     addattribute sub, "write_cont"
 END:
 .end
 
-.namespace ["Stream::Sub"]
+.namespace ['Stream'; 'Sub']
 
 =head1 METHODS
 
@@ -152,7 +152,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Stream/Writer.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Stream/Writer.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Stream/Writer.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -2,7 +2,7 @@
 
 =head1 TITLE
 
-Stream::Writer - a PIR sub as target for a Stream
+Stream;Writer - a PIR sub as target for a Stream
 
 =head1 VERSION
 
@@ -11,7 +11,7 @@
 =head1 SYNOPSIS
 
     # create the stream
-    new stream, "Stream::Writer"
+    new stream, ['Stream'; 'Writer']
 
     # set the source sub
     .const 'Sub' temp = "_reader"
@@ -31,16 +31,16 @@
 =cut
 
 .include "interpinfo.pasm"
-.namespace ["Stream::Writer"]
+.namespace ['Stream'; 'Writer']
 
 .sub __onload :load
-    $P0 = get_class "Stream::Writer"
+    $P0 = get_class ['Stream'; 'Writer']
     unless null $P0 goto END
 
-    load_bytecode "library/Stream/Base.pir"
+    load_bytecode 'Stream/Base.pbc'
 
-    get_class $P0, "Stream::Base"
-    subclass $P1, $P0, "Stream::Writer"
+    get_class $P0, ['Stream'; 'Base']
+    subclass $P1, $P0, ['Stream'; 'Writer']
 
     addattribute $P1, "writer"
     addattribute $P1, "status"
@@ -64,7 +64,7 @@
     source()
 
     # close the source
-    source = get_hll_global ['Stream::Base'], 'close'
+    source = get_hll_global ['Stream'; 'Base'], 'close'
     self."setSource"()
 
     # mark it as closed
@@ -198,7 +198,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pmc_pct/runtime/parrot/library/Test/Builder.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Test/Builder.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Test/Builder.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -7,7 +7,7 @@
 =head1 SYNOPSIS
 
     # load this library
-    load_bytecode 'library/Test/Builder.pbc'
+    load_bytecode 'Test/Builder.pbc'
 
     # create a new Test::Builder object
     .local pmc test
@@ -48,9 +48,9 @@
 .namespace [ 'Test'; 'Builder' ]
 
 .sub '_initialize' :load
-    load_bytecode 'library/Test/Builder/Test.pbc'
-    load_bytecode 'library/Test/Builder/Output.pbc'
-    load_bytecode 'library/Test/Builder/TestPlan.pbc'
+    load_bytecode 'Test/Builder/Test.pbc'
+    load_bytecode 'Test/Builder/Output.pbc'
+    load_bytecode 'Test/Builder/TestPlan.pbc'
 
     .local pmc tb_class
 

Modified: branches/pmc_pct/runtime/parrot/library/Test/Builder/Tester.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Test/Builder/Tester.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Test/Builder/Tester.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -7,7 +7,7 @@
 =head1 SYNOPSIS
 
     # load this library
-    load_bytecode 'library/Test/Builder/Tester.pbc'
+    load_bytecode 'Test/Builder/Tester.pbc'
 
     # grab the subroutines you want to use
     .local pmc plan
@@ -154,7 +154,7 @@
 .namespace [ 'Test'; 'Builder'; 'Tester' ]
 
 .sub _initialize :load
-    load_bytecode 'library/Test/Builder.pbc'
+    load_bytecode 'Test/Builder.pbc'
 
     .local pmc test
     .local pmc output

Modified: branches/pmc_pct/runtime/parrot/library/Test/More.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/Test/More.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/Test/More.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -7,7 +7,7 @@
 =head1 SYNOPSIS
 
     # load this library
-    load_bytecode 'library/Test/More.pbc'
+    load_bytecode 'Test/More.pbc'
 
     # get the testing functions
     .local pmc exports, curr_namespace, test_namespace
@@ -66,7 +66,7 @@
 .namespace [ 'Test'; 'More' ]
 
 .sub _initialize :load
-    load_bytecode 'library/Test/Builder.pbc'
+    load_bytecode 'Test/Builder.pbc'
 
     .local pmc test
     test = new [ 'Test'; 'Builder' ]

Modified: branches/pmc_pct/runtime/parrot/library/YAML/Dumper.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/YAML/Dumper.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/YAML/Dumper.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -9,7 +9,7 @@
     goto END
 
   load_library:
-        load_bytecode "library/YAML/Dumper/Default.pir"
+        load_bytecode 'YAML/Dumper/Default.pbc'
         newclass $P0, "YAML::Dumper"
 END:
     .return ()

Modified: branches/pmc_pct/runtime/parrot/library/YAML/Dumper/Default.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/YAML/Dumper/Default.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/YAML/Dumper/Default.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -25,7 +25,7 @@
     goto END
 
   create_ydb:
-    load_bytecode "library/YAML/Dumper/Base.pir"
+    load_bytecode 'YAML/Dumper/Base.pbc'
     get_class $P0, "YAML::Dumper::Base"
     subclass $P0, $P0, "YAML::Dumper::Default"
 END:

Modified: branches/pmc_pct/runtime/parrot/library/dumper.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/dumper.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/dumper.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -30,7 +30,7 @@
 .sub __library_dumper_print_usage
     say "# usage:"
     say ".sub main"
-    say "    load_bytecode 'Data/Dumper.pir'"
+    say "    load_bytecode 'Data/Dumper.pbc'"
     say ''
     say "    .local pmc foo, dumper"
     say "    foo    = new 'ResizablePMCArray'"
@@ -153,13 +153,13 @@
     goto TYPE_OK
 
   load_dd_pir:
-    load_bytecode "Data/Dumper.pir"
+    load_bytecode "Data/Dumper.pbc"
     get_class dd_class, "Data::Dumper"
     if null dd_class goto no_class
     goto TYPE_OK
 
   no_class:
-    print "fatal error: failure while loading Data/Dumper.pir\n"
+    print "fatal error: failure while loading Data/Dumper.pbc\n"
     end
 TYPE_OK:
 

Modified: branches/pmc_pct/runtime/parrot/library/pcre.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/pcre.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/pcre.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -7,7 +7,7 @@
 
 =head1 SYNOPSIS
 
-    load_bytecode 'library/pcre.pir'
+    load_bytecode 'pcre.pbc'
     lib = pcre_init()
 
     func = get_hll_global ['PCRE'], 'compile'
@@ -81,7 +81,7 @@
 LIB_LOADED:
     set_hll_global ['PCRE'], 'lib', libpcre
 
-    load_bytecode 'library/libpcre.pir'
+    load_bytecode 'libpcre.pbc'
 
     # pcre *pcre_compile(const char *pattern, int options,
     #            const char **errptr, int *erroffset,

Modified: branches/pmc_pct/runtime/parrot/library/tcpstream.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/tcpstream.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/tcpstream.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -8,7 +8,7 @@
 =head1 SYNOPSIS
 
   .sub main :main
-      load_bytecode 'library/tcpstream.pir'
+      load_bytecode 'tcpstream.pir'
 
       .local pmc stream
       stream = new 'TCPStream'

Modified: branches/pmc_pct/runtime/parrot/library/yaml_dumper.pir
==============================================================================
--- branches/pmc_pct/runtime/parrot/library/yaml_dumper.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/runtime/parrot/library/yaml_dumper.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -30,7 +30,7 @@
 .sub __library_yaml_dumper_print_usage
     say "# usage:"
     say ".sub main"
-    say "    load_bytecode 'YAML/Dumper.pir'"
+    say "    load_bytecode 'YAML/Dumper.pbc'"
     say ''
     say "    .local pmc foo, yaml_dumper"
     say "    foo         = new 'ResizablePMCArray'"
@@ -153,13 +153,13 @@
     goto TYPE_OK
 
   load_yd_pir:
-    load_bytecode "YAML/Dumper.pir"
+    load_bytecode "YAML/Dumper.pbc"
     get_class yd_class, "YAML::Dumper"
     if null yd_class goto no_class
     goto TYPE_OK
 
   no_class:
-    print "fatal error: failure while loading YAML/Dumper.pir\n"
+    print "fatal error: failure while loading YAML/Dumper.pbc\n"
     end
 TYPE_OK:
 

Modified: branches/pmc_pct/src/call/pcc.c
==============================================================================
--- branches/pmc_pct/src/call/pcc.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/call/pcc.c	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 Parrot Calling Conventions
@@ -1199,7 +1199,7 @@
     if (key->vtable->base_type != enum_class_Key)
         return;
 
-    for (; key; key=key_next(interp, key)) {
+    for (; key; key = VTABLE_shift_pmc(interp, key)) {
         /* register keys have to be cloned */
         if (PObj_get_FLAGS(key) & KEY_register_FLAG) {
             Parrot_Context temp_ctx;
@@ -1666,8 +1666,7 @@
              * RT #54860 and others
              * Save current value while setting the optional
              */
-            UnionVal old_value;
-            old_value = st->val;
+            UnionVal old_value = st->val;
 
             while (dest->sig & PARROT_ARG_OPTIONAL) {
                 null_val(st->dest.sig, st);

Modified: branches/pmc_pct/src/dynpmc/dynlexpad.pmc
==============================================================================
--- branches/pmc_pct/src/dynpmc/dynlexpad.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/dynpmc/dynlexpad.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -203,7 +203,7 @@
     VTABLE void mark() {
         PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
         if (std_pad)
-            pobject_lives(interp, (PObj *)std_pad);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)std_pad);
         if (PARROT_DYNLEXPAD(SELF)->hash)
             parrot_mark_hash(interp, PARROT_DYNLEXPAD(SELF)->hash);
     }

Modified: branches/pmc_pct/src/dynpmc/pair.pmc
==============================================================================
--- branches/pmc_pct/src/dynpmc/pair.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/dynpmc/pair.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -87,10 +87,10 @@
         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
 
         if (pair->key)
-            pobject_lives(INTERP, (PObj *)pair->key);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)pair->key);
 
         if (pair->value)
-            pobject_lives(INTERP, (PObj *)pair->value);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)pair->value);
     }
 
 /*
@@ -248,7 +248,6 @@
     VTABLE void visit(visit_info *info) {
         PMC               **pos;
         Parrot_Pair_attributes * const pair     = PARROT_PAIR(SELF);
-        IMAGE_IO    * const io       = info->image_io;
         DPOINTER   ** const temp_pos = (DPOINTER **)pair->key;
         info->thaw_ptr               = (PMC **)temp_pos;
         (info->visit_pmc_now)(INTERP, (PMC *)temp_pos, info);

Modified: branches/pmc_pct/src/extend.c
==============================================================================
--- branches/pmc_pct/src/extend.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/extend.c	Fri May 15 21:49:40 2009	(r38803)
@@ -1540,8 +1540,6 @@
 {
     ASSERT_ARGS(Parrot_PMC_newclass)
     Parrot_PMC result;
-    Parrot_PMC hllns;
-    INTVAL hll;
     PARROT_CALLIN_START(interp);
 
     result = pmc_new_init(interp, enum_class_Class, classtype);

Modified: branches/pmc_pct/src/gc/api.c
==============================================================================
--- branches/pmc_pct/src/gc/api.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/api.c	Fri May 15 21:49:40 2009	(r38803)
@@ -33,30 +33,186 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static PMC_EXT * new_pmc_ext(PARROT_INTERP)
+static void cleanup_next_for_GC_pool(ARGIN(Small_Object_Pool *pool))
         __attribute__nonnull__(1);
 
-#define ASSERT_ARGS_new_pmc_ext __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
+static void fix_pmc_syncs(
+    ARGMOD(Interp *dest_interp),
+    ARGIN(Small_Object_Pool *pool))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*dest_interp);
+
+static int sweep_cb_buf(PARROT_INTERP,
+    ARGMOD(Small_Object_Pool *pool),
+    SHIM(int flag),
+    ARGIN(void *arg))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(4)
+        FUNC_MODIFIES(*pool);
+
+static int sweep_cb_pmc(PARROT_INTERP,
+    ARGMOD(Small_Object_Pool *pool),
+    SHIM(int flag),
+    SHIM(void *arg))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*pool);
+
+#define ASSERT_ARGS_cleanup_next_for_GC_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_fix_pmc_syncs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(dest_interp) \
+    || PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_sweep_cb_buf __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool) \
+    || PARROT_ASSERT_ARG(arg)
+#define ASSERT_ARGS_sweep_cb_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
 #if ! DISABLE_GC_DEBUG
 
-/* Set when walking the system stack */
-int CONSERVATIVE_POINTER_CHASING = 0;
+#endif
+
+/*
+
+=item C<void Parrot_gc_mark_PObj_alive(PARROT_INTERP, PObj *obj)>
+
+Marks the PObj as "alive" for the Garbage Collector. Takes a pointer to a PObj,
+and performs necessary marking to ensure the PMC and its direct children nodes
+are marked alive. Implementation is generally dependant on the particular
+garbage collector in use.
+
+Previously known as C<pobject_lives>.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_gc_mark_PObj_alive(PARROT_INTERP, ARGMOD(PObj *obj))
+{
+    ASSERT_ARGS(Parrot_gc_mark_PObj_alive)
+    /* TODO: Have each core register a ->pobject_lives function pointer in the
+       Arenas struct, and call that pointer directly instead of having a messy
+       set of #if preparser conditions. */
+#if PARROT_GC_GMS
+    do {
+        if (!PObj_live_TEST(obj) && \
+                PObj_to_GMSH(obj)->gen->gen_no >= interp->gc_generation) \
+            parrot_gc_gms_Parrot_gc_mark_PObj_alive(interp, obj); \
+    } while (0);
+#else /* not PARROT_GC_GMS */
+
+    /* if object is live or on free list return */
+    if (PObj_is_live_or_free_TESTALL(obj))
+        return;
+
+#  if ! DISABLE_GC_DEBUG
+#    if GC_VERBOSE
+    if (CONSERVATIVE_POINTER_CHASING)
+        fprintf(stderr, "GC Warning! Unanchored %s %p found in system areas \n",
+                PObj_is_PMC_TEST(obj) ? "PMC" : "Buffer", obj);
+
+#    endif
+#  endif
+    /* mark it live */
+    PObj_live_SET(obj);
+
+    /* if object is a PMC and contains buffers or PMCs, then attach the PMC
+     * to the chained mark list. */
+    if (PObj_is_PMC_TEST(obj)) {
+        PMC * const p = (PMC *)obj;
+
+        if (PObj_is_special_PMC_TEST(obj))
+            mark_special(interp, p);
+
+#  ifndef NDEBUG
+        else if (p->pmc_ext && PMC_metadata(p))
+            fprintf(stderr, "GC: error obj %p (%s) has properties\n",
+                    (void *)p, (char*)p->vtable->whoami->strstart);
+#  endif
+    }
+#  if GC_VERBOSE
+    /* buffer GC_DEBUG stuff */
+    if (GC_DEBUG(interp) && PObj_report_TEST(obj))
+        fprintf(stderr, "GC: buffer %p pointing to %p marked live\n",
+                obj, PObj_bufstart((Buffer *)obj));
+#  endif
+#endif  /* PARROT_GC_GMS */
+}
+
+/*
+
+=item C<void Parrot_gc_initialize(PARROT_INTERP, void *stacktop)>
+
+Initializes the memory allocator and the garbage collection subsystem.
+Calls the initialization function associated with each collector, which
+is determined at compile time.
+
+The "stacktop" parameter is required; it provides an upper bound for
+stack scanning during a garbage collection run.
+
+=cut
 
+*/
+
+void
+Parrot_gc_initialize(PARROT_INTERP, ARGIN(void *stacktop))
+{
+    ASSERT_ARGS(Parrot_gc_initialize)
+    interp->arena_base = mem_allocate_zeroed_typed(Arenas);
+    interp->arena_base->sized_header_pools = NULL;
+
+    interp->lo_var_ptr = stacktop;
+
+#if PARROT_GC_MS
+    Parrot_gc_ms_init(interp);
+#endif
+#if PARROT_GC_IMS
+    Parrot_gc_ims_init(interp);
 #endif
+#if PARROT_GC_GMS
+    Parrot_gc_gms_init(interp);
+#endif
+
+    Parrot_initialize_memory_pools(interp);
+    Parrot_initialize_header_pools(interp);
+}
+
+/*
+
+=item C<void Parrot_gc_finalize(PARROT_INTERP)>
+
+Finalize the GC system, if the current GC core has defined a finalization
+routine.
+
+=cut
+
+*/
+
+void
+Parrot_gc_finalize(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_finalize)
+    if (interp->arena_base->finalize_gc_system)
+        interp->arena_base->finalize_gc_system(interp);
+}
+
 
 /*
 
-=item C<PMC * new_pmc_header(PARROT_INTERP, UINTVAL flags)>
+=item C<PMC * Parrot_gc_new_pmc_header(PARROT_INTERP, UINTVAL flags)>
 
 Gets a new PMC header from the PMC pool's free list. Guaranteed to return a
-valid PMC object or else Parrot will panic. Sets the necessary flags for the
-objects and initializes the PMC data pointer to C<NULL>.
+valid PMC object or else Parrot will throw an exception. Sets the necessary
+flags for the objects and initializes the PMC data pointer to C<NULL>.
 
 =cut
 
@@ -65,9 +221,9 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 PMC *
-new_pmc_header(PARROT_INTERP, UINTVAL flags)
+Parrot_gc_new_pmc_header(PARROT_INTERP, UINTVAL flags)
 {
-    ASSERT_ARGS(new_pmc_header)
+    ASSERT_ARGS(Parrot_gc_new_pmc_header)
     Small_Object_Pool * const pool = flags & PObj_constant_FLAG
             ? interp->arena_base->constant_pmc_pool
             : interp->arena_base->pmc_pool;
@@ -79,11 +235,12 @@
 
     /* clear flags, set is_PMC_FLAG */
     if (flags & PObj_is_PMC_EXT_FLAG) {
+        Small_Object_Pool * const pool = interp->arena_base->pmc_ext_pool;
         flags |= PObj_is_special_PMC_FLAG;
-        pmc->pmc_ext = new_pmc_ext(interp);
+        pmc->pmc_ext = (PMC_EXT *)pool->get_free_object(interp, pool);
 
         if (flags & PObj_is_PMC_shared_FLAG)
-            add_pmc_sync(interp, pmc);
+            Parrot_gc_add_pmc_sync(interp, pmc);
     }
     else
         pmc->pmc_ext = NULL;
@@ -95,35 +252,37 @@
     return pmc;
 }
 
-
 /*
 
-=item C<static PMC_EXT * new_pmc_ext(PARROT_INTERP)>
+=item C<void Parrot_gc_free_pmc_header(PARROT_INTERP, PMC *pmc)>
 
-Gets a new free C<PMC_EXT> structure from the PMC_EXT pool. A pointer to the
-new PMC_EXT is returned. Does not check to ensure the PMC_EXT is non-null
-before it is returned (yet).
+Adds the given PMC to the free list for later reuse.
 
 =cut
 
 */
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static PMC_EXT *
-new_pmc_ext(PARROT_INTERP)
+void
+Parrot_gc_free_pmc_header(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
-    ASSERT_ARGS(new_pmc_ext)
-    Small_Object_Pool * const pool = interp->arena_base->pmc_ext_pool;
-    /* XXX: Should we check here to ensure the PMC_EXT is non-null
-            like we do in C<new_pmc>? */
-    return (PMC_EXT *)pool->get_free_object(interp, pool);
-}
+    ASSERT_ARGS(Parrot_gc_free_pmc_header)
+    Small_Object_Pool * const pool = (PObj_constant_TEST(pmc)) ?
+        interp->arena_base->constant_pmc_pool : interp->arena_base->pmc_pool;
 
+    if (PObj_active_destroy_TEST(pmc))
+        VTABLE_destroy(interp, pmc);
+
+    if (PObj_is_PMC_EXT_TEST(pmc))
+        Parrot_gc_free_pmc_ext(interp, pmc);
+
+    PObj_flags_SETTO((PObj *)pmc, PObj_on_free_list_FLAG);
+    pool->add_free_object(interp, pool, (PObj *)pmc);
+    pool->num_free_objects++;
+}
 
 /*
 
-=item C<void add_pmc_ext(PARROT_INTERP, PMC *pmc)>
+=item C<void Parrot_gc_add_pmc_ext(PARROT_INTERP, PMC *pmc)>
 
 Obtains a new C<PMC_EXT> structure, and attaches it to the given C<PMC>.
 Sets the necessary flags associated with the PMC_EXT structure. Ensures
@@ -134,10 +293,14 @@
 */
 
 void
-add_pmc_ext(PARROT_INTERP, ARGMOD(PMC *pmc))
+Parrot_gc_add_pmc_ext(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
-    ASSERT_ARGS(add_pmc_ext)
-    pmc->pmc_ext = new_pmc_ext(interp);
+    ASSERT_ARGS(Parrot_gc_add_pmc_ext)
+    Small_Object_Pool * const pool = interp->arena_base->pmc_ext_pool;
+    pmc->pmc_ext = (PMC_EXT *)pool->get_free_object(interp, pool);
+    if (!pmc->pmc_ext)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,
+            "Parrot VM: PMC_EXT allocation failed!\n");
     PObj_is_PMC_EXT_SET(pmc);
 
 #ifdef PARROT_GC_IMS
@@ -153,38 +316,68 @@
     PMC_next_for_GC(pmc) = PMCNULL;
 }
 
+/*
+
+=item C<void Parrot_gc_free_pmc_ext(PARROT_INTERP, PMC *p)>
+
+Frees the C<PMC_EXT> structure attached to a PMC, if it exists.
+
+=cut
+
+*/
+
+void
+Parrot_gc_free_pmc_ext(PARROT_INTERP, ARGMOD(PMC *p))
+{
+    ASSERT_ARGS(Parrot_gc_free_pmc_ext)
+    /* if the PMC has a PMC_EXT structure, return it to the pool/arena */
+    Arenas            * const arena_base = interp->arena_base;
+    Small_Object_Pool * const ext_pool   = arena_base->pmc_ext_pool;
+
+    if (PObj_is_PMC_shared_TEST(p) && PMC_sync(p)) {
+        MUTEX_DESTROY(PMC_sync(p)->pmc_lock);
+        mem_internal_free(PMC_sync(p));
+        PMC_sync(p) = NULL;
+    }
+
+    if (p->pmc_ext) {
+        ext_pool->add_free_object(interp, ext_pool, p->pmc_ext);
+        ext_pool->num_free_objects++;
+    }
+
+    p->pmc_ext = NULL;
+}
 
 /*
 
-=item C<void add_pmc_sync(PARROT_INTERP, PMC *pmc)>
+=item C<void Parrot_gc_add_pmc_sync(PARROT_INTERP, PMC *pmc)>
 
 Adds a C<Sync*> structure to the given C<PMC>. Initializes the PMC's owner
-field and the synchronization mutext. Does not check to ensure the C<Sync *> is
-non-null.
+field and the synchronization mutext. Throws an exception if Sync allocation
+fails.
 
 =cut
 
 */
 
 void
-add_pmc_sync(PARROT_INTERP, ARGMOD(PMC *pmc))
+Parrot_gc_add_pmc_sync(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
-    ASSERT_ARGS(add_pmc_sync)
+    ASSERT_ARGS(Parrot_gc_add_pmc_sync)
     if (!PObj_is_PMC_EXT_TEST(pmc))
-        add_pmc_ext(interp, pmc);
+        Parrot_gc_add_pmc_ext(interp, pmc);
+    PMC_sync(pmc) = mem_allocate_typed(Sync);
+    if (!PMC_sync(pmc))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,
+            "Parrot VM: PMC Sync allocation failed!\n");
 
-    /* XXX: Should we test the Sync * for non-null? should we allocate these
-            from a bufferlike pool instead of directly from the system? */
-    PMC_sync(pmc)        = mem_allocate_typed(Sync);
     PMC_sync(pmc)->owner = interp;
-
     MUTEX_INIT(PMC_sync(pmc)->pmc_lock);
 }
 
-
 /*
 
-=item C<STRING * new_string_header(PARROT_INTERP, UINTVAL flags)>
+=item C<STRING * Parrot_gc_new_string_header(PARROT_INTERP, UINTVAL flags)>
 
 Returns a new C<STRING> header from the string pool or the constant string
 pool. Sets default flags on the string object: C<PObj_is_string_FLAG>,
@@ -198,13 +391,16 @@
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 STRING *
-new_string_header(PARROT_INTERP, UINTVAL flags)
+Parrot_gc_new_string_header(PARROT_INTERP, UINTVAL flags)
 {
-    ASSERT_ARGS(new_string_header)
+    ASSERT_ARGS(Parrot_gc_new_string_header)
     STRING * const string = (STRING *)get_free_buffer(interp,
         (flags & PObj_constant_FLAG)
             ? interp->arena_base->constant_string_header_pool
             : interp->arena_base->string_header_pool);
+    if (!string)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,
+            "Parrot VM: STRING allocation failed!\n");
 
     string->strstart        = NULL;
     PObj_get_FLAGS(string) |=
@@ -213,34 +409,35 @@
     return string;
 }
 
-
 /*
 
-=item C<Buffer * new_buffer_header(PARROT_INTERP)>
+=item C<void Parrot_gc_free_string_header(PARROT_INTERP, STRING *s)>
 
-Creates and returns a new C<Buffer> from the buffer header pool.  Calls
-C<get_free_buffer> to do all the work.
+Adds the given STRING to the free list for later reuse.
 
 =cut
 
 */
 
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-Buffer *
-new_buffer_header(PARROT_INTERP)
+void
+Parrot_gc_free_string_header(PARROT_INTERP, ARGMOD(STRING *s))
 {
-    ASSERT_ARGS(new_buffer_header)
-    return (Buffer *)get_free_buffer(interp,
-            interp->arena_base->buffer_header_pool);
+    ASSERT_ARGS(Parrot_gc_free_string_header)
+    if (!PObj_constant_TEST(s)) {
+        Small_Object_Pool * const pool = interp->arena_base->string_header_pool;
+        pool->add_free_object(interp, pool, s);
+    }
 }
 
-
 /*
 
-=item C<void * new_bufferlike_header(PARROT_INTERP, size_t size)>
+=item C<void * Parrot_gc_new_bufferlike_header(PARROT_INTERP, size_t size)>
 
 Returns a new buffer-like header from the appropriate sized pool.
+A "bufferlike object" is an object that is considered to be isomorphic to the
+PObj, so it will participate in normal GC. At the moment these are only used
+to create ListChunk objects in src/list.c and Stack_Chunk objects in
+src/stacks.c.
 
 =cut
 
@@ -249,272 +446,988 @@
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 void *
-new_bufferlike_header(PARROT_INTERP, size_t size)
+Parrot_gc_new_bufferlike_header(PARROT_INTERP, size_t size)
 {
-    ASSERT_ARGS(new_bufferlike_header)
+    ASSERT_ARGS(Parrot_gc_new_bufferlike_header)
     Small_Object_Pool * const pool = get_bufferlike_pool(interp, size);
 
     return get_free_buffer(interp, pool);
 }
 
+/*
+
+=item C<void Parrot_gc_free_bufferlike_header(PARROT_INTERP, PObj *obj, size_t
+size)>
+
+Free a bufferlike header that is not being used, so that Parrot can recycle
+it and use it again.
+
+=cut
+
+*/
+
+void
+Parrot_gc_free_bufferlike_header(PARROT_INTERP, ARGMOD(PObj *obj),
+    size_t size)
+{
+    ASSERT_ARGS(Parrot_gc_free_bufferlike_header)
+    Small_Object_Pool * const pool = get_bufferlike_pool(interp, size);
+    pool->add_free_object(interp, pool, obj);
+}
 
 /*
 
-=item C<void Parrot_gc_free_pmc(PARROT_INTERP, Small_Object_Pool *pool, PObj
-*p)>
+=item C<void Parrot_gc_allocate_buffer_storage_aligned(PARROT_INTERP, Buffer
+*buffer, size_t size)>
 
-Frees a PMC that is no longer being used. Calls a custom C<destroy> VTABLE
-method if one is available. If the PMC uses a PMC_EXT structure, that is freed
-as well.
+Allocates a chunk of memory of at least size C<size> for the given Buffer.
+buffer is guaranteed to be properly aligned for things like C<FLOATVALS>,
+so the size may be rounded up or down to guarantee that this alignment holds.
 
 =cut
 
 */
 
 void
-Parrot_gc_free_pmc(PARROT_INTERP, SHIM(Small_Object_Pool *pool),
-        ARGMOD(PObj *p))
+Parrot_gc_allocate_buffer_storage_aligned(PARROT_INTERP,
+    ARGOUT(Buffer *buffer), size_t size)
 {
-    ASSERT_ARGS(Parrot_gc_free_pmc)
-    PMC    * const pmc        = (PMC *)p;
-    Arenas * const arena_base = interp->arena_base;
+    ASSERT_ARGS(Parrot_gc_allocate_buffer_storage_aligned)
+    size_t new_size;
+    char *mem;
+
+    PObj_buflen(buffer) = 0;
+    PObj_bufstart(buffer) = NULL;
+    new_size = aligned_size(buffer, size);
+    mem = (char *)mem_allocate(interp, new_size,
+        interp->arena_base->memory_pool);
+    mem = aligned_mem(buffer, mem);
+    PObj_bufstart(buffer) = mem;
+    if (PObj_is_COWable_TEST(buffer))
+        new_size -= sizeof (void*);
+    PObj_buflen(buffer) = new_size;
+}
 
-    /* TODO collect objects with finalizers */
-    if (PObj_needs_early_gc_TEST(p))
-        --arena_base->num_early_gc_PMCs;
+/*
 
-    if (PObj_active_destroy_TEST(p))
-        VTABLE_destroy(interp, pmc);
+=item C<void Parrot_gc_reallocate_buffer_storage(PARROT_INTERP, Buffer *buffer,
+size_t newsize)>
 
-    if (PObj_is_PMC_EXT_TEST(p))
-         Parrot_gc_free_pmc_ext(interp, pmc);
+Reallocate the Buffer's buffer memory to the given size. The
+allocated buffer will not shrink. If the buffer was allocated with
+L<Parrot_allocate_aligned> the new buffer will also be aligned. As with
+all reallocation, the new buffer might have moved and the additional
+memory is not cleared.
 
-#ifndef NDEBUG
+=cut
 
-    pmc->pmc_ext     = (PMC_EXT *)0xdeadbeef;
-    pmc->vtable      = (VTABLE  *)0xdeadbeef;
+*/
 
-#endif
+void
+Parrot_gc_reallocate_buffer_storage(PARROT_INTERP, ARGMOD(Buffer *buffer),
+    size_t newsize)
+{
+    ASSERT_ARGS(Parrot_gc_reallocate_buffer_storage)
+    size_t copysize;
+    char  *mem;
+    Memory_Pool * const pool = interp->arena_base->memory_pool;
+    size_t new_size, needed, old_size;
+
+    /*
+     * we don't shrink buffers
+     */
+    if (newsize <= PObj_buflen(buffer))
+        return;
+
+    /*
+     * same as below but barely used and tested - only 3 list related
+     * tests do use true reallocation
+     *
+     * list.c, which does _reallocate, has 2 reallocations
+     * normally, which play ping pong with buffers.
+     * The normal case is therefore always to allocate a new block
+     */
+    new_size = aligned_size(buffer, newsize);
+    old_size = aligned_size(buffer, PObj_buflen(buffer));
+    needed   = new_size - old_size;
+
+    if ((pool->top_block->free >= needed)
+    &&  (pool->top_block->top  == (char *)PObj_bufstart(buffer) + old_size)) {
+        pool->top_block->free -= needed;
+        pool->top_block->top  += needed;
+        PObj_buflen(buffer) = newsize;
+        return;
+    }
+
+    copysize = PObj_buflen(buffer);
+
+    if (!PObj_COW_TEST(buffer))
+        pool->guaranteed_reclaimable += copysize;
+
+    pool->possibly_reclaimable += copysize;
+    mem                         = (char *)mem_allocate(interp, new_size, pool);
+    mem                         = aligned_mem(buffer, mem);
 
+    /* We shouldn't ever have a 0 from size, but we do. If we can track down
+     * those bugs, this can be removed which would make things cheaper */
+    if (copysize)
+        memcpy(mem, PObj_bufstart(buffer), copysize);
+
+    PObj_bufstart(buffer) = mem;
+
+    if (PObj_is_COWable_TEST(buffer))
+        new_size -= sizeof (void *);
+
+    PObj_buflen(buffer) = new_size;
 }
 
 /*
 
-=item C<void Parrot_gc_free_pmc_ext(PARROT_INTERP, PMC *p)>
+=item C<void Parrot_gc_allocate_string_storage(PARROT_INTERP, STRING *str,
+size_t size)>
 
-Frees the C<PMC_EXT> structure attached to a PMC, if it exists.
+Allocate the STRING's buffer memory to the given size. The allocated
+buffer maybe slightly bigger than the given C<size>. This function
+sets also C<< str->strstart >> to the new buffer location, C<< str->bufused >>
+is B<not> changed.
 
 =cut
 
 */
 
 void
-Parrot_gc_free_pmc_ext(PARROT_INTERP, ARGMOD(PMC *p))
+Parrot_gc_allocate_string_storage(PARROT_INTERP, ARGOUT(STRING *str),
+    size_t size)
 {
-    ASSERT_ARGS(Parrot_gc_free_pmc_ext)
-    /* if the PMC has a PMC_EXT structure, return it to the pool/arena */
-    Arenas            * const arena_base = interp->arena_base;
-    Small_Object_Pool * const ext_pool   = arena_base->pmc_ext_pool;
+    ASSERT_ARGS(Parrot_gc_allocate_string_storage)
+    size_t       new_size;
+    Memory_Pool *pool;
+    char        *mem;
+
+    PObj_buflen(str)   = 0;
+    PObj_bufstart(str) = NULL;
+
+    /* there's no sense in allocating zero memory, when the overhead of
+     * allocating a string is one pointer; this can fill the pools in an
+     * uncompactable way.  See RT #42320.
+     */
+    if (size == 0)
+        return;
 
-    if (PObj_is_PMC_shared_TEST(p) && PMC_sync(p)) {
-        MUTEX_DESTROY(PMC_sync(p)->pmc_lock);
-        mem_internal_free(PMC_sync(p));
-        PMC_sync(p) = NULL;
+    pool     = PObj_constant_TEST(str)
+                ? interp->arena_base->constant_string_pool
+                : interp->arena_base->memory_pool;
+
+    new_size = aligned_string_size(size);
+    mem      = (char *)mem_allocate(interp, new_size, pool);
+    mem     += sizeof (void*);
+
+    PObj_bufstart(str) = str->strstart = mem;
+    PObj_buflen(str)   = new_size - sizeof (void*);
+}
+
+/*
+
+=item C<void Parrot_gc_reallocate_string_storage(PARROT_INTERP, STRING *str,
+size_t newsize)>
+
+Reallocate the STRING's buffer memory to the given size. The allocated
+buffer will not shrink. This function sets also C<str-E<gt>strstart> to the
+new buffer location, C<str-E<gt>bufused> is B<not> changed.
+
+=cut
+
+*/
+
+void
+Parrot_gc_reallocate_string_storage(PARROT_INTERP, ARGMOD(STRING *str),
+    size_t newsize)
+{
+    ASSERT_ARGS(Parrot_gc_reallocate_string_storage)
+    size_t copysize;
+    char *mem, *oldmem;
+    size_t new_size, needed, old_size;
+
+    Memory_Pool * const pool =
+        PObj_constant_TEST(str)
+            ? interp->arena_base->constant_string_pool
+            : interp->arena_base->memory_pool;
+
+    /* if the requested size is smaller then buflen, we are done */
+    if (newsize <= PObj_buflen(str))
+        return;
+
+    /*
+     * first check, if we can reallocate:
+     * - if the passed strings buffer is the last string in the pool and
+     * - if there is enough size, we can just move the pool's top pointer
+     */
+    new_size = aligned_string_size(newsize);
+    old_size = aligned_string_size(PObj_buflen(str));
+    needed   = new_size - old_size;
+
+    if (pool->top_block->free >= needed
+    &&  pool->top_block->top  == (char *)PObj_bufstart(str) + old_size) {
+        pool->top_block->free -= needed;
+        pool->top_block->top  += needed;
+        PObj_buflen(str) = new_size - sizeof (void*);
+        return;
     }
 
-    if (p->pmc_ext)
-        ext_pool->add_free_object(interp, ext_pool, p->pmc_ext);
+    PARROT_ASSERT(str->bufused <= newsize);
 
-    ext_pool->num_free_objects++;
+    /* only copy used memory, not total string buffer */
+    copysize = str->bufused;
 
-    p->pmc_ext = NULL;
+    if (!PObj_COW_TEST(str))
+        pool->guaranteed_reclaimable += PObj_buflen(str);
+
+    pool->possibly_reclaimable += PObj_buflen(str);
+
+    mem = (char *)mem_allocate(interp, new_size, pool);
+    mem += sizeof (void *);
+
+    /* copy mem from strstart, *not* bufstart */
+    oldmem             = str->strstart;
+    PObj_bufstart(str) = (void *)mem;
+    str->strstart      = mem;
+    PObj_buflen(str)   = new_size - sizeof (void*);
+
+    /* We shouldn't ever have a 0 from size, but we do. If we can track down
+     * those bugs, this can be removed which would make things cheaper */
+    if (copysize)
+        memcpy(mem, oldmem, copysize);
 }
 
 /*
 
-=item C<void Parrot_gc_free_sysmem(PARROT_INTERP, Small_Object_Pool *pool, PObj
-*b)>
+=item C<void Parrot_gc_mark_and_sweep(PARROT_INTERP, UINTVAL flags)>
 
-If the PMC uses memory allocated directly from the system, this function
-frees that memory.
+Calls the configured garbage collector to find and reclaim unused
+headers. Performs a complete mark & sweep run of the GC.
 
 =cut
 
 */
 
 void
-Parrot_gc_free_sysmem(SHIM_INTERP, SHIM(Small_Object_Pool *pool),
-        ARGMOD(PObj *b))
+Parrot_gc_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
 {
-    ASSERT_ARGS(Parrot_gc_free_sysmem)
-    /* has sysmem allocated, e.g. Parrot_str_pin */
-    if (PObj_sysmem_TEST(b) && PObj_bufstart(b))
-        mem_sys_free(PObj_bufstart(b));
+    ASSERT_ARGS(Parrot_gc_mark_and_sweep)
+    interp->arena_base->do_gc_mark(interp, flags);
+    parrot_gc_context(interp);
+}
+
+/*
+
+=item C<void Parrot_gc_compact_memory_pool(PARROT_INTERP)>
+
+Scan the string pools and compact them. This does not perform a GC mark or
+sweep run, and does not check whether string buffers are still alive.
+Redirects to C<compact_pool>.
+
+=cut
+
+*/
 
-    PObj_bufstart(b) = NULL;
-    PObj_buflen(b)   = 0;
+void
+Parrot_gc_compact_memory_pool(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_compact_memory_pool)
+    compact_pool(interp, interp->arena_base->memory_pool);
 }
 
 /*
 
-=item C<void Parrot_gc_free_buffer_malloc(PARROT_INTERP, Small_Object_Pool
-*pool, PObj *b)>
+=item C<void Parrot_gc_merge_header_pools(Interp *dest_interp, Interp
+*source_interp)>
 
-Frees the given buffer, returning the storage space to the operating system
-and removing it from Parrot's memory management system. If the buffer is COW,
-The buffer is not freed if the reference count is greater then 1.
+Merges the header pools of C<source_interp> into those of C<dest_interp>.
+(Used to deal with shared objects left after interpreter destruction.)
 
 =cut
 
 */
 
 void
-Parrot_gc_free_buffer_malloc(SHIM_INTERP, SHIM(Small_Object_Pool *pool),
-        ARGMOD(PObj *b))
+Parrot_gc_merge_header_pools(ARGMOD(Interp *dest_interp),
+    ARGIN(Interp *source_interp))
 {
-    ASSERT_ARGS(Parrot_gc_free_buffer_malloc)
-    /* free allocated space at (int *)bufstart - 1, but not if it used COW or is
-     * external */
-    PObj_buflen(b) = 0;
+    ASSERT_ARGS(Parrot_gc_merge_header_pools)
 
-    if (!PObj_bufstart(b) || PObj_is_external_or_free_TESTALL(b))
-        return;
+    Arenas * const dest_arena   = dest_interp->arena_base;
+    Arenas * const source_arena = source_interp->arena_base;
+    UINTVAL        i;
+
+    /* heavily borrowed from forall_header_pools */
+    fix_pmc_syncs(dest_interp, source_arena->constant_pmc_pool);
+    Parrot_small_object_pool_merge(dest_interp, dest_arena->constant_pmc_pool,
+            source_arena->constant_pmc_pool);
+
+    fix_pmc_syncs(dest_interp, source_arena->pmc_pool);
+    Parrot_small_object_pool_merge(dest_interp, dest_arena->pmc_pool,
+            source_arena->pmc_pool);
+
+    Parrot_small_object_pool_merge(dest_interp,
+            dest_arena->constant_string_header_pool,
+            source_arena->constant_string_header_pool);
+
+    Parrot_small_object_pool_merge(dest_interp,
+            dest_arena->pmc_ext_pool, source_arena->pmc_ext_pool);
+
+    for (i = 0; i < source_arena->num_sized; ++i) {
+        if (!source_arena->sized_header_pools[i])
+            continue;
+
+        if (i >= dest_arena->num_sized
+        || !dest_arena->sized_header_pools[i]) {
+            Small_Object_Pool *ignored = get_bufferlike_pool(dest_interp,
+                    i * sizeof (void *));
+            UNUSED(ignored);
+            PARROT_ASSERT(dest_arena->sized_header_pools[i]);
+        }
+
+        Parrot_small_object_pool_merge(dest_interp,
+            dest_arena->sized_header_pools[i],
+            source_arena->sized_header_pools[i]);
+    }
+}
+
+/*
+
+=item C<static void fix_pmc_syncs(Interp *dest_interp, Small_Object_Pool *pool)>
+
+Walks through the given arena, looking for all live and shared PMCs,
+transferring their sync values to the destination interpreter.
+
+=cut
+
+*/
 
-    if (PObj_COW_TEST(b)) {
-        INTVAL * const refcount = PObj_bufrefcountptr(b);
+static void
+fix_pmc_syncs(ARGMOD(Interp *dest_interp), ARGIN(Small_Object_Pool *pool))
+{
+    ASSERT_ARGS(fix_pmc_syncs)
+    Small_Object_Arena *cur_arena;
+    const UINTVAL       object_size = pool->object_size;
+
+    for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) {
+        PMC   *p = (PMC *)((char*)cur_arena->start_objects + GC_HEADER_SIZE);
+        size_t i;
+
+        for (i = 0; i < cur_arena->used; i++) {
+            if (!PObj_on_free_list_TEST(p) && PObj_is_PMC_TEST(p)) {
+                if (PObj_is_PMC_shared_TEST(p))
+                    PMC_sync(p)->owner = dest_interp;
+                else
+                    Parrot_ex_throw_from_c_args(dest_interp, NULL,
+                        EXCEPTION_INTERP_ERROR,
+                        "Unshared PMC still alive after interpreter"
+                        "destruction. address=%p, base_type=%d\n",
+                        p, p->vtable->base_type);
+            }
 
-        if (--(*refcount) == 0) {
-            mem_sys_free(refcount); /* the actual bufstart */
+            p = (PMC *)((char *)p + object_size);
         }
     }
-    else
-        mem_sys_free(PObj_bufrefcountptr(b));
 }
 
 /*
 
-=item C<void Parrot_gc_free_buffer(PARROT_INTERP, Small_Object_Pool *pool, PObj
-*b)>
+=item C<void Parrot_gc_destroy_header_pools(PARROT_INTERP)>
 
-Frees a buffer, returning it to the memory pool for Parrot to possibly
-reuse later.
+Performs a garbage collection sweep on all pools, then frees them.  Calls
+C<Parrot_forall_header_pools> to loop over all the pools, passing
+C<sweep_cb_pmc> and C<sweep_cb_buf> callback routines. Frees the array of sized
+header pointers in the C<Arenas> structure too.
 
 =cut
 
 */
 
 void
-Parrot_gc_free_buffer(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), ARGMOD(PObj *b))
+Parrot_gc_destroy_header_pools(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_destroy_header_pools)
+    INTVAL pass;
+
+    /* const/non const COW strings life in different pools
+     * so in first pass
+     * COW refcount is done, in 2. refcounting
+     * in 3rd freeing
+     */
+#ifdef GC_IS_MALLOC
+    const INTVAL start = 0;
+#else
+    const INTVAL start = 2;
+#endif
+
+    Parrot_forall_header_pools(interp, POOL_PMC, NULL, sweep_cb_pmc);
+    Parrot_forall_header_pools(interp, POOL_PMC | POOL_CONST, NULL,
+            sweep_cb_pmc);
+
+    for (pass = start; pass <= 2; pass++) {
+        Parrot_forall_header_pools(interp, POOL_BUFFER | POOL_CONST,
+                (void *)pass, sweep_cb_buf);
+    }
+
+    free_pool(interp->arena_base->pmc_ext_pool);
+    interp->arena_base->pmc_ext_pool = NULL;
+
+    mem_internal_free(interp->arena_base->sized_header_pools);
+    interp->arena_base->sized_header_pools = NULL;
+}
+
+/*
+
+=item C<static int sweep_cb_pmc(PARROT_INTERP, Small_Object_Pool *pool, int
+flag, void *arg)>
+
+Performs a garbage collection sweep of the given pmc pool, then frees it. Calls
+C<Parrot_gc_sweep> to perform the sweep, and C<free_pool> to free the pool and
+all its arenas. Always returns C<0>.
+
+=cut
+
+*/
+
+static int
+sweep_cb_pmc(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool),
+        SHIM(int flag), SHIM(void *arg))
 {
-    ASSERT_ARGS(Parrot_gc_free_buffer)
-    Memory_Pool * const mem_pool = (Memory_Pool *)pool->mem_pool;
+    Parrot_gc_sweep(interp, pool);
+    free_pool(pool);
+    return 0;
+}
+
+/*
+
+=item C<static int sweep_cb_buf(PARROT_INTERP, Small_Object_Pool *pool, int
+flag, void *arg)>
 
-    /* XXX Jarkko reported that on irix pool->mem_pool was NULL, which really
-     * shouldn't happen */
-    if (mem_pool) {
-        if (!PObj_COW_TEST(b))
-            mem_pool->guaranteed_reclaimable += PObj_buflen(b);
+Performs a final garbage collection sweep, then frees the pool. Calls
+C<Parrot_gc_sweep> to perform the sweep, and C<free_pool> to free the pool and
+all its arenas.
 
-         mem_pool->possibly_reclaimable += PObj_buflen(b);
+=cut
+
+*/
+
+static int
+sweep_cb_buf(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool), SHIM(int flag),
+        ARGIN(void *arg))
+{
+#ifdef GC_IS_MALLOC
+    const int pass = (int)(INTVAL)arg;
+
+    if (pass == 0)
+        clear_cow(interp, pool, 1);
+    else if (pass == 1)
+        used_cow(interp, pool, 1);
+    else
+#endif
+
+    {
+        UNUSED(arg);
+        Parrot_gc_sweep(interp, pool);
+        free_pool(pool);
     }
 
-    PObj_buflen(b)        = 0;
+    return 0;
 }
 
 /*
 
-=item C<void Parrot_gc_profile_start(PARROT_INTERP)>
+=item C<void Parrot_gc_destroy_memory_pools(PARROT_INTERP)>
 
-Records the start time of a GC mark run when profiling is enabled.
+Destroys the memory pool and the constant string pool. Loop through both
+pools and destroy all memory blocks contained in them. Once all the
+blocks are freed, free the pools themselves.
 
 =cut
 
 */
 
 void
-Parrot_gc_profile_start(PARROT_INTERP)
+Parrot_gc_destroy_memory_pools(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_destroy_memory_pools)
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        Memory_Pool * const pool = i ?
+                interp->arena_base->constant_string_pool :
+                interp->arena_base->memory_pool;
+        Memory_Block *cur_block;
+
+        cur_block = pool->top_block;
+
+        while (cur_block) {
+            Memory_Block * const next_block = cur_block->prev;
+            mem_internal_free(cur_block);
+            cur_block = next_block;
+        }
+
+        mem_internal_free(pool);
+    }
+}
+
+/*
+
+=item C<int Parrot_gc_ptr_in_memory_pool(PARROT_INTERP, void *bufstart)>
+
+Determines if the given C<bufstart> pointer points to a location inside the
+memory pool. Returns 1 if the pointer is in the memory pool, 0 otherwise.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+int
+Parrot_gc_ptr_in_memory_pool(PARROT_INTERP, ARGIN(void *bufstart))
+{
+    ASSERT_ARGS(Parrot_gc_ptr_in_memory_pool)
+    Memory_Pool * const pool = interp->arena_base->memory_pool;
+    Memory_Block * cur_block = pool->top_block;
+
+    while (cur_block) {
+        if ((char *)bufstart >= cur_block->start &&
+            (char *) bufstart < cur_block->start + cur_block->size) {
+            return 1;
+        }
+        cur_block = cur_block->prev;
+    }
+    return 0;
+}
+
+/*
+
+=item C<int Parrot_gc_ptr_is_pmc(PARROT_INTERP, void *ptr)>
+
+Determines if a given pointer is a PMC or not. It is a PMC if it is properly
+contained in one of this interpreters PMC pools.
+
+=cut
+
+*/
+
+int
+Parrot_gc_ptr_is_pmc(PARROT_INTERP, ARGIN(void *ptr))
+{
+    ASSERT_ARGS(Parrot_gc_ptr_is_pmc)
+    return contained_in_pool(interp->arena_base->pmc_pool, ptr) ||
+           contained_in_pool(interp->arena_base->constant_pmc_pool, ptr);
+}
+
+/*
+
+=item C<int Parrot_gc_get_pmc_index(PARROT_INTERP, PMC* pmc)>
+
+Gets the index of the PMC in the pool. The first PMC in the first pool is 1,
+the second is 2, etc.
+
+=cut
+
+*/
+
+int
+Parrot_gc_get_pmc_index(PARROT_INTERP, ARGIN(PMC* pmc))
 {
-    ASSERT_ARGS(Parrot_gc_profile_start)
-    if (Interp_flags_TEST(interp, PARROT_PROFILE_FLAG))
-        interp->profile->gc_time = Parrot_floatval_time();
+    ASSERT_ARGS(Parrot_gc_get_pmc_index)
+    UINTVAL id = 1;     /* first PMC in first arena */
+    Small_Object_Arena *arena;
+    Small_Object_Pool *pool;
+
+    pmc = (PMC*)PObj_to_ARENA(pmc);
+    pool = interp->arena_base->pmc_pool;
+    for (arena = pool->last_Arena; arena; arena = arena->prev) {
+        const ptrdiff_t ptr_diff = (ptrdiff_t)pmc - (ptrdiff_t)arena->start_objects;
+        if (ptr_diff >= 0 && ptr_diff <
+                (ptrdiff_t)(arena->used * pool->object_size)) {
+            PARROT_ASSERT(ptr_diff % pool->object_size == 0);
+            id += ptr_diff / pool->object_size;
+            return id;
+        }
+        id += arena->total_objects;
+    }
+
+    pool = interp->arena_base->constant_pmc_pool;
+    for (arena = pool->last_Arena; arena; arena = arena->prev) {
+        const ptrdiff_t ptr_diff = (ptrdiff_t)pmc - (ptrdiff_t)arena->start_objects;
+        if (ptr_diff >= 0 && ptr_diff <
+                (ptrdiff_t)(arena->used * pool->object_size)) {
+            PARROT_ASSERT(ptr_diff % pool->object_size == 0);
+            id += ptr_diff / pool->object_size;
+            return id;
+        }
+        id += arena->total_objects;
+    }
+
+    Parrot_ex_throw_from_c_args(interp, NULL, 1, "Couldn't find PMC in arenas");
 }
 
 /*
 
-=item C<void Parrot_gc_profile_end(PARROT_INTERP, int what)>
+=item C<void Parrot_gc_cleanup_next_for_GC(PARROT_INTERP)>
 
-Records the end time of the GC mark run part C<what> run when profiling is
-enabled. Also record start time of next part.
+Cleans up the C<next_for_GC> pointers. Sets all of them in the PMC and Constant
+PMC pools to NULL.
 
 =cut
 
 */
 
 void
-Parrot_gc_profile_end(PARROT_INTERP, int what)
+Parrot_gc_cleanup_next_for_GC(PARROT_INTERP)
 {
-    ASSERT_ARGS(Parrot_gc_profile_end)
-    if (Interp_flags_TEST(interp, PARROT_PROFILE_FLAG)) {
-        RunProfile * const profile = interp->profile;
-        const FLOATVAL     now     = Parrot_floatval_time();
+    ASSERT_ARGS(Parrot_gc_cleanup_next_for_GC)
+    cleanup_next_for_GC_pool(interp->arena_base->pmc_pool);
+    cleanup_next_for_GC_pool(interp->arena_base->constant_pmc_pool);
+}
 
-        profile->data[what].numcalls++;
-        profile->data[what].time += now - profile->gc_time;
+/*
 
-        /*
-         * we've recorded the time of a GC piece from
-         * gc_time until now, so add this to the start of the
-         * currently executing opcode, which hasn't run this
-         * interval.
-         */
-        profile->starttime += now - profile->gc_time;
+=item C<static void cleanup_next_for_GC_pool(Small_Object_Pool *pool)>
+
+Sets all the C<next_for_GC> pointers to C<NULL>.
+
+=cut
 
-        /* prepare start for next step */
-        profile->gc_time    = now;
+*/
+
+static void
+cleanup_next_for_GC_pool(ARGIN(Small_Object_Pool *pool))
+{
+    ASSERT_ARGS(cleanup_next_for_GC_pool)
+    Small_Object_Arena *arena;
+
+    for (arena = pool->last_Arena; arena; arena = arena->prev) {
+        PMC *p = (PMC *)arena->start_objects;
+        UINTVAL i;
+
+        for (i = 0; i < arena->used; i++) {
+            if (!PObj_on_free_list_TEST(p)) {
+                if (p->pmc_ext)
+                    PMC_next_for_GC(p) = PMCNULL;
+            }
+            p++;
+        }
     }
 }
 
 /*
 
-=item C<void Parrot_gc_ms_run_init(PARROT_INTERP)>
+=item C<int Parrot_gc_active_sized_buffers(PARROT_INTERP)>
 
-Prepares the collector for a mark & sweep GC run. This is the
-initializer function for the MS garbage collector.
+Returns the number of actively used sized buffers.
 
 =cut
 
 */
 
+int
+Parrot_gc_active_sized_buffers(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_active_sized_buffers)
+    int j, ret = 0;
+    const Arenas * const arena_base = interp->arena_base;
+    for (j = 0; j < (INTVAL)arena_base->num_sized; j++) {
+        Small_Object_Pool * const header_pool =
+            arena_base->sized_header_pools[j];
+        if (header_pool)
+            ret += header_pool->total_objects -
+                header_pool->num_free_objects;
+    }
+    return ret;
+}
+
+/*
+
+=item C<int Parrot_gc_total_sized_buffers(PARROT_INTERP)>
+
+Returns the total number of sized buffers that we are managing.
+
+=cut
+
+*/
+
+int
+Parrot_gc_total_sized_buffers(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_total_sized_buffers)
+    int j, ret = 0;
+    const Arenas * const arena_base = interp->arena_base;
+    for (j = 0; j < (INTVAL)arena_base->num_sized; j++) {
+        Small_Object_Pool * const header_pool =
+            arena_base->sized_header_pools[j];
+        if (header_pool)
+            ret += header_pool->total_objects;
+    }
+    return ret;
+}
+
+/*
+
+=item C<int Parrot_gc_active_pmcs(PARROT_INTERP)>
+
+Return the number of actively used PMCs.
+
+=cut
+
+*/
+
+int
+Parrot_gc_active_pmcs(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_active_pmcs)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->pmc_pool->total_objects -
+           arena_base->pmc_pool->num_free_objects;
+}
+
+/*
+
+=item C<int Parrot_gc_total_pmcs(PARROT_INTERP)>
+
+Return the total number of PMCs that we are managing.
+
+=cut
+
+*/
+
+int
+Parrot_gc_total_pmcs(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_total_pmcs)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->pmc_pool->total_objects;
+}
+
+/*
+
+=item C<size_t Parrot_gc_count_mark_runs(PARROT_INTERP)>
+
+Return the number of mark runs the GC has performed.
+
+=item C<size_t Parrot_gc_count_collect_runs(PARROT_INTERP)>
+
+Return the number of collect runs the GC has performed.
+
+=item C<size_t Parrot_gc_count_lazy_mark_runs(PARROT_INTERP)>
+
+Return the number of lazy mark runs the GC has performed.
+
+=item C<size_t Parrot_gc_total_memory_allocated(PARROT_INTERP)>
+
+Return the total number of memory allocations made by the GC.
+
+=item C<size_t Parrot_gc_headers_alloc_since_last_collect(PARROT_INTERP)>
+
+Return the number of new headers allocated since the last collection run.
+
+=item C<size_t Parrot_gc_mem_alloc_since_last_collect(PARROT_INTERP)>
+
+Return the number of memory allocations made since the last collection run.
+
+=item C<UINTVAL Parrot_gc_total_copied(PARROT_INTERP)>
+
+=item C<UINTVAL Parrot_gc_impatient_pmcs(PARROT_INTERP)>
+
+Returns the number of PMCs that are marked as needing timely destruction.
+
+=item C<UINTVAL Parrot_gc_extended_pmcs(PARROT_INTERP)>
+
+Returns the number of extended PMCs.
+
+=cut
+
+*/
+
+size_t
+Parrot_gc_count_mark_runs(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_count_mark_runs)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->gc_mark_runs;
+}
+
+size_t
+Parrot_gc_count_collect_runs(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_count_collect_runs)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->gc_collect_runs;
+}
+
+size_t
+Parrot_gc_count_lazy_mark_runs(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_count_lazy_mark_runs)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->gc_lazy_mark_runs;;
+}
+
+size_t
+Parrot_gc_total_memory_allocated(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_total_memory_allocated)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->memory_allocated;
+}
+
+size_t
+Parrot_gc_headers_alloc_since_last_collect(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_headers_alloc_since_last_collect)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->header_allocs_since_last_collect;
+}
+
+size_t
+Parrot_gc_mem_alloc_since_last_collect(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_mem_alloc_since_last_collect)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->mem_allocs_since_last_collect;
+}
+
+UINTVAL
+Parrot_gc_total_copied(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_total_copied)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->memory_collected;
+}
+
+UINTVAL
+Parrot_gc_impatient_pmcs(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_impatient_pmcs)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->num_early_gc_PMCs;
+}
+
+UINTVAL
+Parrot_gc_extended_pmcs(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_extended_pmcs)
+    const Arenas * const arena_base = interp->arena_base;
+    return arena_base->num_extended_PMCs;
+}
+
+/*
+
+=item C<void Parrot_block_GC_mark(PARROT_INTERP)>
+
+Blocks the GC from performing it's mark phase.
+
+=item C<void Parrot_unblock_GC_mark(PARROT_INTERP)>
+
+Unblocks the GC mark.
+
+=item C<void Parrot_block_GC_sweep(PARROT_INTERP)>
+
+Blocks the GC from performing it's sweep phase.
+
+=item C<void Parrot_unblock_GC_sweep(PARROT_INTERP)>
+
+Unblocks GC sweep.
+
+=item C<unsigned int Parrot_is_blocked_GC_mark(PARROT_INTERP)>
+
+Determines if the GC mark is currently blocked.
+
+=item C<unsigned int Parrot_is_blocked_GC_sweep(PARROT_INTERP)>
+
+Determines if the GC sweep is currently blocked.
+
+=item C<void Parrot_gc_completely_unblock(PARROT_INTERP)>
+
+Completely unblock the GC mark and sweep. This is only used at interpreter
+destruction, using it anywhere else will cause problems.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_block_GC_mark(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_block_GC_mark)
+    interp->arena_base->gc_mark_block_level++;
+    Parrot_shared_gc_block(interp);
+}
+
+PARROT_EXPORT
+void
+Parrot_unblock_GC_mark(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_unblock_GC_mark)
+    if (interp->arena_base->gc_mark_block_level) {
+        interp->arena_base->gc_mark_block_level--;
+        Parrot_shared_gc_unblock(interp);
+    }
+}
+
+PARROT_EXPORT
+void
+Parrot_block_GC_sweep(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_block_GC_sweep)
+    interp->arena_base->gc_sweep_block_level++;
+}
+
+PARROT_EXPORT
 void
-Parrot_gc_ms_run_init(PARROT_INTERP)
+Parrot_unblock_GC_sweep(PARROT_INTERP)
 {
-    ASSERT_ARGS(Parrot_gc_ms_run_init)
-    Arenas * const arena_base       = interp->arena_base;
+    ASSERT_ARGS(Parrot_unblock_GC_sweep)
+    if (interp->arena_base->gc_sweep_block_level)
+        interp->arena_base->gc_sweep_block_level--;
+}
 
-    arena_base->gc_trace_ptr        = NULL;
-    arena_base->gc_mark_start       = NULL;
-    arena_base->num_early_PMCs_seen = 0;
-    arena_base->num_extended_PMCs   = 0;
+PARROT_EXPORT
+unsigned int
+Parrot_is_blocked_GC_mark(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_is_blocked_GC_mark)
+    return interp->arena_base->gc_mark_block_level;
 }
 
+PARROT_EXPORT
+unsigned int
+Parrot_is_blocked_GC_sweep(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_is_blocked_GC_sweep)
+    return interp->arena_base->gc_sweep_block_level;
+}
+
+void
+Parrot_gc_completely_unblock(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_completely_unblock)
+    interp->arena_base->gc_mark_block_level  = 0;
+    interp->arena_base->gc_sweep_block_level = 0;
+}
 
 /*
 
-=item C<void Parrot_do_gc_run(PARROT_INTERP, UINTVAL flags)>
+=item C<void Parrot_gc_pmc_needs_early_collection(PARROT_INTERP, PMC *pmc)>
 
-Calls the configured garbage collector to find and reclaim unused
-headers.
+Mark a PMC as needing timely destruction
 
 =cut
 
 */
 
 void
-Parrot_do_gc_run(PARROT_INTERP, UINTVAL flags)
+Parrot_gc_pmc_needs_early_collection(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
-    ASSERT_ARGS(Parrot_do_gc_run)
-    interp->arena_base->do_gc_mark(interp, flags);
-    parrot_gc_context(interp);
+    ASSERT_ARGS(Parrot_gc_pmc_needs_early_collection)
+    PObj_needs_early_gc_SET(pmc);
+    ++interp->arena_base->num_early_gc_PMCs;
 }
 
 /*

Modified: branches/pmc_pct/src/gc/gc_private.h
==============================================================================
--- branches/pmc_pct/src/gc/gc_private.h	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/gc_private.h	Fri May 15 21:49:40 2009	(r38803)
@@ -29,7 +29,12 @@
 extern void *flush_reg_store(void);
 #  define BACKING_STORE_BASE 0x80000fff80000000
 
-#endif
+#  ifdef __hpux
+#    include <sys/pstat.h>
+#    include <ia64/sys/inline.h>
+#  endif /* __hpux */
+
+#endif /* __ia64__ */
 
 /* We're using this here to add an additional pointer to a PObj without
    having to actually add an entire pointer to every PObj-alike structure
@@ -43,6 +48,171 @@
     PObj *next_ptr;
 } GC_MS_PObj_Wrapper;
 
+typedef struct Small_Object_Arena {
+    size_t                     used;
+    size_t                     total_objects;
+    struct Small_Object_Arena *prev;
+    struct Small_Object_Arena *next;
+    void                      *start_objects;
+} Small_Object_Arena;
+
+#if PARROT_GC_GMS
+/*
+ * all objects have this header in front of the actual
+ * object pointer. The prev/next pointers chain all existing
+ * objects for one pool (sizeclass) together.
+ *
+ * XXX this could lead to unaligned FLOATVALs in the adjacent PMC
+ *     if that's true either insert a dummy or reorder PMC members
+ *     ??? How is that possible?
+ */
+typedef struct _gc_gms_hdr {
+    struct _gc_gms_hdr *prev;
+    struct _gc_gms_hdr *next;
+    struct _gc_gms_gen *gen;
+    void *gc_dummy_align;       /* see above */
+} Gc_gms_hdr;
+
+#  define PObj_to_GMSH(o) (((Gc_gms_hdr*)(o))-1)
+#  define GMSH_to_PObj(p) ((PObj*) ((p)+1))
+
+/* the structure uses 2 ptrs itself */
+#  define GC_GMS_STORE_SIZE (64-2)
+
+typedef struct _gc_gms_hdr_store {
+    struct _gc_gms_hdr_store *next;
+    Gc_gms_hdr **ptr;                           /* insert location */
+    Gc_gms_hdr * (store[GC_GMS_STORE_SIZE]);    /* array of hdr pointers */
+} Gc_gms_hdr_store;
+
+typedef struct _gc_gms_hdr_list {
+    Gc_gms_hdr_store *first;
+    Gc_gms_hdr_store *last;
+} Gc_gms_hdr_list;
+
+
+/*
+ * all objects belong to one generation
+ */
+typedef struct _gc_gms_gen {
+    UINTVAL gen_no;                     /* generation number */
+    UINTVAL timely_destruct_obj_sofar;  /* sum up to this generation */
+    UINTVAL black_color;                /* live color of this generation */
+    struct _gc_gms_hdr *first;          /* first header in this generation */
+    struct _gc_gms_hdr *last;           /* last header in this generation */
+    struct _gc_gms_hdr *fin;            /* need destruction/finalization */
+    struct Small_Object_Pool *pool;     /* where this generation belongs to */
+    Gc_gms_hdr_list igp;                /* IGPs for this generation */
+    UINTVAL n_possibly_dead;            /* overwritten count */
+    UINTVAL n_objects;                  /* live objects count */
+    struct _gc_gms_gen *prev;
+    struct _gc_gms_gen *next;
+} Gc_gms_gen;
+
+#endif /* PARROT_GC_GMS */
+
+/* Tracked resource pool */
+typedef struct Small_Object_Pool {
+    Small_Object_Arena *last_Arena;
+    /* Size in bytes of an individual pool item. This size may include
+     * a GC-system specific GC header.
+     * See the macros below.
+     */
+    size_t object_size;
+    size_t objects_per_alloc;
+    size_t total_objects;
+    size_t num_free_objects;    /* number of resources in the free pool */
+    int skip;
+    size_t replenish_level;
+    void *free_list;
+    /* adds a free object to the pool's free list  */
+    add_free_object_fn_type     add_free_object;
+    get_free_object_fn_type     get_free_object;
+    alloc_objects_fn_type       alloc_objects;
+    alloc_objects_fn_type       more_objects;
+    gc_object_fn_type           gc_object;
+    /* gets and removes a free object from the pool's free list */
+    /* allocates more objects */
+    struct Memory_Pool *mem_pool;
+    size_t start_arena_memory;
+    size_t end_arena_memory;
+    const char *name;
+#if PARROT_GC_GMS
+    struct _gc_gms_hdr marker;          /* limit of list */
+    struct _gc_gms_hdr *black;          /* alive */
+    struct _gc_gms_hdr *black_fin;      /* alive, needs destruction */
+    struct _gc_gms_hdr *gray;           /* to be scanned */
+    struct _gc_gms_hdr *white;          /* unprocessed */
+    struct _gc_gms_hdr *white_fin;      /* unprocesse, needs destruction */
+
+    struct _gc_gms_gen *first_gen;      /* linked list of generations */
+    struct _gc_gms_gen *last_gen;
+
+#endif
+} Small_Object_Pool;
+
+typedef struct Arenas {
+    Memory_Pool *memory_pool;
+    Memory_Pool *constant_string_pool;
+    struct Small_Object_Pool *string_header_pool;
+    struct Small_Object_Pool *pmc_pool;
+    struct Small_Object_Pool *pmc_ext_pool;
+    struct Small_Object_Pool *constant_pmc_pool;
+    struct Small_Object_Pool *buffer_header_pool;
+    struct Small_Object_Pool *constant_string_header_pool;
+    struct Small_Object_Pool **sized_header_pools;
+    size_t num_sized;
+    /*
+     * function slots that each subsystem must provide
+     */
+    void (*do_gc_mark)(PARROT_INTERP, UINTVAL flags);
+    void (*finalize_gc_system) (PARROT_INTERP);
+    void (*init_pool)(PARROT_INTERP, struct Small_Object_Pool *);
+    /*
+     * statistics for GC
+     */
+    size_t  gc_mark_runs;       /* Number of times we've done a mark run*/
+    size_t  gc_lazy_mark_runs;  /* Number of successful lazy mark runs */
+    size_t  gc_collect_runs;    /* Number of times we've done a memory
+                                   compaction */
+    size_t  mem_allocs_since_last_collect;      /* The number of memory
+                                                 * allocations from the
+                                                 * system since the last
+                                                 * compaction run */
+    size_t  header_allocs_since_last_collect;   /* The number of header
+                                                 * blocks allocated from
+                                                 * the system since the last
+                                                 * GC run */
+    size_t  memory_allocated;     /* The total amount of
+                                   * allocatable memory
+                                   * allocated. Doesn't count
+                                   * memory for headers or
+                                   * internal structures or
+                                   * anything */
+    UINTVAL memory_collected;     /* Total amount of memory copied
+                                     during collection */
+    UINTVAL num_early_gc_PMCs;    /* how many PMCs want immediate destruction */
+    UINTVAL num_early_PMCs_seen;  /* how many such PMCs has GC seen */
+    UINTVAL num_extended_PMCs;    /* active PMCs having pmc_ext */
+    PMC* gc_mark_start;           /* first PMC marked during a GC run */
+    PMC* gc_mark_ptr;             /* last PMC marked during a GC run */
+    PMC* gc_trace_ptr;            /* last PMC trace_children was called on */
+    int lazy_gc;                  /* flag that indicates whether we should stop
+                                     when we've seen all impatient PMCs */
+    /*
+     * GC blocking
+     */
+    UINTVAL gc_mark_block_level;  /* How many outstanding GC block
+                                     requests are there? */
+    UINTVAL gc_sweep_block_level; /* How many outstanding GC block
+                                     requests are there? */
+    /*
+     * private data for the GC subsystem
+     */
+    void *  gc_private;           /* gc subsystem data */
+} Arenas;
+
+
 /* HEADERIZER BEGIN: src/gc/system.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
@@ -59,6 +229,498 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/gc/system.c */
 
+/* HEADERIZER BEGIN: src/gc/generational_ms.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+PARROT_EXPORT
+void Parrot_gc_gms_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void parrot_gc_gms_Parrot_gc_mark_PObj_alive(PARROT_INTERP,
+    ARGMOD(PObj *obj))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*obj);
+
+void parrot_gc_gms_wb(PARROT_INTERP,
+    ARGIN(PMC *agg),
+    ARGIN(void *old),
+    ARGIN(void *_new))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        __attribute__nonnull__(4);
+
+void parrot_gc_gms_wb_key(PARROT_INTERP,
+    ARGIN(PMC *agg),
+    ARGIN(void *old),
+    ARGIN(void *old_key),
+    ARGIN(void *_new),
+    ARGIN(void *new_key))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        __attribute__nonnull__(4)
+        __attribute__nonnull__(5)
+        __attribute__nonnull__(6);
+
+#define ASSERT_ARGS_Parrot_gc_gms_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_parrot_gc_gms_Parrot_gc_mark_PObj_alive \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(obj)
+#define ASSERT_ARGS_parrot_gc_gms_wb __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(agg) \
+    || PARROT_ASSERT_ARG(old) \
+    || PARROT_ASSERT_ARG(_new)
+#define ASSERT_ARGS_parrot_gc_gms_wb_key __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(agg) \
+    || PARROT_ASSERT_ARG(old) \
+    || PARROT_ASSERT_ARG(old_key) \
+    || PARROT_ASSERT_ARG(_new) \
+    || PARROT_ASSERT_ARG(new_key)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/gc/generational_ms.c */
+
+/* HEADERIZER BEGIN: src/gc/incremental_ms.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+void Parrot_gc_ims_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_ims_wb(PARROT_INTERP, ARGMOD(PMC *agg), ARGMOD(PMC *_new))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*agg)
+        FUNC_MODIFIES(*_new);
+
+#define ASSERT_ARGS_Parrot_gc_ims_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_ims_wb __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(agg) \
+    || PARROT_ASSERT_ARG(_new)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/gc/incremental_ms.c */
+
+/* HEADERIZER BEGIN: src/gc/mark_sweep.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+PARROT_WARN_UNUSED_RESULT
+INTVAL contained_in_pool(
+    ARGIN(const Small_Object_Pool *pool),
+    ARGIN(const void *ptr))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+void gc_pmc_ext_pool_init(ARGMOD(Small_Object_Pool *pool))
+        __attribute__nonnull__(1)
+        FUNC_MODIFIES(*pool);
+
+void mark_special(PARROT_INTERP, ARGIN(PMC *obj))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_MALLOC
+PARROT_CANNOT_RETURN_NULL
+Small_Object_Pool * new_small_object_pool(
+    size_t object_size,
+    size_t objects_per_alloc);
+
+void Parrot_add_to_free_list(PARROT_INTERP,
+    ARGMOD(Small_Object_Pool *pool),
+    ARGMOD(Small_Object_Arena *arena))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*pool)
+        FUNC_MODIFIES(*arena);
+
+void Parrot_append_arena_in_pool(PARROT_INTERP,
+    ARGMOD(Small_Object_Pool *pool),
+    ARGMOD(Small_Object_Arena *new_arena),
+    size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*pool)
+        FUNC_MODIFIES(*new_arena);
+
+void Parrot_gc_clear_live_bits(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_ms_free_pmc(PARROT_INTERP,
+    SHIM(Small_Object_Pool *pool),
+    ARGMOD(PObj *p))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*p);
+
+void Parrot_gc_ms_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_ms_run(PARROT_INTERP, UINTVAL flags)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_ms_run_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_sweep(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*pool);
+
+int Parrot_gc_trace_children(PARROT_INTERP, size_t how_many)
+        __attribute__nonnull__(1);
+
+int Parrot_gc_trace_root(PARROT_INTERP, Parrot_gc_trace_type trace)
+        __attribute__nonnull__(1);
+
+int Parrot_is_const_pmc(PARROT_INTERP, ARGIN(const PMC *pmc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+void Parrot_small_object_pool_merge(PARROT_INTERP,
+    ARGMOD(Small_Object_Pool *dest),
+    ARGMOD(Small_Object_Pool *source))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*dest)
+        FUNC_MODIFIES(*source);
+
+#define ASSERT_ARGS_contained_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(pool) \
+    || PARROT_ASSERT_ARG(ptr)
+#define ASSERT_ARGS_gc_pmc_ext_pool_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_mark_special __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(obj)
+#define ASSERT_ARGS_new_small_object_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
+#define ASSERT_ARGS_Parrot_add_to_free_list __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool) \
+    || PARROT_ASSERT_ARG(arena)
+#define ASSERT_ARGS_Parrot_append_arena_in_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool) \
+    || PARROT_ASSERT_ARG(new_arena)
+#define ASSERT_ARGS_Parrot_gc_clear_live_bits __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_ms_free_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(p)
+#define ASSERT_ARGS_Parrot_gc_ms_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_ms_run __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_ms_run_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_Parrot_gc_trace_children __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_trace_root __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_is_const_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmc)
+#define ASSERT_ARGS_Parrot_small_object_pool_merge \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(dest) \
+    || PARROT_ASSERT_ARG(source)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/gc/mark_sweep.c */
+
+/* HEADERIZER BEGIN: src/gc/pools.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+void free_pool(ARGMOD(Small_Object_Pool *pool))
+        __attribute__nonnull__(1)
+        FUNC_MODIFIES(*pool);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+Small_Object_Pool * get_bufferlike_pool(PARROT_INTERP, size_t buffer_size)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+void * get_free_buffer(PARROT_INTERP, ARGIN(Small_Object_Pool *pool))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
+size_t get_max_buffer_address(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+size_t get_max_pmc_address(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+size_t get_min_buffer_address(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+size_t get_min_pmc_address(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+int is_buffer_ptr(PARROT_INTERP, ARGIN(const void *ptr))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
+int is_pmc_ptr(PARROT_INTERP, ARGIN(const void *ptr))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+Small_Object_Pool * new_buffer_pool(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+Small_Object_Pool * new_bufferlike_pool(PARROT_INTERP,
+    size_t actual_buffer_size)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+Small_Object_Pool * new_pmc_pool(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+Small_Object_Pool * new_string_pool(PARROT_INTERP, INTVAL constant)
+        __attribute__nonnull__(1);
+
+PARROT_IGNORABLE_RESULT
+int /*@alt void@*/
+Parrot_forall_header_pools(PARROT_INTERP,
+    int flag,
+    ARGIN_NULLOK(void *arg),
+    NOTNULL(pool_iter_fn func))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(4);
+
+void Parrot_initialize_header_pools(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_merge_memory_pools(
+    ARGIN(Interp *dest_interp),
+    ARGIN(Interp *source_interp))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+#define ASSERT_ARGS_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_get_bufferlike_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_get_free_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_get_max_buffer_address __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_get_max_pmc_address __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_get_min_buffer_address __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_get_min_pmc_address __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_is_buffer_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ptr)
+#define ASSERT_ARGS_is_pmc_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ptr)
+#define ASSERT_ARGS_new_buffer_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_new_bufferlike_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_new_pmc_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_new_string_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_forall_header_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(func)
+#define ASSERT_ARGS_Parrot_initialize_header_pools \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_merge_memory_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(dest_interp) \
+    || PARROT_ASSERT_ARG(source_interp)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/gc/pools.c */
+
+/* HEADERIZER BEGIN: src/gc/resources.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+char * aligned_mem(ARGIN(const Buffer *buffer), ARGIN(char *mem))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_PURE_FUNCTION
+PARROT_WARN_UNUSED_RESULT
+size_t aligned_size(ARGIN(const Buffer *buffer), size_t len)
+        __attribute__nonnull__(1);
+
+PARROT_CONST_FUNCTION
+PARROT_WARN_UNUSED_RESULT
+size_t aligned_string_size(size_t len);
+
+void compact_pool(PARROT_INTERP, ARGMOD(Memory_Pool *pool))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*pool);
+
+PARROT_MALLOC
+PARROT_CANNOT_RETURN_NULL
+void * mem_allocate(PARROT_INTERP, size_t size, ARGMOD(Memory_Pool *pool))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*pool);
+
+void merge_pools(ARGMOD(Memory_Pool *dest), ARGMOD(Memory_Pool *source))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*dest)
+        FUNC_MODIFIES(*source);
+
+void Parrot_allocate(PARROT_INTERP, ARGOUT(Buffer *buffer), size_t size)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*buffer);
+
+void Parrot_gc_profile_end(PARROT_INTERP, int what)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_profile_start(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_initialize_memory_pools(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+#define ASSERT_ARGS_aligned_mem __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(buffer) \
+    || PARROT_ASSERT_ARG(mem)
+#define ASSERT_ARGS_aligned_size __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(buffer)
+#define ASSERT_ARGS_aligned_string_size __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
+#define ASSERT_ARGS_compact_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_mem_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pool)
+#define ASSERT_ARGS_merge_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(dest) \
+    || PARROT_ASSERT_ARG(source)
+#define ASSERT_ARGS_Parrot_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(buffer)
+#define ASSERT_ARGS_Parrot_gc_profile_end __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_profile_start __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_initialize_memory_pools \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/gc/resources.c */
+
+/* GC subsystem init functions */
+/* HEADERIZER BEGIN: src/gc/generational_ms.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+PARROT_EXPORT
+void Parrot_gc_gms_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void parrot_gc_gms_Parrot_gc_mark_PObj_alive(PARROT_INTERP, ARGMOD(PObj *obj))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*obj);
+
+void parrot_gc_gms_wb(PARROT_INTERP,
+    ARGIN(PMC *agg),
+    ARGIN(void *old),
+    ARGIN(void *_new))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        __attribute__nonnull__(4);
+
+void parrot_gc_gms_wb_key(PARROT_INTERP,
+    ARGIN(PMC *agg),
+    ARGIN(void *old),
+    ARGIN(void *old_key),
+    ARGIN(void *_new),
+    ARGIN(void *new_key))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        __attribute__nonnull__(4)
+        __attribute__nonnull__(5)
+        __attribute__nonnull__(6);
+
+#define ASSERT_ARGS_Parrot_gc_gms_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_parrot_gc_gms_Parrot_gc_mark_PObj_alive __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(obj)
+#define ASSERT_ARGS_parrot_gc_gms_wb __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(agg) \
+    || PARROT_ASSERT_ARG(old) \
+    || PARROT_ASSERT_ARG(_new)
+#define ASSERT_ARGS_parrot_gc_gms_wb_key __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(agg) \
+    || PARROT_ASSERT_ARG(old) \
+    || PARROT_ASSERT_ARG(old_key) \
+    || PARROT_ASSERT_ARG(_new) \
+    || PARROT_ASSERT_ARG(new_key)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/gc/generational_ms.c */
+
+/* HEADERIZER BEGIN: src/gc/incremental_ms.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+void Parrot_gc_ims_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_gc_ims_wb(PARROT_INTERP, ARGMOD(PMC *agg), ARGMOD(PMC *_new))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*agg)
+        FUNC_MODIFIES(*_new);
+
+#define ASSERT_ARGS_Parrot_gc_ims_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_gc_ims_wb __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(agg) \
+    || PARROT_ASSERT_ARG(_new)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/gc/incremental_ms.c */
+
+
 #endif /* PARROT_GC_PRIVATE_H_GUARD */
 
 /*

Modified: branches/pmc_pct/src/gc/generational_ms.c
==============================================================================
--- branches/pmc_pct/src/gc/generational_ms.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/generational_ms.c	Fri May 15 21:49:40 2009	(r38803)
@@ -112,7 +112,6 @@
 
 #include "parrot/parrot.h"
 #include "parrot/gc_api.h"
-#include "parrot/gc_mark_sweep.h"
 
 #if PARROT_GC_GMS
 
@@ -120,7 +119,7 @@
     UINTVAL current_gen_no;             /* the nursery generation number */
 } Gc_gms_private;
 
-/* HEADERIZER HFILE: include/parrot/gc_api.h */
+/* HEADERIZER HFILE: src/gc/gc_private.h */
 
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
@@ -744,7 +743,7 @@
     if (pool->skip)
         pool->skip = 0;
     else if (pool->last_Arena) {
-        Parrot_do_gc_run(interp, GC_trace_stack_FLAG);
+        Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
         if (pool->num_free_objects <= pool->replenish_level)
             pool->skip = 1;
     }
@@ -878,6 +877,8 @@
 =item C<static Gc_gms_gen * gc_gms_find_gen(PARROT_INTERP, const Gc_gms_hdr *h,
 UINTVAL gen_no)>
 
+Finds the generation associated with the given header and generation number.
+
 =cut
 
 */
@@ -915,6 +916,8 @@
 =item C<static void gc_gms_promote(PARROT_INTERP, Gc_gms_hdr *h, UINTVAL
 gen_no)>
 
+Promote the header to the specified generation.
+
 =cut
 
 */
@@ -962,6 +965,8 @@
 =item C<static void gc_gms_store_hdr_list(PARROT_INTERP, Gc_gms_hdr_list *l,
 Gc_gms_hdr *h)>
 
+Store the header into the header list.
+
 =cut
 
 */
@@ -994,6 +999,8 @@
 
 =item C<static void gc_gms_clear_hdr_list(PARROT_INTERP, Gc_gms_hdr_list *l)>
 
+Clear the header list and free it's memory to the OS.
+
 =cut
 
 */
@@ -1015,6 +1022,8 @@
 
 =item C<static void gc_gms_store_igp(PARROT_INTERP, Gc_gms_hdr *h)>
 
+Add the header to the inter-generational pointer list of it's generation.
+
 =cut
 
 */
@@ -1033,6 +1042,8 @@
 
 =item C<static void gc_gms_clear_igp(PARROT_INTERP, Gc_gms_gen *gen)>
 
+Clear the inter-generational pointer list of the given generation.
+
 =cut
 
 */
@@ -1123,6 +1134,8 @@
 =item C<static void gc_gms_merge_gen(PARROT_INTERP, Small_Object_Pool *pool, int
 flag, Gc_gms_plan *plan)>
 
+Merge black pointers to the previous generation, and update the free list.
+
 =cut
 
 */
@@ -1157,6 +1170,8 @@
 =item C<static void gc_gms_use_gen(PARROT_INTERP, Small_Object_Pool *pool, int
 flag, const Gc_gms_plan *plan)>
 
+Specify what generation to use by default.
+
 =cut
 
 */
@@ -1192,6 +1207,8 @@
 =item C<static int set_gen_cb(PARROT_INTERP, Small_Object_Pool *pool, int flag,
 void *arg)>
 
+Set the generation to use, merging if necessary.
+
 =cut
 
 */
@@ -1214,6 +1231,9 @@
 
 =item C<static void gc_gms_set_gen(PARROT_INTERP)>
 
+Setup the generations, deciding what to do based on the plan and moving
+headers around as necessary.
+
 =cut
 
 */
@@ -1452,9 +1472,9 @@
 
 /*
 
-=item C<void parrot_gc_gms_pobject_lives(PARROT_INTERP, PObj *obj)>
+=item C<void parrot_gc_gms_Parrot_gc_mark_PObj_alive(PARROT_INTERP, PObj *obj)>
 
-Set the object live - called by the pobject_lives macro
+Set the object live - called by the Parrot_gc_mark_PObj_alive macro
 
 =cut
 
@@ -1462,9 +1482,9 @@
 
 PARROT_EXPORT
 void
-parrot_gc_gms_pobject_lives(PARROT_INTERP, ARGMOD(PObj *obj))
+parrot_gc_gms_Parrot_gc_mark_PObj_alive(PARROT_INTERP, ARGMOD(PObj *obj))
 {
-    ASSERT_ARGS(parrot_gc_gms_pobject_lives)
+    ASSERT_ARGS(parrot_gc_gms_Parrot_gc_mark_PObj_alive)
     Gc_gms_hdr *h;
     int priority;
 
@@ -1485,6 +1505,8 @@
 =item C<static int init_mark_cb(PARROT_INTERP, Small_Object_Pool *pool, int
 flag, void *arg)>
 
+Initialization callback, initialize all the pointers.
+
 =cut
 
 */
@@ -1529,6 +1551,9 @@
 =item C<static int trace_igp_cb(PARROT_INTERP, Small_Object_Pool *pool, int
 flag, void *arg)>
 
+Trace through the IGP of the pool to find alive items that are pointing
+to items in other generations.
+
 =cut
 
 */
@@ -1545,7 +1570,7 @@
         const Gc_gms_hdr **p;
         for (p = s->store; p < s->ptr; ++p) {
             Gc_gms_hdr * const h = *p;
-            pobject_lives(interp, GMSH_to_PObj(h));
+            Parrot_gc_mark_PObj_alive(interp, GMSH_to_PObj(h));
         }
     }
     return 0;
@@ -1578,6 +1603,8 @@
 =item C<static int trace_children_cb(PARROT_INTERP, Small_Object_Pool *pool, int
 flag, void *arg)>
 
+Trace through child objects
+
 =cut
 
 */
@@ -1598,7 +1625,7 @@
                 arena_base->num_early_gc_PMCs) {
             return 1;
         }
-        /* TODO propagate flag in pobject_lives */
+        /* TODO propagate flag in Parrot_gc_mark_PObj_alive */
         arena_base->gc_trace_ptr = current;
         if (!PObj_needs_early_gc_TEST(current))
             PObj_high_priority_gc_CLEAR(current);
@@ -1684,6 +1711,8 @@
 =item C<static int sweep_cb_buf(PARROT_INTERP, Small_Object_Pool *pool, int
 flag, void *arg)>
 
+Sweep the buffer pool, freeing things that are dead.
+
 =cut
 
 */
@@ -1769,6 +1798,8 @@
 =item C<static int end_cycle_cb(PARROT_INTERP, Small_Object_Pool *pool, int
 flag, void *arg)>
 
+Reset the pointers in the pool at the end of the cycle.
+
 =cut
 
 */
@@ -1794,6 +1825,8 @@
 
 =item C<static void gc_gms_end_cycle(PARROT_INTERP)>
 
+End the cycle, resetting pointers in all pools.
+
 =cut
 
 */
@@ -1815,7 +1848,7 @@
 
 =item C<static void parrot_gc_gms_run(PARROT_INTERP, UINTVAL flags)>
 
-Interface to C<Parrot_do_gc_run>. C<flags> is one of:
+Interface to C<Parrot_gc_mark_and_sweep>. C<flags> is one of:
 
   GC_lazy_FLAG   ... timely destruction
   GC_finish_FLAG ... run a final sweep to destruct objects at
@@ -1872,6 +1905,8 @@
 =item C<static void gms_debug_verify(PARROT_INTERP, Small_Object_Pool *pool,
 const char *action)>
 
+Debug function, check that everything is right.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/gc/incremental_ms.c
==============================================================================
--- branches/pmc_pct/src/gc/incremental_ms.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/incremental_ms.c	Fri May 15 21:49:40 2009	(r38803)
@@ -330,9 +330,9 @@
 
 #include "parrot/parrot.h"
 #include "parrot/gc_api.h"
-#include "parrot/gc_mark_sweep.h"
+#include "gc_private.h"
 
-/* HEADERIZER HFILE: include/parrot/gc_api.h */
+/* HEADERIZER HFILE: src/gc/gc_private.h */
 
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
@@ -1011,7 +1011,7 @@
 
 =item C<static void parrot_gc_ims_run(PARROT_INTERP, UINTVAL flags)>
 
-Interface to C<Parrot_do_gc_run>. C<flags> is one of:
+Interface to C<Parrot_gc_mark_and_sweep>. C<flags> is one of:
 
   GC_lazy_FLAG   ... timely destruction
   GC_finish_FLAG ... run until live bits are clear
@@ -1132,10 +1132,10 @@
     IMS_DEBUG((stderr, "%d agg %p mark %p\n",
                 ((Gc_ims_private *)interp->arena_base->
                 gc_private)->state, agg, _new));
-    pobject_lives(interp, (PObj*)_new);
+    Parrot_gc_mark_PObj_alive(interp, (PObj*)_new);
 #else
     PObj_get_FLAGS(agg) &= ~ (PObj_live_FLAG|PObj_custom_GC_FLAG);
-    pobject_lives(interp, (PObj*)agg);
+    Parrot_gc_mark_PObj_alive(interp, (PObj*)agg);
 #endif
 }
 

Modified: branches/pmc_pct/src/gc/mark_sweep.c
==============================================================================
--- branches/pmc_pct/src/gc/mark_sweep.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/mark_sweep.c	Fri May 15 21:49:40 2009	(r38803)
@@ -20,10 +20,9 @@
 */
 
 #include "parrot/parrot.h"
-#include "parrot/gc_mark_sweep.h"
 #include "gc_private.h"
 
-/* HEADERIZER HFILE: include/parrot/gc_mark_sweep.h */
+/* HEADERIZER HFILE: src/gc/gc_private.h */
 
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
@@ -71,10 +70,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pool);
 
-static void mark_special(PARROT_INTERP, ARGIN(PMC *obj))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
 static void more_traceable_objects(PARROT_INTERP,
     ARGMOD(Small_Object_Pool *pool))
         __attribute__nonnull__(1)
@@ -113,9 +108,6 @@
     || PARROT_ASSERT_ARG(pool)
 #define ASSERT_ARGS_gc_ms_pool_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(pool)
-#define ASSERT_ARGS_mark_special __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(obj)
 #define ASSERT_ARGS_more_traceable_objects __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pool)
@@ -138,6 +130,9 @@
 
 #define POOL_MAX_BYTES                         65536 * 128
 
+/* Set when walking the system stack */
+int CONSERVATIVE_POINTER_CHASING = 0;
+
 /*
 
 =item C<void Parrot_gc_ms_run(PARROT_INTERP, UINTVAL flags)>
@@ -182,7 +177,7 @@
         /* keep the scheduler and its kids alive for Task-like PMCs to destroy
          * themselves; run a sweep to collect them */
         if (interp->scheduler) {
-            pobject_lives(interp, (PObj *)interp->scheduler);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)interp->scheduler);
             VTABLE_mark(interp, interp->scheduler);
             Parrot_gc_sweep(interp, interp->arena_base->pmc_pool);
         }
@@ -202,7 +197,7 @@
     Parrot_gc_ms_run_init(interp);
 
     /* compact STRING pools to collect free headers and allocated buffers */
-    Parrot_go_collect(interp);
+    Parrot_gc_compact_memory_pool(interp);
 
     /* Now go trace the PMCs */
     if (trace_active_PMCs(interp, (flags & GC_trace_stack_FLAG)
@@ -299,12 +294,12 @@
     }
 
     /* mark it as used  */
-    pobject_lives(interp, (PObj *)interp->iglobals);
+    Parrot_gc_mark_PObj_alive(interp, (PObj *)interp->iglobals);
 
     /* mark the current continuation */
     obj = (PObj *)interp->current_cont;
     if (obj && obj != (PObj *)NEED_CONTINUATION)
-        pobject_lives(interp, obj);
+        Parrot_gc_mark_PObj_alive(interp, obj);
 
     /* mark the current context. */
     ctx = CONTEXT(interp);
@@ -325,11 +320,11 @@
     mark_vtables(interp);
 
     /* mark the root_namespace */
-    pobject_lives(interp, (PObj *)interp->root_namespace);
+    Parrot_gc_mark_PObj_alive(interp, (PObj *)interp->root_namespace);
 
     /* mark the concurrency scheduler */
     if (interp->scheduler)
-        pobject_lives(interp, (PObj *)interp->scheduler);
+        Parrot_gc_mark_PObj_alive(interp, (PObj *)interp->scheduler);
 
     /* s. packfile.c */
     mark_const_subs(interp);
@@ -338,11 +333,11 @@
     mark_object_cache(interp);
 
     /* Now mark the class hash */
-    pobject_lives(interp, (PObj *)interp->class_hash);
+    Parrot_gc_mark_PObj_alive(interp, (PObj *)interp->class_hash);
 
     /* Mark the registry */
     PARROT_ASSERT(interp->gc_registry);
-    pobject_lives(interp, (PObj *)interp->gc_registry);
+    Parrot_gc_mark_PObj_alive(interp, (PObj *)interp->gc_registry);
 
     /* Mark the MMD cache. */
     if (interp->op_mmd_cache)
@@ -366,6 +361,69 @@
     return 1;
 }
 
+/*
+
+=item C<void Parrot_gc_ms_run_init(PARROT_INTERP)>
+
+Prepares the collector for a mark & sweep GC run. This is the
+initializer function for the MS garbage collector.
+
+=cut
+
+*/
+
+void
+Parrot_gc_ms_run_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_gc_ms_run_init)
+    Arenas * const arena_base       = interp->arena_base;
+
+    arena_base->gc_trace_ptr        = NULL;
+    arena_base->gc_mark_start       = NULL;
+    arena_base->num_early_PMCs_seen = 0;
+    arena_base->num_extended_PMCs   = 0;
+}
+
+
+/*
+
+=item C<void Parrot_gc_ms_free_pmc(PARROT_INTERP, Small_Object_Pool *pool, PObj
+*p)>
+
+Frees a PMC that is no longer being used. Calls a custom C<destroy> VTABLE
+method if one is available. If the PMC uses a PMC_EXT structure, that is freed
+as well.
+
+=cut
+
+*/
+
+void
+Parrot_gc_ms_free_pmc(PARROT_INTERP, SHIM(Small_Object_Pool *pool),
+        ARGMOD(PObj *p))
+{
+    ASSERT_ARGS(Parrot_gc_ms_free_pmc)
+    PMC    * const pmc        = (PMC *)p;
+    Arenas * const arena_base = interp->arena_base;
+
+    /* TODO collect objects with finalizers */
+    if (PObj_needs_early_gc_TEST(p))
+        --arena_base->num_early_gc_PMCs;
+
+    if (PObj_active_destroy_TEST(p))
+        VTABLE_destroy(interp, pmc);
+
+    if (PObj_is_PMC_EXT_TEST(p))
+         Parrot_gc_free_pmc_ext(interp, pmc);
+
+#ifndef NDEBUG
+
+    pmc->pmc_ext     = (PMC_EXT *)0xdeadbeef;
+    pmc->vtable      = (VTABLE  *)0xdeadbeef;
+
+#endif
+
+}
 
 /*
 
@@ -445,7 +503,8 @@
                     }
                 }
 
-                gc_object(interp, pool, b);
+                if (gc_object)
+                    gc_object(interp, pool, b);
 
                 pool->add_free_object(interp, pool, b);
             }
@@ -459,69 +518,6 @@
 
 
 
-/*
-
-=item C<void pobject_lives(PARROT_INTERP, PObj *obj)>
-
-Marks the PObj as "alive" for the Garbage Collector. Takes a pointer to a PObj,
-and performs necessary marking to ensure the PMC and its direct children nodes
-are marked alive. Implementation is generally dependant on the particular
-garbage collector in use.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-pobject_lives(PARROT_INTERP, ARGMOD(PObj *obj))
-{
-    ASSERT_ARGS(pobject_lives)
-#if PARROT_GC_GMS
-    do {
-        if (!PObj_live_TEST(obj) && \
-                PObj_to_GMSH(obj)->gen->gen_no >= interp->gc_generation) \
-            parrot_gc_gms_pobject_lives(interp, obj); \
-    } while (0);
-#else /* not PARROT_GC_GMS */
-
-    /* if object is live or on free list return */
-    if (PObj_is_live_or_free_TESTALL(obj))
-        return;
-
-#  if ! DISABLE_GC_DEBUG
-#    if GC_VERBOSE
-    if (CONSERVATIVE_POINTER_CHASING)
-        fprintf(stderr, "GC Warning! Unanchored %s %p found in system areas \n",
-                PObj_is_PMC_TEST(obj) ? "PMC" : "Buffer", obj);
-
-#    endif
-#  endif
-    /* mark it live */
-    PObj_live_SET(obj);
-
-    /* if object is a PMC and contains buffers or PMCs, then attach the PMC
-     * to the chained mark list. */
-    if (PObj_is_PMC_TEST(obj)) {
-        PMC * const p = (PMC *)obj;
-
-        if (PObj_is_special_PMC_TEST(obj))
-            mark_special(interp, p);
-
-#  ifndef NDEBUG
-        else if (p->pmc_ext && PMC_metadata(p))
-            fprintf(stderr, "GC: error obj %p (%s) has properties\n",
-                    (void *)p, (char*)p->vtable->whoami->strstart);
-#  endif
-    }
-#  if GC_VERBOSE
-    /* buffer GC_DEBUG stuff */
-    if (GC_DEBUG(interp) && PObj_report_TEST(obj))
-        fprintf(stderr, "GC: buffer %p pointing to %p marked live\n",
-                obj, PObj_bufstart((Buffer *)obj));
-#  endif
-#endif  /* PARROT_GC_GMS */
-}
 
 /*
 
@@ -586,7 +582,7 @@
 
 /*
 
-=item C<static void mark_special(PARROT_INTERP, PMC *obj)>
+=item C<void mark_special(PARROT_INTERP, PMC *obj)>
 
 Marks the children of a special PMC. Handles the marking necessary
 for shared PMCs, and ensures timely marking of high-priority PMCs.
@@ -597,7 +593,7 @@
 
 */
 
-static void
+void
 mark_special(PARROT_INTERP, ARGIN(PMC *obj))
 {
     ASSERT_ARGS(mark_special)
@@ -701,14 +697,14 @@
         Small_Object_Arena * const arena = pool->last_Arena;
         if (arena) {
             if (arena->used == arena->total_objects)
-                Parrot_do_gc_run(interp, GC_trace_stack_FLAG);
+                Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 
             if (pool->num_free_objects <= pool->replenish_level)
                 pool->skip = 1;
         }
     }
 
-    /* requires that num_free_objects be updated in Parrot_do_gc_run. If gc
+    /* requires that num_free_objects be updated in Parrot_gc_mark_and_sweep. If gc
      * is disabled, then we must check the free list directly. */
     if (!pool->free_list)
         (*pool->alloc_objects) (interp, pool);
@@ -998,7 +994,7 @@
 
         /* mark properties */
         if (PMC_metadata(current))
-            pobject_lives(interp, (PObj *)PMC_metadata(current));
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)PMC_metadata(current));
 
          if (PObj_custom_mark_TEST(current)) {
             PARROT_ASSERT(!PObj_on_free_list_TEST(current));

Modified: branches/pmc_pct/src/gc/memory.c
==============================================================================
--- branches/pmc_pct/src/gc/memory.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/memory.c	Fri May 15 21:49:40 2009	(r38803)
@@ -343,44 +343,6 @@
 
 /*
 
-=item C<void mem_setup_allocator(PARROT_INTERP, void *stacktop)>
-
-Initializes the memory allocator and the garbage collection subsystem.
-Calls the initialization function associated with each collector, which
-is determined at compile time.
-
-The "stacktop" parameter is required; it provides an upper bound for
-stack scanning during a garbage collection run.
-
-=cut
-
-*/
-
-void
-mem_setup_allocator(PARROT_INTERP, ARGIN(void *stacktop))
-{
-    ASSERT_ARGS(mem_setup_allocator)
-    interp->arena_base = mem_allocate_zeroed_typed(Arenas);
-    interp->arena_base->sized_header_pools = NULL;
-
-    interp->lo_var_ptr = stacktop;
-
-#if PARROT_GC_MS
-    Parrot_gc_ms_init(interp);
-#endif
-#if PARROT_GC_IMS
-    Parrot_gc_ims_init(interp);
-#endif
-#if PARROT_GC_GMS
-    Parrot_gc_gms_init(interp);
-#endif
-
-    Parrot_initialize_memory_pools(interp);
-    Parrot_initialize_header_pools(interp);
-}
-
-/*
-
 =back
 
 =cut

Modified: branches/pmc_pct/src/gc/pools.c
==============================================================================
--- branches/pmc_pct/src/gc/pools.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/pools.c	Fri May 15 21:49:40 2009	(r38803)
@@ -15,53 +15,32 @@
 */
 
 #include "parrot/parrot.h"
-#include "parrot/gc_pools.h"
+#include "gc_private.h"
 
-/* HEADERIZER HFILE: include/parrot/gc_pools.h */
+/* HEADERIZER HFILE: src/gc/gc_private.h */
 
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void fix_pmc_syncs(
-    ARGMOD(Interp *dest_interp),
-    ARGIN(Small_Object_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*dest_interp);
-
-static void free_pool(ARGMOD(Small_Object_Pool *pool))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*pool);
-
-static int sweep_cb_buf(PARROT_INTERP,
-    ARGMOD(Small_Object_Pool *pool),
-    SHIM(int flag),
-    ARGIN(void *arg))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*pool);
-
-static int sweep_cb_pmc(PARROT_INTERP,
+static void Parrot_gc_free_buffer(SHIM_INTERP,
     ARGMOD(Small_Object_Pool *pool),
-    SHIM(int flag),
-    SHIM(void *arg))
-        __attribute__nonnull__(1)
+    ARGMOD(PObj *b))
         __attribute__nonnull__(2)
-        FUNC_MODIFIES(*pool);
-
-#define ASSERT_ARGS_fix_pmc_syncs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(dest_interp) \
-    || PARROT_ASSERT_ARG(pool)
-#define ASSERT_ARGS_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(pool)
-#define ASSERT_ARGS_sweep_cb_buf __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pool) \
-    || PARROT_ASSERT_ARG(arg)
-#define ASSERT_ARGS_sweep_cb_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pool)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*pool)
+        FUNC_MODIFIES(*b);
+
+static void Parrot_gc_free_buffer_malloc(SHIM_INTERP,
+    SHIM(Small_Object_Pool *pool),
+    ARGMOD(PObj *b))
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*b);
+
+#define ASSERT_ARGS_Parrot_gc_free_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(pool) \
+    || PARROT_ASSERT_ARG(b)
+#define ASSERT_ARGS_Parrot_gc_free_buffer_malloc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(b)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
@@ -76,7 +55,8 @@
 #  define STRING_HEADERS_PER_ALLOC 10240 / sizeof (STRING)
 #endif /* GC_IS_MALLOC */
 
-#  define CONSTANT_PMC_HEADERS_PER_ALLOC 64
+#define CONSTANT_PMC_HEADERS_PER_ALLOC 64
+#define GET_SIZED_POOL_IDX(x) ((x) / sizeof (void *))
 
 /*
 
@@ -84,6 +64,30 @@
 
 =over 4
 
+=item C<void Parrot_merge_memory_pools(Interp *dest_interp, Interp
+*source_interp)>
+
+Merge the memory pools of two interpreter structures. Merge the general
+memory pool and the constant string pools from C<source_interp> into
+C<dest_interp>.
+
+=cut
+
+*/
+
+void
+Parrot_merge_memory_pools(ARGIN(Interp *dest_interp), ARGIN(Interp *source_interp))
+{
+    ASSERT_ARGS(Parrot_merge_memory_pools)
+    merge_pools(dest_interp->arena_base->constant_string_pool,
+                source_interp->arena_base->constant_string_pool);
+
+    merge_pools(dest_interp->arena_base->memory_pool,
+                source_interp->arena_base->memory_pool);
+}
+
+/*
+
 =item C<void * get_free_buffer(PARROT_INTERP, Small_Object_Pool *pool)>
 
 Gets a free object or buffer from the given C<pool> and returns it.  If the
@@ -141,7 +145,7 @@
         new_small_object_pool(sizeof (PMC), num_headers);
 
     pmc_pool->mem_pool   = NULL;
-    pmc_pool->gc_object  = Parrot_gc_free_pmc;
+    pmc_pool->gc_object  = Parrot_gc_ms_free_pmc;
 
     (interp->arena_base->init_pool)(interp, pmc_pool);
     return pmc_pool;
@@ -172,7 +176,7 @@
     Small_Object_Pool * const pool =
             new_small_object_pool(buffer_size, num_headers);
 
-    pool->gc_object = Parrot_gc_free_sysmem;
+    pool->gc_object = NULL;
     pool->mem_pool  = interp->arena_base->memory_pool;
     (interp->arena_base->init_pool)(interp, pool);
     return pool;
@@ -208,6 +212,72 @@
     return pool;
 }
 
+/*
+
+=item C<static void Parrot_gc_free_buffer_malloc(PARROT_INTERP,
+Small_Object_Pool *pool, PObj *b)>
+
+Frees the given buffer, returning the storage space to the operating system
+and removing it from Parrot's memory management system. If the buffer is COW,
+The buffer is not freed if the reference count is greater then 1.
+
+=cut
+
+*/
+
+static void
+Parrot_gc_free_buffer_malloc(SHIM_INTERP, SHIM(Small_Object_Pool *pool),
+        ARGMOD(PObj *b))
+{
+    ASSERT_ARGS(Parrot_gc_free_buffer_malloc)
+    /* free allocated space at (int *)bufstart - 1, but not if it used COW or is
+     * external */
+    PObj_buflen(b) = 0;
+
+    if (!PObj_bufstart(b) || PObj_is_external_or_free_TESTALL(b))
+        return;
+
+    if (PObj_COW_TEST(b)) {
+        INTVAL * const refcount = PObj_bufrefcountptr(b);
+
+        if (--(*refcount) == 0) {
+            mem_sys_free(refcount); /* the actual bufstart */
+        }
+    }
+    else
+        mem_sys_free(PObj_bufrefcountptr(b));
+}
+
+/*
+
+=item C<static void Parrot_gc_free_buffer(PARROT_INTERP, Small_Object_Pool
+*pool, PObj *b)>
+
+Frees a buffer, returning it to the memory pool for Parrot to possibly
+reuse later.
+
+=cut
+
+*/
+
+static void
+Parrot_gc_free_buffer(SHIM_INTERP, ARGMOD(Small_Object_Pool *pool), ARGMOD(PObj *b))
+{
+    ASSERT_ARGS(Parrot_gc_free_buffer)
+    Memory_Pool * const mem_pool = (Memory_Pool *)pool->mem_pool;
+
+    /* XXX Jarkko reported that on irix pool->mem_pool was NULL, which really
+     * shouldn't happen */
+    if (mem_pool) {
+        if (!PObj_COW_TEST(b))
+            mem_pool->guaranteed_reclaimable += PObj_buflen(b);
+
+         mem_pool->possibly_reclaimable += PObj_buflen(b);
+    }
+
+    PObj_buflen(b)        = 0;
+}
+
 
 /*
 
@@ -261,8 +331,7 @@
     ASSERT_ARGS(get_bufferlike_pool)
     Small_Object_Pool **sized_pools = interp->arena_base->sized_header_pools;
     const UINTVAL       num_old     = interp->arena_base->num_sized;
-    const UINTVAL       idx         =
-                            (buffer_size - sizeof (Buffer)) / sizeof (void *);
+    const UINTVAL       idx         = GET_SIZED_POOL_IDX(buffer_size);
 
     /* Expands the array of sized resource pools, if necessary */
     if (num_old <= idx) {
@@ -601,7 +670,7 @@
 
 /*
 
-=item C<static void free_pool(Small_Object_Pool *pool)>
+=item C<void free_pool(Small_Object_Pool *pool)>
 
 Frees a pool and all of its arenas. Loops through the list of arenas backwards
 and returns each to the memory manager. Then, frees the pool structure itself.
@@ -610,7 +679,7 @@
 
 */
 
-static void
+void
 free_pool(ARGMOD(Small_Object_Pool *pool))
 {
     ASSERT_ARGS(free_pool)
@@ -625,210 +694,6 @@
     mem_internal_free(pool);
 }
 
-
-/*
-
-=item C<static int sweep_cb_buf(PARROT_INTERP, Small_Object_Pool *pool, int
-flag, void *arg)>
-
-Performs a final garbage collection sweep, then frees the pool. Calls
-C<Parrot_gc_sweep> to perform the sweep, and C<free_pool> to free the pool and
-all its arenas.
-
-=cut
-
-*/
-
-static int
-sweep_cb_buf(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool), SHIM(int flag),
-        ARGIN(void *arg))
-{
-#ifdef GC_IS_MALLOC
-    const int pass = (int)(INTVAL)arg;
-
-    if (pass == 0)
-        clear_cow(interp, pool, 1);
-    else if (pass == 1)
-        used_cow(interp, pool, 1);
-    else
-#endif
-
-    {
-        UNUSED(arg);
-        Parrot_gc_sweep(interp, pool);
-        free_pool(pool);
-    }
-
-    return 0;
-}
-
-
-/*
-
-=item C<static int sweep_cb_pmc(PARROT_INTERP, Small_Object_Pool *pool, int
-flag, void *arg)>
-
-Performs a garbage collection sweep of the given pmc pool, then frees it. Calls
-C<Parrot_gc_sweep> to perform the sweep, and C<free_pool> to free the pool and
-all its arenas. Always returns C<0>.
-
-=cut
-
-*/
-
-static int
-sweep_cb_pmc(PARROT_INTERP, ARGMOD(Small_Object_Pool *pool),
-        SHIM(int flag), SHIM(void *arg))
-{
-    Parrot_gc_sweep(interp, pool);
-    free_pool(pool);
-    return 0;
-}
-
-
-/*
-
-=item C<void Parrot_destroy_header_pools(PARROT_INTERP)>
-
-Performs a garbage collection sweep on all pools, then frees them.  Calls
-C<Parrot_forall_header_pools> to loop over all the pools, passing
-C<sweep_cb_pmc> and C<sweep_cb_buf> callback routines. Frees the array of sized
-header pointers in the C<Arenas> structure too.
-
-=cut
-
-*/
-
-void
-Parrot_destroy_header_pools(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_destroy_header_pools)
-    INTVAL pass;
-
-    /* const/non const COW strings life in different pools
-     * so in first pass
-     * COW refcount is done, in 2. refcounting
-     * in 3rd freeing
-     */
-#ifdef GC_IS_MALLOC
-    const INTVAL start = 0;
-#else
-    const INTVAL start = 2;
-#endif
-
-    Parrot_forall_header_pools(interp, POOL_PMC, NULL, sweep_cb_pmc);
-    Parrot_forall_header_pools(interp, POOL_PMC | POOL_CONST, NULL,
-            sweep_cb_pmc);
-
-    for (pass = start; pass <= 2; pass++) {
-        Parrot_forall_header_pools(interp, POOL_BUFFER | POOL_CONST,
-                (void *)pass, sweep_cb_buf);
-    }
-
-    free_pool(interp->arena_base->pmc_ext_pool);
-    interp->arena_base->pmc_ext_pool = NULL;
-
-    mem_internal_free(interp->arena_base->sized_header_pools);
-    interp->arena_base->sized_header_pools = NULL;
-}
-
-
-/*
-
-=item C<static void fix_pmc_syncs(Interp *dest_interp, Small_Object_Pool *pool)>
-
-Walks through the given arena, looking for all live and shared PMCs,
-transferring their sync values to the destination interpreter.
-
-=cut
-
-*/
-
-static void
-fix_pmc_syncs(ARGMOD(Interp *dest_interp), ARGIN(Small_Object_Pool *pool))
-{
-    ASSERT_ARGS(fix_pmc_syncs)
-    Small_Object_Arena *cur_arena;
-    const UINTVAL       object_size = pool->object_size;
-
-    for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) {
-        PMC   *p = (PMC *)((char*)cur_arena->start_objects + GC_HEADER_SIZE);
-        size_t i;
-
-        for (i = 0; i < cur_arena->used; i++) {
-            if (!PObj_on_free_list_TEST(p) && PObj_is_PMC_TEST(p)) {
-                if (PObj_is_PMC_shared_TEST(p))
-                    PMC_sync(p)->owner = dest_interp;
-                else
-                    Parrot_ex_throw_from_c_args(dest_interp, NULL,
-                        EXCEPTION_INTERP_ERROR,
-                        "Unshared PMC still alive after interpreter"
-                        "destruction. address=%p, base_type=%d\n",
-                        p, p->vtable->base_type);
-            }
-
-            p = (PMC *)((char *)p + object_size);
-        }
-    }
-}
-
-
-/*
-
-=item C<void Parrot_merge_header_pools(Interp *dest_interp, Interp
-*source_interp)>
-
-Merges the header pools of C<source_interp> into those of C<dest_interp>.
-(Used to deal with shared objects left after interpreter destruction.)
-
-=cut
-
-*/
-
-void
-Parrot_merge_header_pools(ARGMOD(Interp *dest_interp), ARGIN(Interp *source_interp))
-{
-    ASSERT_ARGS(Parrot_merge_header_pools)
-
-    Arenas * const dest_arena   = dest_interp->arena_base;
-    Arenas * const source_arena = source_interp->arena_base;
-    UINTVAL        i;
-
-    /* heavily borrowed from forall_header_pools */
-    fix_pmc_syncs(dest_interp, source_arena->constant_pmc_pool);
-    Parrot_small_object_pool_merge(dest_interp, dest_arena->constant_pmc_pool,
-            source_arena->constant_pmc_pool);
-
-    fix_pmc_syncs(dest_interp, source_arena->pmc_pool);
-    Parrot_small_object_pool_merge(dest_interp, dest_arena->pmc_pool,
-            source_arena->pmc_pool);
-
-    Parrot_small_object_pool_merge(dest_interp,
-            dest_arena->constant_string_header_pool,
-            source_arena->constant_string_header_pool);
-
-    Parrot_small_object_pool_merge(dest_interp,
-            dest_arena->pmc_ext_pool, source_arena->pmc_ext_pool);
-
-    for (i = 0; i < source_arena->num_sized; ++i) {
-        if (!source_arena->sized_header_pools[i])
-            continue;
-
-        if (i >= dest_arena->num_sized
-        || !dest_arena->sized_header_pools[i]) {
-            Small_Object_Pool *ignored = get_bufferlike_pool(dest_interp,
-                    i * sizeof (void *) + sizeof (Buffer));
-            UNUSED(ignored);
-            PARROT_ASSERT(dest_arena->sized_header_pools[i]);
-        }
-
-        Parrot_small_object_pool_merge(dest_interp,
-            dest_arena->sized_header_pools[i],
-            source_arena->sized_header_pools[i]);
-    }
-}
-
-
 /*
 
 =back

Modified: branches/pmc_pct/src/gc/res_lea.c
==============================================================================
--- branches/pmc_pct/src/gc/res_lea.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/res_lea.c	Fri May 15 21:49:40 2009	(r38803)
@@ -33,7 +33,7 @@
 
 /*
 
-=item C<void Parrot_go_collect(PARROT_INTERP)>
+=item C<void Parrot_gc_compact_memory_pool(PARROT_INTERP)>
 
 Does nothing other than increment the interpreter's C<gc_collect_runs>
 count.
@@ -43,7 +43,7 @@
 */
 
 void
-Parrot_go_collect(PARROT_INTERP)
+Parrot_gc_compact_memory_pool(PARROT_INTERP)
 {
     ASSERT_ARGS(parrot_go_collect)
     if (interp->arena_base->gc_sweep_block_level) {
@@ -117,7 +117,7 @@
 
 /*
 
-=item C<void Parrot_reallocate(PARROT_INTERP, Buffer *buffer, size_t newsize)>
+=item C<void Parrot_gc_reallocate_buffer_storage(PARROT_INTERP, Buffer *buffer, size_t newsize)>
 
 COWable objects (strings or Buffers) use an INTVAL before C<bufstart> for
 refcounting in GC.
@@ -127,14 +127,14 @@
 */
 
 void
-Parrot_reallocate(PARROT_INTERP, Buffer *buffer, size_t newsize)
+Parrot_gc_reallocate_buffer_storage(PARROT_INTERP, Buffer *buffer, size_t newsize)
 {
     ASSERT_ARGS(parrot_reallocate)
     const size_t oldlen = PObj_buflen(buffer);
     Buffer_alloc_unit *p;
 
     if (!PObj_bufstart(buffer)) {
-        Parrot_allocate_aligned(interp, buffer, newsize);
+        Parrot_gc_allocate_buffer_storage_aligned(interp, buffer, newsize);
         /* The previous version zeroed the memory here, but I'm not
            sure why. */
         memset(PObj_bufstart(buffer), 0, newsize);
@@ -164,7 +164,8 @@
 
 This was never called anyway, so it isn't implemented here.
 
-=item C<void Parrot_allocate_aligned(PARROT_INTERP, Buffer *buffer, size_t size)>
+=item C<void Parrot_gc_allocate_buffer_storage_aligned(PARROT_INTERP, Buffer *buffer,
+size_t size)>
 
 Like above, except the address of the buffer is guaranteed to be
 suitably aligned for holding anything contained in UnionVal
@@ -175,7 +176,7 @@
 */
 
 void
-Parrot_allocate_aligned(PARROT_INTERP, Buffer *buffer, size_t size)
+Parrot_gc_allocate_buffer_storage_aligned(PARROT_INTERP, Buffer *buffer, size_t size)
 {
     ASSERT_ARGS(parrot_allocate_aligned)
     Buffer_alloc_unit *p;
@@ -187,7 +188,7 @@
 
 /*
 
-=item C<void Parrot_reallocate_string(PARROT_INTERP, STRING *str, size_t newsize)>
+=item C<void Parrot_gc_reallocate_string_storage(PARROT_INTERP, STRING *str, size_t newsize)>
 
 Reallocates the string buffer in C<*str> and returns it. C<newsize> is the
 number of bytes memory required.
@@ -197,13 +198,13 @@
 */
 
 void
-Parrot_reallocate_string(PARROT_INTERP, STRING *str, size_t newsize)
+Parrot_gc_reallocate_string_storage(PARROT_INTERP, STRING *str, size_t newsize)
 {
     ASSERT_ARGS(parrot_reallocate_string)
     Buffer_alloc_unit *p;
 
     if (!PObj_bufstart(str)) {
-        Parrot_allocate_string(interp, str, newsize);
+        Parrot_gc_allocate_string_storage(interp, str, newsize);
     }
     else if (newsize) {
         p = (Buffer_alloc_unit *) xrealloc(PObj_bufallocstart(str),
@@ -215,7 +216,7 @@
 
 /*
 
-=item C<void Parrot_allocate_string(PARROT_INTERP, STRING *str, size_t size)>
+=item C<void Parrot_gc_allocate_string_storage(PARROT_INTERP, STRING *str, size_t size)>
 
 Allocates the string buffer in C<*str> and returns it. C<size> is the
 number bytes of memory required.
@@ -225,9 +226,9 @@
 */
 
 void
-Parrot_allocate_string(PARROT_INTERP, STRING *str, size_t size)
+Parrot_gc_allocate_string_storage(PARROT_INTERP, STRING *str, size_t size)
 {
-    ASSERT_ARGS(parrot_allocate_string)
+    ASSERT_ARGS(Parrot_gc_allocate_string_storage)
     Buffer_alloc_unit *p;
     p = (Buffer_alloc_unit *) xcalloc(Buffer_alloc_offset + size, 1);
     p->ref_count = 0;
@@ -268,7 +269,7 @@
 
 /*
 
-=item C<void Parrot_destroy_memory_pools(PARROT_INTERP)>
+=item C<void Parrot_gc_destroy_memory_pools(PARROT_INTERP)>
 
 Does nothing.
 
@@ -277,7 +278,7 @@
 */
 
 void
-Parrot_destroy_memory_pools(PARROT_INTERP)
+Parrot_gc_destroy_memory_pools(PARROT_INTERP)
 {
     ASSERT_ARGS(parrot_destroy_memory_pools)
 }
@@ -288,7 +289,7 @@
 
 =head1 SEE ALSO
 
-F<config/auto/gc.pl>, F<src/malloc.c>, F<include/parrot/resources.h>.
+F<config/auto/gc.pl>, F<src/malloc.c>
 
 =cut
 

Modified: branches/pmc_pct/src/gc/resources.c
==============================================================================
--- branches/pmc_pct/src/gc/resources.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/resources.c	Fri May 15 21:49:40 2009	(r38803)
@@ -19,7 +19,8 @@
 */
 
 #include "parrot/parrot.h"
-#include "parrot/resources.h"
+#include "gc_private.h"
+
 
 #define RECLAMATION_FACTOR 0.20
 #define WE_WANT_EVER_GROWING_ALLOCATIONS 0
@@ -32,26 +33,11 @@
 
 typedef void (*compact_f) (Interp *, Memory_Pool *);
 
-/* HEADERIZER HFILE: include/parrot/resources.h */
+/* HEADERIZER HFILE: src/gc/gc_private.h */
 
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-static char * aligned_mem(ARGIN(const Buffer *buffer), ARGIN(char *mem))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_PURE_FUNCTION
-PARROT_WARN_UNUSED_RESULT
-static size_t aligned_size(ARGIN(const Buffer *buffer), size_t len)
-        __attribute__nonnull__(1);
-
-PARROT_CONST_FUNCTION
-PARROT_WARN_UNUSED_RESULT
-static size_t aligned_string_size(size_t len);
-
 static void alloc_new_block(PARROT_INTERP,
     size_t size,
     ARGMOD(Memory_Pool *pool),
@@ -67,44 +53,16 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-static void compact_pool(PARROT_INTERP, ARGMOD(Memory_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*pool);
-
 static void debug_print_buf(PARROT_INTERP, ARGIN(const PObj *b))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
-static void * mem_allocate(PARROT_INTERP,
-    size_t size,
-    ARGMOD(Memory_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*pool);
-
-static void merge_pools(
-    ARGMOD(Memory_Pool *dest),
-    ARGMOD(Memory_Pool *source))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*dest)
-        FUNC_MODIFIES(*source);
-
-PARROT_MALLOC
-PARROT_CANNOT_RETURN_NULL
 static Memory_Pool * new_memory_pool(
     size_t min_block,
     NULLOK(compact_f compact));
 
-#define ASSERT_ARGS_aligned_mem __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(buffer) \
-    || PARROT_ASSERT_ARG(mem)
-#define ASSERT_ARGS_aligned_size __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(buffer)
-#define ASSERT_ARGS_aligned_string_size __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_alloc_new_block __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pool) \
@@ -112,18 +70,9 @@
 #define ASSERT_ARGS_buffer_location __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(b)
-#define ASSERT_ARGS_compact_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pool)
 #define ASSERT_ARGS_debug_print_buf __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(b)
-#define ASSERT_ARGS_mem_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pool)
-#define ASSERT_ARGS_merge_pools __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(dest) \
-    || PARROT_ASSERT_ARG(source)
 #define ASSERT_ARGS_new_memory_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
@@ -191,8 +140,7 @@
 
 /*
 
-=item C<static void * mem_allocate(PARROT_INTERP, size_t size, Memory_Pool
-*pool)>
+=item C<void * mem_allocate(PARROT_INTERP, size_t size, Memory_Pool *pool)>
 
 Allocates memory for headers.
 
@@ -229,7 +177,7 @@
 
 PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
-static void *
+void *
 mem_allocate(PARROT_INTERP, size_t size, ARGMOD(Memory_Pool *pool))
 {
     ASSERT_ARGS(mem_allocate)
@@ -249,7 +197,7 @@
          */
         if (!interp->arena_base->gc_mark_block_level
         &&   interp->arena_base->mem_allocs_since_last_collect) {
-            Parrot_do_gc_run(interp, GC_trace_stack_FLAG);
+            Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #if !PARROT_GC_IMS
             /* Compact the pool if allowed and worthwhile */
             if (pool->compact) {
@@ -353,7 +301,7 @@
 
 =over 4
 
-=item C<static void compact_pool(PARROT_INTERP, Memory_Pool *pool)>
+=item C<void compact_pool(PARROT_INTERP, Memory_Pool *pool)>
 
 Compact the string buffer pool. Does not perform a GC scan, or mark items
 as being alive in any way.
@@ -362,7 +310,7 @@
 
 */
 
-static void
+void
 compact_pool(PARROT_INTERP, ARGMOD(Memory_Pool *pool))
 {
     ASSERT_ARGS(compact_pool)
@@ -590,26 +538,7 @@
 
 /*
 
-=item C<void Parrot_go_collect(PARROT_INTERP)>
-
-Scan the string pools and compact them. This does not perform a GC mark or
-sweep run, and does not check whether string buffers are still alive.
-Redirects to C<compact_pool>.
-
-=cut
-
-*/
-
-void
-Parrot_go_collect(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_go_collect)
-    compact_pool(interp, interp->arena_base->memory_pool);
-}
-
-/*
-
-=item C<static size_t aligned_size(const Buffer *buffer, size_t len)>
+=item C<size_t aligned_size(const Buffer *buffer, size_t len)>
 
 Determines the size of Buffer C<buffer> which has nominal length C<len>.
 The actual size in RAM of the Buffer might be different because of
@@ -621,7 +550,7 @@
 
 PARROT_PURE_FUNCTION
 PARROT_WARN_UNUSED_RESULT
-static size_t
+size_t
 aligned_size(ARGIN(const Buffer *buffer), size_t len)
 {
     ASSERT_ARGS(aligned_size)
@@ -636,7 +565,7 @@
 
 /*
 
-=item C<static char * aligned_mem(const Buffer *buffer, char *mem)>
+=item C<char * aligned_mem(const Buffer *buffer, char *mem)>
 
 Returns a pointer to the aligned allocated storage for Buffer C<buffer>,
 which might not be the same as the pointer to C<buffeR> because of
@@ -648,7 +577,7 @@
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-static char *
+char *
 aligned_mem(ARGIN(const Buffer *buffer), ARGIN(char *mem))
 {
     ASSERT_ARGS(aligned_mem)
@@ -665,7 +594,7 @@
 
 /*
 
-=item C<static size_t aligned_string_size(size_t len)>
+=item C<size_t aligned_string_size(size_t len)>
 
 Determines the size of a string of length C<len> in RAM, accounting for
 alignment.
@@ -677,7 +606,7 @@
 /* XXX Looks like we can lose buffer here */
 PARROT_CONST_FUNCTION
 PARROT_WARN_UNUSED_RESULT
-static size_t
+size_t
 aligned_string_size(size_t len)
 {
     ASSERT_ARGS(aligned_string_size)
@@ -688,185 +617,12 @@
 
 /*
 
-=item C<int Parrot_in_memory_pool(PARROT_INTERP, void *bufstart)>
-
-Determines if the given C<bufstart> pointer points to a location inside the
-memory pool. Returns 1 if the pointer is in the memory pool, 0 otherwise.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-int
-Parrot_in_memory_pool(PARROT_INTERP, ARGIN(void *bufstart))
-{
-    ASSERT_ARGS(Parrot_in_memory_pool)
-    Memory_Pool * const pool = interp->arena_base->memory_pool;
-    Memory_Block * cur_block = pool->top_block;
-
-    while (cur_block) {
-        if ((char *)bufstart >= cur_block->start &&
-            (char *) bufstart < cur_block->start + cur_block->size) {
-            return 1;
-        }
-        cur_block = cur_block->prev;
-    }
-    return 0;
-}
-
-
-/*
-
 =back
 
 =head2 Parrot Re/Allocate Code
 
 =over 4
 
-=item C<void Parrot_reallocate(PARROT_INTERP, Buffer *buffer, size_t newsize)>
-
-Reallocate the Buffer's buffer memory to the given size. The
-allocated buffer will not shrink. If the buffer was allocated with
-L<Parrot_allocate_aligned> the new buffer will also be aligned. As with
-all reallocation, the new buffer might have moved and the additional
-memory is not cleared.
-
-=cut
-
-*/
-
-void
-Parrot_reallocate(PARROT_INTERP, ARGMOD(Buffer *buffer), size_t newsize)
-{
-    ASSERT_ARGS(Parrot_reallocate)
-    size_t copysize;
-    char  *mem;
-    Memory_Pool * const pool = interp->arena_base->memory_pool;
-    size_t new_size, needed, old_size;
-
-    /*
-     * we don't shrink buffers
-     */
-    if (newsize <= PObj_buflen(buffer))
-        return;
-
-    /*
-     * same as below but barely used and tested - only 3 list related
-     * tests do use true reallocation
-     *
-     * list.c, which does _reallocate, has 2 reallocations
-     * normally, which play ping pong with buffers.
-     * The normal case is therefore always to allocate a new block
-     */
-    new_size = aligned_size(buffer, newsize);
-    old_size = aligned_size(buffer, PObj_buflen(buffer));
-    needed   = new_size - old_size;
-
-    if ((pool->top_block->free >= needed)
-    &&  (pool->top_block->top  == (char *)PObj_bufstart(buffer) + old_size)) {
-        pool->top_block->free -= needed;
-        pool->top_block->top  += needed;
-        PObj_buflen(buffer) = newsize;
-        return;
-    }
-
-    copysize = PObj_buflen(buffer);
-
-    if (!PObj_COW_TEST(buffer))
-        pool->guaranteed_reclaimable += copysize;
-
-    pool->possibly_reclaimable += copysize;
-    mem                         = (char *)mem_allocate(interp, new_size, pool);
-    mem                         = aligned_mem(buffer, mem);
-
-    /* We shouldn't ever have a 0 from size, but we do. If we can track down
-     * those bugs, this can be removed which would make things cheaper */
-    if (copysize)
-        memcpy(mem, PObj_bufstart(buffer), copysize);
-
-    PObj_bufstart(buffer) = mem;
-
-    if (PObj_is_COWable_TEST(buffer))
-        new_size -= sizeof (void *);
-
-    PObj_buflen(buffer) = new_size;
-}
-
-
-/*
-
-=item C<void Parrot_reallocate_string(PARROT_INTERP, STRING *str, size_t
-newsize)>
-
-Reallocate the STRING's buffer memory to the given size. The allocated
-buffer will not shrink. This function sets also C<str-E<gt>strstart> to the
-new buffer location, C<str-E<gt>bufused> is B<not> changed.
-
-=cut
-
-*/
-
-void
-Parrot_reallocate_string(PARROT_INTERP, ARGMOD(STRING *str), size_t newsize)
-{
-    ASSERT_ARGS(Parrot_reallocate_string)
-    size_t copysize;
-    char *mem, *oldmem;
-    size_t new_size, needed, old_size;
-
-    Memory_Pool * const pool =
-        PObj_constant_TEST(str)
-            ? interp->arena_base->constant_string_pool
-            : interp->arena_base->memory_pool;
-
-    /* if the requested size is smaller then buflen, we are done */
-    if (newsize <= PObj_buflen(str))
-        return;
-
-    /*
-     * first check, if we can reallocate:
-     * - if the passed strings buffer is the last string in the pool and
-     * - if there is enough size, we can just move the pool's top pointer
-     */
-    new_size = aligned_string_size(newsize);
-    old_size = aligned_string_size(PObj_buflen(str));
-    needed   = new_size - old_size;
-
-    if (pool->top_block->free >= needed
-    &&  pool->top_block->top  == (char *)PObj_bufstart(str) + old_size) {
-        pool->top_block->free -= needed;
-        pool->top_block->top  += needed;
-        PObj_buflen(str) = new_size - sizeof (void*);
-        return;
-    }
-
-    PARROT_ASSERT(str->bufused <= newsize);
-
-    /* only copy used memory, not total string buffer */
-    copysize = str->bufused;
-
-    if (!PObj_COW_TEST(str))
-        pool->guaranteed_reclaimable += PObj_buflen(str);
-
-    pool->possibly_reclaimable += PObj_buflen(str);
-
-    mem = (char *)mem_allocate(interp, new_size, pool);
-    mem += sizeof (void *);
-
-    /* copy mem from strstart, *not* bufstart */
-    oldmem             = str->strstart;
-    PObj_bufstart(str) = (void *)mem;
-    str->strstart      = mem;
-    PObj_buflen(str)   = new_size - sizeof (void*);
-
-    /* We shouldn't ever have a 0 from size, but we do. If we can track down
-     * those bugs, this can be removed which would make things cheaper */
-    if (copysize)
-        memcpy(mem, oldmem, copysize);
-}
-
-/*
 
 =item C<void Parrot_allocate(PARROT_INTERP, Buffer *buffer, size_t size)>
 
@@ -890,82 +646,6 @@
     PObj_buflen(buffer) = size;
 }
 
-
-/*
-
-=item C<void Parrot_allocate_aligned(PARROT_INTERP, Buffer *buffer, size_t
-size)>
-
-Like above, except the C<size> will be rounded up and the address of
-the buffer will have the same alignment as a pointer returned by
-malloc(3) suitable to hold e.g. a C<FLOATVAL> array.
-
-=cut
-
-*/
-
-void
-Parrot_allocate_aligned(PARROT_INTERP, ARGOUT(Buffer *buffer), size_t size)
-{
-    ASSERT_ARGS(Parrot_allocate_aligned)
-    size_t new_size;
-    char *mem;
-
-    PObj_buflen(buffer) = 0;
-    PObj_bufstart(buffer) = NULL;
-    new_size = aligned_size(buffer, size);
-    mem = (char *)mem_allocate(interp, new_size,
-        interp->arena_base->memory_pool);
-    mem = aligned_mem(buffer, mem);
-    PObj_bufstart(buffer) = mem;
-    if (PObj_is_COWable_TEST(buffer))
-        new_size -= sizeof (void*);
-    PObj_buflen(buffer) = new_size;
-}
-
-/*
-
-=item C<void Parrot_allocate_string(PARROT_INTERP, STRING *str, size_t size)>
-
-Allocate the STRING's buffer memory to the given size. The allocated
-buffer maybe slightly bigger than the given C<size>. This function
-sets also C<< str->strstart >> to the new buffer location, C<< str->bufused >>
-is B<not> changed.
-
-=cut
-
-*/
-
-void
-Parrot_allocate_string(PARROT_INTERP, ARGOUT(STRING *str), size_t size)
-{
-    ASSERT_ARGS(Parrot_allocate_string)
-    size_t       new_size;
-    Memory_Pool *pool;
-    char        *mem;
-
-    PObj_buflen(str)   = 0;
-    PObj_bufstart(str) = NULL;
-
-    /* there's no sense in allocating zero memory, when the overhead of
-     * allocating a string is one pointer; this can fill the pools in an
-     * uncompactable way.  See RT #42320.
-     */
-    if (size == 0)
-        return;
-
-    pool     = PObj_constant_TEST(str)
-                ? interp->arena_base->constant_string_pool
-                : interp->arena_base->memory_pool;
-
-    new_size = aligned_string_size(size);
-    mem      = (char *)mem_allocate(interp, new_size, pool);
-    mem     += sizeof (void*);
-
-    PObj_bufstart(str) = str->strstart = mem;
-    PObj_buflen(str)   = new_size - sizeof (void*);
-}
-
 /*
 
 =item C<static Memory_Pool * new_memory_pool(size_t min_block, compact_f
@@ -1025,45 +705,10 @@
     alloc_new_block(interp, POOL_SIZE, arena_base->constant_string_pool, "init");
 }
 
-/*
-
-=item C<void Parrot_destroy_memory_pools(PARROT_INTERP)>
-
-Destroys the memory pool and the constant string pool. Loop through both
-pools and destroy all memory blocks contained in them. Once all the
-blocks are freed, free the pools themselves.
-
-=cut
-
-*/
-
-void
-Parrot_destroy_memory_pools(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_destroy_memory_pools)
-    int i;
-
-    for (i = 0; i < 2; i++) {
-        Memory_Pool * const pool = i ?
-                interp->arena_base->constant_string_pool :
-                interp->arena_base->memory_pool;
-        Memory_Block *cur_block;
-
-        cur_block = pool->top_block;
-
-        while (cur_block) {
-            Memory_Block * const next_block = cur_block->prev;
-            mem_internal_free(cur_block);
-            cur_block = next_block;
-        }
-
-        mem_internal_free(pool);
-    }
-}
 
 /*
 
-=item C<static void merge_pools(Memory_Pool *dest, Memory_Pool *source)>
+=item C<void merge_pools(Memory_Pool *dest, Memory_Pool *source)>
 
 Merge two memory pools together. Do this by moving all memory blocks
 from the C<*source> pool into the C<*dest> pool. The C<source> pool
@@ -1073,7 +718,7 @@
 
 */
 
-static void
+void
 merge_pools(ARGMOD(Memory_Pool *dest), ARGMOD(Memory_Pool *source))
 {
     ASSERT_ARGS(merge_pools)
@@ -1108,35 +753,65 @@
 
 /*
 
-=item C<void Parrot_merge_memory_pools(Interp *dest_interp, Interp
-*source_interp)>
+=item C<void Parrot_gc_profile_start(PARROT_INTERP)>
 
-Merge the memory pools of two interpreter structures. Merge the general
-memory pool and the constant string pools from C<source_interp> into
-C<dest_interp>.
+Records the start time of a GC mark run when profiling is enabled.
 
 =cut
 
 */
 
 void
-Parrot_merge_memory_pools(ARGIN(Interp *dest_interp), ARGIN(Interp *source_interp))
+Parrot_gc_profile_start(PARROT_INTERP)
 {
-    ASSERT_ARGS(Parrot_merge_memory_pools)
-    merge_pools(dest_interp->arena_base->constant_string_pool,
-                source_interp->arena_base->constant_string_pool);
+    ASSERT_ARGS(Parrot_gc_profile_start)
+    if (Interp_flags_TEST(interp, PARROT_PROFILE_FLAG))
+        interp->profile->gc_time = Parrot_floatval_time();
+}
+
+/*
+
+=item C<void Parrot_gc_profile_end(PARROT_INTERP, int what)>
+
+Records the end time of the GC mark run part C<what> run when profiling is
+enabled. Also record start time of next part.
+
+=cut
 
-    merge_pools(dest_interp->arena_base->memory_pool,
-                source_interp->arena_base->memory_pool);
+*/
+
+void
+Parrot_gc_profile_end(PARROT_INTERP, int what)
+{
+    ASSERT_ARGS(Parrot_gc_profile_end)
+    if (Interp_flags_TEST(interp, PARROT_PROFILE_FLAG)) {
+        RunProfile * const profile = interp->profile;
+        const FLOATVAL     now     = Parrot_floatval_time();
+
+        profile->data[what].numcalls++;
+        profile->data[what].time += now - profile->gc_time;
+
+        /*
+         * we've recorded the time of a GC piece from
+         * gc_time until now, so add this to the start of the
+         * currently executing opcode, which hasn't run this
+         * interval.
+         */
+        profile->starttime += now - profile->gc_time;
+
+        /* prepare start for next step */
+        profile->gc_time    = now;
+    }
 }
 
+
 /*
 
 =back
 
 =head1 SEE ALSO
 
-F<include/parrot/resources.h>, F<src/gc/memory.c>.
+F<src/gc/memory.c>.
 
 =head1 HISTORY
 

Modified: branches/pmc_pct/src/gc/system.c
==============================================================================
--- branches/pmc_pct/src/gc/system.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/gc/system.c	Fri May 15 21:49:40 2009	(r38803)
@@ -93,9 +93,35 @@
 
 #elif defined(__ia64__)
 
-        /* On IA64 systems, we use the function getcontext() to get the current
-           processor context. This function is located in <ucontext.h>, included
-           above. */
+
+#  if defined(__hpux)
+        ucontext_t ucp;
+        void *current_regstore_top;
+
+        getcontext(&ucp);
+        _Asm_flushrs();
+
+#    if defined(_LP64)
+        current_regstore_top = (void*)(uint64_t)_Asm_mov_from_ar(_AREG_BSP);
+#    else
+        current_regstore_top = (void*)(uint32_t)_Asm_mov_from_ar(_AREG_BSP);
+#    endif
+
+        size_t base = 0;
+        struct pst_vm_status buf;
+        int i = 0;
+
+        while (pstat_getprocvm(&buf, sizeof (buf), 0, i++) == 1) {
+            if (buf.pst_type == PS_RSESTACK) {
+                base = (size_t)buf.pst_vaddr;
+                break;
+            }
+        }
+
+#  else /* !__hpux */
+        /* On IA64 Linux systems, we use the function getcontext() to get the
+           current processor context. This function is located in <ucontext.h>,
+           included above. */
         struct ucontext ucp;
         void *current_regstore_top;
 
@@ -110,9 +136,14 @@
            is separate from the normal system stack. The register backing
            stack starts at memory address 0x80000FFF80000000 and ends at
            current_regstore_top. */
-        trace_mem_block(interp, 0x80000fff80000000,
+        size_t base = 0x80000fff80000000;
+
+#  endif /* __hpux */
+
+        trace_mem_block(interp, base,
                 (size_t)current_regstore_top);
-#else
+
+#else /* !__ia64__ */
 
 #  ifdef PARROT_HAS_HEADER_SETJMP
         /* A jump buffer that is used to store the current processor context.
@@ -130,7 +161,7 @@
         setjmp(env);
 #  endif
 
-#endif
+#endif /* __ia64__ */
     }
 
     /* With the processor context accounted for above, we can trace the
@@ -262,16 +293,16 @@
              * free headers... */
             if (pmc_min <= ptr && ptr < pmc_max &&
                     is_pmc_ptr(interp, (void *)ptr)) {
-                /* ...so ensure that pobject_lives checks PObj_on_free_list_FLAG
+                /* ...so ensure that Parrot_gc_mark_PObj_alive checks PObj_on_free_list_FLAG
                  * before adding it to the next_for_GC list, to have
                  * vtable->mark() called. */
-                pobject_lives(interp, (PObj *)ptr);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)ptr);
             }
             else if (buffer_min <= ptr && ptr < buffer_max &&
                     is_buffer_ptr(interp, (void *)ptr)) {
-                /* ...and since pobject_lives doesn't care about bufstart, it
+                /* ...and since Parrot_gc_mark_PObj_alive doesn't care about bufstart, it
                  * doesn't really matter if it sets a flag */
-                pobject_lives(interp, (PObj *)ptr);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)ptr);
             }
         }
     }

Modified: branches/pmc_pct/src/global.c
==============================================================================
--- branches/pmc_pct/src/global.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/global.c	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2004-2008, Parrot Foundation.
+Copyright (C) 2004-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -222,7 +222,7 @@
         }
 
         ns  = sub_ns;
-        key = key_next(interp, key);
+        key = VTABLE_shift_pmc(interp, key);
     }
 
     return ns;

Modified: branches/pmc_pct/src/hash.c
==============================================================================
--- branches/pmc_pct/src/hash.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/hash.c	Fri May 15 21:49:40 2009	(r38803)
@@ -364,10 +364,9 @@
 
 PARROT_EXPORT
 void
-parrot_dump_hash(SHIM_INTERP, ARGIN(const Hash *hash))
+parrot_dump_hash(SHIM_INTERP, SHIM(const Hash *hash))
 {
     ASSERT_ARGS(parrot_dump_hash)
-    UNUSED(hash);
 }
 
 
@@ -439,7 +438,7 @@
                     hash, (int)entries);
 
             PARROT_ASSERT(bucket->key);
-            pobject_lives(interp, (PObj *)bucket->key);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->key);
 
             bucket = bucket->next;
         }
@@ -461,7 +460,7 @@
 parrot_mark_hash_values(PARROT_INTERP, ARGIN(Hash *hash))
 {
     ASSERT_ARGS(parrot_mark_hash_values)
-    UINTVAL entries = hash->entries;
+    const UINTVAL entries = hash->entries;
     UINTVAL found   = 0;
     INTVAL  i;
 
@@ -470,12 +469,12 @@
 
         while (bucket) {
             if (++found > entries)
-            Parrot_ex_throw_from_c_args(interp, NULL, 1,
+                Parrot_ex_throw_from_c_args(interp, NULL, 1,
                         "Detected hash corruption at hash %p entries %d",
                         hash, (int)entries);
 
             PARROT_ASSERT(bucket->value);
-            pobject_lives(interp, (PObj *)bucket->value);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->value);
 
             bucket = bucket->next;
         }
@@ -497,7 +496,7 @@
 parrot_mark_hash_both(PARROT_INTERP, ARGIN(Hash *hash))
 {
     ASSERT_ARGS(parrot_mark_hash_both)
-    UINTVAL entries = hash->entries;
+    const UINTVAL entries = hash->entries;
     UINTVAL found   = 0;
     INTVAL  i;
 
@@ -511,10 +510,10 @@
                         hash, (int)entries);
 
             PARROT_ASSERT(bucket->key);
-            pobject_lives(interp, (PObj *)bucket->key);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->key);
 
             PARROT_ASSERT(bucket->value);
-            pobject_lives(interp, (PObj *)bucket->value);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->value);
 
             bucket = bucket->next;
         }
@@ -616,7 +615,7 @@
     size_t           i;
 
     for (i = 0; i < hash->entries; i++) {
-        HashBucket *b = hash->bs+i;
+        HashBucket * const b = hash->bs+i;
 
         switch (hash->key_type) {
             case Hash_key_type_STRING:
@@ -1099,7 +1098,7 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_PURE_FUNCTION
 INTVAL
-parrot_hash_size(PARROT_INTERP, ARGIN(const Hash *hash))
+parrot_hash_size(SHIM_INTERP, ARGIN(const Hash *hash))
 {
     ASSERT_ARGS(parrot_hash_size)
 

Modified: branches/pmc_pct/src/interp/inter_cb.c
==============================================================================
--- branches/pmc_pct/src/interp/inter_cb.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/interp/inter_cb.c	Fri May 15 21:49:40 2009	(r38803)
@@ -186,7 +186,7 @@
             continue;
         interp = interpreter_array[i];
         if (interp)
-            if (contained_in_pool(interp->arena_base->pmc_pool, user_data))
+            if (Parrot_gc_ptr_is_pmc(interp, user_data))
                 break;
     }
     UNLOCK(interpreter_array_mutex);

Modified: branches/pmc_pct/src/interp/inter_create.c
==============================================================================
--- branches/pmc_pct/src/interp/inter_create.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/interp/inter_create.c	Fri May 15 21:49:40 2009	(r38803)
@@ -151,7 +151,7 @@
     interp->recursion_limit = RECURSION_LIMIT;
 
     /* Must initialize flags here so the GC_DEBUG stuff is available before
-     * mem_setup_allocator() is called. */
+     * Parrot_gc_initialize() is called. */
     interp->flags = flags;
 
     /* PANIC will fail until this is done */
@@ -168,7 +168,7 @@
     }
 
     /* Set up the memory allocation system */
-    mem_setup_allocator(interp, (void*)&stacktop);
+    Parrot_gc_initialize(interp, (void*)&stacktop);
     Parrot_block_GC_mark(interp);
     Parrot_block_GC_sweep(interp);
 
@@ -334,8 +334,7 @@
      * Need to turn off GC blocking, else things stay alive and IO
      * handles aren't closed
      */
-    interp->arena_base->gc_mark_block_level  = 0;
-    interp->arena_base->gc_sweep_block_level = 0;
+    Parrot_gc_completely_unblock(interp);
 
     if (Interp_trace_TEST(interp, ~0)) {
         Parrot_io_eprintf(interp, "FileHandle objects (like stdout and stderr)"
@@ -348,7 +347,7 @@
     if (interp->thread_data)
         interp->thread_data->state |= THREAD_STATE_SUSPENDED_GC;
 
-    Parrot_do_gc_run(interp, GC_finish_FLAG);
+    Parrot_gc_mark_and_sweep(interp, GC_finish_FLAG);
 
     /*
      * that doesn't get rid of constant PMCs like these in vtable->data
@@ -384,12 +383,11 @@
     if (interp->parent_interpreter
     &&  interp->thread_data
     && (interp->thread_data->state & THREAD_STATE_JOINED)) {
-        Parrot_merge_header_pools(interp->parent_interpreter, interp);
-        Parrot_merge_memory_pools(interp->parent_interpreter, interp);
+        Parrot_gc_merge_header_pools(interp->parent_interpreter, interp);
+        Parrot_gc_merge_header_pools(interp->parent_interpreter, interp);
     }
 
-    if (interp->arena_base->finalize_gc_system)
-        interp->arena_base->finalize_gc_system(interp);
+    Parrot_gc_finalize(interp);
 
     /* MMD cache */
     Parrot_mmd_cache_destroy(interp, interp->op_mmd_cache);
@@ -398,10 +396,10 @@
     Parrot_destroy_constants(interp);
 
     /* buffer headers, PMCs */
-    Parrot_destroy_header_pools(interp);
+    Parrot_gc_destroy_header_pools(interp);
 
     /* memory pools in resources */
-    Parrot_destroy_memory_pools(interp);
+    Parrot_gc_destroy_memory_pools(interp);
 
     /* mem subsystem is dead now */
     mem_sys_free(interp->arena_base);

Modified: branches/pmc_pct/src/interp/inter_misc.c
==============================================================================
--- branches/pmc_pct/src/interp/inter_misc.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/interp/inter_misc.c	Fri May 15 21:49:40 2009	(r38803)
@@ -205,13 +205,12 @@
 */
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 INTVAL
 interpinfo(PARROT_INTERP, INTVAL what)
 {
     ASSERT_ARGS(interpinfo)
-    INTVAL ret = 0;
-    int j;
-    Arenas *arena_base = interp->arena_base;
+    INTVAL ret;
 
     switch (what) {
         case TOTAL_MEM_ALLOC:
@@ -220,57 +219,43 @@
             interp->memory_allocated = mallinfo().uordblks;
 #  endif
 #endif
-            ret = arena_base->memory_allocated;
+            ret = Parrot_gc_total_memory_allocated(interp);
             break;
         case GC_MARK_RUNS:
-            ret = arena_base->gc_mark_runs;
+            ret = Parrot_gc_count_mark_runs(interp);
             break;
         case GC_LAZY_MARK_RUNS:
-            ret = arena_base->gc_lazy_mark_runs;
+            ret = Parrot_gc_count_lazy_mark_runs(interp);
             break;
         case GC_COLLECT_RUNS:
-            ret = arena_base->gc_collect_runs;
+            ret = Parrot_gc_count_collect_runs(interp);
             break;
         case ACTIVE_PMCS:
-            ret = arena_base->pmc_pool->total_objects -
-                arena_base->pmc_pool->num_free_objects;
+            ret = Parrot_gc_active_pmcs(interp);
             break;
         case ACTIVE_BUFFERS:
-            ret = 0;
-            for (j = 0; j < (INTVAL)arena_base->num_sized; j++) {
-                Small_Object_Pool * const header_pool =
-                    arena_base->sized_header_pools[j];
-                if (header_pool)
-                    ret += header_pool->total_objects -
-                        header_pool->num_free_objects;
-            }
+            ret = Parrot_gc_active_sized_buffers(interp);
             break;
         case TOTAL_PMCS:
-            ret = arena_base->pmc_pool->total_objects;
+            ret = Parrot_gc_total_pmcs(interp);
             break;
         case TOTAL_BUFFERS:
-            ret = 0;
-            for (j = 0; j < (INTVAL)arena_base->num_sized; j++) {
-                Small_Object_Pool * const header_pool =
-                    arena_base->sized_header_pools[j];
-                if (header_pool)
-                    ret += header_pool->total_objects;
-            }
+            ret = Parrot_gc_total_sized_buffers(interp);
             break;
         case HEADER_ALLOCS_SINCE_COLLECT:
-            ret = arena_base->header_allocs_since_last_collect;
+            ret = Parrot_gc_headers_alloc_since_last_collect(interp);
             break;
         case MEM_ALLOCS_SINCE_COLLECT:
-            ret = arena_base->mem_allocs_since_last_collect;
+            ret = Parrot_gc_mem_alloc_since_last_collect(interp);
             break;
         case TOTAL_COPIED:
-            ret = arena_base->memory_collected;
+            ret = Parrot_gc_total_copied(interp);
             break;
         case IMPATIENT_PMCS:
-            ret = arena_base->num_early_gc_PMCs;
+            ret = Parrot_gc_impatient_pmcs(interp);
             break;
         case EXTENDED_PMCS:
-            ret = arena_base->num_extended_PMCs;
+            ret = Parrot_gc_extended_pmcs(interp);
             break;
         case CURRENT_RUNCORE:
             ret = interp->run_core;

Modified: branches/pmc_pct/src/io/api.c
==============================================================================
--- branches/pmc_pct/src/io/api.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/api.c	Fri May 15 21:49:40 2009	(r38803)
@@ -11,7 +11,7 @@
 The Parrot I/O subsystem provides the core I/O functionality for all parts of
 Parrot. This file implements the public interface to the I/O subsystem. Common
 utility functions that aren't part of the public interface are defined in
-F<src/io/common.c> and utility functions for a specific platform are in
+F<src/io/core.c> and utility functions for a specific platform are in
 F<src/io/unix.c>, F<src/io/win32.c>, or F<src/io/portable.c>. The platform is
 selected in F<include/parrot/io.h>, based on #defines from the configuration
 process.
@@ -46,6 +46,7 @@
 */
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 PMC *
 Parrot_io_stdhandle(PARROT_INTERP, INTVAL fileno, ARGIN_NULLOK(PMC *newhandle))
@@ -203,6 +204,7 @@
 */
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 INTVAL
 Parrot_io_is_closed(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
@@ -378,6 +380,7 @@
 */
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 INTVAL
 Parrot_io_peek(PARROT_INTERP, ARGMOD(PMC *pmc), ARGOUT(STRING **buffer))
 {
@@ -476,6 +479,7 @@
 */
 
 PARROT_EXPORT
+PARROT_IGNORABLE_RESULT
 INTVAL
 Parrot_io_fprintf(PARROT_INTERP, ARGMOD(PMC *pmc), ARGIN(const char *s), ...)
 {
@@ -503,6 +507,7 @@
 */
 
 PARROT_EXPORT
+PARROT_IGNORABLE_RESULT
 INTVAL
 Parrot_io_printf(PARROT_INTERP, ARGIN(const char *s), ...)
 {
@@ -692,6 +697,7 @@
 */
 
 PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
 PIOOFF_T
 Parrot_io_make_offset(INTVAL offset)
 {
@@ -710,6 +716,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PIOOFF_T
 Parrot_io_make_offset32(INTVAL hi, INTVAL lo)
 {
@@ -727,6 +734,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PIOOFF_T
 Parrot_io_make_offset_pmc(PARROT_INTERP, ARGMOD(PMC *pmc))
 {

Modified: branches/pmc_pct/src/io/buffer.c
==============================================================================
--- branches/pmc_pct/src/io/buffer.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/buffer.c	Fri May 15 21:49:40 2009	(r38803)
@@ -299,7 +299,7 @@
         return Parrot_io_readline_buffer(interp, filehandle, buf);
 
     if (*buf == NULL) {
-        *buf = new_string_header(interp, 0);
+        *buf = Parrot_gc_new_string_header(interp, 0);
         (*buf)->bufused = len = 2048;
     }
 
@@ -307,7 +307,7 @@
     len = s->bufused;
 
     if (!s->strstart)
-        Parrot_allocate_string(interp, s, len);
+        Parrot_gc_allocate_string_storage(interp, s, len);
 
     out_buf = (unsigned char *)s->strstart;
 
@@ -478,7 +478,7 @@
     STRING *s;
 
     if (*buf == NULL) {
-        *buf = new_string_header(interp, 0);
+        *buf = Parrot_gc_new_string_header(interp, 0);
     }
     s = *buf;
     s->strlen = 0;
@@ -514,10 +514,10 @@
             len = buffer_end - buf_start;
             if (s->bufused < l) {
                 if (s->strstart) {
-                    Parrot_reallocate_string(interp, s, l);
+                    Parrot_gc_reallocate_string_storage(interp, s, l);
                 }
                 else {
-                    Parrot_allocate_string(interp, s, l);
+                    Parrot_gc_allocate_string_storage(interp, s, l);
                 }
             }
             out_buf = (unsigned char*)s->strstart + s->strlen;
@@ -533,10 +533,10 @@
     }
     if (s->bufused < l) {
         if (s->strstart) {
-            Parrot_reallocate_string(interp, s, l);
+            Parrot_gc_reallocate_string_storage(interp, s, l);
         }
         else {
-            Parrot_allocate_string(interp, s, l);
+            Parrot_gc_allocate_string_storage(interp, s, l);
         }
     }
     out_buf = (unsigned char*)s->strstart + s->strlen;

Modified: branches/pmc_pct/src/io/core.c
==============================================================================
--- branches/pmc_pct/src/io/core.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/core.c	Fri May 15 21:49:40 2009	(r38803)
@@ -126,7 +126,7 @@
      */
     for (i = 0; i < 3; i++) {
         if (table[i]) {
-            pobject_lives(interp, (PObj *)table[i]);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)table[i]);
         }
     }
 }

Modified: branches/pmc_pct/src/io/filehandle.c
==============================================================================
--- branches/pmc_pct/src/io/filehandle.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/filehandle.c	Fri May 15 21:49:40 2009	(r38803)
@@ -126,7 +126,7 @@
     else {
         STRING *s = *buf;
         if (s->bufused < len)
-            Parrot_reallocate_string(interp, s, len);
+            Parrot_gc_reallocate_string_storage(interp, s, len);
         return s;
     }
 }

Modified: branches/pmc_pct/src/io/io_string.c
==============================================================================
--- branches/pmc_pct/src/io/io_string.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/io_string.c	Fri May 15 21:49:40 2009	(r38803)
@@ -95,6 +95,8 @@
 
 =item C<ParrotIOLayer * PIO_string_register_layer(void)>
 
+Get  a pointer to the C<pio_string_layer> structure.
+
 =cut
 
 */
@@ -112,6 +114,8 @@
 =item C<static size_t PIO_string_read(PARROT_INTERP, ParrotIOLayer *l,
 ParrotIO *io, STRING **buf)>
 
+Read a string from layer C<l> and store it in the specified buffer.
+
 =cut
 
 */
@@ -132,6 +136,8 @@
 
 =item C<static size_t PIO_string_write(PARROT_INTERP, ParrotIOLayer *l, ParrotIO *io, STRING *s)>
 
+Write the string C<s> to the layer C<l>.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/io/socket_api.c
==============================================================================
--- branches/pmc_pct/src/io/socket_api.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/socket_api.c	Fri May 15 21:49:40 2009	(r38803)
@@ -31,6 +31,8 @@
 
 =item C<INTVAL Parrot_io_socket_is_closed(PMC *socket)>
 
+Returns 1 if the socket is closed, 0 if it is open.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/io/socket_unix.c
==============================================================================
--- branches/pmc_pct/src/io/socket_unix.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/socket_unix.c	Fri May 15 21:49:40 2009	(r38803)
@@ -410,7 +410,6 @@
     int usec)
 {
     ASSERT_ARGS(Parrot_io_poll_unix)
-    int n;
     fd_set r, w, e;
     struct timeval t;
     Parrot_Socket_attributes * io = PARROT_SOCKET(socket);
@@ -424,6 +423,7 @@
     if (which & 4) FD_SET(io->os_handle, &e);
 AGAIN:
     if ((select(io->os_handle+1, &r, &w, &e, &t)) >= 0) {
+        int n;
         n = (FD_ISSET(io->os_handle, &r) ? 1 : 0);
         n |= (FD_ISSET(io->os_handle, &w) ? 2 : 0);
         n |= (FD_ISSET(io->os_handle, &e) ? 4 : 0);
@@ -442,6 +442,9 @@
 =item C<static void get_sockaddr_in(PARROT_INTERP, PMC * sockaddr, const char*
 host, int port)>
 
+Get a new C<sockaddr_in> structure for the given PMC to connect to the
+specified host and port.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/io/socket_win32.c
==============================================================================
--- branches/pmc_pct/src/io/socket_win32.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/socket_win32.c	Fri May 15 21:49:40 2009	(r38803)
@@ -388,6 +388,8 @@
 =item C<static void get_sockaddr_in(PARROT_INTERP, PMC * sockaddr, const char*
 host, int port)>
 
+Get a C<sockaddr_in> structure to connect to the given host.
+
 =cut
 
 */
@@ -428,6 +430,8 @@
 
 =item C<PMC * Parrot_io_sockaddr_in(PARROT_INTERP, STRING *addr, INTVAL port)>
 
+Create a new Sockaddr PMC to connect to the given address and port.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/io/unix.c
==============================================================================
--- branches/pmc_pct/src/io/unix.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/unix.c	Fri May 15 21:49:40 2009	(r38803)
@@ -654,8 +654,8 @@
         else
             io = filehandle;
 
-        Parrot_io_set_flags(interp, filehandle,
-                (Parrot_io_get_flags(interp, filehandle) & PIO_F_PIPE));
+        Parrot_io_set_flags(interp, io,
+                (Parrot_io_get_flags(interp, io) & (~PIO_F_PIPE)));
 
         if (flags & PIO_F_READ) {
             /* close this writer's end of pipe */
@@ -672,13 +672,24 @@
 
     /* Child - exec process */
     if (pid == 0) {
+        /* See above comments */
+#    if 0
         char *argv[10], *p, *c, *cmd, *orig_cmd;
         int   n;
+#    else
+        char * argv[10], *orig_cmd;
+
+        /* C strings for the execv call defined that way to avoid
+         * const problems without copying them.
+         */
+        static char auxarg0 [] = "/bin/sh";
+        static char auxarg1 [] = "-c";
+#    endif
 
         if (flags & PIO_F_WRITE) {
             /* the other end is writing - we read from the pipe */
             close(STDIN_FILENO);
-            close(fds[1]);
+            /*close(fds[1]);*/
 
             if (Parrot_dup(fds[0]) != STDIN_FILENO)
                 exit(EXIT_SUCCESS);
@@ -695,6 +706,13 @@
                 exit(EXIT_SUCCESS);
         }
 
+        /*******************************************************
+         *     THIS IS A QUICK TEST IMPLEMENTATION
+         * Thus the if'ed out code is not deleted yet
+         * TT #661
+         *******************************************************
+         */
+#    if 0
         /* XXX ugly hack to be able to pass some arguments
          *     split cmd at blanks */
         orig_cmd = cmd = Parrot_str_to_cstring(interp, command);
@@ -710,6 +728,16 @@
 
         Parrot_str_free_cstring(c); /* done with C string */
         execv(cmd, argv);       /* XXX use execvp ? */
+#    else
+
+        orig_cmd = Parrot_str_to_cstring(interp, command);
+        argv [0] = auxarg0;
+        argv [1] = auxarg1;
+        argv [2] = orig_cmd;
+        argv [3] = NULL;
+        execv(argv [0], argv);
+
+#    endif
 
         /* Will never reach this unless exec fails. */
         Parrot_str_free_cstring(orig_cmd);

Modified: branches/pmc_pct/src/io/utf8.c
==============================================================================
--- branches/pmc_pct/src/io/utf8.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/io/utf8.c	Fri May 15 21:49:40 2009	(r38803)
@@ -119,7 +119,7 @@
         return Parrot_io_write_buffer(interp, filehandle, s);
 
     dest = Parrot_utf8_encoding_ptr->to_encoding(interp, s,
-            new_string_header(interp, 0));
+            Parrot_gc_new_string_header(interp, 0));
     return Parrot_io_write_buffer(interp, filehandle, dest);
 }
 

Modified: branches/pmc_pct/src/jit.c
==============================================================================
--- branches/pmc_pct/src/jit.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/jit.c	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -372,7 +372,7 @@
                     if (n < NUM_REGISTERS && !ru[typ].reg_count[n]++)
                         ru[typ].reg_dir[n] |= PARROT_ARGDIR_IN;
                 }
-                key = key_next(interp, key);
+                key = VTABLE_shift_pmc(interp, key);
             }
         }
     }

Modified: branches/pmc_pct/src/key.c
==============================================================================
--- branches/pmc_pct/src/key.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/key.c	Fri May 15 21:49:40 2009	(r38803)
@@ -331,8 +331,7 @@
     STRING  *str_key;
     FLOATVAL num_key;
 
-    if (VTABLE_isa(interp, key, CONST_STRING(interp, "Key"))) {
-        switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
+    switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
         case KEY_hash_iterator_FLAGS:
 
         case KEY_integer_FLAG:
@@ -378,7 +377,6 @@
         case KEY_inf_slice_FLAG:
         default:
             break;
-        }
     }
 
     return VTABLE_get_integer(interp, key);
@@ -550,9 +548,8 @@
         GETATTR_Key_next_key(interp, key, next_key);
         return next_key;
     }
-    else {
-        return NULL;
-    }
+
+    return NULL;
 }
 
 
@@ -615,7 +612,7 @@
 
     if (flags == KEY_string_FLAG) {
         GETATTR_Key_str_key(interp, key, str_key);
-        pobject_lives(interp, (PObj *)str_key);
+        Parrot_gc_mark_PObj_alive(interp, (PObj *)str_key);
     }
 
     /*
@@ -629,7 +626,7 @@
     /* if iteration hasn't started, above flag isn't set yet */
     GETATTR_Key_next_key(interp, key, next_key);
     if (next_key && (void *)next_key != (void *)INITBucketIndex)
-        pobject_lives(interp, (PObj *)next_key);
+        Parrot_gc_mark_PObj_alive(interp, (PObj *)next_key);
 
 }
 

Modified: branches/pmc_pct/src/list.c
==============================================================================
--- branches/pmc_pct/src/list.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/list.c	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2002-2008, Parrot Foundation.
+Copyright (C) 2002-2009, Parrot Foundation.
 License:  Artistic 2.0, see README and LICENSE for details
 $Id$
 
@@ -361,13 +361,13 @@
 
     Parrot_block_GC_mark(interp);
     /*Parrot_block_GC_sweep(interp); - why */
-    chunk = (List_chunk *)new_bufferlike_header(interp, sizeof (*chunk));
+    chunk = (List_chunk *)Parrot_gc_new_bufferlike_header(interp, sizeof (*chunk));
     chunk->items = items;
     chunk->n_chunks = 0;
     chunk->n_items  = 0;
     chunk->next     = NULL;
     chunk->prev     = NULL;
-    Parrot_allocate_aligned(interp, (Buffer *)chunk, size);
+    Parrot_gc_allocate_buffer_storage_aligned(interp, (Buffer *)chunk, size);
     memset(PObj_bufstart((Buffer*)chunk), 0, size);
 
     /* see also src/hash.c */
@@ -396,11 +396,11 @@
 {
     ASSERT_ARGS(rebuild_chunk_ptrs)
     List_chunk *chunk, *prev;
-    UINTVAL len = 0, start = list->start;
-    UINTVAL cap;
+    UINTVAL start = list->start;
+    UINTVAL len = 0;
+    UINTVAL cap = 0;
 
-    cap = 0;
-    for (prev = 0, chunk = list->first; chunk; chunk = chunk->next) {
+    for (prev = NULL, chunk = list->first; chunk; chunk = chunk->next) {
         /* skip empty chunks, first is empty, when all items get skipped due
          * to list->start */
         if (chunk->items == start) {
@@ -424,10 +424,10 @@
         cap += chunk->items;
     }
     if (list->last)
-        list->last->next = 0;
+        list->last->next = NULL;
     list->cap = cap;
     if (list->first)
-        list->first->prev = 0;
+        list->first->prev = NULL;
     list->n_chunks = len;
 }
 
@@ -489,7 +489,7 @@
              * but: if bigger, split them in a next pass
              * TODO test the logic that solves the above problem */
             if (prev->items + chunk->items > MAX_ITEMS) {
-                Parrot_reallocate(interp, (Buffer *)prev,
+                Parrot_gc_reallocate_buffer_storage(interp, (Buffer *)prev,
                         MAX_ITEMS * list->item_size);
                 if (list->container) {
                     GC_WRITE_BARRIER(interp, list->container, 0, prev);
@@ -497,11 +497,11 @@
                 mem_sys_memmove(
                         (char *) PObj_bufstart(&prev->data) +
                         prev->items * list->item_size,
-                        (char *) PObj_bufstart(&chunk->data),
+                        (const char *) PObj_bufstart(&chunk->data),
                         (MAX_ITEMS - prev->items) * list->item_size);
                 mem_sys_memmove(
                         (char *) PObj_bufstart(&chunk->data),
-                        (char *) PObj_bufstart(&chunk->data) +
+                        (const char *) PObj_bufstart(&chunk->data) +
                         (MAX_ITEMS - prev->items) * list->item_size,
                         (chunk->items - (MAX_ITEMS - prev->items))
                                                         * list->item_size);
@@ -509,7 +509,7 @@
                 prev->items = MAX_ITEMS;
             }
             else {
-                Parrot_reallocate(interp, (Buffer *)prev,
+                Parrot_gc_reallocate_buffer_storage(interp, (Buffer *)prev,
                         (prev->items + chunk->items) * list->item_size);
                 if (list->container) {
                     GC_WRITE_BARRIER(interp, list->container, 0, prev);
@@ -517,7 +517,7 @@
                 mem_sys_memmove(
                         (char *) PObj_bufstart(&prev->data) +
                         prev->items * list->item_size,
-                        (char *) PObj_bufstart(&chunk->data),
+                        (const char *) PObj_bufstart(&chunk->data),
                         chunk->items * list->item_size);
                 prev->items += chunk->items;
                 chunk->items = 0;
@@ -594,18 +594,18 @@
 
     /* allocate a new chunk_list buffer, if old one has moved or is too small */
     len = list->n_chunks;
-    if (list->collect_runs != interp->arena_base->gc_collect_runs ||
+    if (list->collect_runs != Parrot_gc_count_collect_runs(interp) ||
             len > chunk_list_size(list)) {
         /* round up to reasonable size */
         len = 1 << (ld(len) + 1);
         if (len < 4)
             len = 4;
-        Parrot_reallocate(interp, (Buffer *)list,
+        Parrot_gc_reallocate_buffer_storage(interp, (Buffer *)list,
                 len * sizeof (List_chunk *));
         if (list->container) {
             GC_WRITE_BARRIER(interp, list->container, 0, list);
         }
-        list->collect_runs = interp->arena_base->gc_collect_runs;
+        list->collect_runs = Parrot_gc_count_collect_runs(interp);
     }
 
     /* reset type, actual state of chunks will show, what we really have */
@@ -937,7 +937,7 @@
     UINTVAL i;
 
 #ifndef GC_IS_MALLOC
-    if (list->collect_runs != interp->arena_base->gc_collect_runs)
+    if (list->collect_runs != Parrot_gc_count_collect_runs(interp))
         rebuild_chunk_list(interp, list);
 #endif
 #ifdef SLOW_AND_BORING
@@ -1057,7 +1057,7 @@
     /* allocate space at idx */
     if (chunk->items <= MAX_ITEMS) {
         /* it fits, just allocate */
-        Parrot_reallocate(interp, (Buffer *)chunk,
+        Parrot_gc_reallocate_buffer_storage(interp, (Buffer *)chunk,
                 chunk->items * list->item_size);
         if (list->container) {
             GC_WRITE_BARRIER(interp, list->container, 0, chunk);
@@ -1074,7 +1074,7 @@
         const INTVAL n1 = chunk->items - n2 - n3;
 
         chunk->items = n2;
-        Parrot_reallocate(interp, (Buffer *)chunk,
+        Parrot_gc_reallocate_buffer_storage(interp, (Buffer *)chunk,
                 chunk->items * list->item_size);
         if (list->container) {
             GC_WRITE_BARRIER(interp, list->container, 0, chunk);
@@ -1274,7 +1274,7 @@
 list_new(PARROT_INTERP, PARROT_DATA_TYPE type)
 {
     ASSERT_ARGS(list_new)
-    List * const list = (List *)new_bufferlike_header(interp, sizeof (*list));
+    List * const list = (List *)Parrot_gc_new_bufferlike_header(interp, sizeof (*list));
 
     list->item_type = type;
     switch (type) {
@@ -1476,9 +1476,9 @@
     l = list_new(interp, other->item_type);
     STRUCT_COPY(l, other);
     PObj_buflen(&l->chunk_list) = 0;
-    PObj_bufstart(&l->chunk_list) = 0;
+    PObj_bufstart(&l->chunk_list) = NULL;
 
-    for (chunk = other->first, prev = 0; chunk; chunk = chunk->next) {
+    for (chunk = other->first, prev = NULL; chunk; chunk = chunk->next) {
         List_chunk * const new_chunk = allocate_chunk(interp, l,
                 chunk->items, PObj_buflen(&chunk->data));
         new_chunk->flags = chunk->flags;
@@ -1540,7 +1540,7 @@
     List_chunk *chunk;
 
     for (chunk = list->first; chunk; chunk = chunk->next) {
-        pobject_lives(interp, (PObj *)chunk);
+        Parrot_gc_mark_PObj_alive(interp, (PObj *)chunk);
         if (list->item_type == enum_type_PMC ||
                 list->item_type == enum_type_STRING) {
             if (!(chunk->flags & sparse)) {
@@ -1549,14 +1549,14 @@
 
                 for (i = 0; i < chunk->items; i++, ++p) {
                     if (*p)
-                        pobject_lives(interp, *p);
+                        Parrot_gc_mark_PObj_alive(interp, *p);
                 }
             }
 
         }
     }
 
-    pobject_lives(interp, (PObj *)list);
+    Parrot_gc_mark_PObj_alive(interp, (PObj *)list);
 }
 
 /*
@@ -1649,7 +1649,7 @@
                 }
             }
 
-            list_append(interp, list, 0, list->item_type, idx);
+            list_append(interp, list, NULL, list->item_type, idx);
         }
         else {
             rebuild_chunk_ptrs(list, 1);
@@ -1892,7 +1892,7 @@
     if (idx < list->cap - chunk->items) {
         list->cap -= chunk->items;
         chunk = list->last = chunk->prev;
-        chunk->next = 0;
+        chunk->next = NULL;
         if (list->n_chunks <= 2)
             list->first = list->last;
         rebuild_chunk_list(interp, list);

Modified: branches/pmc_pct/src/malloc-trace.c
==============================================================================
--- branches/pmc_pct/src/malloc-trace.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/malloc-trace.c	Fri May 15 21:49:40 2009	(r38803)
@@ -52,8 +52,9 @@
 
 /*
 
-=item C<static void
-open_log_file()>
+=item C<static void open_log_file()>
+
+Open a logfile for storing debugging information.
 
 =cut
 
@@ -98,8 +99,9 @@
 
 /*
 
-=item C<static void
-malloc_trace_destructor(void)>
+=item C<static void malloc_trace_destructor(void)>
+
+Print out a final timestamp and message to the log file.
 
 =cut
 
@@ -131,8 +133,9 @@
 
 /*
 
-=item C<static void
-malloc_segv_handler(int i, struct sigcontext_struct sc)>
+=item C<static void malloc_segv_handler(int i, struct sigcontext_struct sc)>
+
+Catch a segfault signal, print an error message, and end the logfile.
 
 =cut
 
@@ -151,8 +154,9 @@
 
 /*
 
-=item C<static void
-malloc_record(int code, size_t size, void *ptr, void *ptr2)>
+=item C<static void malloc_record(int code, size_t size, void *ptr, void *ptr2)>
+
+Record information about the allocation into the logfile.
 
 =cut
 
@@ -197,6 +201,9 @@
 
 =item C<void* malloc(size_t bytes)>
 
+Allocate memory with the specified size in bytes. Record information about it
+in the logfile.
+
 =cut
 
 */
@@ -221,6 +228,8 @@
 
 =item C<void free(void* mem)>
 
+Record information about the free in the logfile, and free the memory.
+
 =cut
 
 */
@@ -238,6 +247,8 @@
 
 =item C<void* realloc(void* mem, size_t bytes)>
 
+Resize the allocated memory buffer to the new size.
+
 =cut
 
 */
@@ -258,6 +269,9 @@
 
 =item C<void* memalign(size_t alignment, size_t bytes)>
 
+Return an allocated memory buffer that's of at least the given size in bytes
+and is aligned along the given boundary.
+
 =cut
 
 */
@@ -282,6 +296,8 @@
 
 =item C<void* calloc(size_t n, size_t elem_size)>
 
+Allocate memory of the given size, initializing the memory to the given value.
+
 =cut
 
 */
@@ -306,6 +322,8 @@
 
 =item C<void cfree(void *mem)>
 
+free the given buffer, recording information about it in the log.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/multidispatch.c
==============================================================================
--- branches/pmc_pct/src/multidispatch.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/multidispatch.c	Fri May 15 21:49:40 2009	(r38803)
@@ -535,6 +535,9 @@
 
 =item C<static INTVAL distance_cmp(PARROT_INTERP, INTVAL a, INTVAL b)>
 
+Compare distance values C<a> and C<b>. Return 1 if C<a> is larger, -1 if
+C<b> is.
+
 =cut
 
 */
@@ -794,6 +797,10 @@
 =item C<static PMC * Parrot_mmd_get_cached_multi_sig(PARROT_INTERP, PMC
 *sub_pmc)>
 
+Get the cached multisig of the given sub, if one exists. The cached signature
+might be in different formats, so put it into a type tuple like the rest of the
+MMD system expects.
+
 =cut
 
 */
@@ -850,6 +857,13 @@
     /* has to be a builtin multi method */
     if (pmc->vtable->base_type == enum_class_NCI) {
         GETATTR_NCI_multi_sig(interp, pmc, multi_sig);
+        if (PMC_IS_NULL(multi_sig)) {
+            STRING *long_sig;
+
+            GETATTR_NCI_long_signature(interp, pmc, long_sig);
+            multi_sig = mmd_build_type_tuple_from_long_sig(interp, long_sig);
+            SETATTR_NCI_multi_sig(interp, pmc, multi_sig);
+        }
     }
     else {
         /* not a multi; no distance */
@@ -1337,13 +1351,10 @@
         STRING   *sub_name  = mmd_info[i].multi_name;
         STRING   *long_sig  = mmd_info[i].full_sig;
         STRING   *short_sig = mmd_info[i].short_sig;
-        PMC      *type_list = Parrot_str_split(interp, CONST_STRING(interp, ","), long_sig);
-        STRING   *ns_name   = VTABLE_get_string_keyed_int(interp, type_list, 0);
+        STRING   *ns_name   = mmd_info[i].ns_name;
 
-    /* Create an NCI sub for the C function */
+        /* Create an NCI sub for the C function */
         PMC    *sub_obj       = constant_pmc_new(interp, enum_class_NCI);
-        PMC    *multi_sig     = mmd_build_type_tuple_from_long_sig(interp,
-                                long_sig);
 
 #ifdef PARROT_HAS_ALIGNED_FUNCPTR
         PARROT_ASSERT((PTR2UINTVAL(func_ptr) & 3) == 0);
@@ -1353,7 +1364,7 @@
                                      F2DPTR(func_ptr));
 
         /* Attach a type tuple array to the NCI sub for multi dispatch */
-        SETATTR_NCI_multi_sig(interp, sub_obj, multi_sig);
+        SETATTR_NCI_long_signature(interp, sub_obj, long_sig);
 
         mmd_add_multi_to_namespace(interp, ns_name, sub_name, sub_obj);
         mmd_add_multi_global(interp, sub_name, sub_obj);

Modified: branches/pmc_pct/src/oo.c
==============================================================================
--- branches/pmc_pct/src/oo.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/oo.c	Fri May 15 21:49:40 2009	(r38803)
@@ -366,13 +366,14 @@
 {
     ASSERT_ARGS(Parrot_oo_find_vtable_override)
     Parrot_Class_attributes * const _class = PARROT_CLASS(classobj);
+    PMC                            *result =
+        VTABLE_get_pmc_keyed_str(interp, _class->parent_overrides, name);
 
-    if (VTABLE_exists_keyed_str(interp, _class->parent_overrides, name))
-        return VTABLE_get_pmc_keyed_str(interp, _class->parent_overrides, name);
+    if (!PMC_IS_NULL(result))
+        return result;
     else {
         /* Walk and search for the vtable method. */
         const INTVAL num_classes = VTABLE_elements(interp, _class->all_parents);
-        PMC         *result      = PMCNULL;
         INTVAL       i;
 
         for (i = 0; i < num_classes; i++) {
@@ -623,7 +624,7 @@
         for (entry = 0; entry < TBL_SIZE; ++entry) {
             Meth_cache_entry *e = mc->idx[type][entry];
             while (e) {
-                pobject_lives(interp, (PObj *)e->pmc);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)e->pmc);
                 e = e->next;
             }
         }
@@ -654,6 +655,9 @@
 
 =item C<void destroy_object_cache(PARROT_INTERP)>
 
+Destroy the object cache. Loop over all caches and invalidate them. Then
+free the caches back to the OS.
+
 =cut
 
 */
@@ -680,6 +684,9 @@
 
 =item C<static void invalidate_type_caches(PARROT_INTERP, UINTVAL type)>
 
+Invalidate the cache of the specified type. Free each entry and then free
+the entire cache.
+
 =cut
 
 */
@@ -716,6 +723,9 @@
 
 =item C<static void invalidate_all_caches(PARROT_INTERP)>
 
+Invalidate all caches by looping over each cache and calling
+C<invalidate_type_caches> on them.
+
 =cut
 
 */
@@ -900,6 +910,8 @@
 =item C<static void debug_trace_find_meth(PARROT_INTERP, const PMC *_class,
 const STRING *name, const PMC *sub)>
 
+Print some information about the search for a sub.
+
 =cut
 
 */
@@ -954,6 +966,8 @@
 =item C<static PMC * find_method_direct_1(PARROT_INTERP, PMC *_class, STRING
 *method_name)>
 
+Find the method with the given name in the specified class.
+
 =cut
 
 */
@@ -992,6 +1006,8 @@
 
 =item C<static PMC* C3_merge(PARROT_INTERP, PMC *merge_list)>
 
+Merge together the MRO of the items in the list.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/ops/core.ops
==============================================================================
--- branches/pmc_pct/src/ops/core.ops	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/ops/core.ops	Fri May 15 21:49:40 2009	(r38803)
@@ -1245,10 +1245,10 @@
 
 op sweep(inconst INT) {
     if ($1)
-        Parrot_do_gc_run(interp, 0);
+        Parrot_gc_mark_and_sweep(interp, 0);
     else
-        if (interp->arena_base->num_early_gc_PMCs)
-            Parrot_do_gc_run(interp, GC_lazy_FLAG);
+        if (Parrot_gc_impatient_pmcs(interp))
+            Parrot_gc_mark_and_sweep(interp, GC_lazy_FLAG);
 }
 
 =item B<collect>()
@@ -1258,7 +1258,7 @@
 =cut
 
 op collect() {
-    Parrot_go_collect(interp);
+    Parrot_gc_compact_memory_pool(interp);
 }
 
 =item B<sweepoff>()
@@ -1309,8 +1309,7 @@
 =cut
 
 op needs_destroy(invar PMC) {
-     PObj_needs_early_gc_SET($1);
-     ++interp->arena_base->num_early_gc_PMCs;
+     Parrot_gc_pmc_needs_early_collection(interp, $1);
 }
 
 =back

Modified: branches/pmc_pct/src/ops/io.ops
==============================================================================
--- branches/pmc_pct/src/ops/io.ops	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/ops/io.ops	Fri May 15 21:49:40 2009	(r38803)
@@ -383,14 +383,18 @@
   STRING ** const s = &$1;
 
   *s = NULL;
-  Parrot_io_peek(interp, _PIO_STDIN(interp), s);
+  if (Parrot_io_peek(interp, _PIO_STDIN(interp), s) < 0) {
+    $1 = Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
+  }
 }
 
 op peek(out STR, invar PMC) :base_io {
   STRING ** const s = &$1;
 
   *s = NULL;
-  Parrot_io_peek(interp, $2, s);
+  if (Parrot_io_peek(interp, $2, s) < 0) {
+    $1 = Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
+  }
 }
 
 ##########################################

Modified: branches/pmc_pct/src/ops/string.ops
==============================================================================
--- branches/pmc_pct/src/ops/string.ops	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/ops/string.ops	Fri May 15 21:49:40 2009	(r38803)
@@ -551,7 +551,7 @@
 }
 
 op trans_charset(out STR, in STR, in INT) {
-    STRING *dest = new_string_header(interp, 0);
+    STRING *dest = Parrot_gc_new_string_header(interp, 0);
     $1 = Parrot_str_change_charset(interp, $2, $3, dest);
 }
 
@@ -607,7 +607,7 @@
 }
 
 op trans_encoding(out STR, in STR, in INT) {
-    STRING * const dest = new_string_header(interp, 0);
+    STRING * const dest = Parrot_gc_new_string_header(interp, 0);
     $1 = Parrot_str_change_encoding(interp, $2, $3, dest);
 }
 

Modified: branches/pmc_pct/src/packfile.c
==============================================================================
--- branches/pmc_pct/src/packfile.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/packfile.c	Fri May 15 21:49:40 2009	(r38803)
@@ -144,6 +144,7 @@
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*cursor);
 
+PARROT_WARN_UNUSED_RESULT
 static size_t directory_packed_size(PARROT_INTERP,
     ARGMOD(PackFile_Segment *self))
         __attribute__nonnull__(1)
@@ -485,6 +486,8 @@
 
 =item C<void Parrot_trace_eprintf(const char *s, ...)>
 
+Print out an error message. Passes arguments directly to C<vfprintf>.
+
 =cut
 
 */
@@ -615,7 +618,7 @@
     DECL_CONST_CAST;
     Parrot_sub *sub;
     int         todo    = 0;
-    int         pragmas = PObj_get_FLAGS(sub_pmc) &  SUB_FLAG_PF_MASK
+    const int   pragmas = PObj_get_FLAGS(sub_pmc) &  SUB_FLAG_PF_MASK
                                                   & ~SUB_FLAG_IS_OUTER;
     PMC_get_sub(interp, PARROT_const_cast(PMC *, sub_pmc), sub);
     if (!pragmas && !Sub_comp_INIT_TEST(sub))
@@ -802,7 +805,7 @@
         if (constants[i]->type == PFC_PMC) {
             PMC * const pmc = constants[i]->u.key;
             if (pmc)
-                pobject_lives(interp, (PObj *)pmc);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)pmc);
         }
     }
 }
@@ -1035,7 +1038,7 @@
             header->uuid_size);
 
         /* NULL terminate */
-        header->uuid_data[header->uuid_size] = 0;
+        header->uuid_data[header->uuid_size] = '\0';
     }
     else
         /* Don't know this UUID type. */
@@ -1134,7 +1137,7 @@
 
 /*
 
-=item C<INTVAL PackFile_add_segment(PARROT_INTERP, PackFile_Directory *dir,
+=item C<void PackFile_add_segment(PARROT_INTERP, PackFile_Directory *dir,
 PackFile_Segment *seg)>
 
 Adds the Segment C<seg> to the directory C<dir>.  The PackFile becomes the
@@ -1145,7 +1148,7 @@
 */
 
 PARROT_EXPORT
-INTVAL
+void
 PackFile_add_segment(SHIM_INTERP, ARGMOD(PackFile_Directory *dir),
         ARGIN(PackFile_Segment *seg))
 {
@@ -1155,7 +1158,7 @@
     dir->num_segments++;
     seg->dir = dir;
 
-    return 0;
+    return;
 }
 
 
@@ -1404,8 +1407,8 @@
 
 /*
 
-=item C<INTVAL PackFile_funcs_register(PARROT_INTERP, PackFile *pf, UINTVAL
-type, const PackFile_funcs funcs)>
+=item C<void PackFile_funcs_register(PARROT_INTERP, PackFile *pf, UINTVAL type,
+const PackFile_funcs funcs)>
 
 Registers the C<pack>/C<unpack>/... functions for a packfile type.
 
@@ -1414,14 +1417,13 @@
 */
 
 PARROT_EXPORT
-INTVAL
+void
 PackFile_funcs_register(SHIM_INTERP, ARGOUT(PackFile *pf), UINTVAL type,
                         const PackFile_funcs funcs)
 {
     ASSERT_ARGS(PackFile_funcs_register)
     /* TODO dynamic registering */
     pf->PackFuncs[type] = funcs;
-    return 1;
 }
 
 
@@ -2063,8 +2065,8 @@
 #endif
             else {
                 fprintf(stderr, "directory_unpack failed: invalid wordsize %d\n",
-                        pf->header->wordsize);
-                return 0;
+                        (int)pf->header->wordsize);
+                return NULL;
             }
             TRACE_PRINTF_VAL(("Segment offset: new pos 0x%x "
                               "(src=0x%x cursor=0x%x).\n",
@@ -2120,7 +2122,7 @@
         if (!pos) {
             fprintf(stderr, "PackFile_unpack segment '%s' failed\n",
                     dir->segments[i]->name);
-            return 0;
+            return NULL;
         }
         else {
             TRACE_PRINTF_VAL(("PackFile_Segment_unpack ok. pos=0x%x\n", pos));
@@ -2241,6 +2243,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 static size_t
 directory_packed_size(PARROT_INTERP, ARGMOD(PackFile_Segment *self))
 {
@@ -2630,19 +2633,8 @@
 {
     ASSERT_ARGS(pf_debug_packed_size)
     PackFile_Debug * const debug = (PackFile_Debug *)self;
-    int                    size = 0;
-    int i;
 
-    /* Size of mappings count. */
-    size += 1;
-
-    /* Size of entries in mappings list. */
-    for (i = 0; i < debug->num_mappings; i++) {
-        /* Bytecode offset and filename */
-        size += 2;
-    }
-
-    return size;
+    return (debug->num_mappings*2) + 1;
 }
 
 
@@ -2728,7 +2720,7 @@
     /* find seg e.g. CODE_DB => CODE and attach it */
     code_name              = str_dup(debug->base.name);
     str_len                = strlen(code_name);
-    code_name[str_len - 3] = 0;
+    code_name[str_len - 3] = '\0';
     code                   = (PackFile_ByteCode *)PackFile_find_segment(interp,
                                 self->dir, code_name, 0);
 
@@ -2769,13 +2761,11 @@
 
     Parrot_io_printf(interp, "\n  mappings => [\n");
     for (i = 0; i < debug->num_mappings; i++) {
-        char * const filename = Parrot_str_to_cstring(interp,
-            PF_CONST(debug->code, debug->mappings[i]->filename)->u.string);;
         Parrot_io_printf(interp, "    #%d\n    [\n", i);
         Parrot_io_printf(interp, "        OFFSET => %d,\n",
                    debug->mappings[i]->offset);
-        Parrot_io_printf(interp, "        FILENAME => %s\n", filename);
-        Parrot_str_free_cstring(filename);
+        Parrot_io_printf(interp, "        FILENAME => %Ss\n",
+                PF_CONST(debug->code, debug->mappings[i]->filename)->u.string);
         Parrot_io_printf(interp, "    ],\n");
     }
 
@@ -4107,14 +4097,14 @@
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
 PackFile_Segment *
-PackFile_Annotations_new(PARROT_INTERP, ARGIN(struct PackFile *pf),
+PackFile_Annotations_new(SHIM_INTERP, SHIM(struct PackFile *pf),
         SHIM(const char *name), SHIM(int add))
 {
     ASSERT_ARGS(PackFile_Annotations_new)
 
     /* Allocate annotations structure; create it all zeroed, and we will
      * allocate memory for each of the arrays on demand. */
-    PackFile_Annotations *seg = mem_allocate_zeroed_typed(PackFile_Annotations);
+    PackFile_Annotations * const seg = mem_allocate_zeroed_typed(PackFile_Annotations);
     return (PackFile_Segment *) seg;
 }
 
@@ -4172,11 +4162,12 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 size_t
-PackFile_Annotations_packed_size(PARROT_INTERP, ARGIN(PackFile_Segment *seg))
+PackFile_Annotations_packed_size(SHIM_INTERP, ARGIN(PackFile_Segment *seg))
 {
     ASSERT_ARGS(PackFile_Annotations_packed_size)
-    PackFile_Annotations *self = (PackFile_Annotations *)seg;
+    const PackFile_Annotations * const self = (PackFile_Annotations *)seg;
     return 3                      /* Counts. */
          + self->num_keys    * 2  /* Keys. */
          + self->num_groups  * 2  /* Groups. */
@@ -4195,6 +4186,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 opcode_t *
 PackFile_Annotations_pack(PARROT_INTERP, ARGIN(PackFile_Segment *seg),
@@ -4301,7 +4293,7 @@
     /* Need to associate this segment with the applicable code segment. */
     code_name              = str_dup(self->base.name);
     str_len                = strlen(code_name);
-    code_name[str_len - 4] = 0;
+    code_name[str_len - 4] = '\0';
     code                   = (PackFile_ByteCode *)PackFile_find_segment(interp,
                                 self->base.dir, code_name, 0);
 
@@ -4343,17 +4335,15 @@
     /* Dump keys. */
     Parrot_io_printf(interp, "\n  keys => [\n");
     for (i = 0; i < self->num_keys; i++) {
-        char * const key_name = Parrot_str_to_cstring(interp,
-                PF_CONST(self->code, self->keys[i]->name)->u.string);
         Parrot_io_printf(interp, "    #%d\n    [\n", i);
-        Parrot_io_printf(interp, "        NAME => %s\n", key_name);
+        Parrot_io_printf(interp, "        NAME => %Ss\n",
+                PF_CONST(self->code, self->keys[i]->name)->u.string);
         Parrot_io_printf(interp, "        TYPE => %s\n",
                 self->keys[i]->type == PF_ANNOTATION_KEY_TYPE_INT ? "integer" :
                 self->keys[i]->type == PF_ANNOTATION_KEY_TYPE_STR ? "string" :
                 self->keys[i]->type == PF_ANNOTATION_KEY_TYPE_NUM ? "number" :
                 "PMC");
         Parrot_io_printf(interp, "    ],\n");
-        Parrot_str_free_cstring(key_name);
     }
 
     Parrot_io_printf(interp, "  ],\n");
@@ -4403,7 +4393,7 @@
 */
 PARROT_EXPORT
 void
-PackFile_Annotations_add_group(PARROT_INTERP, ARGMOD(PackFile_Annotations *self),
+PackFile_Annotations_add_group(SHIM_INTERP, ARGMOD(PackFile_Annotations *self),
         opcode_t offset)
 {
     ASSERT_ARGS(PackFile_Annotations_add_group)
@@ -4791,13 +4781,13 @@
     ASSERT_ARGS(PackFile_append_pbc)
     PackFile * const pf = Parrot_pbc_read(interp, filename, 0);
 
-    if (!pf)
-        return NULL;
+    if (pf) {
+        PackFile_add_segment(interp, &interp->initial_pf->directory,
+                &pf->directory.base);
 
-    PackFile_add_segment(interp, &interp->initial_pf->directory,
-            &pf->directory.base);
+        do_sub_pragmas(interp, pf->cur_cs, PBC_LOADED, NULL);
+    }
 
-    do_sub_pragmas(interp, pf->cur_cs, PBC_LOADED, NULL);
     return pf;
 }
 

Modified: branches/pmc_pct/src/parrot_debugger.c
==============================================================================
--- branches/pmc_pct/src/parrot_debugger.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/parrot_debugger.c	Fri May 15 21:49:40 2009	(r38803)
@@ -242,6 +242,8 @@
 
 =item C<static void PDB_run_code(PARROT_INTERP, int argc, char *argv[])>
 
+Run the code, catching exceptions if they are left unhandled.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/pmc.c
==============================================================================
--- branches/pmc_pct/src/pmc.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc.c	Fri May 15 21:49:40 2009	(r38803)
@@ -41,15 +41,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pmc);
 
-static void pmc_free_to_pool(PARROT_INTERP,
-    ARGMOD(PMC *pmc),
-    ARGMOD(Small_Object_Pool *pool))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*pmc)
-        FUNC_MODIFIES(*pool);
-
 #define ASSERT_ARGS_create_class_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_get_new_pmc_header __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -57,10 +48,6 @@
 #define ASSERT_ARGS_pmc_free __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
-#define ASSERT_ARGS_pmc_free_to_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pmc) \
-    || PARROT_ASSERT_ARG(pool)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
@@ -196,7 +183,7 @@
     if (new_vtable->flags & VTABLE_PMC_NEEDS_EXT) {
         /* If we need an ext area, go allocate one */
         if (!has_ext)
-            add_pmc_ext(interp, pmc);
+            Parrot_gc_add_pmc_ext(interp, pmc);
 
         new_flags = PObj_is_PMC_EXT_FLAG;
     }
@@ -226,7 +213,9 @@
 =item C<static PMC * get_new_pmc_header(PARROT_INTERP, INTVAL base_type, UINTVAL
 flags)>
 
-Gets a new PMC header.
+Gets a new PMC header of the given integer type. Initialize the pmc if
+necessary. In the case of singleton PMC types, get the existing singleton
+instead of allocating a new one.
 
 =cut
 
@@ -265,7 +254,7 @@
 
         /* LOCK */
         if (!pmc) {
-            pmc            = new_pmc_header(interp, PObj_constant_FLAG);
+            pmc = Parrot_gc_new_pmc_header(interp, PObj_constant_FLAG);
             PARROT_ASSERT(pmc);
 
             pmc->vtable    = vtable;
@@ -303,7 +292,7 @@
             flags |= PObj_is_PMC_shared_FLAG;
     }
 
-    pmc            = new_pmc_header(interp, flags);
+    pmc            = Parrot_gc_new_pmc_header(interp, flags);
     pmc->vtable    = vtable;
 
 #if GC_VERBOSE
@@ -474,31 +463,6 @@
 
 /*
 
-=item C<static void pmc_free_to_pool(PARROT_INTERP, PMC *pmc, Small_Object_Pool
-*pool)>
-
-=cut
-
-*/
-
-static void
-pmc_free_to_pool(PARROT_INTERP, ARGMOD(PMC *pmc),
-    ARGMOD(Small_Object_Pool *pool))
-{
-    ASSERT_ARGS(pmc_free_to_pool)
-    if (PObj_active_destroy_TEST(pmc))
-        VTABLE_destroy(interp, pmc);
-
-    if (PObj_is_PMC_EXT_TEST(pmc))
-        Parrot_gc_free_pmc_ext(interp, pmc);
-
-    PObj_flags_SETTO((PObj *)pmc, PObj_on_free_list_FLAG);
-    pool->add_free_object(interp, pool, (PObj *)pmc);
-    pool->num_free_objects++;
-}
-
-/*
-
 =item C<void temporary_pmc_free(PARROT_INTERP, PMC *pmc)>
 
 Frees a new temporary PMC created by C<temporary_pmc_new()>.  Do not call this
@@ -514,14 +478,18 @@
 temporary_pmc_free(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(temporary_pmc_free)
-    Small_Object_Pool *pool = interp->arena_base->constant_pmc_pool;
-    pmc_free_to_pool(interp, pmc, pool);
+    Parrot_gc_free_pmc_header(interp, pmc);
 }
 
 /*
 
 =item C<static void pmc_free(PARROT_INTERP, PMC *pmc)>
 
+Free the given PMC. This function does not call the custom destroy VTABLE if
+one is specified for PMCs of that type (should it?).
+
+TT #663: As of r38727, this function is not called from anywhere
+
 =cut
 
 */
@@ -530,8 +498,7 @@
 pmc_free(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(pmc_free)
-    Small_Object_Pool *pool = interp->arena_base->pmc_pool;
-    pmc_free_to_pool(interp, pmc, pool);
+    Parrot_gc_free_pmc_header(interp, pmc);
 
 }
 
@@ -539,6 +506,9 @@
 
 =item C<INTVAL get_new_vtable_index(PARROT_INTERP)>
 
+Get a new unique identifier number and allocate a new vtable structure for a
+new PMC type.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/pmc/addrregistry.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/addrregistry.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/addrregistry.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -25,8 +25,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /* included manually to prevent breaking C++ builds -- see RT #56534 */
 #include "parrot/hash.h"
 #include "pmc_hash.h"

Modified: branches/pmc_pct/src/pmc/array.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/array.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/array.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -18,8 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /*
 
 =item C<static PMC *undef(PARROT_INTERP)>
@@ -119,15 +117,7 @@
 */
 
     void class_init() {
-        /* class_init_code; called for side effects */
-        Small_Object_Pool *List_chunks =
-            get_bufferlike_pool(INTERP, sizeof (List_chunk));
-        Small_Object_Pool *Lists       =
-            get_bufferlike_pool(INTERP, sizeof (List));
-
-        /* XXX until there's a function to allocate a pool in an arena */
-        UNUSED(List_chunks);
-        UNUSED(Lists);
+
     }
 
 /*
@@ -338,7 +328,7 @@
         if (!key)
             return 0;
 
-        ix      = key_integer(INTERP, key);
+        ix      = VTABLE_get_integer(INTERP, key);
         nextkey = key_next(INTERP, key);
 
         if (!nextkey)
@@ -386,7 +376,7 @@
         if (!key)
             return (FLOATVAL)0;
 
-        ix      = key_integer(INTERP, key);
+        ix      = VTABLE_get_integer(INTERP, key);
         nextkey = key_next(INTERP, key);
 
         if (!nextkey)
@@ -433,7 +423,7 @@
         if (!key)
             return 0;
 
-        ix      = key_integer(INTERP, key);
+        ix      = VTABLE_get_integer(INTERP, key);
         nextkey = key_next(INTERP, key);
 
         if (!nextkey)
@@ -480,7 +470,7 @@
         if (!key)
             return 0;
 
-        ix      = key_integer(INTERP, key);
+        ix      = VTABLE_get_integer(INTERP, key);
         nextkey = key_next(INTERP, key);
 
         if (!nextkey)
@@ -556,7 +546,7 @@
         if (!key)
             return;
 
-        ix      = key_integer(INTERP, key);
+        ix      = VTABLE_get_integer(INTERP, key);
         nextkey = key_next(INTERP, key);
 
         if (!nextkey) {
@@ -607,7 +597,7 @@
         if (!key)
             return;
 
-        ix      = key_integer(INTERP, key);
+        ix      = VTABLE_get_integer(INTERP, key);
         nextkey = key_next(INTERP, key);
 
         if (!nextkey) {
@@ -658,7 +648,7 @@
         if (!key)
             return;
 
-        ix      = key_integer(INTERP, key);
+        ix      = VTABLE_get_integer(INTERP, key);
         nextkey = key_next(INTERP, key);
 
         if (!nextkey) {
@@ -709,7 +699,7 @@
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
         PMC *box;
 
-        const INTVAL ix      = key_integer(INTERP, key);
+        const INTVAL ix      = VTABLE_get_integer(INTERP, key);
         PMC * const  nextkey = key_next(INTERP, key);
 
         if (!nextkey) {
@@ -1040,7 +1030,7 @@
     VTABLE INTVAL defined_keyed(PMC *key) {
         PMC *box;
 
-        const INTVAL ix      = key_integer(INTERP, key);
+        const INTVAL ix      = VTABLE_get_integer(INTERP, key);
         PMC * const  nextkey = key_next(INTERP, key);
 
         if (!nextkey)
@@ -1087,7 +1077,7 @@
     VTABLE INTVAL exists_keyed(PMC *key) {
         PMC *box;
 
-        const INTVAL ix      = key_integer(INTERP, key);
+        const INTVAL ix      = VTABLE_get_integer(INTERP, key);
         PMC * const  nextkey = key_next(INTERP, key);
 
         if (!nextkey)
@@ -1126,7 +1116,7 @@
 */
 
     VTABLE void delete_keyed(PMC *key) {
-        const INTVAL ix = key_integer(INTERP, key);
+        const INTVAL ix = VTABLE_get_integer(INTERP, key);
         list_splice(INTERP, (List *)PMC_data(pmc), NULL, ix, 1);
     }
 

Modified: branches/pmc_pct/src/pmc/bigint.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/bigint.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/bigint.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -22,8 +22,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /* TODO split that out into a separate file */
 
 #ifdef S_SPLINT_S

Modified: branches/pmc_pct/src/pmc/bignum.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/bignum.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/bignum.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -131,8 +131,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #ifdef S_SPLINT_S
 #  undef PARROT_HAS_GMP /* splint barfs on the gmp.h header */
 #endif /* S_SPLINT_S */

Modified: branches/pmc_pct/src/pmc/boolean.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/boolean.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/boolean.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -21,8 +21,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass Boolean extends Integer provides boolean provides scalar {
 
 /*

Modified: branches/pmc_pct/src/pmc/callsignature.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/callsignature.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/callsignature.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #define CAPTURE_DATA_SIZE   2
 #define CAPTURE_array_CREATE(i, obj) \
     if (!PARROT_CAPTURE(obj)->array) \
@@ -191,15 +189,15 @@
         if (attrs) {
 
             if (attrs->array)
-                pobject_lives(interp, (PObj*)attrs->array);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)attrs->array);
             if (attrs->hash)
-                pobject_lives(interp, (PObj*)attrs->hash);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)attrs->hash);
             if (attrs->returns)
-                pobject_lives(interp, (PObj*)attrs->returns);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)attrs->returns);
             if (attrs->type_tuple)
-                pobject_lives(interp, (PObj*)attrs->type_tuple);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)attrs->type_tuple);
             if (attrs->short_sig)
-                pobject_lives(interp, (PObj*)attrs->short_sig);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)attrs->short_sig);
         }
 
         if (!data)
@@ -207,7 +205,7 @@
 
         for (i = attrs->data_size - 1; i >= 0; --i)
             if (data[i])
-                pobject_lives(interp, (PObj *)data[i]);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)data[i]);
     }
 
 

Modified: branches/pmc_pct/src/pmc/capture.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/capture.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/capture.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,9 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
-
 #define CAPTURE_DATA_SIZE   2
 #define CAPTURE_array_CREATE(i, obj) \
     if (!PARROT_CAPTURE(obj)->array) \
@@ -525,7 +522,7 @@
 
         for (i = PARROT_CAPTURE(SELF)->data_size - 1; i >= 0; --i)
             if (data[i])
-                pobject_lives(interp, (PObj *)data[i]);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)data[i]);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/class.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/class.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/class.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -90,7 +90,6 @@
 */
 
 #define PARROT_IN_OBJECTS_C /* To get the vtable.h imports we want. */
-#include "parrot/parrot.h"
 #include "parrot/oo_private.h"
 #include "pmc_object.h"
 #include "pmc_namespace.h"
@@ -596,31 +595,31 @@
     VTABLE void mark() {
         Parrot_Class_attributes * const _class = PARROT_CLASS(SELF);
         if (_class->name)
-            pobject_lives(interp, (PObj *)_class->name);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->name);
         if (_class->fullname)
-            pobject_lives(interp, (PObj *)_class->fullname);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->fullname);
         if (_class->_namespace)
-            pobject_lives(interp, (PObj *)_class->_namespace);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->_namespace);
         if (_class->parents)
-            pobject_lives(interp, (PObj *)_class->parents);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->parents);
         if (_class->all_parents)
-            pobject_lives(interp, (PObj *)_class->all_parents);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->all_parents);
         if (_class->roles)
-            pobject_lives(interp, (PObj *)_class->roles);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->roles);
         if (_class->methods)
-            pobject_lives(interp, (PObj *)_class->methods);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->methods);
         if (_class->vtable_overrides)
-            pobject_lives(interp, (PObj *)_class->vtable_overrides);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->vtable_overrides);
         if (_class->parent_overrides)
-            pobject_lives(interp, (PObj *)_class->parent_overrides);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->parent_overrides);
         if (_class->attrib_metadata)
-            pobject_lives(interp, (PObj *)_class->attrib_metadata);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->attrib_metadata);
         if (_class->attrib_index)
-            pobject_lives(interp, (PObj *)_class->attrib_index);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->attrib_index);
         if (_class->attrib_cache)
-            pobject_lives(interp, (PObj *)_class->attrib_cache);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->attrib_cache);
         if (_class->resolve_method)
-            pobject_lives(interp, (PObj *)_class->resolve_method);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_class->resolve_method);
     }
 
 
@@ -820,7 +819,7 @@
             STRING * const current_name = VTABLE_get_string(interp, current_parent);
 
             /* throw an exception if we already have this parent */
-            if (Parrot_str_equal(interp, current_name, parent_name))
+            if (current_parent == parent)
                 Parrot_ex_throw_from_c_args(interp, NULL,
                     EXCEPTION_INVALID_OPERATION,
                     "The class '%S' already has a parent class '%S'. "

Modified: branches/pmc_pct/src/pmc/codestring.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/codestring.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/codestring.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -30,8 +30,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #if PARROT_HAS_ICU
 #  include <unicode/uchar.h>
 #endif

Modified: branches/pmc_pct/src/pmc/complex.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/complex.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/complex.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -22,8 +22,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /*
 
 =item C<static void

Modified: branches/pmc_pct/src/pmc/continuation.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/continuation.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/continuation.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -21,7 +21,6 @@
 */
 
 
-#include "parrot/parrot.h"
 #include "parrot/oplib/ops.h"
 #include "pmc_sub.h"
 

Modified: branches/pmc_pct/src/pmc/coroutine.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/coroutine.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/coroutine.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -30,7 +30,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/oplib/ops.h"
 
 static void

Modified: branches/pmc_pct/src/pmc/cpointer.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/cpointer.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/cpointer.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -46,8 +46,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass CPointer need_ext {
     ATTR void   *pointer; /* The stored pointer. */
     ATTR STRING *sig;     /* A string signature for the pointer. */
@@ -88,18 +86,18 @@
         Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
 
         if (data->sig)
-            pobject_lives(interp, (PObj *)data->sig);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data->sig);
 
         if (data->pointer) {
             if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "P"))) {
                 PMC ** const pmc_pointer = (PMC **) data->pointer;
                 PARROT_ASSERT(*pmc_pointer);
-                pobject_lives(interp, (PObj *) *pmc_pointer);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *) *pmc_pointer);
             }
             else if (Parrot_str_equal(interp, data->sig, CONST_STRING(interp, "S"))) {
                 STRING ** const str_pointer = (STRING **) data->pointer;
                 PARROT_ASSERT(*str_pointer);
-                pobject_lives(interp, (PObj *) *str_pointer);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *) *str_pointer);
             }
         }
     }

Modified: branches/pmc_pct/src/pmc/default.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/default.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/default.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -21,8 +21,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #define INT2KEY(i, k) key_new_integer((i), (k))
 
 /* undef 'interface' to keep MSVC happy */
@@ -68,6 +66,28 @@
             caller(interp, pmc));
 }
 
+
+/*
+
+=item C<static void cant_do_write_method(PARROT_INTERP, PMC *pmc,
+                                   const char *methname)>
+
+Throws an exception "$methname() on read-only instance of '$class'", used by
+all updating messages on read-only instances.
+
+=cut
+
+*/
+
+PARROT_DOES_NOT_RETURN
+static void
+cant_do_write_method(PARROT_INTERP, PMC *pmc /*NULLOK*/, const char *methname)
+{
+    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_WRITE_TO_CONSTCLASS,
+            "%s() in read-only instance of '%Ss'", methname,
+            caller(interp, pmc));
+}
+
 /*
 
 =item C<static INTVAL
@@ -209,7 +229,7 @@
     PMC *prop;
 
     if (!self->pmc_ext)
-        add_pmc_ext(interp, self);
+        Parrot_gc_add_pmc_ext(interp, self);
 
     PMC_metadata(self) = prop = pmc_new(interp, enum_class_Hash);
     GC_WRITE_BARRIER(interp, self, NULL, prop);
@@ -414,7 +434,7 @@
 
     VTABLE PMC *getprops() {
         if (!SELF->pmc_ext)
-            add_pmc_ext(INTERP, SELF);
+            Parrot_gc_add_pmc_ext(INTERP, SELF);
 
         if (!PMC_metadata(SELF)) {
             if (has_pending_std_props(SELF))
@@ -1087,7 +1107,7 @@
         /* default - initialize the PMC */
         if (info->extra_flags == EXTRA_IS_PROP_HASH) {
             if (!SELF->pmc_ext)
-                add_pmc_ext(INTERP, SELF);
+                Parrot_gc_add_pmc_ext(INTERP, SELF);
 
             info->thaw_ptr  = &PMC_metadata(SELF);
             info->container = SELF;

Modified: branches/pmc_pct/src/pmc/env.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/env.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/env.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /* array of environment variables,
    speced in POSIX.1, but not in ISO-C
    MS C compilers know about environ, as it is declared in stdlib.h.

Modified: branches/pmc_pct/src/pmc/eval.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/eval.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/eval.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,7 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "pmc_sub.h"
 
 static void
@@ -121,7 +120,7 @@
             PMC      *sub = ct->constants[ci]->u.key;
 
             if (!PMC_IS_NULL(sub))
-                pobject_lives(interp, (PObj *)sub);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)sub);
         }
     }
 }

Modified: branches/pmc_pct/src/pmc/eventhandler.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/eventhandler.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/eventhandler.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass EventHandler extends Sub need_ext {
 
     ATTR STRING *type;          /* the type of the event to handle */
@@ -133,13 +131,13 @@
 
         if (e) {
             if (e->type)
-                pobject_lives(INTERP, (PObj *)e->type);
+                Parrot_gc_mark_PObj_alive(INTERP, (PObj *)e->type);
 
             if (! PMC_IS_NULL(e->interp))
-                pobject_lives(INTERP, (PObj *)e->interp);
+                Parrot_gc_mark_PObj_alive(INTERP, (PObj *)e->interp);
 
             if (! PMC_IS_NULL(e->code))
-                pobject_lives(INTERP, (PObj *)e->code);
+                Parrot_gc_mark_PObj_alive(INTERP, (PObj *)e->code);
         }
     }
 

Modified: branches/pmc_pct/src/pmc/exception.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/exception.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/exception.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -49,7 +49,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/exceptions.h"
 #include "pmc_sub.h"
 
@@ -152,15 +151,15 @@
     VTABLE void mark() {
         Parrot_Exception_attributes * const core_struct = PARROT_EXCEPTION(SELF);
         if (core_struct->message)
-            pobject_lives(interp, (PObj *)core_struct->message);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->message);
         if (core_struct->payload)
-            pobject_lives(interp, (PObj *)core_struct->payload);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->payload);
         if (core_struct->resume)
-            pobject_lives(interp, (PObj *)core_struct->resume);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->resume);
         if (core_struct->backtrace)
-            pobject_lives(interp, (PObj *)core_struct->backtrace);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->backtrace);
         if (core_struct->handler_iter)
-            pobject_lives(interp, (PObj *)core_struct->handler_iter);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->handler_iter);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/exceptionhandler.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/exceptionhandler.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/exceptionhandler.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -20,7 +20,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/oplib/ops.h"
 
 pmclass ExceptionHandler extends Continuation need_ext {
@@ -74,9 +73,9 @@
         Parrot_ExceptionHandler_attributes * const core_struct =
             PARROT_EXCEPTIONHANDLER(SELF);
         if (core_struct->handled_types)
-            pobject_lives(interp, (PObj *)core_struct->handled_types);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->handled_types);
         if (core_struct->handled_types_except)
-            pobject_lives(interp, (PObj *)core_struct->handled_types_except);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->handled_types_except);
     }
 
     VTABLE PMC *clone() {

Modified: branches/pmc_pct/src/pmc/exporter.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/exporter.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/exporter.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -78,8 +78,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /*
 
 =back
@@ -153,11 +151,11 @@
         Parrot_Exporter_attributes *exp = PARROT_EXPORTER(SELF);
 
         if (exp->ns_src)
-            pobject_lives(interp, (PObj *)exp->ns_src);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)exp->ns_src);
         if (exp->ns_dest)
-            pobject_lives(interp, (PObj *)exp->ns_dest);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)exp->ns_dest);
         if (exp->globals)
-            pobject_lives(interp, (PObj *)exp->globals);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)exp->globals);
     }
 
 

Modified: branches/pmc_pct/src/pmc/file.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/file.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/file.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -22,8 +22,6 @@
 #  include <direct.h>
 #endif
 
-#include "parrot/parrot.h"
-
 /* RT#46681 apparently, strerror_r is thread-safe and should be used instead.*/
 
 static PMC *File_PMC;

Modified: branches/pmc_pct/src/pmc/filehandle.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/filehandle.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/filehandle.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "../src/io/io_private.h"
 
 #ifdef PARROT_HAS_READLINE
@@ -124,11 +123,11 @@
     VTABLE void mark() {
         Parrot_FileHandle_attributes * const data_struct = PARROT_FILEHANDLE(SELF);
         if (data_struct->mode)
-            pobject_lives(interp, (PObj *)data_struct->mode);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->mode);
         if (data_struct->filename)
-            pobject_lives(interp, (PObj *)data_struct->filename);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->filename);
         if (data_struct->encoding)
-            pobject_lives(interp, (PObj *)data_struct->encoding);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->encoding);
     }
 
 /*
@@ -225,6 +224,7 @@
         }
 
         flags = Parrot_io_parse_open_flags(interp, open_mode);
+        SET_ATTR_flags(INTERP, SELF, flags);
         filehandle = PIO_OPEN(INTERP, SELF, open_filename, flags);
 
         if (PMC_IS_NULL(filehandle))
@@ -509,7 +509,7 @@
 #if ! DISABLE_GC_DEBUG
         /* trigger GC for debug - but not during tests */
         if (0 && GC_DEBUG(interp))
-            Parrot_do_gc_run(interp, GC_trace_stack_FLAG);
+            Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
         if (Parrot_io_is_encoding(interp, SELF, CONST_STRING(interp, "utf8")))

Modified: branches/pmc_pct/src/pmc/fixedbooleanarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/fixedbooleanarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/fixedbooleanarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -21,8 +21,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #define BITS_PER_CHAR 8
 
 pmclass FixedBooleanArray need_ext provides array {
@@ -185,7 +183,7 @@
 
     VTABLE INTVAL get_integer_keyed(PMC *key) {
         /* simple int keys only */
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_integer_keyed_int(k);
     }
 
@@ -216,7 +214,7 @@
 */
 
     VTABLE FLOATVAL get_number_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_number_keyed_int(k);
     }
 
@@ -276,7 +274,7 @@
 */
 
     VTABLE STRING *get_string_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_string_keyed_int(k);
     }
 
@@ -309,7 +307,7 @@
 */
 
     VTABLE PMC *get_pmc_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_pmc_keyed_int(k);
     }
 
@@ -377,7 +375,7 @@
 */
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_integer_keyed_int(k, value);
     }
 
@@ -408,7 +406,7 @@
 */
 
     VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_number_keyed_int(k, value);
     }
 
@@ -444,7 +442,7 @@
 */
 
     VTABLE void set_string_keyed(PMC *key, STRING *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_string_keyed_int(k, value);
     }
 
@@ -475,7 +473,7 @@
 */
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_pmc_keyed_int(k, value);
     }
 

Modified: branches/pmc_pct/src/pmc/fixedfloatarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/fixedfloatarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/fixedfloatarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass FixedFloatArray need_ext provides array {
     ATTR INTVAL    size;
     ATTR FLOATVAL *float_array;
@@ -195,7 +193,7 @@
 
     VTABLE INTVAL get_integer_keyed(PMC *key) {
         /* simple int keys only */
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_integer_keyed_int(k);
     }
 
@@ -234,7 +232,7 @@
 */
 
     VTABLE FLOATVAL get_number_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_number_keyed_int(k);
     }
 
@@ -264,7 +262,7 @@
 */
 
     VTABLE STRING *get_string_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_string_keyed_int(k);
     }
 
@@ -298,7 +296,7 @@
 */
 
     VTABLE PMC *get_pmc_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_pmc_keyed_int(k);
     }
 
@@ -350,7 +348,7 @@
 */
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_integer_keyed_int(k, value);
     }
 
@@ -390,7 +388,7 @@
 */
 
     VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_number_keyed_int(k, value);
     }
 
@@ -425,7 +423,7 @@
 */
 
     VTABLE void set_string_keyed(PMC *key, STRING *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_string_keyed_int(k, value);
     }
 
@@ -456,7 +454,7 @@
 */
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_pmc_keyed_int(k, value);
     }
 

Modified: branches/pmc_pct/src/pmc/fixedintegerarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/fixedintegerarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/fixedintegerarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass FixedIntegerArray need_ext provides array {
     ATTR INTVAL   size;  /* number of INTVALs stored in this array */
     ATTR INTVAL * int_array; /* INTVALs are stored here */
@@ -286,7 +284,7 @@
 
     VTABLE INTVAL get_integer_keyed(PMC *key) {
         /* simple int keys only */
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_integer_keyed_int(k);
     }
 
@@ -317,7 +315,7 @@
 */
 
     VTABLE FLOATVAL get_number_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_number_keyed_int(k);
     }
 
@@ -377,7 +375,7 @@
 */
 
     VTABLE STRING *get_string_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_string_keyed_int(k);
     }
 
@@ -410,7 +408,7 @@
 */
 
     VTABLE PMC *get_pmc_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_pmc_keyed_int(k);
     }
 
@@ -476,7 +474,7 @@
 */
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_integer_keyed_int(k, value);
     }
 
@@ -505,7 +503,7 @@
 */
 
     VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_number_keyed_int(k, value);
     }
 
@@ -539,7 +537,7 @@
 */
 
     VTABLE void set_string_keyed(PMC *key, STRING *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_string_keyed_int(k, value);
     }
 
@@ -569,7 +567,7 @@
 */
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_pmc_keyed_int(k, value);
     }
 

Modified: branches/pmc_pct/src/pmc/fixedpmcarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/fixedpmcarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/fixedpmcarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -24,8 +24,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #define PMC_size(x)  ((Parrot_FixedPMCArray_attributes *)PMC_data(x))->size
 #define PMC_array(x) ((Parrot_FixedPMCArray_attributes *)PMC_data(x))->pmc_array
 
@@ -338,7 +336,7 @@
 */
 
     VTABLE PMC *get_pmc_keyed(PMC *key) {
-        const INTVAL k        = key_integer(INTERP, key);
+        const INTVAL k        = VTABLE_get_integer(INTERP, key);
         PMC   * const nextkey = key_next(INTERP, key);
         PMC   *box;
 
@@ -474,7 +472,7 @@
 */
 
     VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
-        const INTVAL k        = key_integer(INTERP, key);
+        const INTVAL k        = VTABLE_get_integer(INTERP, key);
         PMC   * const nextkey = key_next(INTERP, key);
 
         if (nextkey == NULL) {
@@ -563,7 +561,7 @@
 */
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         PMC   *nextkey = key_next(INTERP, key);
 
         if (!nextkey) {
@@ -685,7 +683,7 @@
     }
 
     VTABLE INTVAL exists_keyed(PMC *key) {
-        const INTVAL ix = key_integer(INTERP, key);
+        const INTVAL ix = VTABLE_get_integer(INTERP, key);
         return SELF.exists_keyed_int(ix);
     }
 
@@ -800,7 +798,7 @@
 
         for (i = PMC_size(SELF) - 1; i >= 0; --i)
             if (data[i])
-                pobject_lives(interp, (PObj *)data[i]);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)data[i]);
     }
 
 

Modified: branches/pmc_pct/src/pmc/fixedstringarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/fixedstringarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/fixedstringarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass FixedStringArray need_ext provides array {
     ATTR STRING **str_array; /* where the STRINGs are stored */
     ATTR UINTVAL  size;      /* element count */
@@ -129,7 +127,7 @@
 
             for (i = 0; i < size; i++) {
                 if (str_array[i])
-                    pobject_lives(INTERP, (PObj *) str_array[i]);
+                    Parrot_gc_mark_PObj_alive(INTERP, (PObj *) str_array[i]);
             }
         }
     }
@@ -231,7 +229,7 @@
 
     VTABLE INTVAL get_integer_keyed(PMC *key) {
         /* simple int keys only */
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_integer_keyed_int(k);
     }
 
@@ -262,7 +260,7 @@
 */
 
     VTABLE FLOATVAL get_number_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_number_keyed_int(k);
     }
 
@@ -301,7 +299,7 @@
 */
 
     VTABLE STRING *get_string_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_string_keyed_int(k);
     }
 
@@ -335,7 +333,7 @@
 */
 
     VTABLE PMC *get_pmc_keyed(PMC *key) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         return SELF.get_pmc_keyed_int(k);
     }
 
@@ -397,7 +395,7 @@
 */
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_integer_keyed_int(k, value);
     }
 
@@ -433,7 +431,7 @@
 */
 
     VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_number_keyed_int(k, value);
     }
 
@@ -471,7 +469,7 @@
 */
 
     VTABLE void set_string_keyed(PMC *key, STRING *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_string_keyed_int(k, value);
     }
 
@@ -502,7 +500,7 @@
 */
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
-        const INTVAL k = key_integer(INTERP, key);
+        const INTVAL k = VTABLE_get_integer(INTERP, key);
         SELF.set_pmc_keyed_int(k, value);
     }
 

Modified: branches/pmc_pct/src/pmc/float.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/float.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/float.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass Float extends scalar provides float provides scalar {
     ATTR FLOATVAL fv;
 

Modified: branches/pmc_pct/src/pmc/hash.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/hash.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/hash.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "pmc_iterator.h"
 #include "pmc_key.h"
 

Modified: branches/pmc_pct/src/pmc/integer.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/integer.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/integer.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #include "pmc_bigint.h"
 
 static void

Modified: branches/pmc_pct/src/pmc/iterator.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/iterator.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/iterator.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -61,8 +61,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass Iterator no_ro {
     ATTR PMC *aggregate; /* the aggregate which this Iterator iterates */
     ATTR PMC *key;       /* the Key used by this Iterator */
@@ -145,11 +143,11 @@
         PMC *key;
         GET_ATTR_key(INTERP, SELF, key);
         if (key)
-             pobject_lives(INTERP, (PObj *)key);
+             Parrot_gc_mark_PObj_alive(INTERP, (PObj *)key);
 
         /* the aggregate */
         if (SELF.get_pmc() != PMCNULL)
-             pobject_lives(INTERP, (PObj *)SELF.get_pmc());
+             Parrot_gc_mark_PObj_alive(INTERP, (PObj *)SELF.get_pmc());
     }
 
 /*
@@ -202,7 +200,7 @@
     VTABLE STRING *get_string() {
         PMC *key;
         GET_ATTR_key(INTERP, SELF, key);
-        return Parrot_str_from_int(INTERP, key_integer(INTERP, key));
+        return Parrot_str_from_int(INTERP, VTABLE_get_integer(INTERP, key));
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/key.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/key.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/key.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass Key need_ext {
     ATTR PMC      *next_key; /* Sometimes it's the next key, sometimes it's
                                 not.  The Key code is like that. */
@@ -277,7 +275,13 @@
 */
 
     VTABLE PMC *shift_pmc() {
-        return key_next(INTERP, SELF);
+        PMC *next_key;
+
+        if (!SELF->pmc_ext)
+            return NULL;
+
+        GET_ATTR_next_key(INTERP, SELF, next_key);
+        return next_key;
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/lexinfo.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/lexinfo.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/lexinfo.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /* included manually to prevent breaking C++ builds -- see RT #56534*/
 #include "pmc_hash.h"
 

Modified: branches/pmc_pct/src/pmc/lexpad.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/lexpad.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/lexpad.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /*
  * LexPad provides a Hash interface for lexical fetch/store
  * needed

Modified: branches/pmc_pct/src/pmc/managedstruct.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/managedstruct.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/managedstruct.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 typedef void (*custom_free_func_t)(PARROT_INTERP, void *ptr, void *priv);
 typedef PMC * (*custom_clone_func_t)(PARROT_INTERP, PMC *ptr, void *priv);
 

Modified: branches/pmc_pct/src/pmc/multisub.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/multisub.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/multisub.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,9 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
-
 pmclass MultiSub extends ResizablePMCArray need_ext provides array {
 
     VTABLE void push_pmc(PMC *value) {

Modified: branches/pmc_pct/src/pmc/namespace.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/namespace.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/namespace.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2005-2008, Parrot Foundation.
+Copyright (C) 2005-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "pmc_sub.h"
 
 static void add_to_class(
@@ -167,15 +166,15 @@
         Parrot_NameSpace_attributes * const nsinfo = PARROT_NAMESPACE(SELF);
         SUPER();
         if (nsinfo->parent)
-            pobject_lives(INTERP, (PObj *)nsinfo->parent);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)nsinfo->parent);
         if (nsinfo->name)
-            pobject_lives(INTERP, (PObj *)nsinfo->name);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)nsinfo->name);
         if (nsinfo->_class)
-            pobject_lives(INTERP, (PObj *)nsinfo->_class);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)nsinfo->_class);
         if (nsinfo->vtable)
-            pobject_lives(INTERP, (PObj *)nsinfo->vtable);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)nsinfo->vtable);
         if (nsinfo->methods)
-            pobject_lives(INTERP, (PObj *)nsinfo->methods);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)nsinfo->methods);
     }
 
 /*
@@ -354,7 +353,7 @@
         if (key->vtable->base_type == enum_class_Key) {
             while (1) {
                 STRING * const part = VTABLE_get_string(INTERP, key);
-                key  = key_next(INTERP, key);
+                key                 = VTABLE_shift_pmc(INTERP, key);
 
                 if (!key) {
                     Parrot_set_global(INTERP, ns, part, value);
@@ -407,7 +406,7 @@
 
         if (key->vtable->base_type == enum_class_Key) {
             STRING * const part = VTABLE_get_string(INTERP, key);
-            key  = key_next(INTERP, key);
+            key                 = VTABLE_shift_pmc(INTERP, key);
 
             if (!key)
                 return VTABLE_get_pmc_keyed_str(INTERP, ns, part);
@@ -476,7 +475,7 @@
                 /* this loop (and function) could use a rewrite for clarity */
                 while (1) {
                     STRING * const part = VTABLE_get_string(INTERP, key);
-                    key  = key_next(INTERP, key);
+                    key                 = VTABLE_shift_pmc(INTERP, key);
 
                     if (!key)
                         return VTABLE_get_pointer_keyed_str(INTERP, ns, part);

Modified: branches/pmc_pct/src/pmc/nci.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/nci.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/nci.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 typedef INTVAL (*nci_sub_t)(PARROT_INTERP, PMC *);
 typedef INTVAL (*nci_jit_sub_t)(PARROT_INTERP, PMC *, char *);
 
@@ -98,12 +96,14 @@
 
 pmclass NCI need_ext {
     ATTR STRING    *signature;              /* The signature. */
-    ATTR void      *func;                   /* Function pointer to what we'll call. */
-    ATTR void      *orig_func;              /* Function pointer used to create func*/
+    ATTR void      *func;                   /* Function pointer to call. */
+    ATTR void      *orig_func;              /* Function pointer
+                                             * used to create func */
     ATTR STRING    *pcc_params_signature;   /* The signature. */
+    ATTR STRING    *long_signature;         /* The full signature. */
+    ATTR PMC       *multi_sig;              /* type tuple array (?) */
     ATTR INTVAL     arity;                  /* Cached arity of the NCI. */
     ATTR INTVAL     jitted;                 /* Is this a jitted NCI stub. */
-    ATTR PMC       *multi_sig;              /* type tuple array (?) */
 
 /*
 
@@ -178,13 +178,19 @@
     VTABLE void set_pointer_keyed_str(STRING *key, void *func) {
         Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
         int                             jitted = 0;
-        char                     * const key_c = Parrot_str_to_cstring(INTERP, key);
 
         /* Store the original function and signature. */
         SET_ATTR_orig_func(INTERP, SELF, func);
-        nci_info->signature  = string_make(interp, key_c, strlen(key_c),
+
+        /* ensure that the STRING signature is constant */
+        if (!PObj_constant_TEST(key)) {
+            char * const key_c = Parrot_str_to_cstring(INTERP, key);
+            key                = string_make(interp, key_c, strlen(key_c),
                                     NULL, PObj_constant_FLAG);
-        Parrot_str_free_cstring(key_c);
+            Parrot_str_free_cstring(key_c);
+        }
+
+        nci_info->signature  = key;
         pcc_params(INTERP, key, nci_info);
 
         /* Arity is length of that string minus one (the return type). */
@@ -210,9 +216,9 @@
             Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
 
             if (nci_info->signature)
-                pobject_lives(interp, (PObj*)nci_info->signature);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)nci_info->signature);
             if (nci_info->pcc_params_signature)
-                pobject_lives(interp, (PObj*)nci_info->pcc_params_signature);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)nci_info->pcc_params_signature);
         }
     }
 

Modified: branches/pmc_pct/src/pmc/null.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/null.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/null.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass Null singleton {
 
 /*

Modified: branches/pmc_pct/src/pmc/object.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/object.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/object.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/oo_private.h"
 #include "pmc_class.h"
 
@@ -189,9 +188,9 @@
             Parrot_Object_attributes * const obj = PARROT_OBJECT(SELF);
 
             if (obj->_class)
-                pobject_lives(interp, (PObj*)obj->_class);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)obj->_class);
             if (obj->attrib_store)
-                pobject_lives(interp, (PObj*)obj->attrib_store);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)obj->attrib_store);
         }
     }
 
@@ -322,17 +321,15 @@
 
 */
     VTABLE PMC *find_method(STRING *name) {
-        Parrot_Object_attributes * const obj    = PARROT_OBJECT(SELF);
-        Parrot_Class_attributes  * const _class = PARROT_CLASS(obj->_class);
+        Parrot_Object_attributes * const obj         = PARROT_OBJECT(SELF);
+        Parrot_Class_attributes  * const _class      = PARROT_CLASS(obj->_class);
+        STRING                   * const find_method = CONST_STRING(interp, "find_method");
         PMC           *method        = PMCNULL;
-        STRING        *find_method   = CONST_STRING(interp, "find_method");
 
         /* Walk and search. One day, we'll use the cache first. */
         const int num_classes        = VTABLE_elements(interp,
                                                       _class->all_parents);
         const int all_in_universe    = !CLASS_has_alien_parents_TEST(obj->_class);
-        int       alien_parents_pos  = VTABLE_elements(interp,
-                                                      _class->attrib_metadata);
         int i;
 
         for (i = 0; i < num_classes; i++) {
@@ -354,11 +351,10 @@
             /* If it's from this universe or the class doesn't inherit from
              * anything outside of it... */
             if (all_in_universe || VTABLE_isa(interp, cur_class, CONST_STRING(interp, "Class"))) {
-                if (VTABLE_exists_keyed_str(interp, class_info->methods, name)) {
-                    /* Found it! */
-                    method = VTABLE_get_pmc_keyed_str(interp, class_info->methods, name);
+                method = VTABLE_get_pmc_keyed_str(interp, class_info->methods, name);
+                /* Found it! */
+                if (!PMC_IS_NULL(method))
                     break;
-                }
             }
             else {
                 Parrot_ex_throw_from_c_args(INTERP, NULL, -1,
@@ -424,8 +420,8 @@
 
 */
     VTABLE PMC *get_class() {
-        PMC    * const classobj = PARROT_OBJECT(SELF)->_class;
-        STRING *get_class       = CONST_STRING(interp, "get_class");
+        PMC    * const classobj  = PARROT_OBJECT(SELF)->_class;
+        STRING * const get_class = CONST_STRING(interp, "get_class");
         /* If there's a vtable override for 'get_class' run that instead. */
         PMC * const method = Parrot_oo_find_vtable_override(interp,
                 classobj, get_class);
@@ -448,8 +444,8 @@
 */
 
     VTABLE PMC *get_namespace() {
-        PMC    * const classobj = VTABLE_get_class(interp, SELF);
-        STRING *get_namespace   = CONST_STRING(interp, "get_namespace");
+        PMC    * const classobj      = VTABLE_get_class(interp, SELF);
+        STRING * const get_namespace = CONST_STRING(interp, "get_namespace");
         /* If there's a vtable override for 'get_namespace' run that instead. */
         PMC * const method = Parrot_oo_find_vtable_override(interp,
                 classobj, get_namespace);
@@ -534,8 +530,8 @@
         if (!role_name)
             return 0;
         else {
-            PMC    * const classobj = VTABLE_get_class(interp, SELF);
-            STRING * meth_name      = CONST_STRING(interp, "does");
+            PMC    * const classobj  = VTABLE_get_class(interp, SELF);
+            STRING * const meth_name = CONST_STRING(interp, "does");
 
             PMC * const method = Parrot_oo_find_vtable_override(interp,
                 classobj, meth_name);
@@ -593,8 +589,8 @@
 
         for (i = 0; i < num_classes; i++) {
             /* Get the class. */
-            STRING *meth_name     = CONST_STRING(interp, "invoke");
-            STRING *proxy         = CONST_STRING(interp, "proxy");
+            STRING * const meth_name = CONST_STRING(interp, "invoke");
+            STRING * const proxy     = CONST_STRING(interp, "proxy");
             PMC * const cur_class =
                 VTABLE_get_pmc_keyed_int(interp, _class->all_parents, i);
 
@@ -628,7 +624,7 @@
 */
 
     VTABLE INTVAL type() {
-        PMC *_class = VTABLE_get_class(interp, SELF);
+        PMC * const _class = VTABLE_get_class(interp, SELF);
         return VTABLE_type(interp, _class);
     }
 
@@ -680,7 +676,7 @@
         PMC_data(cloned)          = cloned_guts;
         num_attrs                 = VTABLE_elements(INTERP, cloned_guts->attrib_store);
         for (i = 0; i < num_attrs; i++) {
-            PMC *to_clone = VTABLE_get_pmc_keyed_int(INTERP, cloned_guts->attrib_store, i);
+            PMC * const to_clone = VTABLE_get_pmc_keyed_int(INTERP, cloned_guts->attrib_store, i);
             if (!PMC_IS_NULL(to_clone)) {
                 VTABLE_set_pmc_keyed_int(INTERP, cloned_guts->attrib_store, i,
                         VTABLE_clone(INTERP, to_clone));
@@ -695,7 +691,7 @@
                 PMC * const cur_class = VTABLE_get_pmc_keyed_int(interp, _class->all_parents, i);
                 if (cur_class->vtable->base_type == enum_class_PMCProxy) {
                     /* Clone this PMC too. */
-                    STRING *proxy         = CONST_STRING(interp, "proxy");
+                    STRING * const proxy = CONST_STRING(interp, "proxy");
                     VTABLE_set_attr_keyed(interp, cloned, cur_class, proxy,
                         VTABLE_clone(interp,
                             VTABLE_get_attr_keyed(interp, cloned, cur_class, proxy)));
@@ -813,14 +809,14 @@
         VTABLE_set_integer_native(INTERP, _true, 1);
         VTABLE_setprop(INTERP, ret, CONST_STRING(interp, "_ro"), _true);
         SELF->vtable->pmc_class = master->vtables[type_num]->pmc_class;
-        add_pmc_sync(INTERP, ret);
+        Parrot_gc_add_pmc_sync(INTERP, ret);
         PObj_is_PMC_shared_SET(ret);
 
         data = PARROT_CLASS(classobj)->parents;
         n    = VTABLE_elements(INTERP, data);
 
         for (i = 0; i < n; ++i) {
-            PMC * cur_class = VTABLE_get_pmc_keyed_int(INTERP, data, i);
+            PMC * const cur_class = VTABLE_get_pmc_keyed_int(INTERP, data, i);
             VTABLE_set_pmc_keyed_int(INTERP, data, i, VTABLE_share_ro(INTERP, cur_class));
         }
 
@@ -845,8 +841,8 @@
 */
 
     VTABLE void morph(PMC* type) {
-        PMC    * const classobj = VTABLE_get_class(interp, SELF);
-        STRING * meth_name      = CONST_STRING(interp, "morph");
+        PMC    * const classobj  = VTABLE_get_class(interp, SELF);
+        STRING * const meth_name = CONST_STRING(interp, "morph");
         /* If there's a vtable override for 'morph' run that instead. */
         PMC * const method = Parrot_oo_find_vtable_override(interp,
                 classobj, meth_name);

Modified: branches/pmc_pct/src/pmc/orderedhash.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/orderedhash.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/orderedhash.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -39,8 +39,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass OrderedHash extends Hash need_ext provides array provides hash {
 
 /*
@@ -67,9 +65,9 @@
             while (b) {
 
                 if (b->key) {
-                    pobject_lives(interp, (PObj *)b->key);
+                    Parrot_gc_mark_PObj_alive(interp, (PObj *)b->key);
                     if (b->value)
-                        pobject_lives(interp, (PObj *)b->value);
+                        Parrot_gc_mark_PObj_alive(interp, (PObj *)b->value);
                 }
 
                 b = b->next;
@@ -112,8 +110,8 @@
 
     VTABLE PMC *get_pmc_keyed(PMC *key) {
         if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
-            PMC * const item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
-            PMC * const next = key_next(INTERP, key);
+            PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
+            PMC * const next = VTABLE_shift_pmc(INTERP, key);
 
             if (!next)
                 return item;
@@ -160,8 +158,8 @@
 
     VTABLE STRING *get_string_keyed(PMC *key) {
         if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
-            PMC * const item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
-            PMC * const next = key_next(INTERP, key);
+            PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
+            PMC * const next = VTABLE_shift_pmc(INTERP, key);
 
             if (!next)
                 return VTABLE_get_string(INTERP, item);
@@ -209,8 +207,8 @@
     VTABLE INTVAL get_integer_keyed(PMC *key) {
 
         if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
-            PMC * const item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
-            PMC * const next = key_next(INTERP, key);
+            PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
+            PMC * const next = VTABLE_shift_pmc(INTERP, key);
 
             if (!next)
                 return VTABLE_get_integer(INTERP, item);
@@ -258,8 +256,8 @@
 
     VTABLE FLOATVAL get_number_keyed(PMC *key) {
         if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
-            PMC * const item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
-            PMC * const next = key_next(INTERP, key);
+            PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
+            PMC * const next = VTABLE_shift_pmc(INTERP, key);
 
             if (!next)
                 return VTABLE_get_number(INTERP, item);
@@ -402,7 +400,7 @@
             PMC        *item, *next;
             HashBucket *b;
             Hash       * const h   = (Hash *)SELF.get_pointer();
-            INTVAL             idx = key_integer(INTERP, key);
+            INTVAL             idx = VTABLE_get_integer(INTERP, key);
             const INTVAL       n   = h->entries;
 
             if (idx < 0)
@@ -417,7 +415,7 @@
                 return 0;
 
             item = (PMC *)b->value;
-            next = key_next(INTERP, key);
+            next = VTABLE_shift_pmc(INTERP, key);
 
             if (!next)
                 return 1;
@@ -450,7 +448,7 @@
     VTABLE INTVAL defined_keyed(PMC *key) {
         if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
             Hash * const h   = (Hash *)SELF.get_pointer();
-            INTVAL       idx = key_integer(INTERP, key);
+            INTVAL       idx = VTABLE_get_integer(INTERP, key);
             const INTVAL n   = h->entries;
 
             HashBucket *b;
@@ -469,7 +467,7 @@
                 return 0;
 
             item = (PMC *)b->value;
-            next = key_next(INTERP, key);
+            next = VTABLE_shift_pmc(INTERP, key);
 
             if (!next)
                 return VTABLE_defined(INTERP, item);
@@ -518,12 +516,12 @@
 
         if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
             if (next) {
-                PMC * const item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
+                PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
                 VTABLE_delete_keyed(INTERP, item, next);
                 return;
             }
 
-            SELF.delete_keyed_int(key_integer(INTERP, key));
+            SELF.delete_keyed_int(VTABLE_get_integer(INTERP, key));
         }
         else {
             if (next) {

Modified: branches/pmc_pct/src/pmc/os.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/os.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/os.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -29,8 +29,6 @@
 #  include <dirent.h>
 #endif
 
-#include "parrot/parrot.h"
-
 /* XXX Check if we need to deallocate strerror strings */
 /* XXX apparently, strerror_r is thread-safe and should be used instead.*/
 

Modified: branches/pmc_pct/src/pmc/packfile.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfile.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfile.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,7 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "pmc_packfiledirectory.h"
 
 /*
@@ -115,9 +114,9 @@
         Parrot_Packfile_attributes * attrs = PARROT_PACKFILE(SELF);
 
         if (attrs->uuid)
-            pobject_lives(INTERP, (PObj *)attrs->uuid);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)attrs->uuid);
         if (attrs->directory)
-            pobject_lives(INTERP, (PObj *)attrs->directory);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)attrs->directory);
     }
 /*
 

Modified: branches/pmc_pct/src/pmc/packfileannotation.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfileannotation.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfileannotation.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass PackfileAnnotation {
     ATTR INTVAL value;
     ATTR INTVAL offset;

Modified: branches/pmc_pct/src/pmc/packfileannotationkeys.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfileannotationkeys.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfileannotationkeys.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -24,8 +24,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 /*
 Fetch PackfileConstantTable from PackfileAnnotationKeys.
 Throw exception if table wasn't initilized.
@@ -86,11 +84,11 @@
                 PARROT_PACKFILEANNOTATIONKEYS(SELF);
 
         if (attrs->const_table)
-            pobject_lives(interp, (PObj *)attrs->const_table);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->const_table);
         if (attrs->names)
-            pobject_lives(interp, (PObj *)attrs->names);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->names);
         if (attrs->types)
-            pobject_lives(interp, (PObj *)attrs->types);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->types);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/packfileannotations.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfileannotations.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfileannotations.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -27,7 +27,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "pmc_packfileannotation.h"
 
 pmclass PackfileAnnotations extends PackfileSegment {
@@ -72,9 +71,9 @@
                 PARROT_PACKFILEANNOTATIONS(SELF);
 
         if (attrs->annotations)
-            pobject_lives(interp, (PObj *)attrs->annotations);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->annotations);
         if (attrs->keys)
-            pobject_lives(interp, (PObj *)attrs->keys);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->keys);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/packfileconstanttable.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfileconstanttable.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfileconstanttable.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -24,8 +24,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass PackfileConstantTable extends PackfileSegment {
     /* ResizablePMCArray for storing constants */
     ATTR PMC *constants;
@@ -69,9 +67,9 @@
                 PARROT_PACKFILECONSTANTTABLE(SELF);
 
         if (attrs->constants)
-            pobject_lives(interp, (PObj *)attrs->constants);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->constants);
         if (attrs->types)
-            pobject_lives(interp, (PObj *)attrs->types);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->types);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/packfiledirectory.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfiledirectory.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfiledirectory.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -25,8 +25,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass PackfileDirectory extends PackfileSegment {
     /* Directory is a hash of Segments */
     ATTR PMC *hash;
@@ -65,7 +63,7 @@
                 PARROT_PACKFILEDIRECTORY(SELF);
 
         if (attrs->hash)
-            pobject_lives(interp, (PObj *)attrs->hash);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->hash);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/packfilefixupentry.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfilefixupentry.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfilefixupentry.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass PackfileFixupEntry {
     ATTR INTVAL     type;
     ATTR STRING     *name;
@@ -61,7 +59,7 @@
                 PARROT_PACKFILEFIXUPENTRY(SELF);
 
         if (attrs->name)
-            pobject_lives(interp, (PObj *)attrs->name);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->name);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/packfilefixuptable.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfilefixuptable.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfilefixuptable.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -24,8 +24,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass PackfileFixupTable extends PackfileSegment {
     /* RPA of entries */
     ATTR PMC *entries;
@@ -65,7 +63,7 @@
                 PARROT_PACKFILEFIXUPTABLE(SELF);
 
         if (attrs->entries)
-            pobject_lives(interp, (PObj *)attrs->entries);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->entries);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/packfilerawsegment.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfilerawsegment.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfilerawsegment.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -24,8 +24,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass PackfileRawSegment extends PackfileSegment {
     /* ResizableIntegerArray of opcodes */
     ATTR PMC    *opcodes;
@@ -65,7 +63,7 @@
                 PARROT_PACKFILERAWSEGMENT(SELF);
 
         if (attrs->opcodes)
-            pobject_lives(interp, (PObj *)attrs->opcodes);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->opcodes);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/packfilesegment.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/packfilesegment.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/packfilesegment.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -23,8 +23,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass PackfileSegment {
     /*
     Directory which owns this segment. Required for correct pack/unpack
@@ -67,7 +65,7 @@
                 PARROT_PACKFILESEGMENT(SELF);
 
         if (attrs->directory)
-            pobject_lives(interp, (PObj *)attrs->directory);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->directory);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/parrotinterpreter.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/parrotinterpreter.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/parrotinterpreter.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -25,7 +25,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/embed.h"
 #include "parrot/dynext.h"
 #include "parrot/io.h"
@@ -68,7 +67,7 @@
     if (flags & PARROT_CLONE_HLL) {
         /* we'd like to share the HLL data. Give it a PMC_sync structure
            if it doesn't have one already */
-        add_pmc_sync(s, s->HLL_info);
+        Parrot_gc_add_pmc_sync(s, s->HLL_info);
         d->HLL_info = s->HLL_info;
         Parrot_regenerate_HLL_namespaces(d);
     }
@@ -444,7 +443,7 @@
         nextkey = key_next(INTERP, key);
 
         if (nextkey)
-            level = key_integer(interp, nextkey);
+            level = VTABLE_get_integer(interp, nextkey);
         else if (outer)
             level = 1;
 
@@ -757,7 +756,7 @@
     }
 
     METHOD run_gc() {
-        Parrot_do_gc_run(PMC_interp(SELF), 0);
+        Parrot_gc_mark_and_sweep(PMC_interp(SELF), 0);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/parrotlibrary.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/parrotlibrary.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/parrotlibrary.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -28,8 +28,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #define PMC_dlhandle(x) ((Parrot_ParrotLibrary_attributes*)PMC_data(x))->dl_handle
 #define PMC_oplib_init(x) ((Parrot_ParrotLibrary_attributes*)PMC_data(x))->oplib_init
 

Modified: branches/pmc_pct/src/pmc/parrotrunningthread.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/parrotrunningthread.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/parrotrunningthread.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -28,7 +28,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/embed.h"
 
 #define PMC_tid(x) ((Parrot_ParrotRunningThread_attributes *)PMC_data(x))->tid

Modified: branches/pmc_pct/src/pmc/parrotthread.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/parrotthread.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/parrotthread.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -36,7 +36,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/embed.h"
 
 #define PMC_interp(x) ((Parrot_ParrotInterpreter_attributes *)PMC_data(x))->interp

Modified: branches/pmc_pct/src/pmc/pccmethod_test.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/pccmethod_test.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/pccmethod_test.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -10,8 +10,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass PCCMETHOD_Test need_ext provides hash {
 
 

Modified: branches/pmc_pct/src/pmc/pmcproxy.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/pmcproxy.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/pmcproxy.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -51,7 +51,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/oo_private.h"
 
 /*
@@ -229,29 +228,29 @@
         Parrot_Class_attributes * const _pmc = PARROT_CLASS(SELF);
 
         if (_pmc->name)
-            pobject_lives(interp, (PObj *)_pmc->name);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->name);
         if (_pmc->_namespace)
-            pobject_lives(interp, (PObj *)_pmc->_namespace);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->_namespace);
         if (_pmc->parents)
-            pobject_lives(interp, (PObj *)_pmc->parents);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->parents);
         if (_pmc->all_parents)
-            pobject_lives(interp, (PObj *)_pmc->all_parents);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->all_parents);
         if (_pmc->roles)
-            pobject_lives(interp, (PObj *)_pmc->roles);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->roles);
         if (_pmc->methods)
-            pobject_lives(interp, (PObj *)_pmc->methods);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->methods);
         if (_pmc->vtable_overrides)
-            pobject_lives(interp, (PObj *)_pmc->vtable_overrides);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->vtable_overrides);
         if (_pmc->parent_overrides)
-            pobject_lives(interp, (PObj *)_pmc->parent_overrides);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->parent_overrides);
         if (_pmc->attrib_metadata)
-            pobject_lives(interp, (PObj *)_pmc->attrib_metadata);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->attrib_metadata);
         if (_pmc->attrib_index)
-            pobject_lives(interp, (PObj *)_pmc->attrib_index);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->attrib_index);
         if (_pmc->attrib_cache)
-            pobject_lives(interp, (PObj *)_pmc->attrib_cache);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->attrib_cache);
         if (_pmc->resolve_method)
-            pobject_lives(interp, (PObj *)_pmc->resolve_method);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)_pmc->resolve_method);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/pointer.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/pointer.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/pointer.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -20,8 +20,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass Pointer need_ext {
     ATTR void * mark_function;
     ATTR void * pointer;

Modified: branches/pmc_pct/src/pmc/random.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/random.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/random.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -20,8 +20,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 static PMC *Rand_PMC;
 
 pmclass Random singleton {

Modified: branches/pmc_pct/src/pmc/resizablebooleanarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/resizablebooleanarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/resizablebooleanarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -20,9 +20,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
-
 #define BITS_PER_CHAR 8
 /* MIN_ALLOC is 8 * BITS_PER_CHAR */
 #define MIN_ALLOC 64

Modified: branches/pmc_pct/src/pmc/resizablefloatarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/resizablefloatarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/resizablefloatarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -20,8 +20,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass ResizableFloatArray extends FixedFloatArray need_ext provides array {
     ATTR INTVAL resize_threshold; /* max size before array needs resizing */
 

Modified: branches/pmc_pct/src/pmc/resizableintegerarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/resizableintegerarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/resizableintegerarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -20,9 +20,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
-
 pmclass ResizableIntegerArray extends FixedIntegerArray need_ext provides array {
     ATTR INTVAL resize_threshold; /* max size before array needs to be resized */
 

Modified: branches/pmc_pct/src/pmc/resizablepmcarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/resizablepmcarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/resizablepmcarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,8 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #define PMC_size(x)      ((Parrot_ResizablePMCArray_attributes *)PMC_data(x))->size
 #define PMC_array(x)     ((Parrot_ResizablePMCArray_attributes *)PMC_data(x))->pmc_array
 #define PMC_threshold(x) ((Parrot_ResizablePMCArray_attributes *)PMC_data(x))->resize_threshold
@@ -278,14 +276,17 @@
     }
 
     VTABLE void delete_keyed(PMC *key) {
-        INTVAL  i;
-        INTVAL  idx  = key_integer(INTERP, key);
-        INTVAL  n    = PMC_size(SELF);
+        const INTVAL idx  = VTABLE_get_integer(INTERP, key);
+        SELF.delete_keyed_int(idx);
+    }
+
+    VTABLE void delete_keyed_int(INTVAL idx) {
         PMC   **data = PMC_array(SELF);
+        INTVAL  n    = PMC_size(SELF);
+        INTVAL  i;
 
-        for (i = idx; i < n - 1; ++i) {
+        for (i = idx; i < n - 1; ++i)
             data[i] = data[i + 1];
-        }
 
         PMC_size(SELF)--;
     }
@@ -315,7 +316,7 @@
     }
 
     VTABLE INTVAL exists_keyed(PMC *key) {
-        INTVAL ix = key_integer(INTERP, key);
+        INTVAL ix = VTABLE_get_integer(INTERP, key);
         return SELF.exists_keyed_int(ix);
     }
 

Modified: branches/pmc_pct/src/pmc/resizablestringarray.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/resizablestringarray.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/resizablestringarray.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass ResizableStringArray extends FixedStringArray need_ext provides array {
     ATTR UINTVAL resize_threshold; /*max capacity before resizing */
 
@@ -563,7 +561,7 @@
 */
 
     VTABLE void delete_keyed(PMC *key) {
-        INTVAL    idx  = key_integer(INTERP, key);
+        INTVAL    idx  = VTABLE_get_integer(INTERP, key);
         STRING  **str_array;
         UINTVAL   size, i;
 

Modified: branches/pmc_pct/src/pmc/retcontinuation.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/retcontinuation.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/retcontinuation.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -21,10 +21,8 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/oplib/ops.h"
 
-
 pmclass RetContinuation extends Continuation need_ext {
 
 /*
@@ -43,7 +41,6 @@
         PMC_data(SELF) = attrs;
 
         PMC_cont(SELF) = new_ret_continuation(INTERP);
-        PMC_data(SELF) = attrs;
         PObj_custom_mark_destroy_SETALL(SELF);
     }
 
@@ -64,11 +61,10 @@
 
 =item C<PMC *clone>
 
-Return a new Continuation PMC with the context of SELF. Note: the
-returned object is not a RetContinuation and creating a real
-Continuation invalidates all RetContinuation all the way up the call
-chain that is, these can't be recycled, they get persistent until
-the GC gets at them.
+Return a new Continuation PMC with the context of SELF. Note: the returned
+object is not a RetContinuation and creating a real Continuation invalidates
+all RetContinuation all the way up the call chain.  That is, these can't be
+recycled; they persist until the GC gets at them.
 
 =cut
 
@@ -81,7 +77,7 @@
 
 =item C<opcode_t *invoke(void *next)>
 
-Transfers control to the calling context, and frees the current context.
+Transfers control to the calling context and frees the current context.
 
 =cut
 
@@ -98,37 +94,20 @@
         Parrot_continuation_rewind_environment(interp, SELF, cc);
         Parrot_free_context(INTERP, from_ctx, 1);
 
-#ifdef NDEBUG
         /* the continuation is dead - delete and destroy it */
-        VTABLE_destroy(interp, SELF);
-        {
-            Arenas            *arena_base = interp->arena_base;
-            Small_Object_Pool *pool       = arena_base->pmc_pool;
-            Small_Object_Pool *ext_pool   = arena_base->pmc_ext_pool;
-            ext_pool->add_free_object(interp, ext_pool,
-                    (PObj *)SELF->pmc_ext);
-            PObj_flags_SETTO((PObj *)SELF, PObj_on_free_list_FLAG);
-            pool->add_free_object(interp, pool, (PObj *)SELF);
-            pool->num_free_objects++;
-        }
-#else
-        cc->from_ctx = NULL;
-
-        /*
-         * the to_ctx is marked in Continuation.mark
-         * NULLify it or turn off the custom_mark bit
-         */
-        cc->to_ctx = NULL;
-#endif
+        /* This line causes a failure in t/pmc/packfiledirectory.t. No idea
+           what the relationship is between this line of code and that test
+           failure. Will look into it later */
+        /* Parrot_gc_free_pmc_header(interp, SELF); */
 
         if (INTERP->code != seg)
             Parrot_switch_to_cs(INTERP, seg, 1);
 
         return next;
     }
-
 }
 
+
 /*
 
 =back

Modified: branches/pmc_pct/src/pmc/role.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/role.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/role.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -48,7 +48,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "pmc_namespace.h"
 
 /* Takes a hash and initializes the role based on it. */
@@ -273,15 +272,15 @@
         Parrot_Role_attributes * const role = PARROT_ROLE(SELF);
 
         if (role->name)
-            pobject_lives(interp, (PObj *)role->name);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)role->name);
         if (role->_namespace)
-            pobject_lives(interp, (PObj *)role->_namespace);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)role->_namespace);
         if (role->roles)
-            pobject_lives(interp, (PObj *)role->roles);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)role->roles);
         if (role->methods)
-            pobject_lives(interp, (PObj *)role->methods);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)role->methods);
         if (role->attrib_metadata)
-            pobject_lives(interp, (PObj *)role->attrib_metadata);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)role->attrib_metadata);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/scalar.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/scalar.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/scalar.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,10 +18,8 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "pmc_bigint.h"
 
-
 static PMC *
 bitwise_left_shift_internal(PARROT_INTERP, PMC *self,
                             PMC *dest, INTVAL shift_amount)
@@ -1380,7 +1378,7 @@
         VTABLE_setprop(INTERP, ret, CONST_STRING(INTERP, "_ro"), _true);
 
         /* now share; we add a PMC_EXT so we can identify the owning interp */
-        add_pmc_sync(INTERP, ret);
+        Parrot_gc_add_pmc_sync(INTERP, ret);
         PObj_is_PMC_shared_SET(ret);
 
         /* XXX FIXME workaround lack of metadata sharing*/

Modified: branches/pmc_pct/src/pmc/scheduler.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/scheduler.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/scheduler.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/scheduler_private.h"
 
 pmclass Scheduler need_ext {
@@ -267,15 +266,15 @@
             Parrot_Scheduler_attributes * const core_struct = PARROT_SCHEDULER(SELF);
 
             if (core_struct->task_list)
-                pobject_lives(interp, (PObj *)core_struct->task_list);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->task_list);
             if (core_struct->task_index)
-                pobject_lives(interp, (PObj *)core_struct->task_index);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->task_index);
             if (core_struct->wait_index)
-                pobject_lives(interp, (PObj *)core_struct->wait_index);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->wait_index);
             if (core_struct->handlers)
-                pobject_lives(interp, (PObj *)core_struct->handlers);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->handlers);
             if (core_struct->messages)
-                pobject_lives(interp, (PObj *)core_struct->messages);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->messages);
         }
     }
 

Modified: branches/pmc_pct/src/pmc/schedulermessage.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/schedulermessage.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/schedulermessage.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/scheduler_private.h"
 
 pmclass SchedulerMessage need_ext {
@@ -216,7 +215,7 @@
                 PARROT_SCHEDULERMESSAGE(SELF);
 
             if (core_struct->data)
-                pobject_lives(interp, (PObj*)core_struct->data);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)core_struct->data);
         }
     }
 

Modified: branches/pmc_pct/src/pmc/sockaddr.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/sockaddr.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/sockaddr.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -21,8 +21,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif

Modified: branches/pmc_pct/src/pmc/socket.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/socket.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/socket.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "../src/io/io_private.h"
 
 pmclass Socket extends FileHandle need_ext {
@@ -82,10 +81,10 @@
 
         if (data) {
             if (data->local)
-                pobject_lives(interp, (PObj *)data->local);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)data->local);
 
             if (data->remote)
-                pobject_lives(interp, (PObj *)data->remote);
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)data->remote);
         }
     }
 /*

Modified: branches/pmc_pct/src/pmc/string.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/string.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/string.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2003-2008, Parrot Foundation.
+Copyright (C) 2003-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -20,8 +20,6 @@
 
 */
 
-#include "parrot/parrot.h"
-
 pmclass String extends scalar provides string provides scalar {
     ATTR STRING * str_val;
 
@@ -98,7 +96,7 @@
         GET_ATTR_str_val(INTERP, SELF, str_val);
 
         if (str_val)
-            pobject_lives(INTERP, (PObj *)str_val);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)str_val);
     }
 
 /*
@@ -646,26 +644,26 @@
 
     VTABLE STRING *get_string_keyed(PMC *key) {
         STRING * const s = SELF.get_string();
-        const INTVAL   k = key_integer(INTERP, key);
+        const INTVAL   k = VTABLE_get_integer(INTERP, key);
         return Parrot_str_substr(INTERP, s, k, 1, NULL, 0);
     }
 
     VTABLE INTVAL get_integer_keyed(PMC *key) {
         STRING * const s = SELF.get_string();
-        return string_ord(INTERP, s, key_integer(INTERP, key));
+        return string_ord(INTERP, s, VTABLE_get_integer(INTERP, key));
     }
 
     VTABLE void set_string_keyed(PMC *key, STRING * const value) {
         STRING * const s   = SELF.get_string();
         const INTVAL   len = Parrot_str_byte_length(INTERP, value);
-        Parrot_str_replace(INTERP, s, key_integer(INTERP, key), len, value, NULL);
+        Parrot_str_replace(INTERP, s, VTABLE_get_integer(INTERP, key), len, value, NULL);
         VTABLE_set_string_native(INTERP, SELF, s);
     }
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
         STRING * const s = SELF.get_string();
         STRING * const c = string_chr(INTERP, (UINTVAL) value);
-        Parrot_str_replace(INTERP, s, key_integer(INTERP, key), 1, c, NULL);
+        Parrot_str_replace(INTERP, s, VTABLE_get_integer(INTERP, key), 1, c, NULL);
         VTABLE_set_string_native(INTERP, SELF, s);
     }
 /*

Modified: branches/pmc_pct/src/pmc/stringhandle.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/stringhandle.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/stringhandle.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -19,7 +19,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "../src/io/io_private.h"
 
 pmclass StringHandle need_ext {
@@ -95,13 +94,13 @@
     VTABLE void mark() {
         Parrot_StringHandle_attributes * const data_struct = PARROT_STRINGHANDLE(SELF);
         if (data_struct->stringhandle)
-            pobject_lives(interp, (PObj *)data_struct->stringhandle);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->stringhandle);
         if (data_struct->mode)
-            pobject_lives(interp, (PObj *)data_struct->mode);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->mode);
         if (data_struct->encoding)
-            pobject_lives(interp, (PObj *)data_struct->encoding);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->encoding);
         if (data_struct->filename)
-            pobject_lives(interp, (PObj *)data_struct->filename);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)data_struct->filename);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc/sub.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/sub.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/sub.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/oplib/ops.h"
 #include "sub.str"
 
@@ -470,23 +469,23 @@
             return;
 
         if (sub->name)
-            pobject_lives(INTERP, (PObj *) sub->name);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->name);
         if (sub->method_name)
-            pobject_lives(INTERP, (PObj *) sub->method_name);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->method_name);
         if (sub->ns_entry_name)
-            pobject_lives(INTERP, (PObj *) sub->ns_entry_name);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->ns_entry_name);
         if (!PMC_IS_NULL(sub->namespace_name))
-            pobject_lives(INTERP, (PObj *) sub->namespace_name);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->namespace_name);
         if (!PMC_IS_NULL(sub->multi_signature))
-            pobject_lives(INTERP, (PObj *) sub->multi_signature);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->multi_signature);
         if (!PMC_IS_NULL(sub->lex_info))
-            pobject_lives(INTERP, (PObj *) sub->lex_info);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->lex_info);
         if (!PMC_IS_NULL(sub->outer_sub))
-            pobject_lives(INTERP, (PObj *) sub->outer_sub);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->outer_sub);
         if (!PMC_IS_NULL(sub->eval_pmc))
-            pobject_lives(INTERP, (PObj *) sub->eval_pmc);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->eval_pmc);
         if (sub->subid)
-            pobject_lives(INTERP, (PObj *) sub->subid);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->subid);
         if (sub->ctx)
             mark_context(interp, sub->ctx);
         if (sub->outer_ctx)

Modified: branches/pmc_pct/src/pmc/task.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/task.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/task.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/scheduler_private.h"
 
 pmclass Task need_ext {
@@ -395,9 +394,9 @@
             Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
 
             if (core_struct->codeblock)
-                pobject_lives(interp, (PObj*)core_struct->codeblock);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)core_struct->codeblock);
             if (core_struct->data)
-                pobject_lives(interp, (PObj*)core_struct->data);
+                Parrot_gc_mark_PObj_alive(interp, (PObj*)core_struct->data);
         }
     }
 

Modified: branches/pmc_pct/src/pmc/timer.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/timer.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/timer.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -55,7 +55,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/scheduler_private.h"
 
 pmclass Timer extends Task provides event need_ext {

Modified: branches/pmc_pct/src/pmc/undef.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/undef.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/undef.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -23,7 +23,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #define UNDEF_STRING_CLASS enum_class_String
 
 pmclass Undef no_ro {

Modified: branches/pmc_pct/src/pmc/unmanagedstruct.pmc
==============================================================================
--- branches/pmc_pct/src/pmc/unmanagedstruct.pmc	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc/unmanagedstruct.pmc	Fri May 15 21:49:40 2009	(r38803)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2008, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -22,7 +22,6 @@
 
 */
 
-#include "parrot/parrot.h"
 #include "parrot/compiler.h"
 
 static INTVAL key_2_idx(PARROT_INTERP, PMC *pmc, PMC *key);
@@ -108,7 +107,7 @@
         ix /= 3;
     }
     else
-        ix = key_integer(interp, key);
+        ix = VTABLE_get_integer(interp, key);
 
     return ix;
 }
@@ -146,7 +145,7 @@
         return p;
 
     if (PObj_get_FLAGS(next) & KEY_integer_FLAG)
-        count = key_integer(interp, next);
+        count = VTABLE_get_integer(interp, next);
     else
         count = 1;
 
@@ -759,7 +758,7 @@
 
     VTABLE void mark() {
         if (PARROT_UNMANAGEDSTRUCT(SELF)->init)
-            pobject_lives(INTERP, (PObj *)PARROT_UNMANAGEDSTRUCT(SELF)->init);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *)PARROT_UNMANAGEDSTRUCT(SELF)->init);
     }
 
 /*

Modified: branches/pmc_pct/src/pmc_freeze.c
==============================================================================
--- branches/pmc_pct/src/pmc_freeze.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/pmc_freeze.c	Fri May 15 21:49:40 2009	(r38803)
@@ -51,12 +51,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
-static void cleanup_next_for_GC(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-static void cleanup_next_for_GC_pool(ARGIN(Small_Object_Pool *pool))
-        __attribute__nonnull__(1);
-
 static void create_image(PARROT_INTERP,
     ARGIN_NULLOK(PMC *pmc),
     ARGMOD(visit_info *info))
@@ -301,10 +295,6 @@
 #define ASSERT_ARGS_add_pmc_todo_list __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(info)
-#define ASSERT_ARGS_cleanup_next_for_GC __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_cleanup_next_for_GC_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(pool)
 #define ASSERT_ARGS_create_image __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(info)
@@ -482,7 +472,7 @@
         size_t new_size = (size_t) (PObj_buflen(s) * 1.5);
         if (new_size < PObj_buflen(s) - need_free + 512)
             new_size = PObj_buflen(s) - need_free + 512;
-        Parrot_reallocate_string(interp, s, new_size);
+        Parrot_gc_reallocate_string_storage(interp, s, new_size);
         PARROT_ASSERT(PObj_buflen(s) - used - len >= 15);
     }
     mem_sys_memcopy((void *)((ptrcast_t)s->strstart + used), b, len);
@@ -730,11 +720,11 @@
         size_t new_size = (size_t) (PObj_buflen(s) * 1.5);
         if (new_size < PObj_buflen(s) - need_free + 512)
             new_size = PObj_buflen(s) - need_free + 512;
-        Parrot_reallocate_string(interp, s, new_size);
+        Parrot_gc_reallocate_string_storage(interp, s, new_size);
         PARROT_ASSERT(PObj_buflen(s) - used - len >= 15);
     }
 #ifndef DISABLE_GC_DEBUG
-    Parrot_go_collect(interp);
+    Parrot_gc_compact_memory_pool(interp);
 #endif
 }
 
@@ -969,55 +959,7 @@
 {
     ASSERT_ARGS(pmc_add_ext)
     if (pmc->vtable->flags & VTABLE_PMC_NEEDS_EXT)
-        add_pmc_ext(interp, pmc);
-}
-
-/*
-
-=item C<static void cleanup_next_for_GC_pool(Small_Object_Pool *pool)>
-
-Sets all the C<next_for_GC> pointers to C<NULL>.
-
-=cut
-
-*/
-
-static void
-cleanup_next_for_GC_pool(ARGIN(Small_Object_Pool *pool))
-{
-    ASSERT_ARGS(cleanup_next_for_GC_pool)
-    Small_Object_Arena *arena;
-
-    for (arena = pool->last_Arena; arena; arena = arena->prev) {
-        PMC *p = (PMC *)arena->start_objects;
-        UINTVAL i;
-
-        for (i = 0; i < arena->used; i++) {
-            if (!PObj_on_free_list_TEST(p)) {
-                if (p->pmc_ext)
-                    PMC_next_for_GC(p) = PMCNULL;
-            }
-            p++;
-        }
-    }
-}
-
-/*
-
-=item C<static void cleanup_next_for_GC(PARROT_INTERP)>
-
-Cleans up the C<next_for_GC> pointers.
-
-=cut
-
-*/
-
-static void
-cleanup_next_for_GC(PARROT_INTERP)
-{
-    ASSERT_ARGS(cleanup_next_for_GC)
-    cleanup_next_for_GC_pool(interp->arena_base->pmc_pool);
-    cleanup_next_for_GC_pool(interp->arena_base->constant_pmc_pool);
+        Parrot_gc_add_pmc_ext(interp, pmc);
 }
 
 /*
@@ -1424,36 +1366,7 @@
 id_from_pmc(PARROT_INTERP, ARGIN(PMC* pmc))
 {
     ASSERT_ARGS(id_from_pmc)
-    UINTVAL id = 1;     /* first PMC in first arena */
-    Small_Object_Arena *arena;
-    Small_Object_Pool *pool;
-
-    pmc = (PMC*)PObj_to_ARENA(pmc);
-    pool = interp->arena_base->pmc_pool;
-    for (arena = pool->last_Arena; arena; arena = arena->prev) {
-        const ptrdiff_t ptr_diff = (ptrdiff_t)pmc - (ptrdiff_t)arena->start_objects;
-        if (ptr_diff >= 0 && ptr_diff <
-                (ptrdiff_t)(arena->used * pool->object_size)) {
-            PARROT_ASSERT(ptr_diff % pool->object_size == 0);
-            id += ptr_diff / pool->object_size;
-            return id << 2;
-        }
-        id += arena->total_objects;
-    }
-
-    pool = interp->arena_base->constant_pmc_pool;
-    for (arena = pool->last_Arena; arena; arena = arena->prev) {
-        const ptrdiff_t ptr_diff = (ptrdiff_t)pmc - (ptrdiff_t)arena->start_objects;
-        if (ptr_diff >= 0 && ptr_diff <
-                (ptrdiff_t)(arena->used * pool->object_size)) {
-            PARROT_ASSERT(ptr_diff % pool->object_size == 0);
-            id += ptr_diff / pool->object_size;
-            return id << 2;
-        }
-        id += arena->total_objects;
-    }
-
-    Parrot_ex_throw_from_c_args(interp, NULL, 1, "Couldn't find PMC in arenas");
+    return Parrot_gc_get_pmc_index(interp, pmc) << 2;
 }
 
 /*
@@ -1846,7 +1759,7 @@
      * collected under us.
      */
     if (1 || (Parrot_str_byte_length(interp, image) > THAW_BLOCK_GC_SIZE)) {
-        Parrot_do_gc_run(interp, 1);
+        Parrot_gc_mark_and_sweep(interp, 1);
         Parrot_block_GC_mark(interp);
         Parrot_block_GC_sweep(interp);
         gc_block = 1;
@@ -1908,7 +1821,7 @@
     visit_info info;
 
     Parrot_block_GC_mark(interp);
-    cleanup_next_for_GC(interp);
+    Parrot_gc_cleanup_next_for_GC(interp);
     info.what = VISIT_FREEZE_AT_DESTRUCT;
     info.mark_ptr = pmc;
     info.thaw_ptr = NULL;

Modified: branches/pmc_pct/src/runcore/cores.c
==============================================================================
--- branches/pmc_pct/src/runcore/cores.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/runcore/cores.c	Fri May 15 21:49:40 2009	(r38803)
@@ -357,11 +357,10 @@
     ASSERT_ARGS(runops_trace_core)
 
     static size_t  gc_mark_runs, gc_collect_runs;
-    Arenas * const arena_base = interp->arena_base;
     Interp        *debugger;
 
-    gc_mark_runs    = arena_base->gc_mark_runs;
-    gc_collect_runs = arena_base->gc_collect_runs;
+    gc_mark_runs    = Parrot_gc_count_mark_runs(interp);
+    gc_collect_runs = Parrot_gc_count_collect_runs(interp);
     if (interp->pdb) {
         debugger = interp->pdb->debugger;
         PARROT_ASSERT(debugger);
@@ -399,6 +398,7 @@
 
     trace_op(interp, code_start, code_end, pc);
     while (pc) {
+        size_t runs;
         if (pc < code_start || pc >= code_end)
             Parrot_ex_throw_from_c_args(interp, NULL, 1,
                 "attempt to access code outside of current code segment");
@@ -408,13 +408,15 @@
         DO_OP(pc, interp);
         trace_op(interp, code_start, code_end, pc);
 
-        if (gc_mark_runs != arena_base->gc_mark_runs) {
-            gc_mark_runs  = arena_base->gc_mark_runs;
+        runs = Parrot_gc_count_mark_runs(interp);
+        if (gc_mark_runs != runs) {
+            gc_mark_runs  = runs;
             Parrot_io_eprintf(debugger, "       GC mark\n");
         }
 
-        if (gc_collect_runs != arena_base->gc_collect_runs) {
-            gc_collect_runs  = arena_base->gc_collect_runs;
+        runs = Parrot_gc_count_collect_runs(interp);
+        if (gc_collect_runs != runs) {
+            gc_collect_runs  = runs;
             Parrot_io_eprintf(debugger, "       GC collect\n");
         }
     }
@@ -487,7 +489,7 @@
             Parrot_ex_throw_from_c_args(interp, NULL, 1,
                 "attempt to access code outside of current code segment");
 
-        Parrot_do_gc_run(interp, 0);
+        Parrot_gc_mark_and_sweep(interp, 0);
         CONTEXT(interp)->current_pc = pc;
 
         DO_OP(pc, interp);
@@ -579,7 +581,7 @@
                     "attempt to access code outside of current code segment");
 
         if (interp->pdb->state & PDB_GCDEBUG)
-            Parrot_do_gc_run(interp, 0);
+            Parrot_gc_mark_and_sweep(interp, 0);
 
         if (interp->pdb->state & PDB_TRACING) {
             trace_op(interp,

Modified: branches/pmc_pct/src/scheduler.c
==============================================================================
--- branches/pmc_pct/src/scheduler.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/scheduler.c	Fri May 15 21:49:40 2009	(r38803)
@@ -127,29 +127,29 @@
     while (VTABLE_get_integer(interp, scheduler) > 0) {
         PMC * const task = VTABLE_pop_pmc(interp, scheduler);
         if (!PMC_IS_NULL(task)) {
-        PMC *type_pmc = VTABLE_get_attr_str(interp, task, CONST_STRING(interp, "type"));
-        STRING *type = VTABLE_get_string(interp, type_pmc);
+            PMC    * const type_pmc = VTABLE_get_attr_str(interp, task, CONST_STRING(interp, "type"));
+            STRING * const type     = VTABLE_get_string(interp, type_pmc);
 
-        if (Parrot_str_equal(interp, type, CONST_STRING(interp, "callback"))) {
-            Parrot_cx_invoke_callback(interp, task);
-        }
-        else if (Parrot_str_equal(interp, type, CONST_STRING(interp, "timer"))) {
-            Parrot_cx_timer_invoke(interp, task);
-        }
-        else if (Parrot_str_equal(interp, type, CONST_STRING(interp, "event"))) {
-            PMC * const handler = Parrot_cx_find_handler_for_task(interp, task);
-            if (!PMC_IS_NULL(handler)) {
-                PMC * handler_sub = VTABLE_get_attr_str(interp, handler, CONST_STRING(interp, "code"));
-                Parrot_runops_fromc_args_event(interp, handler_sub,
-                    "vPP", handler, task);
+            if (Parrot_str_equal(interp, type, CONST_STRING(interp, "callback"))) {
+                Parrot_cx_invoke_callback(interp, task);
+            }
+            else if (Parrot_str_equal(interp, type, CONST_STRING(interp, "timer"))) {
+                Parrot_cx_timer_invoke(interp, task);
+            }
+            else if (Parrot_str_equal(interp, type, CONST_STRING(interp, "event"))) {
+                PMC * const handler = Parrot_cx_find_handler_for_task(interp, task);
+                if (!PMC_IS_NULL(handler)) {
+                    PMC * const handler_sub = VTABLE_get_attr_str(interp, handler, CONST_STRING(interp, "code"));
+                    Parrot_runops_fromc_args_event(interp, handler_sub,
+                            "vPP", handler, task);
+                }
+            }
+            else {
+                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                        "Unknown task type '%Ss'.\n", type);
             }
-        }
-        else {
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-                "Unknown task type '%Ss'.\n", type);
-        }
 
-        Parrot_cx_delete_task(interp, task);
+            Parrot_cx_delete_task(interp, task);
         }
 
         /* If the scheduler was flagged to terminate, make sure you process all
@@ -1008,7 +1008,7 @@
 #if PARROT_HAS_THREADS
     Parrot_cond condition;
     Parrot_mutex lock;
-    FLOATVAL timer_end = time + Parrot_floatval_time();
+    const FLOATVAL timer_end = time + Parrot_floatval_time();
     struct timespec time_struct;
 
     /* Tell the scheduler runloop to wake, this is a good time to process
@@ -1029,7 +1029,7 @@
     /* A more primitive, platform-specific, non-threaded form of sleep. */
     if (time > 1000) {
         /* prevent integer overflow when converting to microseconds */
-        int seconds = floor(time);
+        const int seconds = floor(time);
         Parrot_sleep(seconds);
         time -= seconds;
     }

Modified: branches/pmc_pct/src/stacks.c
==============================================================================
--- branches/pmc_pct/src/stacks.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/stacks.c	Fri May 15 21:49:40 2009	(r38803)
@@ -74,13 +74,12 @@
 cst_new_stack_chunk(PARROT_INTERP, ARGIN(const Stack_Chunk_t *chunk))
 {
     ASSERT_ARGS(cst_new_stack_chunk)
-    Small_Object_Pool * const pool = chunk->pool;
-    Stack_Chunk_t * const new_chunk = (Stack_Chunk_t *)pool->get_free_object(interp, pool);
+    Stack_Chunk_t * const new_chunk =
+        (Stack_Chunk_t *)Parrot_gc_new_bufferlike_header(interp, sizeof (Stack_Chunk_t));
 
     PObj_bufstart(new_chunk) = NULL;
     PObj_buflen(new_chunk)   = 0;
 
-    new_chunk->pool          = chunk->pool;
     new_chunk->name          = chunk->name;
 
     return new_chunk;
@@ -104,12 +103,11 @@
 new_stack(PARROT_INTERP, ARGIN(const char *name))
 {
     ASSERT_ARGS(new_stack)
-    Small_Object_Pool * const pool = get_bufferlike_pool(interp, sizeof (Stack_Chunk_t));
-    Stack_Chunk_t     * const chunk = (Stack_Chunk_t *)(pool->get_free_object)(interp, pool);
+    Stack_Chunk_t * const chunk =
+        (Stack_Chunk_t *)Parrot_gc_new_bufferlike_header(interp, sizeof (Stack_Chunk_t));
 
     chunk->prev = chunk;        /* mark the top of the stack */
     chunk->name = name;
-    chunk->pool = pool;         /* cache the pool pointer, for ease */
 
     return chunk;
 }
@@ -133,7 +131,7 @@
     for (; ; chunk = chunk->prev) {
         Stack_Entry_t  *entry;
 
-        pobject_lives(interp, (PObj *)chunk);
+        Parrot_gc_mark_PObj_alive(interp, (PObj *)chunk);
 
         if (chunk == chunk->prev)
             break;
@@ -141,7 +139,7 @@
         entry = STACK_DATAP(chunk);
 
         if (entry->entry_type == STACK_ENTRY_PMC && UVal_pmc(entry->entry))
-            pobject_lives(interp, (PObj *)UVal_pmc(entry->entry));
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)UVal_pmc(entry->entry));
     }
 }
 
@@ -371,12 +369,8 @@
     }
 
     /* recycle this chunk to the free list if it's otherwise unreferenced */
-    if (cur_chunk->refcount <= 0) {
-        Small_Object_Pool * const pool = cur_chunk->pool;
-
-        pool->gc_object(interp, pool, (PObj *)cur_chunk);
-        pool->add_free_object(interp, pool, (PObj *)cur_chunk);
-    }
+    if (cur_chunk->refcount <= 0)
+        Parrot_gc_free_bufferlike_header(interp, (PObj *)cur_chunk, sizeof (Stack_Chunk_t));
 
     return where;
 }

Modified: branches/pmc_pct/src/string/api.c
==============================================================================
--- branches/pmc_pct/src/string/api.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/string/api.c	Fri May 15 21:49:40 2009	(r38803)
@@ -27,7 +27,6 @@
 #include "parrot/compiler.h"
 #include "parrot/string_funcs.h"
 #include "private_cstring.h"
-#include "parrot/resources.h"
 
 #define nonnull_encoding_name(s) (s) ? (s)->encoding->name : "null string"
 #define saneify_string(s) \
@@ -89,7 +88,7 @@
          * also be sure not to allocate from the constant pool
          */
         PObj_flags_CLEARALL(&for_alloc);
-        Parrot_allocate_string(interp, &for_alloc, PObj_buflen(s));
+        Parrot_gc_allocate_string_storage(interp, &for_alloc, PObj_buflen(s));
 
         /* now copy memory over */
         mem_sys_memcopy(for_alloc.strstart, s->strstart, s->bufused);
@@ -128,7 +127,8 @@
     STRING *d;
 
     if (PObj_constant_TEST(s)) {
-        d = new_string_header(interp, PObj_get_FLAGS(s) & ~PObj_constant_FLAG);
+        d = Parrot_gc_new_string_header(interp,
+            PObj_get_FLAGS(s) & ~PObj_constant_FLAG);
         PObj_COW_SET(s);
         STRUCT_COPY(d, s);
         /* we can't move the memory, because constants aren't
@@ -139,7 +139,7 @@
         PObj_external_SET(d);
     }
     else {
-        d = new_string_header(interp, PObj_get_FLAGS(s));
+        d = Parrot_gc_new_string_header(interp, PObj_get_FLAGS(s));
         PObj_COW_SET(s);
         STRUCT_COPY(d, s);
         PObj_sysmem_CLEAR(d);
@@ -147,7 +147,7 @@
         /* XXX FIXME hack to avoid cross-interpreter issue until it
          * is fixed correctly. */
         if (n_interpreters > 1 && PObj_is_movable_TESTALL(s) &&
-                !Parrot_in_memory_pool(interp, PObj_bufstart(s))) {
+                !Parrot_gc_ptr_in_memory_pool(interp, PObj_bufstart(s))) {
             Parrot_str_write_COW(interp, d);
             Parrot_io_eprintf(interp, "cross-interpreter copy of "
                                      "relocatable string '%Ss' into tid %d\n",
@@ -242,10 +242,7 @@
 Parrot_str_free(PARROT_INTERP, ARGIN(STRING *s))
 {
     ASSERT_ARGS(Parrot_str_free)
-    if (!PObj_constant_TEST(s)) {
-        Small_Object_Pool * const pool = interp->arena_base->string_header_pool;
-        pool->add_free_object(interp, pool, s);
-    }
+    Parrot_gc_free_string_header(interp, s);
 }
 
 /*
@@ -285,14 +282,8 @@
         interp->hash_seed = Parrot_uint_rand(0);
     }
 
-    /* Set up the cstring cache, then load the basic encodings and charsets */
-    if (!interp->parent_interpreter) {
-        const_cstring_hash = parrot_new_cstring_hash(interp);
-        interp->const_cstring_hash  = const_cstring_hash;
-        Parrot_charsets_encodings_init(interp);
-    }
     /* initialize the constant string table */
-    else {
+    if (interp->parent_interpreter) {
         interp->const_cstring_table =
             interp->parent_interpreter->const_cstring_table;
         interp->const_cstring_hash  =
@@ -300,6 +291,11 @@
         return;
     }
 
+    /* Set up the cstring cache, then load the basic encodings and charsets */
+    const_cstring_hash          = parrot_new_cstring_hash(interp);
+    interp->const_cstring_hash  = const_cstring_hash;
+    Parrot_charsets_encodings_init(interp);
+
     interp->const_cstring_table =
         mem_allocate_n_zeroed_typed(n_parrot_cstrings, STRING *);
 
@@ -382,7 +378,7 @@
     parrot_string_representation_t representation, UINTVAL capacity)
 {
     ASSERT_ARGS(Parrot_str_new_noinit)
-    STRING * const s = new_string_header(interp, 0);
+    STRING * const s = Parrot_gc_new_string_header(interp, 0);
 
     /* TODO adapt string creation functions */
     if (representation != enum_stringrep_one)
@@ -392,7 +388,7 @@
     s->charset  = PARROT_DEFAULT_CHARSET;
     s->encoding = CHARSET_GET_PREFERRED_ENCODING(interp, s);
 
-    Parrot_allocate_string(interp, s,
+    Parrot_gc_allocate_string_storage(interp, s,
         (size_t)string_max_bytes(interp, s, capacity));
 
     return s;
@@ -568,7 +564,7 @@
         /* upgrade to utf16 */
         Parrot_utf16_encoding_ptr->to_encoding(interp, a, NULL);
         b = Parrot_utf16_encoding_ptr->to_encoding(interp, b,
-                new_string_header(interp, 0));
+                Parrot_gc_new_string_header(interp, 0));
 
         /* result could be mixed ucs2 / utf16 */
         if (b->encoding == Parrot_utf16_encoding_ptr)
@@ -581,7 +577,7 @@
 
     /* make sure A's big enough for both  */
     if (total_length > a_capacity)
-        Parrot_reallocate_string(interp, a, total_length << 1);
+        Parrot_gc_reallocate_string_storage(interp, a, total_length << 1);
 
     /* A is now ready to receive the contents of B */
 
@@ -761,7 +757,7 @@
 {
     ASSERT_ARGS(Parrot_str_new_init)
     DECL_CONST_CAST;
-    STRING * const s = new_string_header(interp, flags);
+    STRING * const s = Parrot_gc_new_string_header(interp, flags);
     s->encoding      = encoding;
     s->charset       = charset;
 
@@ -786,7 +782,7 @@
         return s;
     }
 
-    Parrot_allocate_string(interp, s, len);
+    Parrot_gc_allocate_string_storage(interp, s, len);
 
     if (buffer) {
         mem_sys_memcopy(s->strstart, buffer, len);
@@ -823,7 +819,7 @@
     Parrot_str_write_COW(interp, s);
 
     /* Don't check buflen, if we are here, we already checked. */
-    Parrot_reallocate_string(interp,
+    Parrot_gc_reallocate_string_storage(interp,
         s, PObj_buflen(s) + string_max_bytes(interp, s, addlen));
     return s;
 }
@@ -1267,7 +1263,7 @@
     if (!cs) {
         Parrot_utf16_encoding_ptr->to_encoding(interp, src, NULL);
         rep = Parrot_utf16_encoding_ptr->to_encoding(interp, rep,
-                new_string_header(interp, 0));
+                Parrot_gc_new_string_header(interp, 0));
     }
     else {
         src->charset  = cs;
@@ -1612,7 +1608,7 @@
 #if ! DISABLE_GC_DEBUG
     /* trigger GC for debug */
     if (interp && GC_DEBUG(interp))
-        Parrot_do_gc_run(interp, GC_trace_stack_FLAG);
+        Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
     make_writable(interp, &res, minlen, enum_stringrep_one);
@@ -1765,7 +1761,7 @@
 #if ! DISABLE_GC_DEBUG
     /* trigger GC for debug */
     if (interp && GC_DEBUG(interp))
-        Parrot_do_gc_run(interp, GC_trace_stack_FLAG);
+        Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
     make_writable(interp, &res, maxlen, enum_stringrep_one);
@@ -1841,7 +1837,7 @@
 #if ! DISABLE_GC_DEBUG
     /* trigger GC for debug */
     if (interp && GC_DEBUG(interp))
-        Parrot_do_gc_run(interp, GC_trace_stack_FLAG);
+        Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
     make_writable(interp, &res, maxlen, enum_stringrep_one);
@@ -1920,7 +1916,7 @@
 #if ! DISABLE_GC_DEBUG
     /* trigger GC for debug */
     if (interp && GC_DEBUG(interp))
-        Parrot_do_gc_run(interp, GC_trace_stack_FLAG);
+        Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 #endif
 
     make_writable(interp, &res, len, enum_stringrep_one);
@@ -2095,12 +2091,10 @@
 Parrot_str_to_num(PARROT_INTERP, ARGIN(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_to_num)
-    FLOATVAL    f = 0.0;
+    FLOATVAL    f;
     char       *cstr;
     const char *p;
 
-    DECL_CONST_CAST;
-
     /*
      * XXX C99 atof interprets 0x prefix
      * XXX would strtod() be better for detecting malformed input?
@@ -2328,13 +2322,13 @@
     memory = PObj_bufstart(s);
 
     /* Reallocate it the same size
-     * NOTE can't use Parrot_reallocate_string because of the LEA
+     * NOTE can't use Parrot_gc_reallocate_string_storage because of the LEA
      * allocator, where this is a noop for the same size
      *
      * We have to block GC here, as we have a pointer to bufstart
      */
     Parrot_block_GC_sweep(interp);
-    Parrot_allocate_string(interp, s, size);
+    Parrot_gc_allocate_string_storage(interp, s, size);
     Parrot_unblock_GC_sweep(interp);
     mem_sys_memcopy(PObj_bufstart(s), memory, size);
 
@@ -2456,7 +2450,7 @@
             if (i >= charlen - 2) {
                 /* resize - still len codepoints to go */
                 charlen += len * 2 + 16;
-                Parrot_reallocate_string(interp, result, charlen);
+                Parrot_gc_reallocate_string_storage(interp, result, charlen);
                 /* start can change */
                 dp = (unsigned char *)result->strstart;
             }

Modified: branches/pmc_pct/src/string/charset/ascii.c
==============================================================================
--- branches/pmc_pct/src/string/charset/ascii.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/string/charset/ascii.c	Fri May 15 21:49:40 2009	(r38803)
@@ -268,7 +268,7 @@
     const UINTVAL len = src->strlen;
 
     if (dest) {
-        Parrot_reallocate_string(interp, dest, len);
+        Parrot_gc_reallocate_string_storage(interp, dest, len);
     }
     else {
         /* the string can't grow - replace inplace */
@@ -308,7 +308,7 @@
     if (dest) {
         dest->charset = Parrot_unicode_charset_ptr;
         dest->encoding = CHARSET_GET_PREFERRED_ENCODING(interp, dest);
-        Parrot_reallocate_string(interp, dest, src->strlen);
+        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
         return dest;
     }
     else {
@@ -913,7 +913,7 @@
     if (dest) {
         UINTVAL offs;
 
-        Parrot_reallocate_string(interp, dest, src->strlen);
+        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
         dest->bufused = src->bufused;
         dest->strlen  = src->strlen;
         for (offs = 0; offs < src->strlen; ++offs) {
@@ -946,7 +946,7 @@
     if (dest) {
         UINTVAL offs;
 
-        Parrot_reallocate_string(interp, dest, src->strlen);
+        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
         dest->bufused = src->bufused;
         dest->strlen  = src->strlen;
         for (offs = 0; offs < src->strlen; ++offs) {

Modified: branches/pmc_pct/src/string/charset/iso-8859-1.c
==============================================================================
--- branches/pmc_pct/src/string/charset/iso-8859-1.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/string/charset/iso-8859-1.c	Fri May 15 21:49:40 2009	(r38803)
@@ -221,7 +221,7 @@
     ENCODING_ITER_INIT(interp, src, &iter);
     src_len = src->strlen;
     if (dest) {
-        Parrot_reallocate_string(interp, dest, src_len);
+        Parrot_gc_reallocate_string_storage(interp, dest, src_len);
         dest->strlen  = src_len;
     }
     else {
@@ -263,7 +263,7 @@
 
         dest->charset = Parrot_unicode_charset_ptr;
         dest->encoding = CHARSET_GET_PREFERRED_ENCODING(interp, dest);
-        Parrot_reallocate_string(interp, dest, src->strlen);
+        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
         ENCODING_ITER_INIT(interp, dest, &iter);
         for (offs = 0; offs < src->strlen; ++offs) {
             const UINTVAL c = ENCODING_GET_BYTE(interp, src, offs);
@@ -272,7 +272,7 @@
                 UINTVAL need = (UINTVAL)((src->strlen - offs) * 1.5);
                 if (need < 16)
                     need = 16;
-                Parrot_reallocate_string(interp, dest,
+                Parrot_gc_reallocate_string_storage(interp, dest,
                         PObj_buflen(dest) + need);
             }
             iter.set_and_advance(interp, &iter, c);
@@ -731,7 +731,7 @@
     ASSERT_ARGS(charset_cvt_iso_8859_1_to_ascii)
     UINTVAL offs;
     if (dest) {
-        Parrot_reallocate_string(interp, dest, src->strlen);
+        Parrot_gc_reallocate_string_storage(interp, dest, src->strlen);
         dest->bufused = src->bufused;
         dest->strlen  = src->strlen;
     }

Modified: branches/pmc_pct/src/string/charset/unicode.c
==============================================================================
--- branches/pmc_pct/src/string/charset/unicode.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/string/charset/unicode.c	Fri May 15 21:49:40 2009	(r38803)
@@ -360,7 +360,7 @@
 
     if (!U_SUCCESS(err)) {
         err = U_ZERO_ERROR;
-        Parrot_reallocate_string(interp, dest, dest->bufused);
+        Parrot_gc_reallocate_string_storage(interp, dest, dest->bufused);
         dest_len = unorm_normalize((UChar *)src->strstart, src_len,
                 UNORM_DEFAULT,      /* default is NFC */
                 0,                  /* options 0 default - no specific
@@ -464,7 +464,7 @@
             &err);
 
     if (needed > dest_len) {
-        Parrot_reallocate_string(interp, src, needed * sizeof (UChar));
+        Parrot_gc_reallocate_string_storage(interp, src, needed * sizeof (UChar));
         dest_len = needed;
     }
 
@@ -539,7 +539,7 @@
 
     if (!U_SUCCESS(err)) {
         err = U_ZERO_ERROR;
-        Parrot_reallocate_string(interp, src, src->bufused);
+        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
         dest_len = u_strToLower((UChar *)src->strstart, dest_len,
                 (UChar *)src->strstart, src_len,
                 NULL,       /* locale = default */
@@ -607,7 +607,7 @@
 
     if (!U_SUCCESS(err)) {
         err = U_ZERO_ERROR;
-        Parrot_reallocate_string(interp, src, src->bufused);
+        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
         dest_len = u_strToTitle((UChar *)src->strstart, dest_len,
                 (UChar *)src->strstart, src_len,
                 NULL, NULL,

Modified: branches/pmc_pct/src/string/encoding/utf16.c
==============================================================================
--- branches/pmc_pct/src/string/encoding/utf16.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/string/encoding/utf16.c	Fri May 15 21:49:40 2009	(r38803)
@@ -286,7 +286,7 @@
         p = (UChar *)mem_sys_allocate(src_len * sizeof (UChar));
     }
     else {
-        Parrot_reallocate_string(interp, dest, sizeof (UChar) * src_len);
+        Parrot_gc_reallocate_string_storage(interp, dest, sizeof (UChar) * src_len);
         p = (UChar *)dest->strstart;
     }
     if (src->charset == Parrot_iso_8859_1_charset_ptr ||
@@ -307,7 +307,7 @@
                 p = (UChar *)mem_sys_realloc(p, dest_len * sizeof (UChar));
             else {
                 result->bufused = dest_len * sizeof (UChar);
-                Parrot_reallocate_string(interp, dest,
+                Parrot_gc_reallocate_string_storage(interp, dest,
                                          sizeof (UChar) * dest_len);
                 p = (UChar *)dest->strstart;
             }
@@ -318,7 +318,7 @@
     }
     result->bufused = dest_len * sizeof (UChar);
     if (in_place) {
-        Parrot_reallocate_string(interp, src, src->bufused);
+        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
         memcpy(src->strstart, p, src->bufused);
         mem_sys_free(p);
     }

Modified: branches/pmc_pct/src/string/encoding/utf8.c
==============================================================================
--- branches/pmc_pct/src/string/encoding/utf8.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/string/encoding/utf8.c	Fri May 15 21:49:40 2009	(r38803)
@@ -596,7 +596,7 @@
         p = (unsigned char *)mem_sys_allocate(src_len);
     }
     else {
-        Parrot_reallocate_string(interp, dest, src_len);
+        Parrot_gc_reallocate_string_storage(interp, dest, src_len);
         p = (unsigned char *)dest->strstart;
     }
     if (src->charset == Parrot_ascii_charset_ptr) {
@@ -619,7 +619,7 @@
                     p = (unsigned char *)mem_sys_realloc(p, dest_len);
                 else {
                     result->bufused = dest_pos;
-                    Parrot_reallocate_string(interp, dest, dest_len);
+                    Parrot_gc_reallocate_string_storage(interp, dest, dest_len);
                     p = (unsigned char *)dest->strstart;
                 }
             }
@@ -631,7 +631,7 @@
         result->bufused = dest_pos;
     }
     if (in_place) {
-        Parrot_reallocate_string(interp, src, src->bufused);
+        Parrot_gc_reallocate_string_storage(interp, src, src->bufused);
         memcpy(src->strstart, p, src->bufused);
         mem_sys_free(p);
     }

Modified: branches/pmc_pct/src/sub.c
==============================================================================
--- branches/pmc_pct/src/sub.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/sub.c	Fri May 15 21:49:40 2009	(r38803)
@@ -80,15 +80,15 @@
 
     obj = (PObj *)ctx->current_sub;
     if (obj)
-        pobject_lives(interp, obj);
+        Parrot_gc_mark_PObj_alive(interp, obj);
 
     obj = (PObj *)ctx->current_object;
     if (obj)
-        pobject_lives(interp, obj);
+        Parrot_gc_mark_PObj_alive(interp, obj);
 
     obj = (PObj *)ctx->current_cont;
     if (obj && !PObj_live_TEST(obj))
-        pobject_lives(interp, obj);
+        Parrot_gc_mark_PObj_alive(interp, obj);
 
     if (ctx->caller_ctx)
         mark_context(interp, ctx->caller_ctx);
@@ -98,15 +98,15 @@
 
     obj = (PObj *)ctx->current_namespace;
     if (obj)
-        pobject_lives(interp, obj);
+        Parrot_gc_mark_PObj_alive(interp, obj);
 
     obj = (PObj *)ctx->lex_pad;
     if (obj)
-        pobject_lives(interp, obj);
+        Parrot_gc_mark_PObj_alive(interp, obj);
 
     obj = (PObj *)ctx->handlers;
     if (obj)
-        pobject_lives(interp, obj);
+        Parrot_gc_mark_PObj_alive(interp, obj);
 
 
     if (!ctx->n_regs_used)
@@ -115,7 +115,7 @@
     for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; ++i) {
         obj = (PObj *)CTX_REG_PMC(ctx, i);
         if (obj)
-            pobject_lives(interp, obj);
+            Parrot_gc_mark_PObj_alive(interp, obj);
     }
 
     for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
@@ -125,7 +125,7 @@
              * yet tracked down */
             PObj_flag_CLEAR(is_PMC, obj);
             PObj_is_string_SET(obj);
-            pobject_lives(interp, obj);
+            Parrot_gc_mark_PObj_alive(interp, obj);
         }
     }
 }
@@ -351,7 +351,7 @@
         }
         else {
             PMC    *ns_array;
-            STRING *j = CONST_STRING(interp, ";");
+            STRING * const semicolon = CONST_STRING(interp, ";");
             STRING *res;
 
             /*
@@ -384,7 +384,7 @@
             if (sub->name)
                 VTABLE_push_string(interp, ns_array, sub->name);
 
-            res = Parrot_str_join(interp, j, ns_array);
+            res = Parrot_str_join(interp, semicolon, ns_array);
             Parrot_unblock_GC_mark(interp);
             return res;
         }
@@ -412,7 +412,6 @@
 {
     ASSERT_ARGS(Parrot_Context_get_info)
     Parrot_sub *sub;
-    DECL_CONST_CAST;
 
     /* set file/line/pc defaults */
     info->file     = CONST_STRING(interp, "(unknown file)");
@@ -512,7 +511,6 @@
 
     Parrot_block_GC_mark(interp);
     if (Parrot_Context_get_info(interp, ctx, &info)) {
-        DECL_CONST_CAST;
 
         res = Parrot_sprintf_c(interp,
             "%s '%Ss' pc %d (%Ss:%d)", msg,

Modified: branches/pmc_pct/src/thread.c
==============================================================================
--- branches/pmc_pct/src/thread.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/thread.c	Fri May 15 21:49:40 2009	(r38803)
@@ -352,7 +352,7 @@
     if (is_ro)
         pmc->vtable = pmc->vtable->ro_variant_vtable;
 
-    add_pmc_sync(interp, pmc);
+    Parrot_gc_add_pmc_sync(interp, pmc);
 
     PObj_is_PMC_shared_SET(pmc);
 
@@ -1260,7 +1260,7 @@
 {
     ASSERT_ARGS(pt_suspend_self_for_gc)
     PARROT_ASSERT(interp);
-    PARROT_ASSERT(!interp->arena_base->gc_mark_block_level);
+    PARROT_ASSERT(!Parrot_is_blocked_GC_mark(interp));
     DEBUG_ONLY(fprintf(stderr, "%p: suspend_self_for_gc\n", interp));
     /* since we are modifying our own state, we need to lock
      * the interpreter_array_mutex.
@@ -1288,7 +1288,7 @@
     /* mark and sweep our world -- later callbacks will keep
      * it sync'd
      */
-    Parrot_gc_ms_run(interp, GC_trace_stack_FLAG);
+    Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
 
     PARROT_ASSERT(!(interp->thread_data->state & THREAD_STATE_SUSPENDED_GC));
 }

Modified: branches/pmc_pct/src/utils.c
==============================================================================
--- branches/pmc_pct/src/utils.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/utils.c	Fri May 15 21:49:40 2009	(r38803)
@@ -892,6 +892,9 @@
 
 =item C<static INTVAL COMPARE(PARROT_INTERP, void *a, void *b, PMC *cmp)>
 
+General PMC comparison function. Takes two PMCs. Returns 0 if they are equal,
+returns 1 if C<a> is bigger, and returns -1 if C<b> is bigger.
+
 =cut
 
 */
@@ -918,6 +921,8 @@
 
 =item C<void Parrot_quicksort(PARROT_INTERP, void **data, UINTVAL n, PMC *cmp)>
 
+Perform a quicksort on a PMC array.
+
 =cut
 
 */

Modified: branches/pmc_pct/src/vtables.c
==============================================================================
--- branches/pmc_pct/src/vtables.c	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/src/vtables.c	Fri May 15 21:49:40 2009	(r38803)
@@ -209,15 +209,15 @@
             continue;
 
         if (vtable->mro)
-            pobject_lives(interp, (PObj *)vtable->mro);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)vtable->mro);
         if (vtable->_namespace)
-            pobject_lives(interp, (PObj *)vtable->_namespace);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)vtable->_namespace);
         if (vtable->whoami)
-            pobject_lives(interp, (PObj *)vtable->whoami);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)vtable->whoami);
         if (vtable->provides_str)
-            pobject_lives(interp, (PObj *)vtable->provides_str);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)vtable->provides_str);
         if (vtable->pmc_class)
-            pobject_lives(interp, (PObj *)vtable->pmc_class);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)vtable->pmc_class);
     }
 }
 

Modified: branches/pmc_pct/t/codingstd/c_function_docs.t
==============================================================================
--- branches/pmc_pct/t/codingstd/c_function_docs.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/codingstd/c_function_docs.t	Fri May 15 21:49:40 2009	(r38803)
@@ -58,10 +58,8 @@
 
         my $escaped_decl = $headerizer->generate_documentation_signature($function_decl);
 
-        my $decl_rx = qr/^\Q$escaped_decl\E$(.*?)^=cut/sm;
-
         my $missing = '';
-        if ( $buf =~ m/$decl_rx/) {
+        if ( $buf =~ m/^\Q$escaped_decl\E$(.*?)^=cut/sm ) {
             my $docs = $1;
             $docs =~ s/\s//g;
             if ($docs eq '') {
@@ -130,30 +128,20 @@
 src/debug.c
 src/gc/res_lea.c
 src/io/io_string.c
-src/io/socket_api.c
-src/io/socket_unix.c
-src/io/socket_win32.c
 src/jit/amd64/jit_defs.c
 src/jit/arm/exec_dep.c
 src/jit/i386/exec_dep.c
 src/jit/ppc/exec_dep.c
-src/malloc-trace.c
-src/multidispatch.c
 src/nci_test.c
-src/oo.c
-src/packfile.c
-src/parrot_debugger.c
 src/pbc_dump.c
 src/pbc_info.c
 src/pic.c
 src/pic_jit.c
-src/pmc.c
 src/string/charset/ascii.c
 src/string/charset/binary.c
 src/string/charset/iso-8859-1.c
 src/string/charset/unicode.c
 src/tsq.c
-src/utils.c
 src/jit/alpha/jit_emit.h
 src/jit/arm/jit_emit.h
 src/jit/hppa/jit_emit.h

Modified: branches/pmc_pct/t/codingstd/copyright.t
==============================================================================
--- branches/pmc_pct/t/codingstd/copyright.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/codingstd/copyright.t	Fri May 15 21:49:40 2009	(r38803)
@@ -51,7 +51,7 @@
 my $copyright_simple =
     qr/Copyright \(C\) \d{4}/i;
 my $copyright_parrot =
-    qr/Copyright \(C\) (?:\d{4}\-)?\d{4}, Parrot Foundation\.$/m;
+    qr/Copyright \(C\) (?:\d{4}\-)?\d{4}, Parrot Foundation\.$/;
 
 foreach my $file (@files) {
 
@@ -69,7 +69,7 @@
 
     # is the copyright text correct?
     # If so, remove it...
-    if ( ! ($buf =~ s/$copyright_parrot//) ) {
+    if ( ! ($buf =~ s/$copyright_parrot//m) ) {
         push @bad_format_copyright_files, $path;
     }
     # ... and then see if any other copyright notices exist.
@@ -159,6 +159,9 @@
     grep { ! $permitted_duplicate_copyright_files{ $_ } }
         @duplicate_copyright_files;
 
+TODO: {
+    local $TODO = 'duplicate copyrights exist.';
+
 ok( !scalar(@non_permitted_duplicate_copyright_files),
     'Duplicate Copyright statements' )
     or diag(
@@ -171,6 +174,7 @@
     "and remove alternate notice; or remove duplicated",
     "notice for Parrot Foundation."
     );
+}
 
 # Local Variables:
 #   mode: cperl

Modified: branches/pmc_pct/t/compilers/imcc/syn/regressions.t
==============================================================================
--- branches/pmc_pct/t/compilers/imcc/syn/regressions.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/imcc/syn/regressions.t	Fri May 15 21:49:40 2009	(r38803)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 10;
+use Parrot::Test tests => 14;
 
 pir_error_output_like( <<'CODE', <<'OUT', 'invalid get_results syntax');
 .sub main :main
@@ -138,6 +138,53 @@
 hello world
 OUT
 
+pir_output_is( <<'CODE', <<'OUT', 'unicode named identifiers (TT #654)');
+ .sub 'main' :main
+    'foo'(1 :named(unicode:"\x{e4}"))
+ .end
+
+ # Perl 6:  sub foo(:$ä) { say "ok $ä"; }
+ .sub 'foo'
+    .param int x :named(unicode:"\x{e4}")
+    print "ok "
+    say x
+ .end
+CODE
+ok 1
+OUT
+
+my $register = "9" x 4096;
+pir_output_is( <<"CODE", <<'OUT', 'long register numbers in PIR (RT #41788)');
+.sub main
+      \$P$register = new 'Integer'
+      \$P$register = 3
+  say \$P$register
+.end
+CODE
+3
+OUT
+
+TODO: {
+    local $TODO = "works in PIR, not PASM";
+
+pasm_output_is( <<"CODE", <<'OUT', 'long register numbers in PASM (RT #41788)');
+      new P$register, 'Integer'
+      assign P$register, 3
+  say P$register
+CODE
+3
+OUT
+
+}
+
+pir_error_output_like( <<'CODE', <<'OUT', 'die in immediate, TT#629');
+.sub 'foo' :immediate
+  die 'no'
+.end
+CODE
+/no\ncurrent inst.*:2\)$/
+OUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Modified: branches/pmc_pct/t/compilers/imcc/syn/subflags.t
==============================================================================
--- branches/pmc_pct/t/compilers/imcc/syn/subflags.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/imcc/syn/subflags.t	Fri May 15 21:49:40 2009	(r38803)
@@ -17,7 +17,7 @@
 .namespace ['FlagTest']
 
 .sub 'main' :main
-    load_bytecode 'library/Test/More.pbc'
+    load_bytecode 'Test/More.pbc'
 
     .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace

Modified: branches/pmc_pct/t/compilers/json/to_parrot.t
==============================================================================
--- branches/pmc_pct/t/compilers/json/to_parrot.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/json/to_parrot.t	Fri May 15 21:49:40 2009	(r38803)
@@ -690,7 +690,7 @@
 
 .sub test :main
     load_bytecode 'compilers/json/JSON.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
 
     .local pmc JSON, result
     JSON = compreg "JSON"

Modified: branches/pmc_pct/t/compilers/pct/past.t
==============================================================================
--- branches/pmc_pct/t/compilers/pct/past.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pct/past.t	Fri May 15 21:49:40 2009	(r38803)
@@ -1,6 +1,6 @@
 #! perl
 
-# Copyright (C) 2006-2008, Parrot Foundation.
+# Copyright (C) 2006-2009, Parrot Foundation.
 # $Id$
 
 use strict;
@@ -14,7 +14,7 @@
     my $code   = <<'CODE'
 .sub _main :main
     load_bytecode 'PCT.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
     .local pmc node
     .local pmc node2
 CODE
@@ -51,7 +51,7 @@
 pir_output_is( <<'CODE', <<'OUT', 'dump PAST::Val node in visual format' );
 .sub _main :main
     load_bytecode 'PCT.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
     .local pmc node
     node = new ['PAST';'Val']
     node.'value'(1)
@@ -78,7 +78,7 @@
 pir_output_is( <<'CODE', <<'OUT', 'dump PAST::Var node in visual format' );
 .sub _main :main
     load_bytecode 'PCT.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
     .local pmc node
     node = new ['PAST';'Var']
     node.'scope'('foo')
@@ -98,7 +98,7 @@
 pir_output_is( <<'CODE', <<'OUT', 'dump PAST::Op node in visual format' );
 .sub _main :main
     load_bytecode 'PCT.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
     .local pmc node
     node = new ['PAST';'Op']
     node.'pasttype'('pirop')
@@ -120,7 +120,7 @@
 pir_output_is( <<'CODE', <<'OUT', 'dump PAST::Block node in visual format' );
 .sub _main :main
     load_bytecode 'PCT.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
     .local pmc node
     node = new ['PAST';'Block']
     node.'blocktype'('declaration')

Modified: branches/pmc_pct/t/compilers/pct/post.t
==============================================================================
--- branches/pmc_pct/t/compilers/pct/post.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pct/post.t	Fri May 15 21:49:40 2009	(r38803)
@@ -1,6 +1,6 @@
 #! perl
 
-# Copyright (C) 2006-2008, Parrot Foundation.
+# Copyright (C) 2006-2009, Parrot Foundation.
 # $Id$
 
 use strict;
@@ -13,7 +13,7 @@
     my $code   = <<'CODE'
 .sub _main
     load_bytecode 'PCT.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
     .local pmc node
     .local pmc node2
 CODE
@@ -50,7 +50,7 @@
 pir_output_is( <<'CODE', <<'OUT', 'dump POST::Op node in visual format' );
 .sub _main
     load_bytecode 'PCT.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
     .local pmc node
     node = new ['POST';'Op']
     node.'pirop'('add')
@@ -70,7 +70,7 @@
 pir_output_is( <<'CODE', <<'OUT', 'dump POST::Label node in visual format' );
 .sub _main
     load_bytecode 'PCT.pbc'
-    load_bytecode 'library/dumper.pbc'
+    load_bytecode 'dumper.pbc'
     .local pmc node
     node = new ['POST';'Label']
     node.'name'('labeler')

Modified: branches/pmc_pct/t/compilers/pge/00-basic.t
==============================================================================
--- branches/pmc_pct/t/compilers/pge/00-basic.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pge/00-basic.t	Fri May 15 21:49:40 2009	(r38803)
@@ -16,7 +16,7 @@
 =cut
 
 .sub main :main
-    load_bytecode 'Test/Builder.pir'
+    load_bytecode 'Test/Builder.pbc'
 
     .local pmc test
 

Modified: branches/pmc_pct/t/compilers/pge/03-optable.t
==============================================================================
--- branches/pmc_pct/t/compilers/pge/03-optable.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pge/03-optable.t	Fri May 15 21:49:40 2009	(r38803)
@@ -90,9 +90,9 @@
     my ( $test, $output, $msg, %opt ) = @_;
     my ($pir) = <<'CODE';
 .sub main :main
-    load_bytecode 'compilers/pge/PGE.pir'
-    load_bytecode 'dumper.pir'
-    load_bytecode 'PGE/Dumper.pir'
+    load_bytecode 'compilers/pge/PGE.pbc'
+    load_bytecode 'dumper.pbc'
+    load_bytecode 'PGE/Dumper.pbc'
 
     .local pmc optable
     $P0 = get_hll_global ['PGE'], 'OPTable'

Modified: branches/pmc_pct/t/compilers/pge/06-grammar.t
==============================================================================
--- branches/pmc_pct/t/compilers/pge/06-grammar.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pge/06-grammar.t	Fri May 15 21:49:40 2009	(r38803)
@@ -16,7 +16,7 @@
 =cut
 
 .sub main :main
-    load_bytecode 'Test/Builder.pir'
+    load_bytecode 'Test/Builder.pbc'
     load_bytecode 'PGE.pbc'
     load_bytecode 'PGE/Perl6Grammar.pbc'
     .include "iglobals.pasm"
@@ -120,7 +120,7 @@
     .param pmc    targets
     .param string description
 
-    load_bytecode 'Test/Builder.pir'
+    load_bytecode 'Test/Builder.pbc'
     .local pmc    test
                   test = new [ 'Test'; 'Builder' ]
 

Modified: branches/pmc_pct/t/compilers/pge/p5regex/p5rx.t
==============================================================================
--- branches/pmc_pct/t/compilers/pge/p5regex/p5rx.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pge/p5regex/p5rx.t	Fri May 15 21:49:40 2009	(r38803)
@@ -56,7 +56,7 @@
 .const int TESTS = 960
 
 .sub main :main
-    load_bytecode 'Test/Builder.pir'
+    load_bytecode 'Test/Builder.pbc'
     load_bytecode 'PGE.pbc'
     load_bytecode 'PGE/Dumper.pbc'
     .include 'iglobals.pasm'

Modified: branches/pmc_pct/t/compilers/pge/perl6regex/01-regex.t
==============================================================================
--- branches/pmc_pct/t/compilers/pge/perl6regex/01-regex.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pge/perl6regex/01-regex.t	Fri May 15 21:49:40 2009	(r38803)
@@ -55,7 +55,7 @@
 .const string TESTS = 'no_plan'
 
 .sub main :main
-    load_bytecode 'Test/Builder.pir'
+    load_bytecode 'Test/Builder.pbc'
     load_bytecode 'PGE.pbc'
     load_bytecode 'PGE/Dumper.pbc'
     load_bytecode 'String/Utils.pbc'

Modified: branches/pmc_pct/t/compilers/pge/perl6regex/context.t
==============================================================================
--- branches/pmc_pct/t/compilers/pge/perl6regex/context.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pge/perl6regex/context.t	Fri May 15 21:49:40 2009	(r38803)
@@ -27,10 +27,10 @@
 my $PRE = <<PRE;
 .sub 'main' :main
     load_bytecode "PGE.pbc"
-    load_bytecode "dumper.pir"
-    load_bytecode "PGE/Dumper.pir"
-    load_bytecode "PGE/Glob.pir"
-    load_bytecode "PGE/Text.pir"
+    load_bytecode "dumper.pbc"
+    load_bytecode "PGE/Dumper.pbc"
+    load_bytecode "PGE/Glob.pbc"
+    load_bytecode "PGE/Text.pbc"
     .local string target, pattern
     .local pmc perl6regex, rulesub, pir, exp, match
     perl6regex = compreg 'PGE::Perl6Regex'

Modified: branches/pmc_pct/t/compilers/pge/pge_text.t
==============================================================================
--- branches/pmc_pct/t/compilers/pge/pge_text.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pge/pge_text.t	Fri May 15 21:49:40 2009	(r38803)
@@ -30,7 +30,7 @@
     .local pmc bracketed
 
     load_bytecode 'PGE.pbc'
-    load_bytecode 'PGE/Text.pir'
+    load_bytecode 'PGE/Text.pbc'
 
     bracketed = get_global ['PGE';'Text'], "bracketed"
 

Modified: branches/pmc_pct/t/compilers/pge/pge_util.t
==============================================================================
--- branches/pmc_pct/t/compilers/pge/pge_util.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/compilers/pge/pge_util.t	Fri May 15 21:49:40 2009	(r38803)
@@ -30,7 +30,7 @@
 
 .sub main :main
   load_bytecode 'PGE.pbc'
-  load_bytecode 'PGE/Util.pir'
+  load_bytecode 'PGE/Util.pbc'
 
   .local pmc split, p6rule, regex
   split  = get_global ['PGE';'Util'], 'split'
@@ -53,7 +53,7 @@
 
 .sub main :main
   load_bytecode 'PGE.pbc'
-  load_bytecode 'PGE/Util.pir'
+  load_bytecode 'PGE/Util.pbc'
 
   .local pmc split, p6rule, regex
   split  = get_global ['PGE';'Util'], 'split'
@@ -74,7 +74,7 @@
 
 .sub main :main
   load_bytecode 'PGE.pbc'
-  load_bytecode 'PGE/Util.pir'
+  load_bytecode 'PGE/Util.pbc'
 
   .local pmc split, p6rule, regex
   split  = get_global ['PGE';'Util'], 'split'
@@ -96,7 +96,7 @@
 
 .sub main :main
   load_bytecode 'PGE.pbc'
-  load_bytecode 'PGE/Util.pir'
+  load_bytecode 'PGE/Util.pbc'
 
   .local pmc split, p6rule, regex
   split  = get_global ['PGE';'Util'], 'split'
@@ -117,7 +117,7 @@
 
 .sub main :main
   load_bytecode 'PGE.pbc'
-  load_bytecode 'PGE/Util.pir'
+  load_bytecode 'PGE/Util.pbc'
 
   .local pmc split, p6rule, regex
   split  = get_global ['PGE';'Util'], 'split'
@@ -140,7 +140,7 @@
 
 .sub main :main
   load_bytecode 'PGE.pbc'
-  load_bytecode 'PGE/Util.pir'
+  load_bytecode 'PGE/Util.pbc'
 
   .local pmc split, p6rule, regex
   split  = get_global ['PGE';'Util'], 'split'
@@ -162,7 +162,7 @@
 
 .sub main :main
   load_bytecode 'PGE.pbc'
-  load_bytecode 'PGE/Util.pir'
+  load_bytecode 'PGE/Util.pbc'
 
   .local pmc split, p6rule, regex
   split  = get_global ['PGE';'Util'], 'split'

Modified: branches/pmc_pct/t/dynpmc/pair.t
==============================================================================
--- branches/pmc_pct/t/dynpmc/pair.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/dynpmc/pair.t	Fri May 15 21:49:40 2009	(r38803)
@@ -6,7 +6,7 @@
 
 .sub main :main
     loadlib $P1, 'pair'
-    load_bytecode 'library/Test/More.pir'
+    load_bytecode 'Test/More.pbc'
 
     .local pmc plan, is, ok
     plan = get_hll_global [ 'Test'; 'More' ], 'plan'

Modified: branches/pmc_pct/t/examples/pod.t
==============================================================================
--- branches/pmc_pct/t/examples/pod.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/examples/pod.t	Fri May 15 21:49:40 2009	(r38803)
@@ -33,6 +33,13 @@
 sub compile_ok {
     my $snippet = shift;
 
+    # If it's a PIR fragment, wrap it in a sub.
+    if ($snippet->{type} eq "PIR" && $snippet->{modifier} =~ /FRAGMENT/) {
+        $snippet->{code} = ".sub 'testing'\n" .
+            $snippet->{code} .  "\n.end";
+    }
+
+    # Generate a temp file we can compile.
     my ($fh,$tempfile) = tempfile(
         SUFFIX => '.' . lc $snippet->{type},
         UNLINK => 1
@@ -40,14 +47,18 @@
     print {$fh} $snippet->{code};
     close $fh;
 
+    # Send the output to /dev/null; similar to perl5's -c
     my $cmd = File::Spec->curdir() . $PConfig{slash} .
               $PConfig{test_prog} . " -o " . File::Spec->devnull() . " " .
               $tempfile;
 
-    my $description = $snippet->{file} . ':' .$snippet->{line};
+    my $description = join (':', map {$snippet->{$_}}
+        qw(file line type modifier));
 
     TODO: {
-        local $TODO = $snippet->{todo} if $snippet->{todo};
+        # conditionally TODO the file.
+        local $TODO = "invalid code" if $snippet->{modifier} =~
+            /TODO|INVALID/;
         is(system($cmd), 0 , $description);
     }
 
@@ -78,12 +89,12 @@
                 $code .= $line;
             }
         }
-        elsif ( $line =~ /^=begin ((PIR|PASM)( .*)?)$/ ) {
+        elsif ( $line =~ /^=begin ((PIR|PASM)(_(.*))?)$/ ) {
             $in_code = 1;
             $snippet->{file} = $file;
             $snippet->{line} = $.;
             $snippet->{type} = $2;
-            $snippet->{todo} = $3;
+            $snippet->{modifier} = defined($4) ? $4 : '';
             $target = $1; 
         }
     }
@@ -93,6 +104,8 @@
     return @snippets;
 }
 
+__END__
+
 =head1 NAME
 
 t/examples/pod.t - Compile examples found in POD
@@ -111,6 +124,46 @@
 repository that contain POD.  Any invalid examples are reported in the
 test output.
 
+To test a snippet of parrot code, wrap it in C<=begin> and C<=end> blocks
+like:
+
+ =begin PASM
+
+   set I0, 0
+
+ =end PASM
+
+C<PASM> and C<PIR> are both valid target languages.
+
+Additionally, you can add the following modifiers (prepending with an 
+underscore).
+
+=over 4
+
+=item * FRAGMENT
+
+For PIR, wraps the code in a C<.sub> block to
+
+=item * TODO
+
+=item * INVALID
+
+Either of these will force the test to be marked TODO.
+
+=back
+
+For example, this PIR fragment uses an old, invalid opcode and needs
+to be updated:
+
+ =begin PIR_FRAGMENT_INVALID
+   
+    find_type $I1, 'Integer'
+
+ =end PIR_FRAGMENT_INVALID
+
+As show, you can "stack" the modifiers. Take care to make the begin and
+and end POD targets identical. Always begin with the target language.
+
 =cut
 
 # Local Variables:

Modified: branches/pmc_pct/t/library/coroutine.t
==============================================================================
--- branches/pmc_pct/t/library/coroutine.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/coroutine.t	Fri May 15 21:49:40 2009	(r38803)
@@ -182,13 +182,13 @@
 .end
 
 .sub main :main
-	load_bytecode 'Test/Builder.pir'
+	load_bytecode 'Test/Builder.pbc'
 	.local pmc test
 	test = new [ 'Test'; 'Builder' ]
 	test.'plan'(N_TESTS)
 
 	push_eh cant_load
-	load_bytecode 'Parrot/Coroutine.pir'
+	load_bytecode 'Parrot/Coroutine.pbc'
 	pop_eh
 	test.'ok'(1, 'loaded bytecode')
 

Modified: branches/pmc_pct/t/library/getopt_obj.t
==============================================================================
--- branches/pmc_pct/t/library/getopt_obj.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/getopt_obj.t	Fri May 15 21:49:40 2009	(r38803)
@@ -35,7 +35,7 @@
         push argv, '--bax=3'
         push argv, '--baz'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -94,7 +94,7 @@
         push argv, '-Abc'
         push argv, '-c'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -140,7 +140,7 @@
         push argv, '-Iinca'
         push argv, '-Iincb'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -174,7 +174,7 @@
         push argv, '-Iinca'
         push argv, '--include=incb'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -210,7 +210,7 @@
         push argv, '--define=bax=baz'
         push argv, '-Dfoobar'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -250,7 +250,7 @@
         argv = new 'ResizablePMCArray'
         push argv, '-abc'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -293,7 +293,7 @@
         push argv, '--ignore'
         push argv, '--foo'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
         getopts."notOptStop"(1)
@@ -328,7 +328,7 @@
         push argv, '--'
         push argv, '--bar'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -371,7 +371,7 @@
         push argv, 'foo'
         push argv, '--bar'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
         getopts."notOptStop"(1)
@@ -420,7 +420,7 @@
         push argv, '-f'
         push argv, '-bbar'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
         getopts."notOptStop"(1)
@@ -474,7 +474,7 @@
         push argv, '--bar'
         push argv, 'bar'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -522,7 +522,7 @@
         push argv, '-'
         push argv, '--bar'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -574,7 +574,7 @@
         push argv, '--define=bax=baz'
         push argv, '-Dfoobar'
 
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
 
@@ -657,7 +657,7 @@
         .local pmc argv
         argv = new 'ResizablePMCArray'
         push argv, '--foo=file'
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
         $P1 = getopts."get_options"(argv)
@@ -681,7 +681,7 @@
         argv = new 'ResizablePMCArray'
         push argv, '--foo=file'
         push argv, '--bar'
-        load_bytecode "Getopt/Obj.pir"
+        load_bytecode "Getopt/Obj.pbc"
         .local pmc getopts
         getopts = new "Getopt::Obj"
         push getopts, 'foo=s'

Modified: branches/pmc_pct/t/library/iter.t
==============================================================================
--- branches/pmc_pct/t/library/iter.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/iter.t	Fri May 15 21:49:40 2009	(r38803)
@@ -32,7 +32,7 @@
 
   T1:
     push_eh err_load_bytecode
-    $S0 = 'Iter.pir'
+    $S0 = 'Iter.pbc'
     load_bytecode $S0
     pop_eh
     $S1 = 'loaded '

Modified: branches/pmc_pct/t/library/mime_base64.t
==============================================================================
--- branches/pmc_pct/t/library/mime_base64.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/mime_base64.t	Fri May 15 21:49:40 2009	(r38803)
@@ -18,8 +18,8 @@
 
 .sub test :main
     load_bytecode "dumper.pbc"
-    load_bytecode 'Test/More.pir'
-    load_bytecode 'MIME/Base64.pir'
+    load_bytecode 'Test/More.pbc'
+    load_bytecode 'MIME/Base64.pbc'
     load_bytecode 'PGE.pbc'
     load_bytecode 'PGE/Util.pbc'
     load_bytecode 'compilers/json/JSON.pbc'

Modified: branches/pmc_pct/t/library/pcre.t
==============================================================================
--- branches/pmc_pct/t/library/pcre.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/pcre.t	Fri May 15 21:49:40 2009	(r38803)
@@ -61,7 +61,7 @@
     include_paths = lib_paths[2]
     unshift include_paths, '$pcre_libpath'
 
-    load_bytecode "pcre.pir"
+    load_bytecode 'pcre.pbc'
     .local pmc func
     .local pmc lib
 

Modified: branches/pmc_pct/t/library/range.t
==============================================================================
--- branches/pmc_pct/t/library/range.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/range.t	Fri May 15 21:49:40 2009	(r38803)
@@ -18,7 +18,7 @@
 
 .sub main :main
     .include 'test_more.pir'
-    load_bytecode 'Range.pir'
+    load_bytecode 'Range.pbc'
 
     plan(78)
 

Modified: branches/pmc_pct/t/library/streams.t
==============================================================================
--- branches/pmc_pct/t/library/streams.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/streams.t	Fri May 15 21:49:40 2009	(r38803)
@@ -30,14 +30,14 @@
     #
     # 1..8
     #
-    pir_output_is( <<"CODE", <<"OUT", "load and create a Stream::$a" );
+    pir_output_is( <<"CODE", <<"OUT", "load and create a Stream;$a" );
 
 .sub _main
     print "loading '$a'...\\n"
-    load_bytecode "library/Stream/$a.pir"
+    load_bytecode 'Stream/$a.pbc'
     print "loaded\\n"
 
-    \$P0 = new "Stream::$a"
+    \$P0 = new ['Stream'; '$a']
 
     \$S0 = typeof \$P0
     print "class name: '"
@@ -48,7 +48,7 @@
 CODE
 loading '$a'...
 loaded
-class name: 'Stream::$a'
+class name: 'Stream;$a'
 done
 OUT
 
@@ -57,14 +57,14 @@
 #
 # 9
 #
-pir_output_is( <<'CODE', <<'OUT', "Stream::Sub" );
+pir_output_is( <<'CODE', <<'OUT', "Stream;Sub" );
 
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "library/Stream/Sub.pir"
+    load_bytecode 'Stream/Sub.pbc'
 
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
 
     # set the stream's source sub   #'
     .const 'Sub' temp = "_hello"
@@ -108,15 +108,15 @@
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "library/Stream/Sub.pir"
-    load_bytecode "library/Stream/Replay.pir"
+    load_bytecode 'Stream/Sub.pbc'
+    load_bytecode 'Stream/Replay.pbc'
 
-    $P0 = new "Stream::Sub"
+    $P0 = new ['Stream'; 'Sub']
     # set the stream's source sub      #'
     .const 'Sub' temp = "_hello"
     assign $P0, temp
 
-    stream = new "Stream::Replay"
+    stream = new ['Stream'; 'Replay']
     assign stream, $P0
 
     $S0 = stream."read_bytes"( 3 )
@@ -185,23 +185,23 @@
     .local pmc text
     .local pmc combined
 
-    load_bytecode "library/Stream/Base.pir"
-    load_bytecode "library/Stream/Combiner.pir"
-    load_bytecode "library/Stream/Sub.pir"
+    load_bytecode 'Stream/Base.pbc'
+    load_bytecode 'Stream/Combiner.pbc'
+    load_bytecode 'Stream/Sub.pbc'
 
     # create the counter stream
-    counter = new "Stream::Sub"
+    counter = new ['Stream'; 'Sub']
     .const 'Sub' ct = "_counter"
     assign counter, ct
 
     # create the text stream
-    text = new "Stream::Sub"
+    text = new ['Stream'; 'Sub']
     # set its source
     .const 'Sub' src = "_text"
     assign text, src
 
     # create a combiner stream
-    combined = new "Stream::Combiner"
+    combined = new ['Stream'; 'Combiner']
     # add the streams
     assign combined, counter
     assign combined, text
@@ -271,11 +271,11 @@
 .sub _main
     .local pmc stream
 
-    load_bytecode "library/Stream/Base.pir"
-    load_bytecode "library/Stream/Coroutine.pir"
+    load_bytecode 'Stream/Base.pbc'
+    load_bytecode 'Stream/Coroutine.pbc'
 
     # create the coroutine stream
-    stream = new "Stream::Coroutine"
+    stream = new ['Stream'; 'Coroutine']
 
     # set the stream's source coroutine #'
     .const 'Sub' temp = "_coro"
@@ -343,26 +343,26 @@
 
     name = "t/library/perlhist.txt"
 
-    load_bytecode "library/Stream/ParrotIO.pir"
-    load_bytecode "library/Stream/Lines.pir"
-    load_bytecode "library/Stream/Sub.pir"
-    load_bytecode "library/Stream/Combiner.pir"
+    load_bytecode 'Stream/ParrotIO.pbc'
+    load_bytecode 'Stream/Lines.pbc'
+    load_bytecode 'Stream/Sub.pbc'
+    load_bytecode 'Stream/Combiner.pbc'
 
     # create a file stream
-    file = new "Stream::ParrotIO"
+    file = new ['Stream'; 'ParrotIO']
     file."open"( name, 'r' )
 
     # process it one line per read
-    lines = new "Stream::Lines"
+    lines = new ['Stream'; 'Lines']
     assign lines, file
 
     # endless counter
-    counter = new "Stream::Sub"
+    counter = new ['Stream'; 'Sub']
     .const 'Sub' temp = "_counter"
     assign counter, temp
 
     # combine the counter and the file's lines   #'
-    combiner = new "Stream::Combiner"
+    combiner = new ['Stream'; 'Combiner']
     assign combiner, counter
     assign combiner, lines
 
@@ -704,17 +704,17 @@
     .local pmc stream
     .local pmc filter
 
-    load_bytecode "library/Stream/Sub.pir"
-    load_bytecode "library/Stream/Filter.pir"
+    load_bytecode 'Stream/Sub.pbc'
+    load_bytecode 'Stream/Filter.pbc'
 
     # create the counter stream
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
     # assign its source
     .const 'Sub' temp = "_counter"
     assign stream, temp
 
     # create the filter stream
-    filter = new "Stream::Filter"
+    filter = new ['Stream'; 'Filter']
     # assign its source
     assign filter, stream
     # set the filter sub
@@ -789,9 +789,9 @@
 .sub _main
     .local pmc stream
 
-    load_bytecode "library/Stream/Sub.pir"
+    load_bytecode 'Stream/Sub.pbc'
 
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
 
     .const 'Sub' temp = "_counter"
     assign stream, temp
@@ -821,7 +821,7 @@
     if i != 4 goto SKIP
     .local pmc temp
 
-    temp = new "Stream::Sub"
+    temp = new ['Stream'; 'Sub']
 
     .const 'Sub' func = "_included"
     assign temp, func
@@ -840,7 +840,7 @@
     self."write"( "hello" )
 
     # create another stream
-    temp = new "Stream::Sub"
+    temp = new ['Stream'; 'Sub']
     .const 'Sub' func = "_counter2"
     assign temp, func
 
@@ -895,17 +895,17 @@
     .local pmc stream
     .local pmc lines
 
-    load_bytecode "library/Stream/Sub.pir"
-    load_bytecode "library/Stream/Lines.pir"
+    load_bytecode 'Stream/Sub.pbc'
+    load_bytecode 'Stream/Lines.pbc'
 
     # create a text stream
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
     # set the source
     .const 'Sub' temp = "_text"
     assign stream, temp
 
     # create a lines stream
-    lines = new "Stream::Lines"
+    lines = new ['Stream'; 'Lines']
     # set the source
     assign lines, stream
 
@@ -942,10 +942,10 @@
     .local pmc stream
     .local pmc temp
 
-    load_bytecode "library/Stream/ParrotIO.pir"
+    load_bytecode 'Stream/ParrotIO.pbc'
 
     # create the ParrotIO stream
-    stream = new "Stream::ParrotIO"
+    stream = new ['Stream'; 'ParrotIO']
 
     # open this file
     stream."open"( "t/library/perlhist.txt", 'r' )
@@ -1256,10 +1256,10 @@
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "library/Stream/Writer.pir"
-    load_bytecode "library/Stream/Replay.pir"
+    load_bytecode 'Stream/Writer.pbc'
+    load_bytecode 'Stream/Replay.pbc'
 
-    stream = new "Stream::Writer"
+    stream = new ['Stream'; 'Writer']
     P0 = global "_reader"
     assign stream, P0
 
@@ -1285,7 +1285,7 @@
     .local pmc stream3
     .local string str
 
-    stream1 = new "Stream::Replay"
+    stream1 = new ['Stream'; 'Replay']
     assign stream1, self
 
     print "reader start\n"
@@ -1357,10 +1357,10 @@
 .sub _main
     .local pmc stream
 
-    load_bytecode "library/Stream/Base.pir"
-    load_bytecode "library/Stream/Sub.pir"
+    load_bytecode 'Stream/Base.pbc'
+    load_bytecode 'Stream/Sub.pbc'
 
-    stream = new "Stream::Sub"
+    stream = new ['Stream'; 'Sub']
 
     .const 'Sub' temp = "_counter"
     assign stream, temp
@@ -1418,9 +1418,9 @@
 .sub _main :main
     .local pmc stream
 
-    load_bytecode "library/Stream/Writer.pir"
+    load_bytecode 'Stream/Writer.pbc'
 
-    stream = new "Stream::Writer"
+    stream = new ['Stream'; 'Writer']
 
     # set the stream's source sub
     .const 'Sub' temp = "_reader"

Modified: branches/pmc_pct/t/library/string_utils.t
==============================================================================
--- branches/pmc_pct/t/library/string_utils.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/string_utils.t	Fri May 15 21:49:40 2009	(r38803)
@@ -15,7 +15,7 @@
 .const string TESTS = '29'
 
 .sub main :main
-    load_bytecode 'Test/Builder.pir'
+    load_bytecode 'Test/Builder.pbc'
 
     .local pmc test       # the test harness object.
                test = new [ 'Test'; 'Builder' ]

Modified: branches/pmc_pct/t/library/tcl_lib.t
==============================================================================
--- branches/pmc_pct/t/library/tcl_lib.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/tcl_lib.t	Fri May 15 21:49:40 2009	(r38803)
@@ -28,7 +28,7 @@
 
     plan(TESTS)
 
-    load_bytecode 'TclLibrary.pir' # TBD pbc
+    load_bytecode 'TclLibrary.pbc' # TBD pbc
     'ok'(1, 'loaded TclLibrary')
 
     goto skip_all    # this is TEMPORARY untill the case of missing libtcl is fixed

Modified: branches/pmc_pct/t/library/test_builder_tester.t
==============================================================================
--- branches/pmc_pct/t/library/test_builder_tester.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/test_builder_tester.t	Fri May 15 21:49:40 2009	(r38803)
@@ -3,7 +3,7 @@
 # $Id$
 
 .sub _main :main
-   load_bytecode 'Test/Builder/Tester.pir'
+   load_bytecode 'Test/Builder/Tester.pbc'
 
    .local pmc tb_args
    tb_args = new 'Hash'

Modified: branches/pmc_pct/t/library/test_class.t
==============================================================================
--- branches/pmc_pct/t/library/test_class.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/test_class.t	Fri May 15 21:49:40 2009	(r38803)
@@ -1,7 +1,7 @@
 #! parrot
 
 .sub 'init_test_builder_tester'
-    load_bytecode 'runtime/parrot/library/Test/Builder/Tester.pir'
+    load_bytecode 'Test/Builder/Tester.pbc'
 
     .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace
@@ -23,7 +23,7 @@
 .end
 
 .sub 'init_test_class'
-    load_bytecode 'runtime/parrot/library/Test/Class.pir'
+    load_bytecode 'Test/Class.pbc'
 .end
 
 .sub 'main' :main

Modified: branches/pmc_pct/t/library/test_more.t
==============================================================================
--- branches/pmc_pct/t/library/test_more.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/library/test_more.t	Fri May 15 21:49:40 2009	(r38803)
@@ -3,8 +3,8 @@
 # $Id$
 
 .sub _main :main
-    load_bytecode 'Test/Builder/Tester.pir'
-    load_bytecode 'Test/More.pir'
+    load_bytecode 'Test/Builder/Tester.pbc'
+    load_bytecode 'Test/More.pbc'
 
     .local pmc tb_args
     tb_args = new 'Hash'

Modified: branches/pmc_pct/t/oo/metamodel.t
==============================================================================
--- branches/pmc_pct/t/oo/metamodel.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/oo/metamodel.t	Fri May 15 21:49:40 2009	(r38803)
@@ -17,7 +17,7 @@
 =cut
 
 .sub _main :main
-    load_bytecode 'library/Test/More.pir'
+    load_bytecode 'Test/More.pbc'
 
     .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace

Modified: branches/pmc_pct/t/op/io.t
==============================================================================
--- branches/pmc_pct/t/op/io.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/op/io.t	Fri May 15 21:49:40 2009	(r38803)
@@ -7,7 +7,7 @@
 use lib qw( . lib ../lib ../../lib );
 
 use Test::More;
-use Parrot::Test tests => 2;
+use Parrot::Test tests => 4;
 
 =head1 NAME
 
@@ -51,6 +51,87 @@
 Catched
 OUTPUT
 
+TODO: {
+local $TODO = 'Testing' unless $^O =~ /linux|darwin/;
+
+pir_output_like( <<'CODE', <<'OUTPUT', 'open pipe for reading' );
+.include 'iglobals.pasm'
+
+.sub testreadpipe :main
+  .local pmc interp
+  interp = getinterp
+  .local pmc conf
+  conf = interp[.IGLOBALS_CONFIG_HASH]
+  .local string command
+  command = conf['build_dir']
+  .local string aux
+  aux = conf['slash']
+  command .= aux
+  aux = conf['test_prog']
+  command .= aux
+  aux = conf['exe']
+  command .= aux
+  command .= ' -V'
+
+  .local pmc pipe
+  pipe = open command, 'rp'
+  unless pipe goto failed
+  .local string line
+nextline:
+  line = readline pipe
+  print line
+  if pipe goto nextline
+  .return()
+failed:
+  say 'FAILED'
+.end
+CODE
+/This is Parrot.*/
+OUTPUT
+
+}
+
+TODO: {
+local $TODO = 'Testing';
+
+pir_output_is( <<'CODE', <<'OUTPUT', 'open pipe for writing' );
+.include 'iglobals.pasm'
+
+.sub testreadpipe :main
+  .local pmc interp
+  interp = getinterp
+  .local pmc conf
+  conf = interp[.IGLOBALS_CONFIG_HASH]
+  .local string command
+  command = conf['build_dir']
+  .local string aux
+  aux = conf['slash']
+  command .= aux
+  .local string filename
+  filename .= command
+  filename .= 'examples/pasm/cat.pasm'
+  aux = conf['test_prog']
+  command .= aux
+  aux = conf['exe']
+  command .= aux
+  command .= ' '
+  command .= filename
+
+  .local pmc pipe
+  pipe = open command, 'wp'
+  unless pipe goto failed
+  pipe.'puts'("Hello, pipe!\n")
+  close pipe
+  .return()
+failed:
+  say 'FAILED'
+.end
+CODE
+Hello, pipe!
+OUTPUT
+
+}
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Modified: branches/pmc_pct/t/op/lexicals.t
==============================================================================
--- branches/pmc_pct/t/op/lexicals.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/op/lexicals.t	Fri May 15 21:49:40 2009	(r38803)
@@ -118,7 +118,7 @@
     $P0 = find_lex 'a'
     print "ok\n"
 .include 'interpinfo.pasm'
-    load_bytecode "pcore.pir"      # TODO autoload/preload
+    load_bytecode 'pcore.pbc'      # TODO autoload/preload
     interpinfo $P1, .INTERPINFO_CURRENT_SUB
     $P2 = $P1.'get_lexinfo'()
     $P2 = $P1.'get_lexenv'()

Modified: branches/pmc_pct/t/op/sprintf.t
==============================================================================
--- branches/pmc_pct/t/op/sprintf.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/op/sprintf.t	Fri May 15 21:49:40 2009	(r38803)
@@ -60,7 +60,7 @@
 .const int TESTS = 308
 
 .sub main :main
-    load_bytecode 'Test/Builder.pir'
+    load_bytecode 'Test/Builder.pbc'
     load_bytecode 'PGE.pbc'
     load_bytecode 'PGE/Dumper.pbc'
     .include "iglobals.pasm"

Modified: branches/pmc_pct/t/op/trans.t
==============================================================================
--- branches/pmc_pct/t/op/trans.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/op/trans.t	Fri May 15 21:49:40 2009	(r38803)
@@ -30,7 +30,7 @@
 # to LABEL if abs(n,n) < epsilon
 
 pasm_output_is( <<"CODE", <<OUTPUT, "sin" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set     N1, 1.0
         sin     N2, N1
         .fp_eq_pasm  (N2, 0.841471, EQ1)
@@ -50,7 +50,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "cos" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set     N1, 1.0
         cos     N2, N1
         .fp_eq_pasm  (N2, 0.540302, EQ1)
@@ -69,7 +69,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "tan" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set     N1, 1.0
         tan     N2, N1
         .fp_eq_pasm  (N2, 1.557408, EQ1)
@@ -88,7 +88,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "sec" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         sec N2, N1
         .fp_eq_pasm  (N2, 1.850816, EQ1)
@@ -107,7 +107,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "atan" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         atan N2, N1
         .fp_eq_pasm  (N2, 0.785398, EQ1)
@@ -126,7 +126,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "asin" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         asin N2, N1
         .fp_eq_pasm  (N2, 1.570796, EQ1)
@@ -146,7 +146,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "acos" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         acos N2, N1
         .fp_eq_pasm  (N2, 0.000000, EQ1)
@@ -166,7 +166,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "asec" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         asec N2, N1
         .fp_eq_pasm  (N2, 0.000000, EQ1)
@@ -186,7 +186,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "cosh" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         cosh N2, N1
         .fp_eq_pasm  (N2, 1.543081, EQ1)
@@ -213,7 +213,7 @@
 );
 
 pasm_output_is( <<"CODE", <<OUTPUT, "sinh", @bsdtodo );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         sinh N2, N1
         .fp_eq_pasm  (N2, 1.175201, EQ1)
@@ -233,7 +233,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "tanh", @bsdtodo );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         tanh N2, N1
         .fp_eq_pasm  (N2, 0.761594, EQ1)
@@ -253,7 +253,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "sech" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 1.0
         sech N2, N1
         .fp_eq_pasm  (N2, 0.648054, EQ1)
@@ -273,7 +273,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, 'atan2' );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N0, 0.0
         set I0, 0
         set N1, 1.0
@@ -386,7 +386,7 @@
 local $TODO = 'fails on netbsd' if $^O =~ /netbsd/;
 
 pasm_output_is( <<"CODE", <<'OUTPUT', 'atan, part 2' );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         atan N4, -0.0, -0.0
         .fp_eq_pasm   (N4, -3.1415926, EQ1)
         print "not "
@@ -400,7 +400,7 @@
 }
 
 pasm_output_is( <<"CODE", <<OUTPUT, "log2" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 10.0
         log2 N2, N1
         .fp_eq_pasm  (N2, 3.321928, EQ1)
@@ -420,7 +420,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "log10" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 15.0
         log10 N2, N1
         .fp_eq_pasm  (N2, 1.176091, EQ1)
@@ -440,7 +440,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "ln" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 10.0
         ln N2, N1
         .fp_eq_pasm  (N2, 2.302585, EQ1)
@@ -459,7 +459,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "exp" );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 10.0
         exp N2, N1
         .fp_eq_pasm  (N2, 22026.465795, EQ1)
@@ -478,7 +478,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "pow", @bsdtodo );
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         set N1, 3.0
         set I1, 3
         set N2, 5.0
@@ -589,7 +589,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "sqrt" );
-       .include 'include/fp_equality.pasm'
+       .include 'fp_equality.pasm'
        set N1, 9.0
        sqrt N2, N1
        .fp_eq_pasm  (N2, 3.0, EQ1)

Modified: branches/pmc_pct/t/pmc/array.t
==============================================================================
--- branches/pmc_pct/t/pmc/array.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/array.t	Fri May 15 21:49:40 2009	(r38803)
@@ -226,7 +226,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via PMC keys, access via INTs" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['Array']
      set P0, 4
      new P1, ['Key']
@@ -275,7 +275,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['Array']
      set P0, 1024
 

Modified: branches/pmc_pct/t/pmc/bigint.t
==============================================================================
--- branches/pmc_pct/t/pmc/bigint.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/bigint.t	Fri May 15 21:49:40 2009	(r38803)
@@ -96,7 +96,7 @@
 OUT
 
 pasm_output_is( <<"CODE", <<'OUT', "set int, get double" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['BigInt']
      set P0, 999999
      set N1, P0

Modified: branches/pmc_pct/t/pmc/bignum.t
==============================================================================
--- branches/pmc_pct/t/pmc/bignum.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/bignum.t	Fri May 15 21:49:40 2009	(r38803)
@@ -94,7 +94,7 @@
 OUT
 
 pasm_output_is( <<"CODE", <<'OUT', "set int, get double" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['BigNum']
      set P0, 999999
      set N1, P0

Modified: branches/pmc_pct/t/pmc/class.t
==============================================================================
--- branches/pmc_pct/t/pmc/class.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/class.t	Fri May 15 21:49:40 2009	(r38803)
@@ -17,11 +17,11 @@
 =cut
 
 
-.const int TESTS = 62 
+.const int TESTS = 63 
 
 
 .sub 'main' :main
-     load_bytecode 'Test/More.pir'
+     load_bytecode 'Test/More.pbc'
      .local pmc exporter, test_ns
      test_ns = get_namespace [ 'Test'; 'More' ]
      exporter = new ['Exporter']
@@ -45,6 +45,7 @@
      'isa'()
      'does'()
      'more does'()
+     'anon_inherit'()
 .end
 
 
@@ -592,6 +593,14 @@
     is($I0, 1, 'does Red')
 .end
 
+.sub 'anon_inherit'
+    $P0 = new 'Class'
+    $P1 = new 'Class'
+    $P2 = new 'Class'
+    addparent $P2, $P0
+    addparent $P2, $P1
+    ok(1, 'inheritance of two different anonymous classes works')
+.end
 
 # Local Variables:
 #   mode: pir

Modified: branches/pmc_pct/t/pmc/exceptionhandler.t
==============================================================================
--- branches/pmc_pct/t/pmc/exceptionhandler.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/exceptionhandler.t	Fri May 15 21:49:40 2009	(r38803)
@@ -16,8 +16,8 @@
 
 =cut
 
-.include 'include/except_severity.pasm'
-.include 'include/except_types.pasm'
+.include 'except_severity.pasm'
+.include 'except_types.pasm'
 
 .sub main :main
     .include 'test_more.pir'

Modified: branches/pmc_pct/t/pmc/exporter.t
==============================================================================
--- branches/pmc_pct/t/pmc/exporter.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/exporter.t	Fri May 15 21:49:40 2009	(r38803)
@@ -283,7 +283,7 @@
 
 pir_output_is( <<'CODE', <<'OUT', 'import - globals as string' );
 .sub 'test' :main
-    load_bytecode 'Test/More.pir'
+    load_bytecode 'Test/More.pbc'
     .local pmc exporter, src
 
     src      = get_namespace [ 'Test'; 'More' ]
@@ -300,7 +300,7 @@
 
 pir_output_is( <<'CODE', <<'OUT', 'import - globals with source passed separately' );
 .sub 'test' :main
-    load_bytecode 'Test/More.pir'
+    load_bytecode 'Test/More.pbc'
     .local pmc exporter, src
 
     src      = get_namespace [ 'Test'; 'More' ]
@@ -318,7 +318,7 @@
 
 pir_output_is( <<'CODE', <<'OUT', 'import - globals as array' );
 .sub 'test' :main
-    load_bytecode 'Test/More.pir'
+    load_bytecode 'Test/More.pbc'
     .local pmc exporter, src, globals
 
     src     = get_namespace [ 'Test'; 'More' ]
@@ -338,7 +338,7 @@
 
 pir_output_is( <<'CODE', <<'OUT', 'import - globals as hash - null + empty string' );
 .sub 'test' :main
-    load_bytecode 'Test/More.pir'
+    load_bytecode 'Test/More.pbc'
     .local pmc exporter, src, globals, nul
 
     nul     = new ['Null']
@@ -359,7 +359,7 @@
 
 pir_output_is( <<'CODE', <<'OUT', 'import - globals as hash - with dest names (latin)' );
 .sub 'test' :main
-    load_bytecode 'Test/More.pir'
+    load_bytecode 'Test/More.pbc'
     .local pmc exporter, src, globals
 
     src     = get_namespace [ 'Test'; 'More' ]
@@ -379,7 +379,7 @@
 
 pir_output_is( <<'CODE', <<'OUT', 'import - globals with destination' );
 .sub 'test' :main
-    load_bytecode 'Test/More.pir'
+    load_bytecode 'Test/More.pbc'
     .local pmc exporter, src, dest, globals
 
     src     = get_namespace [ 'Test'; 'More' ]

Modified: branches/pmc_pct/t/pmc/fixedbooleanarray.t
==============================================================================
--- branches/pmc_pct/t/pmc/fixedbooleanarray.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/fixedbooleanarray.t	Fri May 15 21:49:40 2009	(r38803)
@@ -142,7 +142,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via PMC keys, access via INTs" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['FixedBooleanArray']
      set P0, 3
      new P1, ['Key']
@@ -179,7 +179,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['FixedBooleanArray']
      set P0, 1024
 

Modified: branches/pmc_pct/t/pmc/fixedintegerarray.t
==============================================================================
--- branches/pmc_pct/t/pmc/fixedintegerarray.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/fixedintegerarray.t	Fri May 15 21:49:40 2009	(r38803)
@@ -164,7 +164,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via PMC keys, access via INTs" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['FixedIntegerArray']
      set P0, 3
      new P1, ['Key']
@@ -201,7 +201,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['FixedIntegerArray']
      set P0, 1024
 

Modified: branches/pmc_pct/t/pmc/fixedpmcarray.t
==============================================================================
--- branches/pmc_pct/t/pmc/fixedpmcarray.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/fixedpmcarray.t	Fri May 15 21:49:40 2009	(r38803)
@@ -214,7 +214,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via PMC keys, access via INTs" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['FixedPMCArray']
      set P0, 3
      new P1, ['Key']
@@ -251,7 +251,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['FixedPMCArray']
      set P0, 1024
 

Modified: branches/pmc_pct/t/pmc/fixedstringarray.t
==============================================================================
--- branches/pmc_pct/t/pmc/fixedstringarray.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/fixedstringarray.t	Fri May 15 21:49:40 2009	(r38803)
@@ -142,7 +142,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via PMC keys, access via INTs" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['FixedStringArray']
      set P0, 3
      new P1, ['Key']
@@ -179,7 +179,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['FixedStringArray']
      set P0, 1024
 

Modified: branches/pmc_pct/t/pmc/float.t
==============================================================================
--- branches/pmc_pct/t/pmc/float.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/float.t	Fri May 15 21:49:40 2009	(r38803)
@@ -26,7 +26,7 @@
 
 
 pasm_output_is( <<"CODE", <<OUTPUT, "basic assignment" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
 
     set P0, 0.001
@@ -79,7 +79,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "add number to self" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 0.001
     add P0, P0, P0
@@ -93,7 +93,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "sub number from self" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, -1000.2
     sub P0, P0, P0
@@ -107,7 +107,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "multiply number by self" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 123.4
     mul P0, P0, P0
@@ -121,7 +121,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<OUTPUT, "divide number by self" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 1829354.988
     div P0, P0, P0
@@ -266,7 +266,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Basic integer arithmetic: addition" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 0.001
     add P0, 1
@@ -287,7 +287,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Basic integer arithmetic: subtraction" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 103.45
     sub P0, 77
@@ -308,7 +308,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Basic integer arithmetic: multiplication" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 0.001
     mul P0, 10000
@@ -336,7 +336,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Basic integer arithmetic: division" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 1e8
     div P0, 10000
@@ -357,7 +357,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Basic numeric arithmetic: addition" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 0.001
     add P0, 1.2
@@ -378,7 +378,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Basic numeric arithmetic: subtraction" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 103.45
     sub P0, 3.46
@@ -399,7 +399,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Basic numeric arithmetic: multiplication" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 0.001
     mul P0, 123.5
@@ -427,7 +427,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Basic numeric arithmetic: division" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 1e8
     div P0, 0.5
@@ -448,7 +448,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Increment & decrement" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 0.5
     inc P0
@@ -483,7 +483,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Neg" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 0.5
     neg P0
@@ -599,7 +599,7 @@
 OUTPUT
 
 pasm_output_is( << "CODE", << 'OUTPUT', "Abs" );
-    .include 'include/fp_equality.pasm'
+    .include 'fp_equality.pasm'
     new P0, ['Float']
     set P0, 1.0
     abs P0

Modified: branches/pmc_pct/t/pmc/resizablefloatarray.t
==============================================================================
--- branches/pmc_pct/t/pmc/resizablefloatarray.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/resizablefloatarray.t	Fri May 15 21:49:40 2009	(r38803)
@@ -193,7 +193,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via PMC keys, access via INTs" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableFloatArray']
      new P1, ['Key']
 
@@ -229,7 +229,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableFloatArray']
      set P0, 1
 
@@ -275,7 +275,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', 'basic push' );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableFloatArray']
      push P0, 1.0
      push P0, 2.0
@@ -302,7 +302,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', 'push many values' );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableFloatArray']
      set I0, 0
 L1:  set N0, I0
@@ -321,7 +321,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', 'basic pop' );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableFloatArray']
      set P0[0], 1.0
      set P0[1], 2.0
@@ -348,7 +348,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', 'pop many values' );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableFloatArray']
      set I0, 0
 L1:  set N0, I0
@@ -376,7 +376,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', 'push/pop' );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableFloatArray']
      push P0, 1.0
      push P0, 2.0

Modified: branches/pmc_pct/t/pmc/resizableintegerarray.t
==============================================================================
--- branches/pmc_pct/t/pmc/resizableintegerarray.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/resizableintegerarray.t	Fri May 15 21:49:40 2009	(r38803)
@@ -177,7 +177,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via PMC keys, access via INTs" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableIntegerArray']
      new P1, ['Key']
 
@@ -213,7 +213,7 @@
 OUTPUT
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys" );
-     .include 'include/fp_equality.pasm'
+     .include 'fp_equality.pasm'
      new P0, ['ResizableIntegerArray']
      set P0, 1
 

Modified: branches/pmc_pct/t/pmc/ro.t
==============================================================================
--- branches/pmc_pct/t/pmc/ro.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/ro.t	Fri May 15 21:49:40 2009	(r38803)
@@ -1,13 +1,7 @@
-#! perl
+#! parrot
 # Copyright (C) 2006-2007, Parrot Foundation.
 # $Id$
 
-use strict;
-use warnings;
-use lib qw( . lib ../lib ../../lib );
-use Test::More;
-use Parrot::Test tests => 8;
-
 =head1 NAME
 
 t/pmc/ro.t -- tests read-only value support
@@ -22,8 +16,10 @@
 
 =cut
 
-my $library = <<'CODE';
+.namespace []
+
 .include "except_types.pasm"
+
 .sub make_readonly
     .param pmc arg
     .local pmc one
@@ -39,10 +35,23 @@
     zero = 0
     setprop arg, '_ro', zero
 .end
-CODE
 
-pir_output_is( $library . <<'CODE', <<'OUTPUT', "Integer set read-only is not writable" );
 .sub main :main
+    .include 'test_more.pir'
+
+    plan(12)
+
+    integer_set_read_only_is_not_writable() # 1 test
+    integer_set_read_only_can_be_read()     # 6 tests
+    integer_stays_integer()                 # 1 test
+    integer_add()                           # 1 test
+    complex_i_add()                         # 1 test
+    resizablepmcarray_non_recursive_part()  # 1 test
+    objects()                               # 1 test
+#    resizablepmcarray_recursive()           #
+.end
+
+.sub integer_set_read_only_is_not_writable
     .local pmc foo, eh
 
     foo = new ['Integer']
@@ -56,20 +65,17 @@
     push_eh eh
     foo = 43
     pop_eh
-    print "no exception caught"
+    ok( 0, "integer_set_read_only_is_not_writable" )
     end
 
 eh_label:
+    .local string message
     .get_results($P0)
-    say "RO exception caught"
-    end
+    message = $P0['message']
+    is( message, "set_integer_native() in read-only instance of 'Integer'", "integer_set_read_only_is_not_writable" )
 .end
-CODE
-RO exception caught
-OUTPUT
 
-pir_output_is( $library . <<'CODE', <<'OUTPUT', "Integer set read-only can be read" );
-.sub main :main
+.sub integer_set_read_only_can_be_read
     .local pmc foo
     .local pmc tmp
 
@@ -77,39 +83,24 @@
     foo = 42
 
     make_readonly(foo)
-    print foo
-    print "\n"
+    is(foo, 42, 'foo initialised to 42 is readable after make_readonly')
     $I0 = foo
+    is($I0, 42, 'foo copied to int correctly')
     $S0 = foo
-    print $I0
-    print "\n"
-    print $S0
-    print "\n"
+    is($S0, 42, 'foo copied to string correctly')
 
     tmp = new ['Integer']
     add tmp, foo, foo
-    print tmp
-    print "\n"
+    is(tmp, 84, 'foo can be added to foo correctly and stored elsewhere')
 
     $P0 = foo
     add foo, foo, foo
-    print foo
-    print "\n"
+    is(foo, 84, 'foo can be added to foo correctly and stored to foo')
 
-    print $P0
-    print "\n"
+    is($P0, 42, 'copied foo retains its value')
 .end
-CODE
-42
-42
-42
-84
-84
-42
-OUTPUT
 
-pir_output_is( $library . <<'CODE', <<'OUTPUT', "Integer stays Integer" );
-.sub main :main
+.sub integer_stays_integer
     .local pmc foo
 
     foo = new ['Integer']
@@ -117,14 +108,10 @@
 
     make_readonly(foo)
     typeof $S0, foo
-    say $S0
+    is($S0, 'Integer', 'integer_stays_integer')
 .end
-CODE
-Integer
-OUTPUT
 
-pir_output_is( $library . <<'CODE', <<'OUTPUT', "Integer add" );
-.sub main :main
+.sub integer_add
     .local pmc foo, eh
 
     foo = new ['Integer']
@@ -139,20 +126,16 @@
     foo += 16
     pop_eh
 
-    say "no exception caught"
-    end
+    ok(0, 'integer_add')
 
 eh_label:
+    .local string message
     .get_results($P0)
-    say "RO exception caught"
-    end
+    message = $P0['message']
+    is( message, "i_add_int() in read-only instance of 'Integer'", 'integer_add' )
 .end
-CODE
-RO exception caught
-OUTPUT
 
-pir_output_is( $library . <<'CODE', <<'OUTPUT', "Complex i_add" );
-.sub main :main
+.sub complex_i_add
     .local pmc foo, eh
 
     foo = new ['Complex']
@@ -167,20 +150,17 @@
     push_eh eh
     add foo, 4
     pop_eh
-    say "no exception caught"
-    end
+    ok( 0, 'complex_i_add')
 
 eh_label:
+    .local string message
     .get_results($P0)
-    say "RO exception caught"
-    end
+    message = $P0['message']
+    is( message, "i_add_int() in read-only instance of 'Complex'", 'complex_i_add' )
+
 .end
-CODE
-RO exception caught
-OUTPUT
 
-pir_output_is( $library . <<'CODE', <<'OUTPUT', "ResizablePMCArray (non-recursive part)" );
-.sub main :main
+.sub resizablepmcarray_non_recursive_part
     .local pmc foo, three, four, eh
 
     foo = new ['ResizablePMCArray']
@@ -202,20 +182,17 @@
     push_eh eh
     foo[0] = four
     pop_eh
-    say "no exception caught"
-    end
+
+    ok(0, 'resizablepmcarray_non_recursive_part')
 
 eh_label:
+    .local string message
     .get_results($P0)
-    say "RO exception caught"
-    end
+    message = $P0['message']
+    is( message, "set_pmc_keyed_int() in read-only instance of 'ResizablePMCArray'", 'resizablepmcarray_non_recursive_part' )
 .end
-CODE
-RO exception caught
-OUTPUT
 
-pir_output_is( $library . <<'CODE', <<'OUTPUT', "Objects" );
-.sub main :main
+.sub objects
     .local pmc fooclass, foo, eh, i
 
     i = new ['Integer']
@@ -237,23 +214,20 @@
     setattribute foo, 'bar', i
     pop_eh
 
-    say "no exception caught"
-    end
+    ok( 0, 'objects')
 
 eh_label:
+    .local string message
     .get_results($P0)
-    say "RO exception caught"
-    end
+    message = $P0['message']
+    is( message, "set_attr_str() in read-only instance of 'Foo'", 'objects' )
 .end
-CODE
-RO exception caught
-OUTPUT
-
-# RT #46821: should this work?
-{
-    local $TODO = 1;
-    pir_output_unlike( $library . <<'CODE', <<'OUTPUT', "ResizablePMCArray -- Recursive" );
-.sub main :main
+
+=pod
+
+RT #46821: should this work? 
+
+.sub resizablepmcarray_recursive
     .local pmc foo
     .local pmc three
     .local pmc tmp
@@ -276,14 +250,12 @@
     tmp = foo[0]
     print tmp
 .end
-CODE
-/NOT OKAY/
-OUTPUT
-}
+
+=cut
+
 
 # Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
+#   mode: pir
 #   fill-column: 100
 # End:
-# vim: expandtab shiftwidth=4:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/pmc_pct/t/pmc/string.t
==============================================================================
--- branches/pmc_pct/t/pmc/string.t	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/t/pmc/string.t	Fri May 15 21:49:40 2009	(r38803)
@@ -131,7 +131,7 @@
 .end
 
 # Macro to ease testing of floating point comparisons
-# borrowed from fp_eq in include/fp_equality.pasm
+# borrowed from fp_eq in fp_equality.pasm
 .macro fp_eq_ok (  J, K, L )
     set $N10, .J
     set $N11, .K
@@ -146,7 +146,7 @@
 .endm
 
 .sub setting_numbers
-        .include 'include/fp_equality.pasm'
+        .include 'fp_equality.pasm'
         new $P0, ['String']
         set $P0, "1"
         set $N0, $P0

Copied: branches/pmc_pct/tools/dev/branch_status.pl (from r38802, trunk/tools/dev/branch_status.pl)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/pmc_pct/tools/dev/branch_status.pl	Fri May 15 21:49:40 2009	(r38803, copy of r38802, trunk/tools/dev/branch_status.pl)
@@ -0,0 +1,113 @@
+#! perl
+# $Id$
+# Copyright (C) 2009, Parrot Foundation.
+
+=head1 branch_status
+
+Generate a report to help developers determine status of repository branches.
+
+=cut
+
+use v5.10.0;
+use strict;
+use warnings;
+
+use XML::Twig;
+use Perl6::Form;
+
+my $repo = 'https://svn.parrot.org/parrot/';
+
+my @branches = map {chomp; chop; $_} `svn ls $repo/branches`;
+
+foreach my $branch (@branches) {
+    my $t = XML::Twig->new();
+    my $xml = `svn log --stop-on-copy --xml -v $repo/branches/$branch`;
+    $t->parse($xml);
+
+    my $newest = $t->root->first_child('logentry');
+    my $oldest = $t->root->last_child('logentry');
+    my $creator = $oldest->first_child('author')->xml_text;
+
+    my (%authors,%components);
+    my $merge_log;
+    foreach my $entry ($t->root->children('logentry')) {
+            $authors{$entry->first_child('author')->xml_text}++;
+            my $msg = $entry->first_child('msg')->xml_text;
+            $msg =~ s/\s+$//;
+            $msg =~ s/^\s+//;
+            if (!defined($merge_log) && $msg =~ /merge/i) {
+                    $merge_log = $msg;
+            }
+            while ($msg =~ m/\[(.+?)\]/g) {
+                    my $component = $1;
+                    $component =~ s/\s+$//;
+                    $component =~ s/^\s+//;
+                    if ($component ne '') {
+                            $components{$1} = undef;
+                    }
+            }
+    }
+    $merge_log //= 'N/A';
+
+    my $revisions =  'r' .$oldest->atts->{revision} . ':' .
+        $newest->atts->{revision};
+    my $created_date = $oldest->first_child('date')->xml_text;
+    my $updated_date = $newest->first_child('date')->xml_text;
+    my $author_txt;
+    if (scalar keys %authors == 1) {
+         $author_txt = $creator;
+    }
+    else {
+        my @counts;
+        foreach my $author (sort {$authors{$b} <=> $authors{$a}} keys %authors) {
+            push @counts, "$author [$authors{$author}]";
+        }
+        $author_txt = join (', ', @counts);
+    }
+    my $components = join (', ', sort {lc $a cmp lc $b} keys %components);
+    my $number_commits = scalar $t->root->children('logentry');
+    my $initial_log = $oldest->first_child('msg')->xml_text;
+    $initial_log =~ s/\s+$//;
+    $initial_log =~ s/^\s+//;
+    $merge_log =~ s/\n/ /g;
+    $initial_log =~ s/\n/ /g;
+
+
+    print form
+'+====================================================================+',
+'|        branch: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
+                  $branch,
+'|     revisions: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
+                  $revisions,
+'|       creator: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
+                  $creator,
+'|       authors: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
+                  $author_txt,
+'|    created on: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
+                  $created_date,
+'|    updated on: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
+                  $updated_date,
+'|    components: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
+                  $components,
+'|  # of commits: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
+                  $number_commits,
+{bullet => 'initial log:'},
+'|   initial log: {[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[} |',
+                  $initial_log,
+{bullet => 'last merge log:'},
+'|last merge log: {[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[} |',
+                  $merge_log;
+}
+
+say '+', '=' x 68, '+';
+
+__END__
+
+=head1 Notes
+
+This program uses modules that are not intended to be parrot requirements.
+
+Assumes that you have a command line svn in your path, but doesn't have
+to be run in a working copy.
+
+=cut

Modified: branches/pmc_pct/tools/util/crow.pir
==============================================================================
--- branches/pmc_pct/tools/util/crow.pir	Fri May 15 21:14:54 2009	(r38802)
+++ branches/pmc_pct/tools/util/crow.pir	Fri May 15 21:49:40 2009	(r38803)
@@ -23,7 +23,7 @@
 .sub 'main' :main
     .param pmc    args
 
-    load_bytecode 'Crow.pir' # TODO s/pir/pbc/
+    load_bytecode 'Crow.pbc'
 
     .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace
@@ -73,7 +73,7 @@
 .sub 'get_json'
     .param string filename
 
-    load_bytecode 'Config/JSON.pir'
+    load_bytecode 'Config/JSON.pbc'
 
      .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace


More information about the parrot-commits mailing list