[svn:parrot] r39648 - trunk/lib/Parrot/Pmc2c
cotto at svn.parrot.org
cotto at svn.parrot.org
Thu Jun 18 09:39:28 UTC 2009
Author: cotto
Date: Thu Jun 18 09:39:26 2009
New Revision: 39648
URL: https://trac.parrot.org/parrot/changeset/39648
Log:
[pmc2c] make mro and isa_hash generation happen at runtime
pmcc will be taking this approach and pmc2c makes a good guinea pig (all tests pass, of course)
Modified:
trunk/lib/Parrot/Pmc2c/PMCEmitter.pm
Modified: trunk/lib/Parrot/Pmc2c/PMCEmitter.pm
==============================================================================
--- trunk/lib/Parrot/Pmc2c/PMCEmitter.pm Thu Jun 18 08:02:58 2009 (r39647)
+++ trunk/lib/Parrot/Pmc2c/PMCEmitter.pm Thu Jun 18 09:39:26 2009 (r39648)
@@ -94,6 +94,8 @@
$c->emit( $self->update_vtable_func );
$c->emit( $self->get_vtable_func );
+ $c->emit( $self->get_mro_func );
+ $c->emit( $self->get_isa_func );
$c->emit( $self->init_func );
$c->emit( $self->postamble );
@@ -135,6 +137,8 @@
}
$h->emit("${export}VTABLE* Parrot_${name}_get_vtable(PARROT_INTERP);\n");
$h->emit("${export}VTABLE* Parrot_${name}_ro_get_vtable(PARROT_INTERP);\n");
+ $h->emit("${export}PMC* Parrot_${name}_get_mro(PARROT_INTERP);\n");
+ $h->emit("${export}Hash* Parrot_${name}_get_isa(PARROT_INTERP);\n");
$self->gen_attributes;
@@ -589,7 +593,6 @@
my $flags = $self->vtable_flags;
$cout .= <<"EOC";
if (pass == 0) {
- Hash *isa_hash = NULL;
VTABLE * const vt = Parrot_${classname}_get_vtable(interp);
vt->base_type = $enum_name;
vt->flags = $flags;
@@ -620,15 +623,8 @@
if (@isa) {
unshift @isa, $classname;
$cout .= <<"EOC";
-
- isa_hash = parrot_new_hash(interp);
- vt->isa_hash = isa_hash;
-EOC
- for my $isa (@isa) {
- $cout .= <<"EOC";
- parrot_hash_put(interp, isa_hash, (void *)(CONST_STRING_GEN(interp, "$isa")), PMCNULL);
+ vt->isa_hash = Parrot_${classname}_get_isa(interp);
EOC
- }
}
else {
$cout .= <<"EOC";
@@ -651,7 +647,7 @@
vt_${k}->provides_str = vt->provides_str;
vt->${k}_variant_vtable = vt_${k};
vt_${k}->${k}_variant_vtable = vt;
- vt_${k}->isa_hash = isa_hash;
+ vt_${k}->isa_hash = vt->isa_hash;
}
EOC
@@ -686,23 +682,14 @@
$cout .= <<"EOC";
{
- PMC * const mro = pmc_new(interp, enum_class_ResizableStringArray);
VTABLE * const vt = interp->vtables[entry];
- vt->mro = mro;
+ vt->mro = Parrot_${classname}_get_mro(interp);
if (vt->ro_variant_vtable)
- vt->ro_variant_vtable->mro = mro;
-
-EOC
-
- @isa = $classname unless @isa;
+ vt->ro_variant_vtable->mro = vt->mro;
- for my $isa (@isa) {
- $cout .= <<"EOC";
- VTABLE_push_string(interp, mro, CONST_STRING_GEN(interp, "$isa"));
EOC
- }
$cout .= <<"EOC";
}
@@ -827,6 +814,82 @@
$cout;
}
+=item C<get_mro_func()>
+
+Returns the C code for the PMC's get_mro function.
+
+=cut
+
+sub get_mro_func {
+ my ($self) = @_;
+
+ my $cout = "";
+ my $classname = $self->name;
+ my $get_mro;
+ my $parent_name = @{ $self->parents }[0];
+ my $export = $self->is_dynamic ? 'PARROT_DYNEXT_EXPORT ' : 'PARROT_EXPORT';
+
+ if ($parent_name eq 'default') {
+ $get_mro = "pmc_new(interp, enum_class_ResizableStringArray);";
+ }
+ else {
+ $get_mro = "Parrot_${parent_name}_get_mro(interp);";
+ }
+
+ $cout .= <<"EOC";
+$export
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+PMC* Parrot_${classname}_get_mro(PARROT_INTERP) {
+ PMC *parents = $get_mro;
+ VTABLE_unshift_string(interp, parents,
+ string_make(interp, "$classname", @{[length($classname)]}, NULL, 0));
+ return parents;
+}
+
+EOC
+
+ $cout;
+}
+
+
+=item C<get_isa_func()>
+
+Returns the C code for the PMC's get_isa function.
+
+=cut
+
+sub get_isa_func {
+ my ($self) = @_;
+
+ my $cout = "";
+ my $classname = $self->name;
+ my $get_isa;
+ my $parent_name = @{ $self->parents }[0];
+ my $export = $self->is_dynamic ? 'PARROT_DYNEXT_EXPORT ' : 'PARROT_EXPORT';
+
+ if ($parent_name eq 'default') {
+ $get_isa = "parrot_new_hash(interp);"
+ }
+ else {
+ $get_isa = "Parrot_${parent_name}_get_isa(interp);";
+ }
+
+ $cout .= <<"EOC";
+$export
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+Hash* Parrot_${classname}_get_isa(PARROT_INTERP) {
+ Hash *isa = $get_isa;
+ parrot_hash_put(interp, isa, (void *)(CONST_STRING_GEN(interp, "$classname")), PMCNULL);
+ return isa;
+}
+
+EOC
+
+ $cout;
+}
+
=item C<get_vtable_func()>
Returns the C code for the PMC's update_vtable method.
More information about the parrot-commits
mailing list