[svn:parrot] r45619 - in trunk: . compilers/data_json compilers/imcc compilers/json compilers/nqp compilers/pct compilers/pge compilers/tge config/auto/sizes docs/book/draft docs/book/pct docs/dev docs/pdds examples/embed examples/languages/abc examples/languages/squaak examples/pge ext/nqp-rx include/parrot lib/Parrot lib/Parrot/Configure/Step ports/cpan ports/cygwin ports/debian ports/fedora ports/mandriva ports/suse runtime/parrot/languages runtime/parrot/library runtime/parrot/library/Math src src/call src/gc src/interp src/ops src/packfile src/pmc src/runcore src/string t/compilers/tge t/oo t/pmc t/src t/steps/init/hints tools/build tools/dev tools/util

plobsing at svn.parrot.org plobsing at svn.parrot.org
Mon Apr 12 22:44:04 UTC 2010


Author: plobsing
Date: Mon Apr 12 22:44:02 2010
New Revision: 45619
URL: https://trac.parrot.org/parrot/changeset/45619

Log:
merge stringnull

Modified:
   trunk/   (props changed)
   trunk/compilers/data_json/Rules.mak   (props changed)
   trunk/compilers/imcc/Rules.in   (props changed)
   trunk/compilers/json/Rules.mak   (props changed)
   trunk/compilers/nqp/Rules.mak   (props changed)
   trunk/compilers/pct/Rules.mak   (props changed)
   trunk/compilers/pge/Rules.mak   (props changed)
   trunk/compilers/tge/Rules.mak   (props changed)
   trunk/config/auto/sizes/intval_maxmin_c.in   (props changed)
   trunk/docs/book/draft/README   (props changed)
   trunk/docs/book/draft/appa_glossary.pod   (props changed)
   trunk/docs/book/draft/appb_patch_submission.pod   (props changed)
   trunk/docs/book/draft/appc_command_line_options.pod   (props changed)
   trunk/docs/book/draft/appd_build_options.pod   (props changed)
   trunk/docs/book/draft/appe_source_code.pod   (props changed)
   trunk/docs/book/draft/ch01_introduction.pod   (props changed)
   trunk/docs/book/draft/ch02_getting_started.pod   (props changed)
   trunk/docs/book/draft/ch07_dynpmcs.pod   (props changed)
   trunk/docs/book/draft/ch08_dynops.pod   (props changed)
   trunk/docs/book/draft/ch10_opcode_reference.pod   (props changed)
   trunk/docs/book/draft/ch11_directive_reference.pod   (props changed)
   trunk/docs/book/draft/ch12_operator_reference.pod   (props changed)
   trunk/docs/book/draft/chXX_hlls.pod   (props changed)
   trunk/docs/book/draft/chXX_library.pod   (props changed)
   trunk/docs/book/draft/chXX_testing_and_debugging.pod   (props changed)
   trunk/docs/book/pct/ch01_introduction.pod   (props changed)
   trunk/docs/book/pct/ch02_getting_started.pod   (props changed)
   trunk/docs/book/pct/ch03_compiler_tools.pod   (props changed)
   trunk/docs/book/pct/ch04_pge.pod   (props changed)
   trunk/docs/book/pct/ch05_nqp.pod   (props changed)
   trunk/docs/dev/c_functions.pod   (props changed)
   trunk/docs/pdds/pdd30_install.pod   (props changed)
   trunk/examples/embed/cotorra.c   (props changed)
   trunk/examples/languages/abc/   (props changed)
   trunk/examples/languages/squaak/   (props changed)
   trunk/examples/pge/demo.pir   (props changed)
   trunk/ext/nqp-rx/Rules.mak   (props changed)
   trunk/include/parrot/call.h   (props changed)
   trunk/include/parrot/gc_api.h   (props changed)
   trunk/include/parrot/interpreter.h
   trunk/include/parrot/runcore_api.h   (props changed)
   trunk/include/parrot/runcore_profiling.h   (props changed)
   trunk/include/parrot/runcore_trace.h   (props changed)
   trunk/lib/Parrot/Configure/Step/Test.pm   (props changed)
   trunk/lib/Parrot/H2inc.pm   (props changed)
   trunk/ports/cpan/pause_guide.pod   (props changed)
   trunk/ports/cygwin/parrot-1.0.0-1.cygport   (props changed)
   trunk/ports/debian/libparrot-dev.install.in   (props changed)
   trunk/ports/debian/libparrot.install.in   (props changed)
   trunk/ports/debian/parrot-doc.install.in   (props changed)
   trunk/ports/debian/parrot.install.in   (props changed)
   trunk/ports/fedora/parrot.spec.fedora   (props changed)
   trunk/ports/mandriva/parrot.spec.mandriva   (props changed)
   trunk/ports/suse/parrot.spec.suse   (props changed)
   trunk/runtime/parrot/languages/   (props changed)
   trunk/runtime/parrot/library/Math/Rand.pir   (props changed)
   trunk/runtime/parrot/library/Rules.mak   (props changed)
   trunk/src/call/ops.c   (props changed)
   trunk/src/call/pcc.c   (props changed)
   trunk/src/gc/alloc_memory.c   (props changed)
   trunk/src/gc/alloc_resources.c   (props changed)
   trunk/src/gc/api.c   (props changed)
   trunk/src/gc/malloc.c   (props changed)
   trunk/src/gc/malloc_trace.c   (props changed)
   trunk/src/gc/mark_sweep.c   (props changed)
   trunk/src/gc/system.c   (props changed)
   trunk/src/global.c
   trunk/src/hash.c
   trunk/src/interp/inter_cb.c   (props changed)
   trunk/src/interp/inter_create.c   (contents, props changed)
   trunk/src/interp/inter_misc.c   (props changed)
   trunk/src/ops/set.ops
   trunk/src/packfile/pf_items.c
   trunk/src/pmc/string.pmc
   trunk/src/runcore/cores.c   (props changed)
   trunk/src/runcore/main.c   (props changed)
   trunk/src/runcore/profiling.c   (props changed)
   trunk/src/runcore/trace.c   (props changed)
   trunk/src/string/api.c
   trunk/t/compilers/tge/NoneGrammar.tg   (props changed)
   trunk/t/oo/root_new.t   (props changed)
   trunk/t/pmc/freeze.t
   trunk/t/pmc/namespace-old.t   (props changed)
   trunk/t/pmc/string.t
   trunk/t/src/embed.t   (props changed)
   trunk/t/steps/init/hints/linux-01.t   (props changed)
   trunk/tools/build/h2inc.pl   (props changed)
   trunk/tools/dev/fetch_languages.pl   (props changed)
   trunk/tools/dev/mk_gitignore.pl   (props changed)
   trunk/tools/util/perlcritic-cage.conf   (props changed)

Modified: trunk/include/parrot/interpreter.h
==============================================================================
--- trunk/include/parrot/interpreter.h	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/include/parrot/interpreter.h	Mon Apr 12 22:44:02 2010	(r45619)
@@ -332,30 +332,28 @@
 #define PNCONST   PF_NCONST(interp->code)
 
 /* TODO - Make this a config option */
-/* Splint complains about PMCNULL's storage, so don't use it. */
-#ifdef S_SPLINT_S
-#  define PARROT_CATCH_NULL 0
-#else
-#  define PARROT_CATCH_NULL 1
+#ifndef PARROT_CATCH_NULL
+#  ifdef S_SPLINT_S
+#    define PARROT_CATCH_NULL 0
+#  else
+#    define PARROT_CATCH_NULL 1
+#  endif
 #endif
 
+/* Maybe PMC_IS_NULL(interp, pmc) ? */
 #if PARROT_CATCH_NULL
 PARROT_DATA PMC    *PMCNULL;    /* Holds single Null PMC */
+PARROT_DATA STRING *STRINGNULL; /* a single Null STRING */
+#  define PMC_IS_NULL(pmc)  ((pmc) == PMCNULL || (pmc) == NULL)
+#  define STRING_IS_NULL(s) ((s) == STRINGNULL || (s) == NULL)
 #else
-#  define PMCNULL         ((PMC *)NULL)
+#  define PMCNULL ((PMC *)NULL)
+#  define STRINGNULL ((STRING *)NULL)
+#  define PMC_IS_NULL(pmc)       ((pmc) == NULL)
+#  define STRING_IS_NULL(string) ((string) == NULL)
 #endif /* PARROT_CATCH_NULL */
 
-/* Maybe PMC_IS_NULL(interp, pmc) ? */
-#if PARROT_CATCH_NULL
-#  define PMC_IS_NULL(pmc) ((pmc) == PMCNULL || (pmc) == NULL)
-#else
-#  define PMC_IS_NULL(pmc) ((pmc) == NULL)
-#endif
-
-PARROT_DATA STRING *STRINGNULL; /* a single Null STRING */
-
-#define STRING_IS_NULL(s) ((s) == STRINGNULL || (s) == NULL)
-#define STRING_IS_EMPTY(s) !(int)(s)->strlen
+#define STRING_IS_EMPTY(s) ((s)->strlen == 0)
 
 /* &gen_from_def(sysinfo.pasm) prefix(SYSINFO_) */
 

Modified: trunk/src/global.c
==============================================================================
--- trunk/src/global.c	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/src/global.c	Mon Apr 12 22:44:02 2010	(r45619)
@@ -648,7 +648,7 @@
     ASSERT_ARGS(Parrot_find_global_op)
     PMC *res;
 
-    if (!globalname)
+    if (STRING_IS_NULL(globalname))
         Parrot_ex_throw_from_c_args(interp, next, EXCEPTION_GLOBAL_NOT_FOUND,
             "Tried to get null global");
 

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/src/hash.c	Mon Apr 12 22:44:02 2010	(r45619)
@@ -1661,7 +1661,7 @@
       case Hash_key_type_STRING:
         {
             STRING * const tmp = VTABLE_get_string(interp, key);
-            if (!tmp)
+            if (STRING_IS_NULL(tmp))
                 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
                             "hash: can't use null as key");
             ret = (void *)tmp;

Modified: trunk/src/interp/inter_create.c
==============================================================================
--- trunk/src/interp/inter_create.c	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/src/interp/inter_create.c	Mon Apr 12 22:44:02 2010	(r45619)
@@ -131,7 +131,11 @@
         interp->parent_interpreter = parent;
     else {
         interp->parent_interpreter = NULL;
+
+#if PARROT_CATCH_NULL
         PMCNULL                    = NULL;
+#endif
+
         /*
          * we need a global mutex to protect the interpreter array
          */

Modified: trunk/src/ops/set.ops
==============================================================================
--- trunk/src/ops/set.ops	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/src/ops/set.ops	Mon Apr 12 22:44:02 2010	(r45619)
@@ -560,7 +560,7 @@
 =cut
 
 inline op null(out STR) :base_core {
-    $1 = NULL;
+    $1 = STRINGNULL;
 }
 
 inline op null(out INT) :base_core {

Modified: trunk/src/packfile/pf_items.c
==============================================================================
--- trunk/src/packfile/pf_items.c	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/src/packfile/pf_items.c	Mon Apr 12 22:44:02 2010	(r45619)
@@ -1309,19 +1309,28 @@
 {
     ASSERT_ARGS(PF_fetch_string)
     STRING   *s;
-    UINTVAL   flags      = PF_fetch_opcode(pf, cursor);
-    opcode_t  charset_nr = PF_fetch_opcode(pf, cursor);
-    size_t    size       = (size_t)PF_fetch_opcode(pf, cursor);
-    const int wordsize   = pf ? pf->header->wordsize : sizeof (opcode_t);
+    UINTVAL   flags;
+    opcode_t  charset_nr;
+    size_t    size;
+    const int wordsize = pf ? pf->header->wordsize : sizeof (opcode_t);
+
+    flags      = PF_fetch_opcode(pf, cursor);
+    charset_nr = PF_fetch_opcode(pf, cursor);
+
+    if (charset_nr < 0) {
+        return STRINGNULL;
+    }
+
+    size = (size_t)PF_fetch_opcode(pf, cursor);
 
     /* don't let PBC mess our internals - only constant or not */
-    flags      &= (PObj_constant_FLAG | PObj_private7_FLAG);
+    flags &= (PObj_constant_FLAG | PObj_private7_FLAG);
 
     TRACE_PRINTF(("PF_fetch_string(): flags=0x%04x, ", flags));
     TRACE_PRINTF(("charset_nr=%ld, ", charset_nr));
     TRACE_PRINTF(("size=%ld.\n", size));
 
-    s            = string_make_from_charset(interp, (const char *)*cursor,
+    s = string_make_from_charset(interp, (const char *)*cursor,
                         size, charset_nr, flags);
 
     /* print only printable characters */
@@ -1369,6 +1378,17 @@
     }
 
     *cursor++ = PObj_get_FLAGS(s); /* only constant_FLAG and private7 */
+
+    if (STRING_IS_NULL(s)) {
+        /* preserve NULL-ness of strings
+         * ideally we'd null strings would take only a single opcode_t,
+         * but PObj flags uses a whole word
+         * charset number, OTOH, can't be negative
+         */
+        *cursor++ = -1;
+        return cursor;
+    }
+
     /*
      * TODO as soon as we have dynamically loadable charsets
      *      we have to store the charset name, not the number

Modified: trunk/src/pmc/string.pmc
==============================================================================
--- trunk/src/pmc/string.pmc	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/src/pmc/string.pmc	Mon Apr 12 22:44:02 2010	(r45619)
@@ -126,7 +126,7 @@
         STRING *str_val;
         GET_ATTR_str_val(INTERP, SELF, str_val);
 
-        return str_val ? Parrot_str_copy(INTERP, str_val) : NULL;
+        return STRING_IS_NULL(str_val) ? STRINGNULL : Parrot_str_copy(INTERP, str_val);
     }
 
 /*
@@ -478,7 +478,7 @@
         STRING      *str_val;
         const INTVAL len = Parrot_str_byte_length(INTERP, value);
         GET_ATTR_str_val(INTERP, SELF, str_val);
-        Parrot_str_replace(INTERP, str_val, pos, len, value, &str_val);
+        Parrot_str_replace(INTERP, str_val, pos, len, value, NULL);
     }
 
     VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
@@ -489,7 +489,7 @@
         STRING      *str_val;
         STRING * const c = string_chr(INTERP, (UINTVAL) value);
         GET_ATTR_str_val(INTERP, SELF, str_val);
-        Parrot_str_replace(INTERP, str_val, pos, 1, c, &str_val);
+        Parrot_str_replace(INTERP, str_val, pos, 1, c, NULL);
     }
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {

Modified: trunk/src/string/api.c
==============================================================================
--- trunk/src/string/api.c	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/src/string/api.c	Mon Apr 12 22:44:02 2010	(r45619)
@@ -28,7 +28,9 @@
 #include "api.str"
 
 /* for parrot/interpreter.h */
+#if PARROT_CATCH_NULL
 STRING *STRINGNULL;
+#endif
 
 #define nonnull_encoding_name(s) (s) ? (s)->encoding->name : "null string"
 #define saneify_string(s) \
@@ -88,7 +90,7 @@
 Parrot_str_is_null(SHIM_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_is_null)
-    return !s || s == STRINGNULL;
+    return STRING_IS_NULL(s);
 }
 
 
@@ -109,7 +111,7 @@
 STRING_is_null(SHIM_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(STRING_is_null)
-    return !s || s == STRINGNULL;
+    return STRING_IS_NULL(s);
 }
 
 
@@ -258,7 +260,7 @@
     ASSERT_ARGS(Parrot_str_set)
     if (dest == src)
         return dest;
-    if (dest) { /* && dest != src */
+    if (!STRING_IS_NULL(dest)) { /* && dest != src */
         /* they are different, dest is not an external string */
         dest = Parrot_str_reuse_COW(interp, src, dest);
     }
@@ -319,10 +321,12 @@
     interp->const_cstring_hash  = const_cstring_hash;
     Parrot_charsets_encodings_init(interp);
 
+#if PARROT_CATCH_NULL
     /* initialize STRINGNULL, but not in the constant table */
     STRINGNULL = Parrot_str_new_init(interp, NULL, 0,
                        PARROT_DEFAULT_ENCODING, PARROT_DEFAULT_CHARSET,
                        PObj_constant_FLAG);
+#endif
 
     interp->const_cstring_table =
         mem_gc_allocate_n_zeroed_typed(interp, n_parrot_cstrings, STRING *);
@@ -567,7 +571,7 @@
         return a;
 
     /* Is A real? */
-    if (a == NULL || Buffer_bufstart(a) == NULL)
+    if (STRING_IS_NULL(a) || Buffer_bufstart(a) == NULL)
         return Parrot_str_copy(interp, b);
 
     saneify_string(a);
@@ -966,7 +970,7 @@
 {
     ASSERT_ARGS(Parrot_str_byte_length)
 
-    return s ? s->strlen : 0;
+    return !STRING_IS_NULL(s) ? s->strlen : 0;
 }
 
 
@@ -1245,7 +1249,7 @@
         ARGOUT_NULLOK(STRING **d), int replace_dest)
 {
     ASSERT_ARGS(Parrot_str_substr)
-    if (src == NULL)
+    if (STRING_IS_NULL(src))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_SUBSTR_OUT_OF_STRING,
             "Cannot substr on a null string");
     else {
@@ -1272,7 +1276,7 @@
             true_length = (UINTVAL)(src->strlen - true_offset);
 
         /* do in-place i.e. reuse existing header if one */
-        if (replace_dest && d && *d) {
+        if (replace_dest && d && !STRING_IS_NULL(*d)) {
             PARROT_ASSERT(src->encoding == Parrot_fixed_8_encoding_ptr);
             dest           = *d;
 
@@ -1339,6 +1343,10 @@
     UINTVAL         true_offset = (UINTVAL)offset;
     UINTVAL         true_length = (UINTVAL)length;
 
+    if (STRING_IS_NULL(src))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Cannot replace on a null string");
+
     /* special case */
     if (d             == NULL
     &&  src->encoding == Parrot_fixed_8_encoding_ptr
@@ -1352,7 +1360,7 @@
 
         ((char *)src->strstart)[offset] = ((char *)rep->strstart)[0];
 
-        return NULL;
+        return STRINGNULL;
     }
 
     /* abs(-offset) may not be > strlen-1 */
@@ -1555,10 +1563,10 @@
 Parrot_str_compare(PARROT_INTERP, ARGIN_NULLOK(const STRING *s1), ARGIN_NULLOK(const STRING *s2))
 {
     ASSERT_ARGS(Parrot_str_compare)
-    if (!s2)
+    if (STRING_IS_NULL(s2))
         return s1 && (s1->strlen != 0);
 
-    if (!s1)
+    if (STRING_IS_NULL(s1))
         return -(s2->strlen != 0);
 
     saneify_string(s1);
@@ -1609,13 +1617,13 @@
 Parrot_str_equal(PARROT_INTERP, ARGIN_NULLOK(const STRING *s1), ARGIN_NULLOK(const STRING *s2))
 {
     ASSERT_ARGS(Parrot_str_equal)
-    if ((s1 == s2) || (!s1 && !s2)) {
+    if ((s1 == s2) || (STRING_IS_NULL(s1) && STRING_IS_NULL(s2))) {
         return 1;
     }
-    else if (!s2) {
+    else if (STRING_IS_NULL(s2)) {
         return s1->strlen == 0;
     }
-    else if (!s1) {
+    else if (STRING_IS_NULL(s1)) {
         return s2->strlen == 0;
     }
     else if (s1->strlen != s2->strlen) {
@@ -1659,7 +1667,7 @@
     const size_t len, parrot_string_representation_t representation)
 {
     ASSERT_ARGS(make_writable)
-    if (!*s)
+    if (STRING_IS_NULL(*s))
         *s = Parrot_str_new_noinit(interp, representation, len);
     else if ((*s)->strlen < len)
         Parrot_str_resize(interp, *s, (UINTVAL)(len - (*s)->strlen));
@@ -1703,12 +1711,12 @@
             nonnull_encoding_name(s1), s2->encoding->name);
 
     /* think about case of dest string is one of the operands */
-    if (s1 && s2)
+    if (!STRING_IS_NULL(s1) && !STRING_IS_NULL(s2))
         minlen = s1->strlen > s2->strlen ? s2->strlen : s1->strlen;
     else
         minlen = 0;
 
-    if (dest && *dest) {
+    if (dest && !STRING_IS_NULL(*dest)) {
         res           = *dest;
         res->encoding = Parrot_fixed_8_encoding_ptr;
         res->charset  = Parrot_binary_charset_ptr;
@@ -1717,7 +1725,7 @@
         res = Parrot_str_new_init(interp, NULL, minlen,
                 Parrot_fixed_8_encoding_ptr, Parrot_binary_charset_ptr, 0);
 
-    if (!s1 || !s2) {
+    if (STRING_IS_NULL(s1) || STRING_IS_NULL(s2)) {
         res->bufused = 0;
         res->strlen  = 0;
 
@@ -1759,11 +1767,11 @@
     restype     *dp; \
     size_t       _index; \
  \
-    if (s1) { \
+    if (!STRING_IS_NULL(s1)) { \
         curr1   = (type1 *)(s1)->strstart; \
         length1 = (s1)->strlen; \
     } \
-    if (s2) { \
+    if (!STRING_IS_NULL(s2)) { \
         curr2   = (type2 *)(s2)->strstart; \
         length2 = (s2)->strlen; \
     } \
@@ -1794,11 +1802,11 @@
     restype     *dp; \
     size_t       _index; \
  \
-    if (s1) { \
+    if (!STRING_IS_NULL(s1)) { \
         curr1   = (type1 *)(s1)->strstart; \
         length1 = (s1)->strlen; \
     } \
-    if (s2) { \
+    if (!STRING_IS_NULL(s2)) { \
         curr2   = (type2 *)(s2)->strstart; \
         length2 = (s2)->strlen; \
     } \
@@ -1843,7 +1851,7 @@
     STRING *res;
     size_t  maxlen = 0;
 
-    if (s1) {
+    if (!STRING_IS_NULL(s1)) {
         if (s1->encoding != Parrot_fixed_8_encoding_ptr)
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
                 "string bitwise_or (%s/%s) unsupported",
@@ -1852,7 +1860,7 @@
         maxlen = s1->bufused;
     }
 
-    if (s2) {
+    if (!STRING_IS_NULL(s2)) {
         if (s2->encoding != Parrot_fixed_8_encoding_ptr)
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
                 "string bitwise_or (%s/%s) unsupported",
@@ -1862,7 +1870,7 @@
             maxlen = s2->bufused;
     }
 
-    if (dest && *dest) {
+    if (dest && !STRING_IS_NULL(*dest)) {
         res           = *dest;
         res->encoding = Parrot_fixed_8_encoding_ptr;
         res->charset  = Parrot_binary_charset_ptr;
@@ -1919,7 +1927,7 @@
     STRING *res;
     size_t  maxlen = 0;
 
-    if (s1) {
+    if (!STRING_IS_NULL(s1)) {
         if (s1->encoding != Parrot_fixed_8_encoding_ptr)
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
                 "string bitwise_xor (%s/%s) unsupported",
@@ -1928,7 +1936,7 @@
         maxlen = s1->bufused;
     }
 
-    if (s2) {
+    if (!STRING_IS_NULL(s2)) {
         if (s2->encoding != Parrot_fixed_8_encoding_ptr)
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
                 "string bitwise_xor (%s/%s) unsupported",
@@ -1938,7 +1946,7 @@
             maxlen = s2->bufused;
     }
 
-    if (dest && *dest) {
+    if (dest && !STRING_IS_NULL(*dest)) {
         res           = *dest;
         res->encoding = Parrot_fixed_8_encoding_ptr;
         res->charset  = Parrot_binary_charset_ptr;
@@ -1974,7 +1982,7 @@
 
 #define BITWISE_NOT_STRING(type, s, res) \
 do { \
-    if ((s) && (res)) { \
+    if (!STRING_IS_NULL(s) && !STRING_IS_NULL(res)) { \
         const type   *curr   = (type *)(s)->strstart; \
         size_t        length = (s)->strlen; \
         Parrot_UInt1 *dp     = (Parrot_UInt1 *)(res)->strstart; \
@@ -2006,7 +2014,7 @@
     STRING *res;
     size_t  len;
 
-    if (s) {
+    if (!STRING_IS_NULL(s)) {
         if (s->encoding != Parrot_fixed_8_encoding_ptr)
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_ENCODING,
                 "string bitwise_not (%s/%s) unsupported",
@@ -2017,7 +2025,7 @@
     else
         len = 0;
 
-    if (dest && *dest) {
+    if (dest && !STRING_IS_NULL(*dest)) {
         res           = *dest;
         res->encoding = Parrot_fixed_8_encoding_ptr;
         res->charset  = Parrot_binary_charset_ptr;
@@ -2067,7 +2075,7 @@
 Parrot_str_boolean(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_boolean)
-    const INTVAL len = s ? Parrot_str_byte_length(interp, s) : 0;
+    const INTVAL len = !STRING_IS_NULL(s) ? Parrot_str_byte_length(interp, s) : 0;
 
     if (len == 0)
         return 0;
@@ -2158,7 +2166,7 @@
 Parrot_str_to_int(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_to_int)
-    if (s == NULL)
+    if (STRING_IS_NULL(s))
         return 0;
     {
         const INTVAL        max_safe  = PARROT_INTVAL_MAX / 10;
@@ -2260,7 +2268,7 @@
     UINTVAL     offs;
     number_parse_state state = parse_start;
 
-    if (!s)
+    if (STRING_IS_NULL(s))
         return 0.0;
 
     ENCODING_ITER_INIT(interp, s, &iter);
@@ -2478,7 +2486,7 @@
 Parrot_str_to_cstring(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_to_cstring)
-    if (! s) {
+    if (STRING_IS_NULL(s)) {
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNEXPECTED_NULL,
             "Can't convert NULL string");
     }
@@ -2506,7 +2514,7 @@
 string_to_cstring_nullable(SHIM_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(string_to_cstring_nullable)
-    if (!s)
+    if (STRING_IS_NULL(s))
         return NULL;
     else {
         char * const p = (char*)mem_internal_allocate(s->bufused + 1);
@@ -2645,7 +2653,7 @@
     UINTVAL     offs;
     size_t      hashval = interp->hash_seed;
 
-    if (!s || !s->strlen)
+    if (STRING_IS_NULL(s) || !s->strlen)
         return hashval;
 
     /* ZZZZZ workaround for something not setting up encodings right */
@@ -2713,8 +2721,8 @@
     String_iter iter;
     unsigned char *dp;
 
-    if (!src)
-        return NULL;
+    if (STRING_IS_NULL(src))
+        return STRINGNULL;
 
     len = src->strlen;
 
@@ -3215,7 +3223,7 @@
                           UINTVAL offset, UINTVAL count)
 {
     ASSERT_ARGS(Parrot_str_find_cclass)
-    if (!s)
+    if (STRING_IS_NULL(s))
         return -1;
 
     return CHARSET_FIND_CCLASS(interp, flags, s, offset, count);
@@ -3242,7 +3250,7 @@
     ARGIN_NULLOK(STRING *s), UINTVAL offset, UINTVAL count)
 {
     ASSERT_ARGS(Parrot_str_find_not_cclass)
-    if (!s)
+    if (STRING_IS_NULL(s))
         return -1;
 
     return CHARSET_FIND_NOT_CCLASS(interp, flags, s, offset, count);
@@ -3271,8 +3279,8 @@
     ASSERT_ARGS(Parrot_str_change_charset)
     const CHARSET *new_charset;
 
-    if (!src)
-        return NULL;
+    if (STRING_IS_NULL(src))
+        return STRINGNULL;
 
     new_charset = Parrot_get_charset(interp, charset_nr);
 
@@ -3284,7 +3292,7 @@
      * dest is an empty string header or NULL, if an inplace
      * operation is desired
      */
-    if (dest) {
+    if (!STRING_IS_NULL(dest)) {
         if (new_charset == src->charset) {
             dest          = Parrot_str_reuse_COW(interp, src, dest);
             dest->charset = new_charset;
@@ -3330,8 +3338,8 @@
     ASSERT_ARGS(Parrot_str_change_encoding)
     const ENCODING *new_encoding;
 
-    if (!src)
-        return NULL;
+    if (STRING_IS_NULL(src))
+        return STRINGNULL;
 
     new_encoding = Parrot_get_encoding(interp, encoding_nr);
 
@@ -3343,7 +3351,7 @@
      * dest is an empty string header or NULL, if an inplace
      * operation is desired
      */
-    if (dest) {
+    if (!STRING_IS_NULL(dest)) {
         dest->encoding = new_encoding;
         if (new_encoding == src->encoding) {
             dest = Parrot_str_reuse_COW(interp, src, dest);
@@ -3378,7 +3386,7 @@
 Parrot_str_compose(PARROT_INTERP, ARGIN_NULLOK(STRING *src))
 {
     ASSERT_ARGS(Parrot_str_compose)
-    if (!src)
+    if (STRING_IS_NULL(src))
         return NULL;
 
     if (!src->strlen)
@@ -3415,7 +3423,7 @@
         return Parrot_str_new_noinit(interp, enum_stringrep_one, 0);
 
     s   = VTABLE_get_string_keyed_int(interp, ar, 0);
-    res = s ? Parrot_str_copy(interp, s) : NULL;
+    res = !STRING_IS_NULL(s) ? Parrot_str_copy(interp, s) : NULL;
 
     for (i = 1; i < ar_len; ++i) {
         STRING * const next = VTABLE_get_string_keyed_int(interp, ar, i);

Modified: trunk/t/pmc/freeze.t
==============================================================================
--- trunk/t/pmc/freeze.t	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/t/pmc/freeze.t	Mon Apr 12 22:44:02 2010	(r45619)
@@ -52,9 +52,19 @@
     print " "
     print P10
     print "\n"
+
+    null S1
+    new P1, ['String']
+    set P1, S1
+    freeze S0, P1
+    thaw P10, S0
+    set S10, P10
+    isnull I0, S10
+    say I0
     end
 CODE
 String foo
+1
 OUTPUT
 
 pasm_output_is( <<'CODE', <<'OUTPUT', "freeze/thaw a Float" );

Modified: trunk/t/pmc/string.t
==============================================================================
--- trunk/t/pmc/string.t	Mon Apr 12 22:15:02 2010	(r45618)
+++ trunk/t/pmc/string.t	Mon Apr 12 22:44:02 2010	(r45619)
@@ -20,7 +20,7 @@
 .sub main :main
     .include 'test_more.pir'
 
-    plan(171)
+    plan(173)
 
     set_or_get_strings()
     setting_integers()
@@ -102,6 +102,12 @@
         set $P0, "0xFFFFFF"
         set $S0, $P0
         is( $S0, "0xFFFFFF", 'String obj set with literal hex string' )
+
+        null $S0
+        set $P0, $S0
+        set $S1, $P0
+        isnull $I0, $S1
+        ok( $I0, 'String obj is null-in null-out' )
 .end
 
 .sub setting_integers
@@ -1036,6 +1042,7 @@
 
     # Set
     s = new ['String']
+    s = ''
 
     $S0 = 'f'
     s[0] = $S0
@@ -1049,6 +1056,16 @@
     $P0 = 'o'
     s[2] = $P0
     is(s, 'foo', 'Set PMC keyed')
+
+    push_eh null_replace
+    s = new ['String']
+    s[0] = 'f'
+    nok('Replace on null string throws')
+    goto done_null_replace
+
+  null_replace:
+    ok(1, 'Replace on null string throws')
+  done_null_replace:
 .end
 
 # Local Variables:


More information about the parrot-commits mailing list