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