By chromatic's suggestion, here is a different approach: change pmc_type
signature to allow a null string argument, returning enum_type_undef in
that case.

Other changes in this patch are replacing 0 with enum_type_undef in the
same function, and adding a test in t/pmc/namespace.t checking that
get_class return a null pmc for the root namespace. This test segfault
if the patch is not applied.

Index: src/pmc.c
===================================================================
--- src/pmc.c	(revisión: 28476)
+++ src/pmc.c	(copia de trabajo)
@@ -422,20 +422,24 @@
 PARROT_API
 PARROT_WARN_UNUSED_RESULT
 INTVAL
-pmc_type(PARROT_INTERP, ARGIN(STRING *name))
+pmc_type(PARROT_INTERP, ARGIN_NULLOK(STRING *name))
 {
-    PMC * const classname_hash = interp->class_hash;
-    PMC * const item           =
-        (PMC *)VTABLE_get_pointer_keyed_str(interp, classname_hash, name);
+    if (! name)
+        return enum_type_undef;
+    else {
+        PMC * const classname_hash = interp->class_hash;
+        PMC * const item           =
+            (PMC *)VTABLE_get_pointer_keyed_str(interp, classname_hash, name);
 
-    /* nested namespace with same name */
-    if (item->vtable->base_type == enum_class_NameSpace)
-        return 0;
+        /* nested namespace with same name */
+        if (item->vtable->base_type == enum_class_NameSpace)
+            return enum_type_undef;
 
-    if (!PMC_IS_NULL(item))
-        return VTABLE_get_integer(interp, item);
+        if (!PMC_IS_NULL(item))
+            return VTABLE_get_integer(interp, item);
 
-    return Parrot_get_datatype_enum(interp, name);
+        return Parrot_get_datatype_enum(interp, name);
+    }
 }
 
 /*
Index: include/parrot/pmc.h
===================================================================
--- include/parrot/pmc.h	(revisión: 28476)
+++ include/parrot/pmc.h	(copia de trabajo)
@@ -82,9 +82,8 @@
 
 PARROT_API
 PARROT_WARN_UNUSED_RESULT
-INTVAL pmc_type(PARROT_INTERP, ARGIN(STRING *name))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+INTVAL pmc_type(PARROT_INTERP, ARGIN_NULLOK(STRING *name))
+        __attribute__nonnull__(1);
 
 PARROT_API
 INTVAL pmc_type_p(PARROT_INTERP, ARGIN(PMC *name))
Index: t/pmc/namespace.t
===================================================================
--- t/pmc/namespace.t	(revisión: 28476)
+++ t/pmc/namespace.t	(copia de trabajo)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 62;
+use Parrot::Test tests => 63;
 use Parrot::Config;
 
 =head1 NAME
@@ -1058,6 +1058,20 @@
 Found root namespace.
 OUTPUT
 
+pir_output_is( <<'CODE', <<'OUTPUT', 'root namespace is not a class' );
+.sub main :main
+    .local pmc root_ns
+    root_ns = get_root_namespace
+    .local pmc root_class
+    root_class = get_class root_ns
+    .local int is_class
+    is_class = defined root_class
+    say is_class
+.end
+CODE
+0
+OUTPUT
+
 pir_output_is( <<'CODE', <<'OUTPUT', 'get_root_namespace "Foo"' );
 .sub main :main
     .local pmc foo_ns

Reply via email to