[svn:parrot] r41079 - in branches/pluggable_runcore: . config/auto include/parrot runtime/parrot/include runtime/parrot/library/Test src src/gc src/interp src/pmc src/runcore t/library t/pmc t/src tools/dev

cotto at svn.parrot.org cotto at svn.parrot.org
Sun Sep 6 19:36:09 UTC 2009


Author: cotto
Date: Sun Sep  6 19:36:07 2009
New Revision: 41079
URL: https://trac.parrot.org/parrot/changeset/41079

Log:
sync branch to trunk in preparation for merging

Modified:
   branches/pluggable_runcore/   (props changed)
   branches/pluggable_runcore/NEWS
   branches/pluggable_runcore/config/auto/crypto.pm
   branches/pluggable_runcore/config/auto/gdbm.pm
   branches/pluggable_runcore/config/auto/gmp.pm
   branches/pluggable_runcore/config/auto/readline.pm
   branches/pluggable_runcore/include/parrot/gc_api.h
   branches/pluggable_runcore/include/parrot/register.h
   branches/pluggable_runcore/include/parrot/runcore_trace.h   (props changed)
   branches/pluggable_runcore/include/parrot/sub.h
   branches/pluggable_runcore/runtime/parrot/include/test_more.pir
   branches/pluggable_runcore/runtime/parrot/library/Test/More.pir
   branches/pluggable_runcore/src/debug.c
   branches/pluggable_runcore/src/gc/alloc_register.c
   branches/pluggable_runcore/src/gc/api.c
   branches/pluggable_runcore/src/gc/gc_private.h
   branches/pluggable_runcore/src/gc/generational_ms.c   (props changed)
   branches/pluggable_runcore/src/gc/incremental_ms.c   (props changed)
   branches/pluggable_runcore/src/interp/inter_create.c   (props changed)
   branches/pluggable_runcore/src/pmc.c
   branches/pluggable_runcore/src/pmc/context.pmc
   branches/pluggable_runcore/src/pmc/continuation.pmc
   branches/pluggable_runcore/src/pmc/retcontinuation.pmc
   branches/pluggable_runcore/src/runcore/cores.c   (props changed)
   branches/pluggable_runcore/src/runcore/trace.c   (props changed)
   branches/pluggable_runcore/src/sub.c
   branches/pluggable_runcore/t/library/test_more.t
   branches/pluggable_runcore/t/pmc/fixedpmcarray.t
   branches/pluggable_runcore/t/pmc/namespace.t
   branches/pluggable_runcore/t/src/embed.t   (props changed)
   branches/pluggable_runcore/tools/dev/mk_gitignore.pl   (props changed)

Modified: branches/pluggable_runcore/NEWS
==============================================================================
--- branches/pluggable_runcore/NEWS	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/NEWS	Sun Sep  6 19:36:07 2009	(r41079)
@@ -1,5 +1,30 @@
 # $Id$
 
+New in 1.6.0
+- Core
+  + PMC allocator now automatically allocates ATTR structures
+  + Added fixed-size structure allocator to GC
+  + Contexts are not garbage-collectable
+  + Created a new Context API
+  + Op definitions cache the current Context for subsequent lookups
+  + Unified Continuation PMC and Parrot_cont structure
+  + Unified Sub PMC and Parrot_sub structure
+  + Began proper encapsulation of STRING API
+  + Modify PMC structure to remove UnionVal
+  + Removed PMC_EXT structure
+  + Removed PMC_Sync from PMC
+  + Added a "Lazy" mode to the PObj and Fixed-Size allocators
+  + Reduce string comparisons in VTABLE_isa
+  + Unified all PMC destruction functions
+  + Added several fixes for stack-walking GC code
+  + Copying a NULL string now returns an empty STRING structure
+  + Add find_dynamic_lex and store_dynamic_lex opcodes
+- Tests
+  + Convert several Perl5 tests to PIR
+  + Expand test coverage of NameSpace PMC
+- Compilers
+  + PCT is now included in "make install"
+
 New in 1.5.0
 - Core
   + Removed several deprecated functions and features

Modified: branches/pluggable_runcore/config/auto/crypto.pm
==============================================================================
--- branches/pluggable_runcore/config/auto/crypto.pm	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/config/auto/crypto.pm	Sun Sep  6 19:36:07 2009	(r41079)
@@ -65,6 +65,7 @@
         $has_crypto = $self->_evaluate_cc_run($conf, $test, $has_crypto, $verbose);
     }
     $conf->data->set( has_crypto => $has_crypto );    # for dynpmc.in & digest.t
+    $self->set_result($has_crypto ? 'yes' : 'no');
 
     return 1;
 }

Modified: branches/pluggable_runcore/config/auto/gdbm.pm
==============================================================================
--- branches/pluggable_runcore/config/auto/gdbm.pm	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/config/auto/gdbm.pm	Sun Sep  6 19:36:07 2009	(r41079)
@@ -70,6 +70,7 @@
         $has_gdbm = $self->_evaluate_cc_run($test, $has_gdbm, $verbose);
     }
     $conf->data->set( has_gdbm => $has_gdbm );    # for gdbmhash.t and dynpmc.in
+    $self->set_result($has_gdbm ? 'yes' : 'no');
 
     return 1;
 }

Modified: branches/pluggable_runcore/config/auto/gmp.pm
==============================================================================
--- branches/pluggable_runcore/config/auto/gmp.pm	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/config/auto/gmp.pm	Sun Sep  6 19:36:07 2009	(r41079)
@@ -76,6 +76,7 @@
     if ($has_gmp) {
         $conf->data->add( ' ', libs => $extra_libs );
     }
+    $self->set_result($has_gmp ? 'yes' : 'no');
 
     return 1;
 }

Modified: branches/pluggable_runcore/config/auto/readline.pm
==============================================================================
--- branches/pluggable_runcore/config/auto/readline.pm	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/config/auto/readline.pm	Sun Sep  6 19:36:07 2009	(r41079)
@@ -77,6 +77,7 @@
         }
     }
     $conf->data->set( HAS_READLINE => $has_readline );
+    $self->set_result($has_readline ? 'yes' : 'no');
 
     return 1;
 }

Modified: branches/pluggable_runcore/include/parrot/gc_api.h
==============================================================================
--- branches/pluggable_runcore/include/parrot/gc_api.h	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/include/parrot/gc_api.h	Sun Sep  6 19:36:07 2009	(r41079)
@@ -17,15 +17,6 @@
 
 #include "parrot/parrot.h"
 
-/* Set to 1 if we want to use the fixed-size allocator. Set to 0 if we want
-   to allocate these things using mem_sys_allocate instead */
-/* Disabled on Windows platforms until problems get fixed, TT #940 */
-#if defined(_WIN32) || defined(_WIN64)
-#  define GC_USE_FIXED_SIZE_ALLOCATOR 1
-#else
-#  define GC_USE_FIXED_SIZE_ALLOCATOR 1
-#endif
-
 /*
  * we need an alignment that is the same as malloc(3) have for
  * allocating Buffer items like FLOATVAL (double)
@@ -198,9 +189,7 @@
         __attribute__nonnull__(1);
 
 PARROT_CANNOT_RETURN_NULL
-void * Parrot_gc_allocate_pmc_attributes(PARROT_INTERP,
-    ARGMOD(PMC *pmc),
-    size_t size)
+void * Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pmc);
@@ -253,9 +242,7 @@
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*data);
 
-void Parrot_gc_free_pmc_attributes(PARROT_INTERP,
-    ARGMOD(PMC *pmc),
-    size_t item_size)
+void Parrot_gc_free_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*pmc);

Modified: branches/pluggable_runcore/include/parrot/register.h
==============================================================================
--- branches/pluggable_runcore/include/parrot/register.h	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/include/parrot/register.h	Sun Sep  6 19:36:07 2009	(r41079)
@@ -171,6 +171,10 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+size_t Parrot_pcc_calculate_context_size(SHIM_INTERP,
+    ARGIN(const UINTVAL *number_regs_used))
+        __attribute__nonnull__(2);
+
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 PMC * Parrot_set_new_context(PARROT_INTERP,
@@ -228,6 +232,9 @@
 #define ASSERT_ARGS_Parrot_alloc_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(number_regs_used)
+#define ASSERT_ARGS_Parrot_pcc_calculate_context_size \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(number_regs_used)
 #define ASSERT_ARGS_Parrot_set_new_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(number_regs_used)

Modified: branches/pluggable_runcore/include/parrot/sub.h
==============================================================================
--- branches/pluggable_runcore/include/parrot/sub.h	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/include/parrot/sub.h	Sun Sep  6 19:36:07 2009	(r41079)
@@ -241,15 +241,6 @@
 
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-PMC* Parrot_find_dynamic_pad(PARROT_INTERP,
-    ARGIN(STRING *lex_name),
-    ARGIN(PMC *ctx))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
-
-PARROT_CAN_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
 PMC* Parrot_find_pad(PARROT_INTERP,
     ARGIN(STRING *lex_name),
     ARGIN(PMC *ctx))

Modified: branches/pluggable_runcore/runtime/parrot/include/test_more.pir
==============================================================================
--- branches/pluggable_runcore/runtime/parrot/include/test_more.pir	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/runtime/parrot/include/test_more.pir	Sun Sep  6 19:36:07 2009	(r41079)
@@ -20,7 +20,7 @@
     .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace
     test_namespace = get_root_namespace [ 'parrot'; 'Test'; 'More' ]
-    exports = split ' ', 'plan diag ok nok is is_deeply like isa_ok skip isnt todo'
+    exports = split ' ', 'plan diag ok nok is is_deeply like isa_ok skip isnt todo throws_like'
 
     test_namespace.'export_to'(curr_namespace, exports)
 

Modified: branches/pluggable_runcore/runtime/parrot/library/Test/More.pir
==============================================================================
--- branches/pluggable_runcore/runtime/parrot/library/Test/More.pir	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/runtime/parrot/library/Test/More.pir	Sun Sep  6 19:36:07 2009	(r41079)
@@ -13,7 +13,7 @@
     .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace
     test_namespace = get_namespace [ 'Test'; 'More' ]
-    exports        = split ' ', 'plan diag ok nok is is_deeply like isa_ok skip isnt todo'
+    exports        = split ' ', 'plan diag ok nok is is_deeply like isa_ok skip isnt todo throws_like'
 
     test_namespace.'export_to'(curr_namespace, exports)
 
@@ -814,6 +814,54 @@
     .return( equal )
 .end
 
+=item C<throws_like( codestring, pattern, description )>
+
+Takes PIR code in C<codestring> and a PGE pattern to match in C<pattern>, as
+well as an optional message in C<description>. Passes a test if the PIR throws
+an exception that matches the pattern, fails the test otherwise.
+
+=cut
+
+.sub throws_like
+    .param string target
+    .param string pattern
+    .param string description :optional
+
+    .local pmc test
+    get_hll_global test, [ 'Test'; 'More' ], '_test'
+
+    .local pmc comp
+    .local pmc compfun
+    .local pmc compiler
+    compiler = compreg 'PIR'
+
+    .local pmc eh
+    eh = new 'ExceptionHandler'
+    set_addr eh, handler            # set handler label for exceptions
+    push_eh eh
+
+    compfun = compiler(target)
+    compfun()                       # eval the target code
+
+    pop_eh
+
+    # if it doesn't throw an exception, fail
+    test.'ok'( 0, description )
+    test.'diag'( 'no error thrown' )
+
+    goto done
+
+  handler:
+    .local pmc ex
+    .local string error_msg
+    .get_results (ex)
+    pop_eh
+    error_msg = ex
+    like(error_msg, pattern, description)
+
+  done:
+.end
+
 =item C<like( target, pattern, description )>
 
 Similar to is, but using the Parrot Grammar Engine to compare the string
@@ -995,7 +1043,7 @@
 
 =head1 COPYRIGHT
 
-Copyright (C) 2005-2008, Parrot Foundation.
+Copyright (C) 2005-2009, Parrot Foundation.
 
 =cut
 

Modified: branches/pluggable_runcore/src/debug.c
==============================================================================
--- branches/pluggable_runcore/src/debug.c	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/debug.c	Sun Sep  6 19:36:07 2009	(r41079)
@@ -117,6 +117,11 @@
 PARROT_WARN_UNUSED_RESULT
 static const char * nextarg(ARGIN_NULLOK(const char *command));
 
+static void no_such_register(PARROT_INTERP,
+    char register_type,
+    UINTVAL register_num)
+        __attribute__nonnull__(1);
+
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 static const char * parse_int(ARGIN(const char *str), ARGOUT(int *intP))
@@ -178,6 +183,8 @@
 #define ASSERT_ARGS_list_breakpoints __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(pdb)
 #define ASSERT_ARGS_nextarg __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
+#define ASSERT_ARGS_no_such_register __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_parse_int __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(str) \
     || PARROT_ASSERT_ARG(intP)
@@ -207,7 +214,7 @@
     if (*skip_whitespace(cmd) == '\0')
         return 1;
     else {
-        Parrot_eprintf(pdb->debugger, "Spurious arg\n");
+        Parrot_io_eprintf(pdb->debugger, "Spurious arg\n");
         return 0;
     }
 }
@@ -1239,7 +1246,7 @@
        } while (*ptr == '\0' || *ptr == '#');
 
         if (pdb->state & PDB_ECHO)
-            Parrot_eprintf(pdb->debugger, "[%lu %s]\n", pdb->script_line, buf);
+            Parrot_io_eprintf(pdb->debugger, "[%lu %s]\n", pdb->script_line, buf);
 
 #if TRACE_DEBUGGER
         fprintf(stderr, "(script) %s\n", buf);
@@ -1436,7 +1443,7 @@
 
     new_runloop_jump_point(debugee);
     if (setjmp(debugee->current_runloop->resume)) {
-        Parrot_eprintf(pdb->debugger, "Unhandled exception while tracing\n");
+        Parrot_io_eprintf(pdb->debugger, "Unhandled exception while tracing\n");
         pdb->state |= PDB_STOPPED;
         return;
     }
@@ -1483,7 +1490,7 @@
     /* execute n ops */
     new_runloop_jump_point(debugee);
     if (setjmp(debugee->current_runloop->resume)) {
-        Parrot_eprintf(pdb->debugger, "Unhandled exception while tracing\n");
+        Parrot_io_eprintf(pdb->debugger, "Unhandled exception while tracing\n");
         pdb->state |= PDB_STOPPED;
         return;
     }
@@ -1962,7 +1969,7 @@
 
     new_internal_exception(pdb->debugee);
     if (setjmp(pdb->debugee->exceptions->destination)) {
-        Parrot_eprintf(pdb->debugee, "Unhandled exception while debugging: %Ss\n",
+        Parrot_io_eprintf(pdb->debugee, "Unhandled exception while debugging: %Ss\n",
             pdb->debugee->exceptions->msg);
         pdb->state |= PDB_STOPPED;
         return;
@@ -3185,6 +3192,26 @@
 
 /*
 
+=item C<static void no_such_register(PARROT_INTERP, char register_type, UINTVAL
+register_num)>
+
+Auxiliar error message function.
+
+=cut
+
+*/
+
+static void
+no_such_register(PARROT_INTERP, char register_type, UINTVAL register_num)
+{
+    ASSERT_ARGS(no_such_register)
+
+    Parrot_io_eprintf(interp, "%c%u = no such register\n",
+        register_type, register_num);
+}
+
+/*
+
 =item C<void PDB_assign(PARROT_INTERP, const char *command)>
 
 Assign to registers.
@@ -3197,58 +3224,59 @@
 PDB_assign(PARROT_INTERP, ARGIN(const char *command))
 {
     ASSERT_ARGS(PDB_assign)
-    unsigned long register_num;
-    char reg_type;
-    char *string;
-    int t;
+    UINTVAL register_num;
+    char reg_type_id;
+    int reg_type;
+    PDB_t *pdb       = interp->pdb;
+    Interp *debugger = pdb ? pdb->debugger : interp;
+    Interp *debugee  = pdb ? pdb->debugee : interp;
 
     /* smallest valid commad length is 4, i.e. "I0 1" */
     if (strlen(command) < 4) {
-        fprintf(stderr, "Must give a register number and value to assign\n");
+        Parrot_io_eprintf(debugger, "Must give a register number and value to assign\n");
         return;
     }
-    reg_type = (char) command[0];
+    reg_type_id = (char) command[0];
     command++;
-    register_num   = get_ulong(&command, 0);
+    register_num = get_ulong(&command, 0);
 
-    switch (reg_type) {
+    switch (reg_type_id) {
         case 'I':
-                if (register_num >= Parrot_pcc_get_regs_used(interp,
-                                            CURRENT_CONTEXT(interp), REGNO_INT)) {
-                    fprintf(stderr, "I%ld = no such register\n", register_num);
-                    return;
-                }
-                t                  = REGNO_INT;
-                IREG(register_num) = get_ulong(&command, 0);
-                break;
+            reg_type = REGNO_INT;
+            break;
         case 'N':
-                if (register_num >= Parrot_pcc_get_regs_used(interp,
-                                            CURRENT_CONTEXT(interp), REGNO_NUM)) {
-                    fprintf(stderr, "N%ld = no such register\n", register_num);
-                    return;
-                }
-                t                  = REGNO_NUM;
-                NREG(register_num) = atof(command);
-                break;
+            reg_type = REGNO_NUM;
+            break;
         case 'S':
-                if (register_num >= Parrot_pcc_get_regs_used(interp,
-                                            CURRENT_CONTEXT(interp), REGNO_NUM)) {
-                    fprintf(stderr, "S%ld = no such register\n", register_num);
-                    return;
-                }
-                t                  = REGNO_STR;
-                SREG(register_num) = Parrot_str_new(interp, command, strlen(command));
-                break;
+            reg_type = REGNO_STR;
+            break;
         case 'P':
-                t = REGNO_PMC;
-                fprintf(stderr, "Assigning to PMCs is not currently supported\n");
-                return;
+            reg_type = REGNO_PMC;
+            Parrot_io_eprintf(debugger, "Assigning to PMCs is not currently supported\n");
+            return;
         default:
-            fprintf(stderr, "Invalid register type %c\n", reg_type);
+            Parrot_io_eprintf(debugger, "Invalid register type %c\n", reg_type_id);
             return;
     }
-    Parrot_io_eprintf(interp, "\n  %c%u = ", reg_type, register_num);
-    Parrot_io_eprintf(interp, "%s\n", GDB_print_reg(interp, t, register_num));
+    if (register_num >= Parrot_pcc_get_regs_used(debugee,
+                                CURRENT_CONTEXT(debugee), reg_type)) {
+        no_such_register(debugger, reg_type_id, register_num);
+        return;
+    }
+    switch (reg_type) {
+        case REGNO_INT:
+            IREG(register_num) = get_ulong(&command, 0);
+            break;
+        case REGNO_NUM:
+            NREG(register_num) = atof(command);
+            break;
+        case REGNO_STR:
+            SREG(register_num) = Parrot_str_new(debugee, command, strlen(command));
+            break;
+        default: ; /* Must never come here */
+    }
+    Parrot_io_eprintf(debugger, "\n  %c%u = ", reg_type_id, register_num);
+    Parrot_io_eprintf(debugger, "%s\n", GDB_print_reg(debugee, reg_type, register_num));
 }
 
 /*
@@ -3340,7 +3368,7 @@
         interp->pdb->debugger : interp;
     TRACEDEB_MSG("PDB_eval");
     UNUSED(command);
-    Parrot_eprintf(warninterp, "The eval command is currently unimplemeneted\n");
+    Parrot_io_eprintf(warninterp, "The eval command is currently unimplemeneted\n");
 }
 
 /*

Modified: branches/pluggable_runcore/src/gc/alloc_register.c
==============================================================================
--- branches/pluggable_runcore/src/gc/alloc_register.c	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/gc/alloc_register.c	Sun Sep  6 19:36:07 2009	(r41079)
@@ -294,6 +294,27 @@
     CURRENT_CONTEXT(interp) = old;
 }
 
+/*
+
+=item C<size_t Parrot_pcc_calculate_context_size(PARROT_INTERP, const UINTVAL
+*number_regs_used)>
+
+Calculate size of Context.
+
+=cut
+
+*/
+size_t
+Parrot_pcc_calculate_context_size(SHIM_INTERP, ARGIN(const UINTVAL *number_regs_used))
+{
+    ASSERT_ARGS(Parrot_pcc_calculate_context_size)
+
+    return ALIGNED_CTX_SIZE + ROUND_ALLOC_SIZE(
+            sizeof (INTVAL)   * number_regs_used[REGNO_INT] +
+            sizeof (FLOATVAL) * number_regs_used[REGNO_NUM] +
+            sizeof (STRING *) * number_regs_used[REGNO_STR] +
+            sizeof (PMC *)    * number_regs_used[REGNO_PMC]);
+}
 
 /*
 
@@ -330,7 +351,12 @@
     const size_t reg_alloc     = ROUND_ALLOC_SIZE(all_regs_size);
 
     const size_t to_alloc = reg_alloc + ALIGNED_CTX_SIZE;
-    ctx                   = (Parrot_Context *)mem_sys_allocate(to_alloc);
+
+#ifdef GC_USE_FIXED_SIZE_ALLOCATOR
+    ctx  = (Parrot_Context *)Parrot_gc_allocate_fixed_size_storage(interp, to_alloc);
+#else
+    ctx  = (Parrot_Context *)mem_sys_allocate(to_alloc);
+#endif
 
     ctx->n_regs_used[REGNO_INT] = number_regs_used[REGNO_INT];
     ctx->n_regs_used[REGNO_NUM] = number_regs_used[REGNO_NUM];

Modified: branches/pluggable_runcore/src/gc/api.c
==============================================================================
--- branches/pluggable_runcore/src/gc/api.c	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/gc/api.c	Sun Sep  6 19:36:07 2009	(r41079)
@@ -1586,15 +1586,10 @@
 
 /*
 
-=item C<void * Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, PMC *pmc, size_t
-size)>
-
-EXPERIMENTAL!!!
+=item C<void * Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, PMC *pmc)>
 
-Allocation and deallocation function for PMC Attribute structures.
-
-These functions are not currently used. They are waiting for changes to
-the PMC allocation/deallocation mechanisms. See TT #895 for details.
+Allocates a new attribute structure for a PMC if it has the auto_attrs flag
+set.
 
 =cut
 
@@ -1602,40 +1597,50 @@
 
 PARROT_CANNOT_RETURN_NULL
 void *
-Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc), size_t size)
+Parrot_gc_allocate_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_gc_allocate_pmc_attributes)
-    /* const size_t attr_size = pmc->vtable->attr_size; */
-    const size_t attr_size = size;
+#if GC_USE_FIXED_SIZE_ALLOCATOR
+    const size_t attr_size = pmc->vtable->attr_size;
     PMC_Attribute_Pool * const pool = Parrot_gc_get_attribute_pool(interp,
         attr_size);
     void * const attrs = Parrot_gc_get_attributes_from_pool(interp, pool);
-    memset(attrs, 0, size);
+    memset(attrs, 0, attr_size);
     PMC_data(pmc) = attrs;
     return attrs;
+#else
+    void * const data =  mem_sys_allocate_zeroed(new_vtable->attr_size);
+    PMC_data(pmc) = data;
+    return data;
+#endif
 }
 
 /*
 
-=item C<void Parrot_gc_free_pmc_attributes(PARROT_INTERP, PMC *pmc, size_t
-item_size)>
+=item C<void Parrot_gc_free_pmc_attributes(PARROT_INTERP, PMC *pmc)>
 
-EXPERIMENTAL!!!  See above.
+Deallocates an attibutes structure from a PMC if it has the auto_attrs
+flag set.
 
 */
 
 void
-Parrot_gc_free_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc), size_t item_size)
+Parrot_gc_free_pmc_attributes(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_gc_free_pmc_attributes)
     void * const data = PMC_data(pmc);
 
     if (data) {
-        PMC_Attribute_Pool       **pools = interp->arena_base->attrib_pools;
-        const size_t               idx   = item_size - sizeof (void *);
-        PMC_Attribute_Pool * const pool  = pools[idx];
-        Parrot_gc_free_attributes_from_pool(interp, pool, data);
+#if GC_USE_FIXED_SIZE_ALLOCATOR
+        const size_t attr_size = pmc->vtable->attr_size;
+        const size_t item_size = attr_size < sizeof (void *) ? sizeof (void *) : attr_size;
+        PMC_Attribute_Pool ** const pools = interp->arena_base->attrib_pools;
+        const size_t idx = item_size - sizeof (void *);
+        Parrot_gc_free_attributes_from_pool(interp, pools[idx], data);
+#else
+        mem_sys_free(PMC_data(pmc));
         PMC_data(pmc) = NULL;
+#endif
     }
 }
 
@@ -1644,7 +1649,8 @@
 =item C<void * Parrot_gc_allocate_fixed_size_storage(PARROT_INTERP, size_t
 size)>
 
-EXPERIMENTAL!!!  See above.
+Allocates a fixed-size chunk of memory for use. This memory is not manually
+managed and needs to be freed with C<Parrot_gc_free_fixed_size_storage>
 
 */
 
@@ -1663,7 +1669,8 @@
 =item C<void Parrot_gc_free_fixed_size_storage(PARROT_INTERP, size_t size, void
 *data)>
 
-EXPERIMENTAL!!!  See above.
+Manually deallocates fixed size storage allocated with
+C<Parrot_gc_allocate_fixed_size_storage>
 
 */
 
@@ -1671,11 +1678,10 @@
 Parrot_gc_free_fixed_size_storage(PARROT_INTERP, size_t size, ARGMOD(void *data))
 {
     ASSERT_ARGS(Parrot_gc_free_fixed_size_storage)
-    PMC_Attribute_Pool       **pools = interp->arena_base->attrib_pools;
-    const size_t               idx   = size - sizeof (void *);
-    PMC_Attribute_Pool * const pool  = pools[idx];
-
-    Parrot_gc_free_attributes_from_pool(interp, pool, data);
+    const size_t item_size = size < sizeof (void *) ? sizeof (void *) : size;
+    const size_t idx   = size - sizeof (void *);
+    PMC_Attribute_Pool ** const pools = interp->arena_base->attrib_pools;
+    Parrot_gc_free_attributes_from_pool(interp, pools[idx], data);
 }
 
 /*

Modified: branches/pluggable_runcore/src/gc/gc_private.h
==============================================================================
--- branches/pluggable_runcore/src/gc/gc_private.h	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/gc/gc_private.h	Sun Sep  6 19:36:07 2009	(r41079)
@@ -70,6 +70,15 @@
    enough to satisfy most startup costs. */
 #define GC_USE_LAZY_ALLOCATOR 1
 
+/* Set to 1 if we want to use the fixed-size allocator. Set to 0 if we want
+   to allocate these things using mem_sys_allocate instead */
+/* Had seen errors on Windows. Appears to be fixed now. TT #940 */
+#if defined(_WIN32) || defined(_WIN64)
+#  define GC_USE_FIXED_SIZE_ALLOCATOR 1
+#else
+#  define GC_USE_FIXED_SIZE_ALLOCATOR 1
+#endif
+
 /* 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
    in Parrot. Astute observers may notice that if the PObj is comprised of

Modified: branches/pluggable_runcore/src/pmc.c
==============================================================================
--- branches/pluggable_runcore/src/pmc.c	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/pmc.c	Sun Sep  6 19:36:07 2009	(r41079)
@@ -121,19 +121,10 @@
     if (PObj_is_PMC_shared_TEST(pmc) && PMC_sync(pmc))
         Parrot_gc_free_pmc_sync(interp, pmc);
 
-    if (pmc->vtable->attr_size) {
-        if (PMC_data(pmc)) {
-#if GC_USE_FIXED_SIZE_ALLOCATOR
-            Parrot_gc_free_pmc_attributes(interp, pmc, pmc->vtable->attr_size);
-#else
-            mem_sys_free(PMC_data(pmc));
-            PMC_data(pmc) = NULL;
-#endif
-        }
-    }
-    else {
+    if (pmc->vtable->attr_size)
+        Parrot_gc_free_pmc_attributes(interp, pmc);
+    else
         PMC_data(pmc) = NULL;
-    }
 
 #ifndef NDEBUG
 
@@ -280,13 +271,9 @@
     /* Set the right vtable */
     pmc->vtable = new_vtable;
 
-    if (new_vtable->attr_size) {
-#if GC_USE_FIXED_SIZE_ALLOCATOR
-        Parrot_gc_allocate_pmc_attributes(interp, pmc, new_vtable->attr_size);
-#else
-        PMC_data(pmc) = mem_sys_allocate_zeroed(new_vtable->attr_size);
-#endif
-}
+    if (new_vtable->attr_size)
+        Parrot_gc_allocate_pmc_attributes(interp, pmc);
+
     else
         PMC_data(pmc) = NULL;
 
@@ -332,13 +319,8 @@
     /* Set the right vtable */
     pmc->vtable = new_vtable;
 
-    if (new_vtable->attr_size) {
-#if GC_USE_FIXED_SIZE_ALLOCATOR
-        Parrot_gc_allocate_pmc_attributes(interp, pmc, new_vtable->attr_size);
-#else
-        PMC_data(pmc) = mem_sys_allocate_zeroed(new_vtable->attr_size);
-#endif
-}
+    if (new_vtable->attr_size)
+        Parrot_gc_allocate_pmc_attributes(interp, pmc);
     else
         PMC_data(pmc) = NULL;
 
@@ -476,13 +458,8 @@
     pmc            = Parrot_gc_new_pmc_header(interp, flags);
     pmc->vtable    = vtable;
 
-    if (vtable->attr_size) {
-#if GC_USE_FIXED_SIZE_ALLOCATOR
-        Parrot_gc_allocate_pmc_attributes(interp, pmc, pmc->vtable->attr_size);
-#else
-        PMC_data(pmc) = mem_sys_allocate_zeroed(vtable->attr_size);
-#endif
-    }
+    if (vtable->attr_size)
+        Parrot_gc_allocate_pmc_attributes(interp, pmc);
 
 #if GC_VERBOSE
     if (Interp_flags_TEST(interp, PARROT_TRACE_FLAG)) {

Modified: branches/pluggable_runcore/src/pmc/context.pmc
==============================================================================
--- branches/pluggable_runcore/src/pmc/context.pmc	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/pmc/context.pmc	Sun Sep  6 19:36:07 2009	(r41079)
@@ -126,7 +126,18 @@
     VTABLE void destroy() {
         /* We own this pointer */
         Parrot_Context * const ctx = PMC_data_typed(SELF, Parrot_Context*);
+
+        if (!ctx)
+            return;
+
+#ifdef GC_USE_FIXED_SIZE_ALLOCATOR
+        Parrot_gc_free_fixed_size_storage(interp,
+                Parrot_pcc_calculate_context_size(INTERP, ctx->n_regs_used),
+                ctx);
+#else
         mem_sys_free(ctx);
+#endif
+        PMC_data(SELF) = NULL;
     }
 
 /*

Modified: branches/pluggable_runcore/src/pmc/continuation.pmc
==============================================================================
--- branches/pluggable_runcore/src/pmc/continuation.pmc	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/pmc/continuation.pmc	Sun Sep  6 19:36:07 2009	(r41079)
@@ -67,7 +67,7 @@
 */
 
     VTABLE void init() {
-        Parrot_Continuation_attributes *attrs = PARROT_CONTINUATION(SELF);
+        Parrot_Continuation_attributes * const attrs = PARROT_CONTINUATION(SELF);
 
         attrs->to_ctx     = CURRENT_CONTEXT(interp);
         attrs->from_ctx   = CURRENT_CONTEXT(interp);
@@ -91,13 +91,14 @@
 
     /*if they pass in a PMC to initialize with*/
     VTABLE void init_pmc(PMC *values) {
-        Parrot_Continuation_attributes *attrs = PARROT_CONTINUATION(SELF);
+        Parrot_Continuation_attributes * const attrs  = PARROT_CONTINUATION(SELF);
+        Parrot_Continuation_attributes * const theirs = PARROT_CONTINUATION(values);
 
-        attrs->to_ctx     = PARROT_CONTINUATION(values)->to_ctx;
+        attrs->to_ctx     = theirs->to_ctx;
         attrs->from_ctx   = CURRENT_CONTEXT(interp);
         attrs->runloop_id = 0;
-        attrs->seg        = PARROT_CONTINUATION(values)->seg;
-        attrs->address    = PARROT_CONTINUATION(values)->address;
+        attrs->seg        = theirs->seg;
+        attrs->address    = theirs->address;
         attrs->current_results = Parrot_pcc_get_results(interp, attrs->to_ctx);
 
         PObj_active_destroy_SET(SELF);
@@ -130,7 +131,6 @@
 
         if (cc->seg)
             Parrot_gc_mark_PObj_alive(interp, (PObj *)cc->seg);
-
         if (cc->to_ctx)
             Parrot_gc_mark_PObj_alive(INTERP, (PObj *) cc->to_ctx);
         if (cc->from_ctx)
@@ -139,18 +139,6 @@
 
 /*
 
-=item C<void destroy()>
-
-Destroys the continuation.
-
-=cut
-
-*/
-
-    VTABLE void destroy() {
-    }
-/*
-
 =item C<PMC *clone()>
 
 Creates and returns a clone of the continuation.
@@ -160,7 +148,7 @@
 */
 
     VTABLE PMC *clone() {
-        PMC         * ret      = pmc_new_init(interp, enum_class_Continuation, SELF);
+        PMC * ret = pmc_new_init(interp, enum_class_Continuation, SELF);
         return ret;
     }
 
@@ -248,10 +236,10 @@
 */
 
     VTABLE opcode_t *invoke(void *next) {
-        Parrot_cont *cc           = PMC_cont(SELF);
-        PMC         *from_ctx     = CURRENT_CONTEXT(interp);
-        PMC         *to_ctx       = cc->to_ctx;
-        opcode_t    *pc           = cc->address;
+        Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(SELF);
+        PMC      *from_ctx = CURRENT_CONTEXT(interp);
+        PMC      *to_ctx   = cc->to_ctx;
+        opcode_t *pc       = cc->address;
         UNUSED(next)
 
         Parrot_continuation_check(interp, SELF);
@@ -282,8 +270,8 @@
         /* switch segment */
         INTERP->current_args = NULL;
 
-        if (INTERP->code != PARROT_CONTINUATION(SELF)->seg)
-            Parrot_switch_to_cs(INTERP, PARROT_CONTINUATION(SELF)->seg, 1);
+        if (INTERP->code != cc->seg)
+            Parrot_switch_to_cs(INTERP, cc->seg, 1);
 
         return pc;
     }
@@ -313,8 +301,8 @@
 */
 
     METHOD caller() {
-        Parrot_Continuation_attributes *cc     = PARROT_CONTINUATION(SELF);
-        PMC         *caller = Parrot_pcc_get_sub(interp, cc->to_ctx);
+        Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(SELF);
+        PMC *caller = Parrot_pcc_get_sub(interp, cc->to_ctx);
         Parrot_Sub_attributes  *sub;
 
         if (!caller)
@@ -339,8 +327,8 @@
 */
 
     METHOD continuation() {
-        Parrot_Continuation_attributes *cc   = PARROT_CONTINUATION(SELF);
-        PMC         *cont = Parrot_pcc_get_continuation(interp, cc->to_ctx);
+        Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(SELF);
+        PMC * const cont = Parrot_pcc_get_continuation(interp, cc->to_ctx);
 
         if (cont)
             RETURN(PMC *cont);

Modified: branches/pluggable_runcore/src/pmc/retcontinuation.pmc
==============================================================================
--- branches/pluggable_runcore/src/pmc/retcontinuation.pmc	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/pmc/retcontinuation.pmc	Sun Sep  6 19:36:07 2009	(r41079)
@@ -75,9 +75,10 @@
 */
 
     VTABLE opcode_t *invoke(void *in_next) {
-        PMC               *from_ctx   = PARROT_CONTINUATION(SELF)->from_ctx;
-        PackFile_ByteCode * const seg = PARROT_CONTINUATION(SELF)->seg;
-        opcode_t          *next       = PARROT_CONTINUATION(SELF)->address;
+        Parrot_Continuation_attributes *data = PARROT_CONTINUATION(SELF);
+        PMC               *from_ctx   = data->from_ctx;
+        PackFile_ByteCode * const seg = data->seg;
+        opcode_t          *next       = data->address;
         UNUSED(in_next)
 
         Parrot_continuation_check(interp, SELF);
@@ -86,7 +87,7 @@
         /* the continuation is dead - delete and destroy it */
         /* 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 */
+           failure. */
         /* Parrot_gc_free_pmc_header(interp, SELF); */
 
         if (INTERP->code != seg)

Modified: branches/pluggable_runcore/src/sub.c
==============================================================================
--- branches/pluggable_runcore/src/sub.c	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/src/sub.c	Sun Sep  6 19:36:07 2009	(r41079)
@@ -99,7 +99,6 @@
         ctx  = Parrot_pcc_get_caller_ctx(interp, ctx);
         cont = Parrot_pcc_get_continuation(interp, ctx);
     }
-
 }
 
 /*
@@ -186,7 +185,7 @@
 PARROT_EXPORT
 int
 Parrot_Context_get_info(PARROT_INTERP, ARGIN(PMC *ctx),
-                    ARGOUT(Parrot_Context_info *info))
+    ARGOUT(Parrot_Context_info *info))
 {
     ASSERT_ARGS(Parrot_Context_get_info)
     PMC                   *subpmc;
@@ -453,7 +452,7 @@
 parrot_new_closure(PARROT_INTERP, ARGIN(PMC *sub_pmc))
 {
     ASSERT_ARGS(parrot_new_closure)
-    PMC        * const clos_pmc = VTABLE_clone(interp, sub_pmc);
+    PMC * const clos_pmc = VTABLE_clone(interp, sub_pmc);
     Parrot_capture_lex(interp, clos_pmc);
     return clos_pmc;
 }
@@ -473,16 +472,12 @@
 Parrot_continuation_check(PARROT_INTERP, ARGIN(const PMC *pmc))
 {
     ASSERT_ARGS(Parrot_continuation_check)
-
-    PMC *to_ctx       = PARROT_CONTINUATION(pmc)->to_ctx;
-    PMC *from_ctx     = CURRENT_CONTEXT(interp);
-
+    PMC * const to_ctx       = PARROT_CONTINUATION(pmc)->to_ctx;
     if (PMC_IS_NULL(to_ctx))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                        "Continuation invoked after deactivation.");
 }
 
-
 /*
 
 =item C<void Parrot_continuation_rewind_environment(PARROT_INTERP, PMC *pmc)>
@@ -530,8 +525,7 @@
 void *
 Parrot_get_sub_pmc_from_subclass(PARROT_INTERP, ARGIN(PMC *subclass)) {
     ASSERT_ARGS(Parrot_get_sub_pmc_from_subclass)
-    PMC        *key, *sub_pmc;
-    Parrot_Sub_attributes *sub;
+    PMC *key, *sub_pmc;
 
     /* Ensure we really do have a subclass of sub. */
     if (VTABLE_isa(interp, subclass, CONST_STRING(interp, "Sub"))) {

Modified: branches/pluggable_runcore/t/library/test_more.t
==============================================================================
--- branches/pluggable_runcore/t/library/test_more.t	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/t/library/test_more.t	Sun Sep  6 19:36:07 2009	(r41079)
@@ -1,5 +1,5 @@
-#!./parrot
-# Copyright (C) 2005-2008, Parrot Foundation.
+#!parrot
+# Copyright (C) 2005-2009, Parrot Foundation.
 # $Id$
 
 .sub _main :main
@@ -15,14 +15,14 @@
     .local pmc exports, curr_namespace, test_namespace
     curr_namespace = get_namespace
     test_namespace = get_namespace [ 'Test'; 'More' ]
-    exports = split " ", "ok is diag like skip todo is_deeply isa_ok isnt"
+    exports = split " ", "ok is diag like skip todo is_deeply isa_ok isnt throws_like"
     test_namespace.'export_to'(curr_namespace, exports)
 
     test_namespace = get_namespace [ 'Test'; 'Builder'; 'Tester' ]
     exports = split " ", "plan test_out test_diag test_fail test_pass test_test"
     test_namespace.'export_to'(curr_namespace, exports)
 
-    plan( 75 )
+    plan( 79 )
 
     test_skip()
     test_todo()
@@ -32,11 +32,45 @@
     test_like()
     test_is_deeply()
     test_diagnostics()
+    test_throws_like()
     test_isa_ok()
 
     test.'finish'()
 .end
 
+.sub test_throws_like
+
+    test_fail('throws_like fails when there is no error')
+
+    throws_like( <<'CODE', 'somejunk', 'throws_like fails when there is no error')
+.sub main
+    $I0 = 42
+.end
+CODE
+
+    test_diag( 'no error thrown' )
+    test_test( 'throws_like fails when there is no error')
+    test_pass('throws_like passes when error matches pattern')
+
+    throws_like( <<'CODE', '<[for the lulz]>','throws_like passes when error matches pattern')
+.sub main
+    die 'I did it for the lulz'
+.end
+CODE
+
+    test_test( 'throws_like passes when error matches pattern' )
+
+    test_fail( 'throws_like fails when error does not match pattern' )
+
+    throws_like( <<'CODE', '<[for the lulz]>','throws_like fails when error does not match pattern')
+.sub main
+    die 'DO NOT WANT'
+.end
+CODE
+    test_diag( 'match failed' )
+    test_test('throws_like fails when error does not match pattern' )
+.end
+
 .sub test_ok
     test_pass()
     ok( 1 )
@@ -271,6 +305,10 @@
     test_diag( 'match failed' )
     like( 'abcdef', '<[g]>', 'testing like()' )
     test_test( 'failing test like() with description' )
+
+    test_pass( 'like() can match literal strings' )
+    like( 'foobar', 'foobar', 'like() can match literal strings' )
+    test_test( 'like() can match literal strings' )
 .end
 
 .sub test_is_deeply

Modified: branches/pluggable_runcore/t/pmc/fixedpmcarray.t
==============================================================================
--- branches/pluggable_runcore/t/pmc/fixedpmcarray.t	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/t/pmc/fixedpmcarray.t	Sun Sep  6 19:36:07 2009	(r41079)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw(lib . ../lib ../../lib);
 
-use Parrot::Test tests => 25;
+use Parrot::Test tests => 26;
 use Test::More;
 
 =head1 NAME
@@ -800,6 +800,22 @@
 /FixedPMCArray: index out of bounds!/
 OUTPUT
 
+pir_output_like( <<'CODE', <<'OUTPUT', 'get_repr');
+.sub 'main'
+    .local pmc fpa, n
+    .local string s
+    fpa = new ['FixedPMCArray']
+    fpa = 2
+    n = box 1
+    fpa[0] = n
+    fpa[1] = n
+    s = get_repr fpa
+    say s
+.end
+CODE
+/(1,\s*1)/
+OUTPUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Modified: branches/pluggable_runcore/t/pmc/namespace.t
==============================================================================
--- branches/pluggable_runcore/t/pmc/namespace.t	Sun Sep  6 19:20:10 2009	(r41078)
+++ branches/pluggable_runcore/t/pmc/namespace.t	Sun Sep  6 19:36:07 2009	(r41079)
@@ -12,7 +12,39 @@
 
 =head1 DESCRIPTION
 
-Tests the NameSpace PMC.
+Tests the NameSpace PMC. Some things that it tests specifically:
+
+=over 4
+
+=item* Creating new NameSpace PMCs
+
+=item* Verify that things which are supposed to return a NameSpace actually
+do.
+
+=item* Various forms of get_global opcode
+
+=item* Finding and calling Subs which are stored in the NameSpace
+
+=item* Methods on the NameSpace PMC
+
+=item* Building NameSpace hierarchies on the fly
+
+=item* HLL NameSpaces
+
+=back
+
+Items that need to be tested according to PDD21, or the current source code
+of the NameSpace PMC:
+
+=over 4
+
+=item* methods: add_sub, del_sub, del_var, del_namespace
+
+=item* Typed and Untyped interfaces
+
+=item* Subclassing NameSpace (If it's possible)
+
+=back
 
 =cut
 
@@ -20,10 +52,11 @@
 
 .sub main :main
     .include 'test_more.pir'
-    plan(44)
+    plan(59)
 
     create_namespace_pmc()
     verify_namespace_type()
+    get_namespace_class()
     get_global_opcode()
     get_sub_from_namespace_hash()
     access_sub_in_namespace()
@@ -55,14 +88,76 @@
     typeof $S0, $P0
     is($S0, "NameSpace", "Root NameSpace is a NameSpace")
 
+    # While we're here. Prove that the root namespace stringifies to ""
+    $S0 = $P0
+    is($S0, "", "Root NameSpace stringifies to empty string")
+
     # parrot namespace
     $P1 = $P0["parrot"]
     typeof $S0, $P1
     is($S0, "NameSpace", "::parrot NameSpace is a NameSpace")
 
+    # get_namespace with no args
     $P0 = get_namespace
     typeof $S0, $P1
     is($S0, "NameSpace", "Current NameSpace is a NameSpace")
+
+    # Prove that HLL namespace names are mangled to lower-case
+    $P0 = get_root_namespace ["MyHLL"]
+    $I0 = isnull $P0
+    is($I0, 1, "HLL NameSpace names are stored lowercase")
+
+    $P0 = get_root_namespace ["myhll"]
+    $I0 = isnull $P0
+    is($I0, 0, "HLL NameSpaces are name-mangled lowercase")
+
+    # Get an HLL namespace and verify that it's a NameSpace PMC
+    $P0 = get_root_namespace ["myhll"]
+    $S0 = typeof $P0
+    is($S0, "NameSpace", "HLL NameSpaces are NameSpaces too")
+
+.end
+
+.sub 'get_namespace_class'
+    # First, prove that we don't have a class until it's created
+    $P0 = get_global "Foo"
+    $P1 = get_class $P0
+    $I0 = isnull $P1
+    is($I0, 1, "NameSpace doesn't have a Class till it's created")
+
+    # Can create a new class from a NameSpace
+    $P1 = newclass $P0
+    $I0 = isnull $P1
+    is($I0, 0, "Create Class from NameSpace")
+
+    # New Class is a Class
+    $S0 = typeof $P1
+    is($S0, "Class", "get_class on a NameSpace returns a Class")
+
+    # Class has same name as namespace
+    $S0 = $P0
+    $S1 = $P1
+    is($S0, $S1, "Class has same name as NameSpace")
+
+    # Now, we do have a class
+    $P1 = get_class $P0
+    $I0 = isnull $P1
+    is($I0, 0, "get_class on a NameSpace returns something")
+
+    # Create object from class from NameSpace
+    push_eh eh
+    $P2 = new $P1
+    pop_eh
+    ok(1, "Can create a new object from a namespace")
+    goto pmc_is_created
+  eh:
+    ok(0, "Cannot create a new object from a namespace")
+  pmc_is_created:
+
+    # Object from Class from NameSpace has right type
+    $S0 = typeof $P2
+    is($S0, "Foo", "Object created from class has name of NameSpace")
+
 .end
 
 # L<PDD21//>
@@ -198,11 +293,13 @@
 .end
 
 .sub 'access_sub_in_namespace'
+    # Direct access of sub that does exist in current namespace
     $S0 = baz()
     $P0 = get_global "baz"
     $S1 = $P0()
     is($S0, $S1, "Direct and Indirect Sub calls")
 
+    # Direct access of sub that doesn't exist in current namespace
     push_eh eh
     'SUB_AINT_THERE'()
     ok(0, "Directly called a sub that doesn't exist")
@@ -246,6 +343,13 @@
     $P2 = $P3.'get_name'()
     $S0 = join '::', $P2
     is($S0, "parrot::Temp1", "Add a NameSpace with a given name")
+
+    # test VTABLE_get_string while we are here
+    $S0 = $P1
+    is($S0, "parrot", "get_string on HLL NameSpace")
+
+    $S0 = $P3
+    is($S0, "Temp1", "get_string on NameSpace")
 .end
 
 .sub 'hll_namespaces'
@@ -269,6 +373,22 @@
     $P1 = $P0["baz"]
     $S0 = $P1()
     is($S0, "Foo", "get a Sub from a HLL namespace")
+
+    # find something an a different .HLL
+    push_eh eh1
+    $P0 = get_root_namespace ["myhll"]
+    $P1 = $P0["baz"]
+    $S0 = $P1()
+    pop_eh
+    is($S0, "MyHLL", "Found Sub in HLL namespace by key")
+    goto test2
+  eh1:
+    ok(0, "Cannot find sub in HLL NameSpace by key")
+
+  test2:
+    $P0 = get_root_namespace ["myhll";"baz"]
+    $I0 = isnull $P0
+    is($I0, 1, "get_root_namespace only returns NameSpace PMCs")
 .end
 
 .sub 'namespace_methods'
@@ -378,3 +498,9 @@
 .sub 'baz'
     .return(iso-8859-1:"Foo::François")
 .end
+
+.HLL "MyHLL"
+
+.sub 'baz'
+    .return("MyHLL")
+.end


More information about the parrot-commits mailing list