Permalink
Browse files

[core] WIP fix morph [GH #372]

pass the correct type info to pmc_reuse
allow the 2nd argument to be a Object PMC, so
use Parrot_pmc_reuse_init instead.

Define some FixedPMCArray morphs.

TODO:
- get_class Undef returns a PMCProxy object
- More basic arrays, Integer, String and Hash morphes
- non-builtin types via PARROT_CLASS(type)->id
  and Parrot_pmc_reuse_by_class

- morph old values into new type (pmc specific).
  e.g. *Array => Integer needs to assign the elements to the get_integer iv
  • Loading branch information...
Reini Urban
Reini Urban committed Mar 9, 2014
1 parent 8ff72da commit 1997c9ca32cf24decf074a3388ed3ab2b8eafab8
Showing with 86 additions and 13 deletions.
  1. +2 −0 src/pmc.c
  2. +6 −5 src/pmc/default.pmc
  3. +52 −1 src/pmc/fixedpmcarray.pmc
  4. +3 −2 src/pmc/resizablepmcarray.pmc
  5. +16 −1 src/pmc/undef.pmc
  6. +7 −4 t/src/extend_vtable.t
View
@@ -305,6 +305,8 @@ and the PMC will be inited.
Cannot currently handle converting a non-Object PMC into an Object. Use
C<pmc_reuse_by_class> for that.
The flags argument is currently ignored. The flags of the vtable of the
new_type is used instead.
=cut
View
@@ -1,5 +1,5 @@
/*
Copyright (C) 2001-2012, Parrot Foundation.
Copyright (C) 2001-2014, Parrot Foundation.
=head1 NAME
@@ -433,16 +433,17 @@ Defaults fall back to C<set_pmc> and C<set_string_native>.
/*
=item C<void morph(PMC* type)>
=item C<void morph(PMC* new_type)>
Changes the PMC to a PMC of a new type
Changes the PMC to a PMC of a new type, but we cannot transform
the values generally.
=cut
*/
VTABLE void morph(PMC* type) {
Parrot_pmc_reuse(INTERP, SELF, VTABLE_get_integer(INTERP, type), 0);
VTABLE void morph(PMC* new_type) {
Parrot_pmc_reuse_init(INTERP, SELF, new_type->vtable->base_type, new_type, 0);
}
/*
View
@@ -1,5 +1,5 @@
/*
Copyright (C) 2001-2011, Parrot Foundation.
Copyright (C) 2001-2014, Parrot Foundation.
=head1 NAME
@@ -26,6 +26,9 @@ never be set for user arrays.
#define PMC_size(x) ((Parrot_FixedPMCArray_attributes *)PMC_data(x))->size
#define PMC_array(x) ((Parrot_FixedPMCArray_attributes *)PMC_data(x))->pmc_array
#include "pmc_fixedstringarray.h"
#include "pmc_fixedintegerarray.h"
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
@@ -201,6 +204,54 @@ Returns the number of elements in the array.
/*
=item C<INTVAL morph(PMC *new_type)>
Defined for String and Integer and other arrays.
Not yet for hashes.
=cut
*/
VTABLE INTVAL morph(PMC *new_type) {
INTVAL retval = 1;
if (new_type->vtable->base_type == enum_class_Integer)
VTABLE_init_int(INTERP, SELF, SELF.elements());
else if (new_type->vtable->base_type == enum_class_String)
VTABLE_set_string_native(INTERP, SELF, SELF.get_string());
else if (VTABLE_isa(INTERP, new_type, CONST_STRING(INTERP, "ResizablePMCArray")))
PMC_data(SELF) = PMC_data(new_type);
else if (VTABLE_isa(INTERP, new_type, CONST_STRING(INTERP, "FixedStringArray"))
|| VTABLE_isa(INTERP, new_type, CONST_STRING(INTERP, "ResizableStringArray"))) {
register int i;
STRING **to;
PMC **from = PMC_array(SELF);
GETATTR_FixedStringArray_str_array(INTERP, new_type, to);
for (i = 0; i < PMC_size(SELF); i++) {
to[i] = VTABLE_get_string(INTERP, from[i]);
}
PMC_size(new_type) = PMC_size(SELF);
}
else if (VTABLE_isa(INTERP, new_type, CONST_STRING(INTERP, "FixedIntegerArray"))
|| VTABLE_isa(INTERP, new_type, CONST_STRING(INTERP, "ResizableIntegerArray"))) {
register int i;
INTVAL *to;
PMC **from = PMC_array(SELF);
GETATTR_FixedIntegerArray_int_array(INTERP, new_type, to);
for (i = 0; i < PMC_size(SELF); i++) {
to[i] = VTABLE_get_integer(INTERP, from[i]);
}
PMC_size(new_type) = PMC_size(SELF);
}
else
retval = 0;
Parrot_pmc_reuse(INTERP, SELF, new_type->vtable->base_type, 0);
return retval;
}
/*
=item C<FLOATVAL get_number()>
Returns the number of elements in the array.
@@ -1,5 +1,5 @@
/*
Copyright (C) 2001-2012, Parrot Foundation.
Copyright (C) 2001-2014, Parrot Foundation.
=head1 NAME
@@ -185,7 +185,8 @@ Removes and returns an item from the start of the array.
=cut
TODO: This always moves the array memory, which is not very performant
TODO: This always moves the array memory, which is not very performant.
Store the offset.
TODO: Check whether there is already an element that can be shifted
*/
View
@@ -1,5 +1,5 @@
/*
Copyright (C) 2004-2012, Parrot Foundation.
Copyright (C) 2004-2014, Parrot Foundation.
=head1 NAME
@@ -89,6 +89,21 @@ appropriate type.
VTABLE_set_pmc(INTERP, SELF, other);
}
/*
=item C<void morph(PMC *new_type)>
Same as assign_pmc.
=cut
*/
VTABLE void morph(PMC *new_type) {
if (new_type->vtable->base_type != enum_class_Undef)
VTABLE_set_pmc(INTERP, SELF, new_type);
}
/*
View
@@ -295,13 +295,16 @@ CODE
Done!
OUTPUT
# TODO: Should it really return 'default' here?
extend_vtable_output_is(<<'CODE', <<'OUTPUT', "Parrot_PMC_morph");
# TODO Should return 'Integer', not 'default' here, and the value should be the length
# of the array fpa
extend_vtable_output_is(<<'CODE', <<'OUTPUT', "Parrot_PMC_morph", todo => 'GH #372 morph returns default');
Parrot_PMC_init_int(interp, fpa, 10);
Parrot_PMC_morph(interp, fpa, pmc);
string = Parrot_PMC_name(interp, fpa);
Parrot_printf(interp, "%S\n", string);
integer = Parrot_PMC_get_integer(interp, fpa);
Parrot_printf(interp, "%S %d\n", string, integer);
CODE
default
Integer 10
Done!
OUTPUT

0 comments on commit 1997c9c

Please sign in to comment.