Author: jonathan
Date: Fri Jun 8 05:23:38 2007
New Revision: 18873
Modified:
trunk/include/parrot/pmc.h
trunk/lib/Parrot/Pmc2c.pm
trunk/src/global_setup.c
trunk/src/pmc.c
trunk/src/pmc/pmcproxy.pmc
trunk/t/pmc/pmcproxy.t
Log:
[PDD17] Make each PMC create a PMC Proxy object and put it in the list. Also
attach each of these to the NameSpace that the PMC is attached to. This means
you can now get_class, just as you would with PDD15 classes, for PMCs. However,
it returns a PMC Proxy object rather than a Class. Added a test for this.
Modified: trunk/include/parrot/pmc.h
==============================================================================
--- trunk/include/parrot/pmc.h (original)
+++ trunk/include/parrot/pmc.h Fri Jun 8 05:23:38 2007
@@ -45,6 +45,8 @@
__attribute__warn_unused_result__;
PARROT_API INTVAL pmc_type_p( Interp* interp, PMC *name );
+
+PARROT_API void Parrot_create_pmc_proxy( Interp* interp, int type_num );
/* HEADERIZER END: src/pmc.c */
/* Internal use */
@@ -58,6 +60,19 @@
/* &end_gen */
+/* This is the underlying structure for a PMC Proxy object; we need to set it
+ * up from outside of the PMC. */
+typedef struct Parrot_PMCProxy {
+ int id; /* The type number of the PMC. */
+ STRING *name; /* The name of the PMC. */
+ PMC *_namespace; /* The namespace it's linked to, if any. */
+ PMC *parents; /* Proxy PMCs of any immediate parent classes. */
+ PMC *all_parents; /* Cached list of ourself and all parents, in MRO
order. */
+} Parrot_PMCProxy;
+
+/* Macro to access underlying structure of a PMCProxy PMC. */
+#define PARROT_PMCPROXY(o) ((Parrot_PMCProxy *) PMC_data(o))
+
#endif /* PARROT_PMC_H_GUARD */
/*
Modified: trunk/lib/Parrot/Pmc2c.pm
==============================================================================
--- trunk/lib/Parrot/Pmc2c.pm (original)
+++ trunk/lib/Parrot/Pmc2c.pm Fri Jun 8 05:23:38 2007
@@ -1013,6 +1013,8 @@
$cout .= <<"EOC";
/* setup MRO and _namespace */
Parrot_create_mro(interp, entry);
+ /* create PMC Proxy object */
+ Parrot_create_pmc_proxy(interp, entry);
EOC
# declare each nci method for this class
Modified: trunk/src/global_setup.c
==============================================================================
--- trunk/src/global_setup.c (original)
+++ trunk/src/global_setup.c Fri Jun 8 05:23:38 2007
@@ -114,6 +114,7 @@
{
PMC *iglobals;
PMC *self, *pmc;
+ int i;
#ifdef PARROT_HAS_PLATFORM_INIT_CODE
Parrot_platform_init_code();
@@ -124,6 +125,14 @@
/* Call base vtable class constructor methods */
Parrot_initialize_core_pmcs(interp);
+ /* We have a Proxy PMC for each of the PMCs; now need to attach that to
+ * the class slot for the namespace each of the PMCs reference. */
+ for (i = 0; i <= interp->n_vtable_max; i++)
+ if (interp->vtables[i])
+ Parrot_PCCINVOKE(interp, interp->vtables[i]->_namespace,
+ string_from_const_cstring(interp, "set_class", 0), "P->",
+ VTABLE_get_pmc_keyed_int(interp, interp->pmc_proxies, i));
+
iglobals = interp->iglobals;
VTABLE_set_pmc_keyed_int(interp, iglobals,
(INTVAL)IGLOBALS_CLASSNAME_HASH, interp->class_hash);
Modified: trunk/src/pmc.c
==============================================================================
--- trunk/src/pmc.c (original)
+++ trunk/src/pmc.c Fri Jun 8 05:23:38 2007
@@ -545,6 +545,44 @@
VTABLE_delete_keyed(interp, interp->DOD_registry, pmc);
}
+
+/*
+
+=head2 PMC Proxy related things
+
+FUNCDOC: Parrot_create_pmc_proxy
+Creates a PMC Proxy for the supplied class number and puts it into the array
+of proxies.
+
+*/
+
+PARROT_API
+void
+Parrot_create_pmc_proxy(Interp* interp, int type_num)
+{
+ PMC *proxy;
+ Parrot_PMCProxy *proxy_info;
+
+ /* Ensure that it's a valid type number. */
+ if (type_num > interp->n_vtable_max || type_num < 0)
+ internal_exception(1,
+ "Attempt to create PMC Proxy for invalid type number!");
+
+ /* Create PMC proxy object and set up number, name and namespcae. */
+ proxy = pmc_new(interp, enum_class_PMCProxy);
+ proxy_info = PARROT_PMCPROXY(proxy);
+ proxy_info->id = type_num;
+ proxy_info->name = interp->vtables[type_num]->whoami;
+ proxy_info->_namespace = interp->vtables[type_num]->_namespace;
+
+ /* XXX Parents and MRO still todo. */
+
+ /* Enter it in the list of proxy objects. */
+ VTABLE_set_pmc_keyed_int(interp, interp->pmc_proxies, type_num, proxy);
+}
+
+
+
/*
=head1 SEE ALSO
Modified: trunk/src/pmc/pmcproxy.pmc
==============================================================================
--- trunk/src/pmc/pmcproxy.pmc (original)
+++ trunk/src/pmc/pmcproxy.pmc Fri Jun 8 05:23:38 2007
@@ -51,17 +51,6 @@
#include "parrot/parrot.h"
-typedef struct Parrot_PMCProxy {
- int id; /* The type number of the PMC. */
- STRING *name; /* The name of the PMC. */
- PMC *_namespace; /* The namespace it's linked to, if any. */
- PMC *parents; /* Proxy PMCs of any immediate parent classes. */
- PMC *all_parents; /* Cached list of ourself and all parents, in MRO
order. */
-} Parrot_PMCProxy;
-
-/* Macro to access underlying structure of a PMCProxy PMC. */
-#define PARROT_PMCPROXY(o) ((Parrot_PMCProxy *) PMC_data(o))
-
/*
=head2 Functions
Modified: trunk/t/pmc/pmcproxy.t
==============================================================================
--- trunk/t/pmc/pmcproxy.t (original)
+++ trunk/t/pmc/pmcproxy.t Fri Jun 8 05:23:38 2007
@@ -6,7 +6,7 @@
use warnings;
use lib qw( . lib ../lib ../../lib );
use Test::More;
-use Parrot::Test tests => 1;
+use Parrot::Test tests => 2;
=head1 NAME
@@ -38,6 +38,28 @@
ok 2 - isa $P0, 'PMCProxy'
OUT
+pir_output_is( <<'CODE', <<'OUT', 'get_class gives back Proxy PMC' );
+.sub 'test' :main
+push_eh nok_1
+ $P0 = get_class 'NameSpace'
+ clear_eh
+ goto ok_1
+nok_1:
+ print "not "
+ok_1:
+ print "ok 1 - get_class returned something\n"
+
+ $I0 = isa $P0, 'PMCProxy'
+ if $I0 goto ok_2
+ print 'not '
+ ok_2:
+ say "ok 2 - isa $P0, 'PMCProxy'"
+.end
+CODE
+ok 1 - get_class returned something
+ok 2 - isa $P0, 'PMCProxy'
+OUT
+
# Local Variables:
# mode: cperl
# cperl-indent-level: 4