[svn:parrot] r48796 - in branches/charset_massacre: . compilers/imcc examples/japh include/parrot lib/Parrot/Pmc2c src src/interp src/io src/ops src/pmc src/string t/examples t/pmc

nwellnhof at svn.parrot.org nwellnhof at svn.parrot.org
Sun Sep 5 03:02:55 UTC 2010


Author: nwellnhof
Date: Sun Sep  5 03:02:55 2010
New Revision: 48796
URL: https://trac.parrot.org/parrot/changeset/48796

Log:
Bring branch up-to-date with trunk

Added:
   branches/charset_massacre/src/pmc/nativepccmethod.pmc
Deleted:
   branches/charset_massacre/examples/japh/README
   branches/charset_massacre/examples/japh/japh1.pasm
   branches/charset_massacre/examples/japh/japh3.pasm
   branches/charset_massacre/examples/japh/japh4.pasm
   branches/charset_massacre/examples/japh/japh5.pasm
   branches/charset_massacre/t/examples/japh.t
Modified:
   branches/charset_massacre/DEPRECATED.pod
   branches/charset_massacre/MANIFEST
   branches/charset_massacre/compilers/imcc/pbc.c
   branches/charset_massacre/include/parrot/interpreter.h
   branches/charset_massacre/include/parrot/nci.h
   branches/charset_massacre/lib/Parrot/Pmc2c/PMCEmitter.pm
   branches/charset_massacre/src/dynext.c
   branches/charset_massacre/src/interp/inter_misc.c
   branches/charset_massacre/src/io/utf8.c
   branches/charset_massacre/src/multidispatch.c
   branches/charset_massacre/src/namespace.c
   branches/charset_massacre/src/oo.c
   branches/charset_massacre/src/ops/core_ops.c
   branches/charset_massacre/src/ops/object.ops
   branches/charset_massacre/src/ops/pmc.ops
   branches/charset_massacre/src/pmc/default.pmc
   branches/charset_massacre/src/pmc/namespace.pmc
   branches/charset_massacre/src/pmc/nci.pmc
   branches/charset_massacre/src/pmc/object.pmc
   branches/charset_massacre/src/pmc/stringbuilder.pmc
   branches/charset_massacre/src/pmc/stringhandle.pmc
   branches/charset_massacre/src/pmc/undef.pmc
   branches/charset_massacre/src/string/api.c
   branches/charset_massacre/t/pmc/object-meths.t
   branches/charset_massacre/t/pmc/stringbuilder.t

Modified: branches/charset_massacre/DEPRECATED.pod
==============================================================================
--- branches/charset_massacre/DEPRECATED.pod	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/DEPRECATED.pod	Sun Sep  5 03:02:55 2010	(r48796)
@@ -71,13 +71,6 @@
 
 L<https://trac.parrot.org/parrot/ticket/103>
 
-=item NCI without signature ("raw" pointers) [eligible in 2.4]
-
-No equivalent functionality is promised. You shouldn't be using this. Here be
-segfaults.
-
-L<https://trac.parrot.org/parrot/ticket/1549>
-
 =item UnManagedStruct handling nested structure [eligible in 2.4]
 
 UnManagedStruct will be simplified to only support flat structures. This means

Modified: branches/charset_massacre/MANIFEST
==============================================================================
--- branches/charset_massacre/MANIFEST	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/MANIFEST	Sun Sep  5 03:02:55 2010	(r48796)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Wed Sep  1 00:17:03 2010 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Sun Sep  5 23:53:29 2010 UT
 #
 # See below for documentation on the format of this file.
 #
@@ -602,11 +602,6 @@
 examples/io/http.pir                                        [examples]
 examples/io/httpd.pir                                       [examples]
 examples/io/post.pir                                        [examples]
-examples/japh/README                                        [examples]
-examples/japh/japh1.pasm                                    [examples]
-examples/japh/japh3.pasm                                    [examples]
-examples/japh/japh4.pasm                                    [examples]
-examples/japh/japh5.pasm                                    [examples]
 examples/json/postalcodes.pir                               [examples]
 examples/json/test.pir                                      [examples]
 examples/languages/abc/MAINTAINER                           [examples]
@@ -1392,6 +1387,7 @@
 src/pmc/managedstruct.pmc                                   []
 src/pmc/multisub.pmc                                        []
 src/pmc/namespace.pmc                                       []
+src/pmc/nativepccmethod.pmc                                 []
 src/pmc/nci.pmc                                             []
 src/pmc/null.pmc                                            []
 src/pmc/object.pmc                                          []
@@ -1680,7 +1676,6 @@
 t/dynpmc/subclass_with_pir_method.t                         [test]
 t/dynpmc/subproxy.t                                         [test]
 t/examples/catchall.t                                       [test]
-t/examples/japh.t                                           [test]
 t/examples/library.t                                        [test]
 t/examples/namespace.t                                      [test]
 t/examples/pasm.t                                           [test]

Modified: branches/charset_massacre/compilers/imcc/pbc.c
==============================================================================
--- branches/charset_massacre/compilers/imcc/pbc.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/compilers/imcc/pbc.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -2375,7 +2375,7 @@
                     &interp->initial_pf->directory;
             interp->code->annotations = (PackFile_Annotations *)
                     PackFile_Segment_new_seg(interp, dir,
-                        PF_ANNOTATIONS_SEG, name, add);
+                        PF_ANNOTATIONS_SEG, name, 1);
             interp->code->annotations->code = interp->code;
 
             /* Create initial group. */

Deleted: branches/charset_massacre/examples/japh/README
==============================================================================
--- branches/charset_massacre/examples/japh/README	Sun Sep  5 03:02:55 2010	(r48795)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,13 +0,0 @@
-# Copyright (C) 2001-2005, Parrot Foundation.
-$Id$
-
-These programs show very different ways how to print a simple
-string. Some are obfuscated, some are horribly platform dependent.
-
-To run them all (from the top level directory)
-
-$ make
-$ for f in examples/japh/japh*.pasm; do ./parrot $f ; done
-
-These JAPHs are also tested by 'make test' in the Parrot root directory.
-The test file is 't/examples/japh.t'.

Deleted: branches/charset_massacre/examples/japh/japh1.pasm
==============================================================================
--- branches/charset_massacre/examples/japh/japh1.pasm	Sun Sep  5 03:02:55 2010	(r48795)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,29 +0,0 @@
-# Copyright (C) 2004-2009, Parrot Foundation.
-# $Id$
-
-	newclass P0, "Japh"
-	new P0, "Japh"
-	set I0, 0
-	set S0, P0[I0]
-	print S0
-	inc I0
-	set S0, P0[I0]
-	print S0
-	end
-.namespace ["Japh"]
-.pcc_sub :vtable get_string_keyed:
-	get_params "0,0", P1, I1
-	unless I1, x
-	set S1, "Parrot Hacker\n"
-	set_returns "0", S1
-	returncc
-x:
-	set S1, "Just another "
-	set_returns "0", S1
-	returncc
-
-# Local Variables:
-#   mode: pir
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:

Deleted: branches/charset_massacre/examples/japh/japh3.pasm
==============================================================================
--- branches/charset_massacre/examples/japh/japh3.pasm	Sun Sep  5 03:02:55 2010	(r48795)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,19 +0,0 @@
-# Copyright (C) 2004-2010, Parrot Foundation.
-# $Id$
-
-# the substr JaPH
-    set S0, "Hacker\n"
-    set S1, "Parrot "
-    set S2, "another "
-    set S3, "Just "
-    replace S3, S3, 5,  1, S2
-    replace S3, S3, 13, 1, S1
-    replace S3, S3, 20, 1, S0
-    print S3
-    end
-
-# Local Variables:
-#   mode: pir
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:

Deleted: branches/charset_massacre/examples/japh/japh4.pasm
==============================================================================
--- branches/charset_massacre/examples/japh/japh4.pasm	Sun Sep  5 03:02:55 2010	(r48795)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,19 +0,0 @@
-# Copyright (C) 2004-2009, Parrot Foundation.
-# $Id$
-
-newclass P1, "Japh"
-new P2, "Japh"
-print P2
-end
-
-.namespace ["Japh"]
-.pcc_sub :vtable get_string:
-	set S3, "Just another Parrot Hacker\n"
-	set_returns "0", S3
-	returncc
-
-# Local Variables:
-#   mode: pir
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:

Deleted: branches/charset_massacre/examples/japh/japh5.pasm
==============================================================================
--- branches/charset_massacre/examples/japh/japh5.pasm	Sun Sep  5 03:02:55 2010	(r48795)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,27 +0,0 @@
-# Copyright (C) 2004-2009, Parrot Foundation.
-# $Id$
-
-# JaPH utilizing an object
-    newclass P0, "Japh"
-    new P0, "Japh"
-    set P0[1], "Just"
-    set P0[2], "another"
-    set P0[3], "Parrot"
-    set P0[0], "Hacker"
-    end
-.namespace ["Japh"]
-.pcc_sub :vtable set_string_keyed:
-    get_params "0,0,0", P5, I5, S5
-    print S5
-    if I5, sp
-    print "\n"
-    returncc
-sp:
-    print " "
-    returncc
-
-# Local Variables:
-#   mode: pir
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/charset_massacre/include/parrot/interpreter.h
==============================================================================
--- branches/charset_massacre/include/parrot/interpreter.h	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/include/parrot/interpreter.h	Sun Sep  5 03:02:55 2010	(r48796)
@@ -503,24 +503,26 @@
         __attribute__nonnull__(3);
 
 PARROT_EXPORT
-void register_nci_method(PARROT_INTERP,
+void register_native_pcc_method_in_ns(PARROT_INTERP,
     const int type,
     ARGIN(void *func),
-    ARGIN(const char *name),
-    ARGIN(const char *proto))
+    ARGIN(STRING *name),
+    ARGIN(STRING *signature))
         __attribute__nonnull__(1)
         __attribute__nonnull__(3)
         __attribute__nonnull__(4)
         __attribute__nonnull__(5);
 
 PARROT_EXPORT
-void register_raw_nci_method_in_ns(PARROT_INTERP,
+void register_nci_method(PARROT_INTERP,
     const int type,
     ARGIN(void *func),
-    ARGIN(STRING *name))
+    ARGIN(const char *name),
+    ARGIN(const char *proto))
         __attribute__nonnull__(1)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4);
+        __attribute__nonnull__(4)
+        __attribute__nonnull__(5);
 
 #define ASSERT_ARGS_interpinfo __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
@@ -539,15 +541,17 @@
 #define ASSERT_ARGS_Parrot_mark_method_writes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(name))
-#define ASSERT_ARGS_register_nci_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_register_native_pcc_method_in_ns \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(func) \
     , PARROT_ASSERT_ARG(name) \
-    , PARROT_ASSERT_ARG(proto))
-#define ASSERT_ARGS_register_raw_nci_method_in_ns __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+    , PARROT_ASSERT_ARG(signature))
+#define ASSERT_ARGS_register_nci_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(func) \
-    , PARROT_ASSERT_ARG(name))
+    , PARROT_ASSERT_ARG(name) \
+    , PARROT_ASSERT_ARG(proto))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/interp/inter_misc.c */
 

Modified: branches/charset_massacre/include/parrot/nci.h
==============================================================================
--- branches/charset_massacre/include/parrot/nci.h	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/include/parrot/nci.h	Sun Sep  5 03:02:55 2010	(r48796)
@@ -17,6 +17,7 @@
 
 typedef PMC *(*nci_fb_func_t)(PARROT_INTERP, PMC *user_data, STRING *signature);
 typedef void (*nci_thunk_t)(PARROT_INTERP, PMC *, PMC *);
+typedef void (*native_pcc_method_t)(PARROT_INTERP);
 
 void Parrot_nci_load_core_thunks(PARROT_INTERP);
 void Parrot_nci_load_extra_thunks(PARROT_INTERP);

Modified: branches/charset_massacre/lib/Parrot/Pmc2c/PMCEmitter.pm
==============================================================================
--- branches/charset_massacre/lib/Parrot/Pmc2c/PMCEmitter.pm	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/lib/Parrot/Pmc2c/PMCEmitter.pm	Sun Sep  5 03:02:55 2010	(r48796)
@@ -656,11 +656,18 @@
         next unless $method->type eq Parrot::Pmc2c::Method::NON_VTABLE;
 
         #these differ for METHODs
-        my $method_name = $method->name;
-        my $symbol_name = $method->symbol;
+        my $method_name     = $method->name;
+        my $symbol_name     = $method->symbol;
+        my ($pcc_signature) = $method->pcc_signature;
 
         $cout .= <<"EOC";
-        register_raw_nci_method_in_ns(interp, entry, F2DPTR(Parrot_${classname}_${method_name}), CONST_STRING_GEN(interp, "$symbol_name"));
+        {
+            STRING *method_name = CONST_STRING_GEN(interp, "$symbol_name");
+            STRING *signature   = CONST_STRING_GEN(interp, "$pcc_signature");
+            register_native_pcc_method_in_ns(interp, entry,
+                F2DPTR(Parrot_${classname}_${method_name}),
+                method_name, signature);
+        }
 EOC
         if ( $method->{attrs}{write} ) {
             $cout .= <<"EOC";

Modified: branches/charset_massacre/src/dynext.c
==============================================================================
--- branches/charset_massacre/src/dynext.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/dynext.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -477,12 +477,6 @@
     Parrot_pcc_set_namespace(interp, context,
             Parrot_get_HLL_namespace(interp, parrot_hll_id));
 
-    /*
-     * work around gcc 3.3.3 and other problem with dynpmcs
-     * something during library loading doesn't stand a GC run
-     */
-    Parrot_block_GC_mark(interp);
-
     if (lib_name) {
         STRING * const load_name       = Parrot_sprintf_c(interp,
                                         "Parrot_lib_%Ss_load", lib_name);
@@ -517,9 +511,6 @@
     /* remember lib_pmc in iglobals */
     store_lib_pmc(interp, lib_pmc, wo_ext, type, lib_name);
 
-    /* UNLOCK */
-    Parrot_unblock_GC_mark(interp);
-
     Parrot_pop_context(interp);
 
     return lib_pmc;

Modified: branches/charset_massacre/src/interp/inter_misc.c
==============================================================================
--- branches/charset_massacre/src/interp/inter_misc.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/interp/inter_misc.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -64,8 +64,8 @@
 
 /*
 
-=item C<void register_raw_nci_method_in_ns(PARROT_INTERP, const int type, void
-*func, STRING *name)>
+=item C<void register_native_pcc_method_in_ns(PARROT_INTERP, const int type,
+void *func, STRING *name, STRING *signature)>
 
 Create an entry in the C<nci_method_table> for the given raw NCI method
 of PMC class C<type>.
@@ -76,14 +76,14 @@
 
 PARROT_EXPORT
 void
-register_raw_nci_method_in_ns(PARROT_INTERP, const int type, ARGIN(void *func),
-        ARGIN(STRING *name))
+register_native_pcc_method_in_ns(PARROT_INTERP, const int type, ARGIN(void *func),
+        ARGIN(STRING *name), ARGIN(STRING *signature))
 {
-    ASSERT_ARGS(register_raw_nci_method_in_ns)
-    PMC    * const method      = Parrot_pmc_new(interp, enum_class_NCI);
+    ASSERT_ARGS(register_native_pcc_method_in_ns)
+    PMC * method = Parrot_pmc_new(interp, enum_class_NativePCCMethod);
 
     /* setup call func */
-    VTABLE_set_pointer(interp, method, func);
+    VTABLE_set_pointer_keyed_str(interp, method, signature, func);
 
     /* insert it into namespace */
     VTABLE_set_pmc_keyed_str(interp, interp->vtables[type]->_namespace,

Modified: branches/charset_massacre/src/io/utf8.c
==============================================================================
--- branches/charset_massacre/src/io/utf8.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/io/utf8.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -77,7 +77,6 @@
                         Parrot_utf8_encoding_ptr, 0);
                 s2->bufused  = len2;
 
-                /* TT #1257: need to check the amount read here? */
                 read = Parrot_io_read_buffer(interp, filehandle, &s2);
                 UNUSED(read);
 

Modified: branches/charset_massacre/src/multidispatch.c
==============================================================================
--- branches/charset_massacre/src/multidispatch.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/multidispatch.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -43,6 +43,7 @@
 #include "parrot/oplib/ops.h"
 #include "multidispatch.str"
 #include "pmc/pmc_nci.h"
+#include "pmc/pmc_nativepccmethod.h"
 #include "pmc/pmc_sub.h"
 #include "pmc/pmc_callcontext.h"
 
@@ -590,8 +591,17 @@
     Parrot_Sub_attributes *sub;
     INTVAL      args, dist, i, j, n, m;
 
-    /* has to be a builtin multi method */
-    if (pmc->vtable->base_type == enum_class_NCI) {
+    if (pmc->vtable->base_type == enum_class_NativePCCMethod) {
+        GETATTR_NativePCCMethod_mmd_multi_sig(interp, pmc, multi_sig);
+        if (PMC_IS_NULL(multi_sig)) {
+            STRING *long_sig;
+
+            GETATTR_NativePCCMethod_mmd_long_signature(interp, pmc, long_sig);
+            multi_sig = mmd_build_type_tuple_from_long_sig(interp, long_sig);
+            SETATTR_NativePCCMethod_mmd_multi_sig(interp, pmc, multi_sig);
+        }
+    }
+    else 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;
@@ -602,10 +612,10 @@
         }
     }
     else {
-        /* not a multi; no distance */
         PMC_get_sub(interp, pmc, sub);
+
         if (!sub->multi_signature)
-            return 0;
+            return 0; /* not a multi; no distance */
 
         multi_sig = Parrot_mmd_get_cached_multi_sig(interp, pmc);
     }
@@ -969,7 +979,10 @@
     /* Attach a type tuple array to the sub for multi dispatch */
     PMC    *multi_sig = mmd_build_type_tuple_from_type_list(interp, type_list);
 
-    if (sub_obj->vtable->base_type == enum_class_NCI) {
+    if (sub_obj->vtable->base_type == enum_class_NativePCCMethod) {
+        SETATTR_NativePCCMethod_mmd_multi_sig(interp, sub_obj, multi_sig);
+    }
+    else if (sub_obj->vtable->base_type == enum_class_NCI) {
         SETATTR_NCI_multi_sig(interp, sub_obj, multi_sig);
     }
     else if (VTABLE_isa(interp, sub_obj, sub_str)) {

Modified: branches/charset_massacre/src/namespace.c
==============================================================================
--- branches/charset_massacre/src/namespace.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/namespace.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -727,9 +727,6 @@
     PMC *ns;
     Parrot_Sub_attributes *sub;
 
-    /* PF structures aren't fully constructed yet */
-    Parrot_block_GC_mark(interp);
-
     /* store relative to HLL namespace */
     PMC_get_sub(interp, sub_pmc, sub);
     Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), sub->HLL_id);
@@ -762,7 +759,6 @@
 
     /* restore HLL_id */
     Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_id);
-    Parrot_unblock_GC_mark(interp);
 }
 
 /*

Modified: branches/charset_massacre/src/oo.c
==============================================================================
--- branches/charset_massacre/src/oo.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/oo.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -120,7 +120,9 @@
         class_name = _class->vtable->whoami;
 
     if (sub) {
-        if (sub->vtable->base_type == enum_class_NCI)
+        if (sub->vtable->base_type == enum_class_NativePCCMethod)
+            result = "NativePCCMethod";
+        else if (sub->vtable->base_type == enum_class_NCI)
             result = "NCI";
         else
             result = "Sub";

Modified: branches/charset_massacre/src/ops/core_ops.c
==============================================================================
--- branches/charset_massacre/src/ops/core_ops.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/ops/core_ops.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -20453,32 +20453,14 @@
 opcode_t *
 Parrot_addattribute_p_s(opcode_t *cur_opcode, PARROT_INTERP)  {
     const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
-    STRING * const class_name  = string_from_literal(interp, "Class");
-    STRING * const role_name   = string_from_literal(interp, "Role");
-
-    if (VTABLE_isa(interp, PREG(1), class_name) || VTABLE_isa(interp, PREG(1), role_name))
-        VTABLE_add_attribute(interp, PREG(1), SREG(2), PMCNULL);
-    else {
-        opcode_t *handler = Parrot_ex_throw_from_op_args(interp, NULL,
-            EXCEPTION_INVALID_OPERATION,
-            "Cannot add attribute to non-class");return (opcode_t *)handler;
-    }
+    VTABLE_add_attribute(interp, PREG(1), SREG(2), PMCNULL);
 
 return (opcode_t *)cur_opcode + 3;}
 
 opcode_t *
 Parrot_addattribute_p_sc(opcode_t *cur_opcode, PARROT_INTERP)  {
     const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
-    STRING * const class_name  = string_from_literal(interp, "Class");
-    STRING * const role_name   = string_from_literal(interp, "Role");
-
-    if (VTABLE_isa(interp, PREG(1), class_name) || VTABLE_isa(interp, PREG(1), role_name))
-        VTABLE_add_attribute(interp, PREG(1), CONST(2).u.string, PMCNULL);
-    else {
-        opcode_t *handler = Parrot_ex_throw_from_op_args(interp, NULL,
-            EXCEPTION_INVALID_OPERATION,
-            "Cannot add attribute to non-class");return (opcode_t *)handler;
-    }
+    VTABLE_add_attribute(interp, PREG(1), CONST(2).u.string, PMCNULL);
 
 return (opcode_t *)cur_opcode + 3;}
 

Modified: branches/charset_massacre/src/ops/object.ops
==============================================================================
--- branches/charset_massacre/src/ops/object.ops	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/ops/object.ops	Sun Sep  5 03:02:55 2010	(r48796)
@@ -463,17 +463,7 @@
 =cut
 
 inline op addattribute(invar PMC, in STR) :object_classes {
-    STRING * const class_name  = string_from_literal(interp, "Class");
-    STRING * const role_name   = string_from_literal(interp, "Role");
-
-    if (VTABLE_isa(interp, $1, class_name) || VTABLE_isa(interp, $1, role_name))
-        VTABLE_add_attribute(interp, $1, $2, PMCNULL);
-    else {
-        opcode_t *handler = Parrot_ex_throw_from_op_args(interp, NULL,
-            EXCEPTION_INVALID_OPERATION,
-            "Cannot add attribute to non-class");
-        goto ADDRESS(handler);
-    }
+    VTABLE_add_attribute(interp, $1, $2, PMCNULL);
 }
 
 =item B<removeattribute>(invar PMC, in STR) B<(unimplemented)>

Modified: branches/charset_massacre/src/ops/pmc.ops
==============================================================================
--- branches/charset_massacre/src/ops/pmc.ops	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/ops/pmc.ops	Sun Sep  5 03:02:55 2010	(r48796)
@@ -681,7 +681,7 @@
 
 =item B<morph>(invar PMC, in PMC)
 
-Have $1 turn itself into a PMC of type $2.
+Have $1 turn itself into a PMC of type $2. $2 should be a Class PMC.
 
 =cut
 

Modified: branches/charset_massacre/src/pmc/default.pmc
==============================================================================
--- branches/charset_massacre/src/pmc/default.pmc	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/pmc/default.pmc	Sun Sep  5 03:02:55 2010	(r48796)
@@ -533,6 +533,22 @@
 
 /*
 
+=item C<void PMC *add_attribute(STRING *name, PMC *type)>
+
+Throws an exception, as you can only add an attribute to something Class-y or
+Role-y.
+
+=cut
+
+*/
+
+    VTABLE void add_attribute(STRING *name, PMC *type) {
+        Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
+            "Cannot add attribute to non-class");
+    }
+
+/*
+
 =item C<PMC *get_namespace>
 
 Return the namespace for this PMC.

Modified: branches/charset_massacre/src/pmc/namespace.pmc
==============================================================================
--- branches/charset_massacre/src/pmc/namespace.pmc	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/pmc/namespace.pmc	Sun Sep  5 03:02:55 2010	(r48796)
@@ -32,7 +32,7 @@
         __attribute__nonnull__(2)
         __attribute__nonnull__(3);
 
-static void add_nci_to_namespace(PARROT_INTERP,
+static void add_native_to_namespace(PARROT_INTERP,
     ARGIN(PMC *SELF),
     ARGIN(STRING *key),
     ARGIN_NULLOK(PMC *value))
@@ -76,7 +76,7 @@
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(SELF) \
     , PARROT_ASSERT_ARG(key))
-#define ASSERT_ARGS_add_nci_to_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_add_native_to_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(SELF) \
     , PARROT_ASSERT_ARG(key))
@@ -235,15 +235,14 @@
 */
 
 static void
-add_nci_to_namespace(PARROT_INTERP, ARGIN(PMC *SELF), ARGIN(STRING *key),
+add_native_to_namespace(PARROT_INTERP, ARGIN(PMC *SELF), ARGIN(STRING *key),
         ARGIN_NULLOK(PMC *value))
 {
-    ASSERT_ARGS(add_nci_to_namespace)
-
-    STRING * const nci_str = CONST_STRING(interp, "NCI");
+    ASSERT_ARGS(add_native_to_namespace)
 
     if (!PMC_IS_NULL(value)
-    &&   VTABLE_isa(interp, value, nci_str)) {
+    && (value->vtable->base_type == enum_class_NativePCCMethod ||
+        value->vtable->base_type == enum_class_NCI)) {
         Parrot_NameSpace_attributes * const nsinfo = PARROT_NAMESPACE(SELF);
         PMC * const classobj = VTABLE_get_class(interp, SELF);
 
@@ -433,8 +432,8 @@
         if (maybe_add_sub_to_namespace(INTERP, SELF, key, value))
             return;
 
-        /* If it's an NCI method */
-        add_nci_to_namespace(INTERP, SELF, key, value);
+        /* If it's an native method */
+        add_native_to_namespace(INTERP, SELF, key, value);
 
         /* If it's a multi-sub and the first in this NS... */
         add_multi_to_namespace(INTERP, SELF, key, value);

Added: branches/charset_massacre/src/pmc/nativepccmethod.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/charset_massacre/src/pmc/nativepccmethod.pmc	Sun Sep  5 03:02:55 2010	(r48796)
@@ -0,0 +1,198 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/nativepccmethod.pmc - Native PCC Method PMC
+
+=head1 DESCRIPTION
+
+Container for native functions that handle PCC on their own.
+
+=head2 Methods
+
+=over 4
+
+=cut
+
+*/
+
+/* HEADERIZER HFILE: none */
+
+pmclass NativePCCMethod auto_attrs {
+    ATTR STRING *signature;
+    ATTR void   *func;
+
+    /* MMD fields */
+    ATTR STRING *mmd_long_signature;
+    ATTR PMC    *mmd_multi_sig;
+
+/*
+
+=item C<void init()>
+
+Initializes the PMC with a C<NULL> function pointer.
+
+=cut
+
+*/
+
+    VTABLE void init() {
+        Parrot_NativePCCMethod_attributes *attrs = PARROT_NATIVEPCCMETHOD(SELF);
+
+        attrs->func               = NULL;
+        attrs->signature          = STRINGNULL;
+        attrs->mmd_long_signature = STRINGNULL;
+        attrs->mmd_multi_sig      = PMCNULL;
+
+        PObj_custom_mark_SET(SELF);
+    }
+
+/*
+
+=item C<void *get_pointer()>
+
+Get the pointer to the native function.
+
+=item C<void set_pointer_keyed_str(STRING *sig, void *func)>
+
+Set the pointer to the native function and the PCC signature.
+
+=cut
+
+*/
+
+
+    VTABLE void *get_pointer() {
+        return PARROT_NATIVEPCCMETHOD(SELF)->func;
+    }
+
+    VTABLE void set_pointer_keyed_str(STRING *sig, void *func) {
+        PARROT_NATIVEPCCMETHOD(SELF)->signature = sig;
+        PARROT_NATIVEPCCMETHOD(SELF)->func = func;
+    }
+
+/*
+
+=item C<INTVAL defined()>
+
+=item C<INTVAL get_bool()>
+
+NULLness check.
+
+=cut
+
+*/
+
+    VTABLE INTVAL defined() {
+        return !! PARROT_NATIVEPCCMETHOD(SELF)->func;
+    }
+
+    VTABLE INTVAL get_bool() {
+        return STATICSELF.defined();
+    }
+
+/*
+
+=item C<opcode_t *invoke(void *next)>
+
+Call the function pointer.
+
+=cut
+
+*/
+
+    VTABLE opcode_t *invoke(void *next) {
+        void                *func;
+        native_pcc_method_t  fptr;
+
+        GET_ATTR_func(INTERP, SELF, func);
+        if (!func)
+            Parrot_ex_throw_from_c_args(INTERP, NULL,
+                    EXCEPTION_INVALID_OPERATION,
+                    "attempt to call NULL native function");
+
+        fptr = D2FPTR(func);
+        fptr(INTERP);
+
+        /*
+         * If this function was tailcalled, the return result
+         * is already passed back to the caller of this frame.
+         * We therefore invoke the return continuation here,
+         * which gets rid of this frame and returns the real
+         * return address.
+         */
+        {
+            PMC *cont = INTERP->current_cont;
+
+            if (cont && cont != NEED_CONTINUATION
+            && (PObj_get_FLAGS(cont) & SUB_FLAG_TAILCALL)) {
+                cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
+                next = VTABLE_invoke(INTERP, cont, next);
+            }
+        }
+
+        return (opcode_t *)next;
+    }
+
+/*
+
+=item C<void mark()>
+
+Mark contained elements for GC.
+
+=cut
+
+*/
+
+    VTABLE void mark() {
+        Parrot_NativePCCMethod_attributes *attrs = PARROT_NATIVEPCCMETHOD(SELF);
+
+        Parrot_gc_mark_STRING_alive(interp, attrs->signature);
+        Parrot_gc_mark_STRING_alive(interp, attrs->mmd_long_signature);
+        Parrot_gc_mark_PMC_alive(interp,    attrs->mmd_multi_sig);
+    }
+
+/*
+
+=item C<PMC *clone()>
+
+Create a clone of this PMC.
+
+=cut
+
+*/
+
+    VTABLE PMC *clone() {
+        PMC *ret = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
+        Parrot_NativePCCMethod_attributes *self_attrs = PARROT_NATIVEPCCMETHOD(SELF);
+        Parrot_NativePCCMethod_attributes *ret_attrs  = PARROT_NATIVEPCCMETHOD(ret);
+
+        ret_attrs->func               = self_attrs->func;
+        ret_attrs->signature          = self_attrs->signature;
+        ret_attrs->mmd_long_signature = self_attrs->mmd_long_signature;
+        ret_attrs->mmd_multi_sig      = self_attrs->mmd_multi_sig;
+
+        return ret;
+    }
+}
+
+/*
+
+=back
+
+=head1 SEE ALSO
+
+F<docs/pdds/pdd03_calling_conventions.pod>.
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: branches/charset_massacre/src/pmc/nci.pmc
==============================================================================
--- branches/charset_massacre/src/pmc/nci.pmc	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/pmc/nci.pmc	Sun Sep  5 03:02:55 2010	(r48796)
@@ -221,20 +221,6 @@
 
 /*
 
-=item C<METHOD set_raw_nci_ptr(void *func)>
-
-Sets the specified function pointer and raw flag.
-
-=cut
-
-*/
-
-    METHOD make_raw_nci(PMC *func) {
-        VTABLE_set_pointer(interp, SELF, (void *)func);
-    }
-
-/*
-
 =item C<void init()>
 
 Initializes the NCI with a C<NULL> function pointer.
@@ -244,11 +230,13 @@
 */
 
     VTABLE void init() {
-        /* Mark that we're not a raw NCI. */
-        PObj_flag_CLEAR(private2, SELF);
         PObj_custom_mark_SET(SELF);
     }
 
+    VTABLE void *get_pointer() {
+        return PARROT_NCI(SELF)->orig_func;
+    }
+
 /*
 
 =item C<void set_pointer_keyed_str(STRING *key, void *func)>
@@ -259,15 +247,6 @@
 
 */
 
-    VTABLE void set_pointer(void *ptr) {
-        SET_ATTR_orig_func(INTERP, SELF, ptr);
-        PObj_flag_SET(private2, SELF);
-    }
-
-    VTABLE void *get_pointer() {
-        return PARROT_NCI(SELF)->orig_func;
-    }
-
     VTABLE void set_pointer_keyed_str(STRING *key, void *func) {
         Parrot_NCI_attributes * const nci_info   = PARROT_NCI(SELF);
 
@@ -337,7 +316,7 @@
         nci_info_ret->pcc_params_signature  = nci_info_self->pcc_params_signature;
         nci_info_ret->pcc_return_signature  = nci_info_self->pcc_params_signature;
         nci_info_ret->arity                 = nci_info_self->arity;
-        PObj_get_FLAGS(ret)                |= (PObj_get_FLAGS(SELF) & 0x7);
+        PObj_get_FLAGS(ret)                 = PObj_get_FLAGS(SELF);
 
         return ret;
     }
@@ -377,9 +356,7 @@
         PMC                          *cont;
 
         GET_ATTR_orig_func(INTERP, SELF, orig_func);
-        func = PObj_flag_TEST(private2, SELF)
-            ? (nci_thunk_t) D2FPTR(orig_func)
-            : (nci_thunk_t) D2FPTR(nci_info->func);
+        func = D2FPTR(nci_info->func);
 
         GET_ATTR_fb_info(INTERP, SELF, fb_info);
 

Modified: branches/charset_massacre/src/pmc/object.pmc
==============================================================================
--- branches/charset_massacre/src/pmc/object.pmc	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/pmc/object.pmc	Sun Sep  5 03:02:55 2010	(r48796)
@@ -355,7 +355,7 @@
 
         /* If there's a vtable override for 'get_attr_str' run that first. */
         PMC * const method = Parrot_oo_find_vtable_override(INTERP,
-                VTABLE_get_class(INTERP, SELF), get_attr);
+                obj->_class, get_attr);
 
         if (!PMC_IS_NULL(method)) {
             PMC *result = PMCNULL;
@@ -420,7 +420,7 @@
 
         /* If there's a vtable override for 'set_attr_str' run that first. */
         PMC * const method = Parrot_oo_find_vtable_override(INTERP,
-                VTABLE_get_class(INTERP, SELF), vtable_meth_name);
+                obj->_class, vtable_meth_name);
 
         if (!PMC_IS_NULL(method)) {
             Parrot_ext_call(INTERP, method, "PiSP->", SELF, name, value);
@@ -594,20 +594,7 @@
 
 */
     VTABLE PMC *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);
-
-        if (!PMC_IS_NULL(method)) {
-            PMC *result;
-            Parrot_ext_call(INTERP, method, "Pi->P", SELF, &result);
-            return result;
-        }
-
-        return classobj;
+        return PARROT_OBJECT(SELF)->_class;
     }
 
 

Modified: branches/charset_massacre/src/pmc/stringbuilder.pmc
==============================================================================
--- branches/charset_massacre/src/pmc/stringbuilder.pmc	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/pmc/stringbuilder.pmc	Sun Sep  5 03:02:55 2010	(r48796)
@@ -37,6 +37,7 @@
 pmclass StringBuilder provides string auto_attrs {
     ATTR STRING *buffer;    /* Mutable string to gather results */
 
+
 /*
 
 =item C<void init()>
@@ -51,6 +52,7 @@
         STATICSELF.init_int(INITIAL_STRING_CAPACITY);
     }
 
+
 /*
 
 =item C<void init_int()>
@@ -63,18 +65,52 @@
 
     VTABLE void init_int(INTVAL initial_size) {
         STRING * const buffer = mem_gc_allocate_zeroed_typed(INTERP, STRING);
-        buffer->encoding  = Parrot_default_encoding_ptr;
-        /* We need all string flags here because we use this buffer in substr_str */
-        buffer->flags     = PObj_is_string_FLAG | PObj_external_FLAG;
-        buffer->_bufstart = buffer->strstart = mem_gc_allocate_n_typed(INTERP,
-                initial_size, char);
-        buffer->_buflen   = initial_size;
+
+        buffer->encoding      = Parrot_default_encoding_ptr;
+        buffer->_buflen       = initial_size;
+        buffer->_bufstart     = buffer->strstart
+                              = mem_gc_allocate_n_typed(INTERP,
+                                        initial_size, char);
+
+        /* We need these string flags to use this buffer in substr_str */
+        buffer->flags         = PObj_is_string_FLAG | PObj_external_FLAG;
 
         SET_ATTR_buffer(INTERP, SELF, buffer);
 
         PObj_custom_destroy_SET(SELF);
     }
 
+
+/*
+
+=item C<void init_pmc()>
+
+Initializes the StringBuilder with an array of STRINGs.
+
+=cut
+
+*/
+
+    VTABLE void init_pmc(PMC *ar) {
+        const INTVAL count = VTABLE_elements(INTERP, ar);
+
+        if (!count)
+            STATICSELF.init_int(INITIAL_STRING_CAPACITY);
+        else {
+            STRING * const first = VTABLE_get_string_keyed_int(INTERP, ar, 0);
+            const INTVAL   size  = Parrot_str_byte_length(INTERP, first);
+            INTVAL         i;
+
+            /* it's just an estimate, but estimates help */
+            STATICSELF.init_int(size * count);
+            SELF.push_string(first);
+
+            for (i = 1; i < count; ++i)
+                SELF.push_string(VTABLE_get_string_keyed_int(INTERP, ar, i));
+        }
+    }
+
+
 /*
 
 =item C<void destroy()>

Modified: branches/charset_massacre/src/pmc/stringhandle.pmc
==============================================================================
--- branches/charset_massacre/src/pmc/stringhandle.pmc	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/pmc/stringhandle.pmc	Sun Sep  5 03:02:55 2010	(r48796)
@@ -195,7 +195,7 @@
             if (encoding_is_utf8(INTERP, encoding))
                 new_string = string_make(INTERP, "", 0, "unicode", 0);
             else
-                new_string = Parrot_str_new(INTERP, "", 0);
+                new_string = CONST_STRING(INTERP, "");
 
             SET_ATTR_stringhandle(INTERP, SELF, new_string);
         }
@@ -203,7 +203,7 @@
         /* Set a default mode of read-only. */
         GET_ATTR_mode(INTERP, SELF, open_mode);
         if (STRING_IS_NULL(open_mode)) {
-            open_mode = Parrot_str_new_constant(INTERP, "r");
+            open_mode = CONST_STRING(INTERP, "r");
             SET_ATTR_mode(INTERP, SELF, open_mode);
         }
 
@@ -315,7 +315,7 @@
             if (encoding_is_utf8(INTERP, encoding))
                 string_result = string_make(INTERP, "", 0, "unicode", 0);
             else
-                string_result = Parrot_str_new_constant(INTERP, "");
+                string_result = CONST_STRING(INTERP, "");
         }
 
         RETURN(STRING *string_result);

Modified: branches/charset_massacre/src/pmc/undef.pmc
==============================================================================
--- branches/charset_massacre/src/pmc/undef.pmc	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/pmc/undef.pmc	Sun Sep  5 03:02:55 2010	(r48796)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2004-2009, Parrot Foundation.
+Copyright (C) 2004-2010, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -178,7 +178,7 @@
         Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG,
             "Stringifying an Undef PMC");
 
-        return Parrot_str_new_noinit(INTERP, enum_stringrep_one, 0);
+        return CONST_STRING(INTERP, "");
     }
 
 /*

Modified: branches/charset_massacre/src/string/api.c
==============================================================================
--- branches/charset_massacre/src/string/api.c	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/src/string/api.c	Sun Sep  5 03:02:55 2010	(r48796)
@@ -3134,108 +3134,39 @@
 Parrot_str_join(PARROT_INTERP, ARGIN_NULLOK(STRING *j), ARGIN(PMC *ar))
 {
     ASSERT_ARGS(Parrot_str_join)
-    PMC      *chunks;
-    STRING   *res;
-    STRING   *s;
-    char     *pos;
-    const int ar_len       = VTABLE_elements(interp, ar);
-    int       total_length = 0;
-    int       transcoded   = 0;
-    int       i;
-
-    if (ar_len == 0)
-        return Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
-
-    if (STRING_IS_NULL(j))
-        j = Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
-
-    chunks = Parrot_pmc_new_init_int(interp, enum_class_FixedStringArray,
-        ar_len);
-
-    for (i = 0; i < ar_len; ++i) {
-        STRING *next = VTABLE_get_string_keyed_int(interp, ar, i);
-
-        if (STRING_IS_NULL(next))
-            continue;
-
-        if (!transcoded && next->encoding != j->encoding) {
-            const STR_VTABLE *enc = string_rep_compatible(interp, next, j);
-
-            if (!enc) {
-                if (j->encoding != Parrot_utf8_encoding_ptr)
-                    j = Parrot_utf8_encoding_ptr->to_encoding(interp, j);
-
-                transcoded = 1;
-            }
-            else if (enc != j->encoding) {
-                j = enc->to_encoding(interp, j);
-
-                if (STRING_max_bytes_per_codepoint(j) != 1)
-                    transcoded = 1;
-            }
-        }
-
-        VTABLE_set_string_keyed_int(interp, chunks, i, next);
 
-        total_length += next->bufused;
+    if (STRING_IS_NULL(j)) {
+        PMC *sb = Parrot_pmc_new_init(interp, enum_class_StringBuilder, ar);
+        return VTABLE_get_string(interp, sb);
     }
-
-    /* with the right charset, transcode any strings if necessary */
-    if (transcoded) {
-        const STR_VTABLE *enc = j->encoding;
-
-        for (i = 0; i < ar_len; ++i) {
-            STRING *s = VTABLE_get_string_keyed_int(interp, chunks, i);
-
-            if (STRING_IS_NULL(s))
-                continue;
-
-            if (s->encoding != enc) {
-                STRING *new_s = enc->to_encoding(interp, s);
-                VTABLE_set_string_keyed_int(interp, chunks, i, new_s);
-                total_length += new_s->bufused - s->bufused;
-            }
+    else {
+        PMC      *sb;
+        STRING   *first;
+        const int count = VTABLE_elements(interp, ar);
+        INTVAL    length, j_length;
+        int       i;
+
+        if (count == 0)
+            return Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
+
+        first    = VTABLE_get_string_keyed_int(interp, ar, 0);
+        length   = Parrot_str_byte_length(interp, first);
+        j_length = Parrot_str_byte_length(interp, j);
+
+        /* it's an approximiation, but it doesn't hurt */
+        sb       = Parrot_pmc_new_init_int(interp, enum_class_StringBuilder,
+                    (length + j_length) * count);
+
+        VTABLE_push_string(interp, sb, first);
+
+        for (i = 1; i < count; ++i) {
+            VTABLE_push_string(interp, sb, j);
+            VTABLE_push_string(interp, sb,
+                VTABLE_get_string_keyed_int(interp, ar, i));
         }
-    }
-
-    /* add the length of the separator, now that it's transcoded */
-    total_length += j->bufused * ar_len;
-
-    res = Parrot_gc_new_string_header(interp, 0);
-    Parrot_gc_allocate_string_storage(interp, res, total_length);
-
-    res->encoding = j->encoding;
-
-    /* Iterate over chunks and append it to res */
-    pos = res->strstart;
-
-    /* Copy first chunk */
-    s = VTABLE_get_string_keyed_int(interp, chunks, 0);
-    if (!STRING_IS_NULL(s)) {
-        mem_sys_memcopy(pos, s->strstart, s->bufused);
-        pos += s->bufused;
-    }
-
-    for (i = 1; i < ar_len; ++i) {
-        STRING *next = VTABLE_get_string_keyed_int(interp, chunks, i);
-
-        if (STRING_IS_NULL(next))
-            continue;
-
-        mem_sys_memcopy(pos, j->strstart, j->bufused);
-        pos += j->bufused;
 
-        mem_sys_memcopy(pos, next->strstart, next->bufused);
-        pos += next->bufused;
-
-        /* We can consume all buffer and pos will be next-after-end of buffer */
-        PARROT_ASSERT(pos <= res->strstart + Buffer_buflen(res) + 1);
+        return VTABLE_get_string(interp, sb);
     }
-
-    res->bufused = pos - res->strstart;
-    res->strlen  = STRING_scan(interp, res);
-
-    return res;
 }
 
 

Deleted: branches/charset_massacre/t/examples/japh.t
==============================================================================
--- branches/charset_massacre/t/examples/japh.t	Sun Sep  5 03:02:55 2010	(r48795)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,56 +0,0 @@
-#!perl
-# Copyright (C) 2005-2009, Parrot Foundation.
-# $Id$
-
-use strict;
-use warnings;
-use lib qw( . lib ../lib ../../lib );
-use Test::More;
-use Parrot::Test tests => 5;
-use Parrot::Config;
-
-=head1 NAME
-
-t/examples/japh.t - Test some JAPHs
-
-=head1 SYNOPSIS
-
-    % prove t/examples/japh.t
-
-=head1 DESCRIPTION
-
-Test the JAPHs in 'examples/japh'.
-For now there are only JAPHs in PASM.
-
-Some JAPH are not really suitable for inclusion in automated tests.
-
-=head1 TODO
-
-Get the TODO JAPHs working or decide that they are not suitable for testing.
-
-=cut
-
-# known reasons for failure
-my %todo = ();
-if ( defined( $ENV{TEST_PROG_ARGS}) && $ENV{TEST_PROG_ARGS} =~ /--runcore=jit/ ) {
-    $todo{4} = 'broken with JIT';
-}
-
-# run all tests and tell about todoness
-foreach ( 1..5 ) {
-    my $pasm_fn = "examples/japh/japh$_.pasm";
-    unless ( -e $pasm_fn ) {
-        pass("deleted");
-        next;
-    }
-
-    my @todo = $todo{$_} ? ( todo => $todo{$_} ) : ();
-    example_output_is( $pasm_fn, "Just another Parrot Hacker\n", @todo );
-}
-
-# Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:

Modified: branches/charset_massacre/t/pmc/object-meths.t
==============================================================================
--- branches/charset_massacre/t/pmc/object-meths.t	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/t/pmc/object-meths.t	Sun Sep  5 03:02:55 2010	(r48796)
@@ -1,12 +1,12 @@
 #! perl
-# Copyright (C) 2001-2009, Parrot Foundation.
+# Copyright (C) 2001-2010, Parrot Foundation.
 # $Id$
 
 use strict;
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 37;
+use Parrot::Test tests => 36;
 
 =head1 NAME
 
@@ -1080,24 +1080,6 @@
 get_attr_str was called
 OUTPUT
 
-pir_output_is( <<'CODE', <<'OUTPUT', "overloading get_class vtable" );
-.sub main :main
-    .local pmc cl, o, cl2
-    cl = newclass 'MyClass'
-    o = new ['MyClass']
-    cl2 = class o
-.end
-
-.namespace ['MyClass']
-
-.sub get_class :method :vtable
-    print "get_class was called\n"
-.end
-
-CODE
-get_class was called
-OUTPUT
-
 pir_error_output_like( <<'CODE', <<'OUTPUT', "method called on non-object" );
 .namespace [ 'Foo' ]
 

Modified: branches/charset_massacre/t/pmc/stringbuilder.t
==============================================================================
--- branches/charset_massacre/t/pmc/stringbuilder.t	Sun Sep  5 00:40:49 2010	(r48795)
+++ branches/charset_massacre/t/pmc/stringbuilder.t	Sun Sep  5 03:02:55 2010	(r48796)
@@ -21,6 +21,7 @@
     .include 'test_more.pir'
 
     test_create()               # 2 tests
+    test_init_pmc()
     test_push_string()
     test_push_pmc()             # 4 tests
     test_push_string_unicode()  # 1 test
@@ -110,7 +111,6 @@
     push sb, $S0
     $I0 = sb
     is( $I0, 16384, "push a null string does nothing" )
-
 .end
 
 .sub 'test_push_pmc'
@@ -305,6 +305,34 @@
     ok( $S0, "Pushing unicode strings doesn't kill StringBuilder")
 .end
 
+.sub 'test_init_pmc'
+    .local pmc ar
+    ar = new ['ResizableStringArray']
+
+    push ar, "foo"
+    push ar, "bar"
+
+    $S99 = repeat "x", 12
+    push ar, $S99
+    $S1 = 'foobar' . $S99
+
+    $S99 = repeat "y", 13
+    push ar, $S99
+    $S1 = $S1 . $S99
+
+    $S99 = repeat "z", 14
+    push ar, $S99
+    $S1 = $S1 . $S99
+
+    null $S0
+    push ar, $S0
+
+    .local pmc sb
+    sb  = new ["StringBuilder"], ar
+    $S0 = sb
+    is( $S0, $S1, 'init_pmc() should join all passed strings' )
+.end
+
 # Local Variables:
 #   mode: pir
 #   fill-column: 100


More information about the parrot-commits mailing list