Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 3 commits
  • 7 files changed
  • 0 commit comments
  • 1 contributor
Commits on Mar 10, 2014
@rurban rurban [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
0e72e0f
@rurban rurban morph: add morph methods to undef and fixedpmcarray
fixes the test to morph fixedpmcarray to integer
t/src/extend_vtable.t 9

t/pmc/undef.t: 10 still broken: String morph to Undef, get_class Undef is a PMCProxy
70f6245
@rurban rurban [test] start t/op/morph.t 64b47ff
Showing with 232 additions and 13 deletions.
  1. +2 −0 src/pmc.c
  2. +6 −5 src/pmc/default.pmc
  3. +71 −1 src/pmc/fixedpmcarray.pmc
  4. +3 −2 src/pmc/resizablepmcarray.pmc
  5. +16 −1 src/pmc/undef.pmc
  6. +127 −0 t/op/morph.t
  7. +7 −4 t/src/extend_vtable.t
View
2 src/pmc.c
@@ -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
11 src/pmc/default.pmc
@@ -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
72 src/pmc/fixedpmcarray.pmc
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2001-2011, Parrot Foundation.
+Copyright (C) 2001-2014, Parrot Foundation.
=head1 NAME
@@ -26,6 +26,10 @@ 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_resizablepmcarray.h"
+#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 +205,72 @@ 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) {
+ INTVAL iv = SELF.elements();
+ Parrot_pmc_reuse(INTERP, SELF, new_type->vtable->base_type, 0);
+ VTABLE_init_int(INTERP, SELF, iv);
+ }
+ else if (new_type->vtable->base_type == enum_class_String) {
+ STRING *s = SELF.get_string();
+ Parrot_pmc_reuse(INTERP, SELF, new_type->vtable->base_type, 0);
+ VTABLE_set_string_native(INTERP, SELF, s);
+ }
+ else if (VTABLE_isa(INTERP, new_type, CONST_STRING(INTERP, "ResizablePMCArray"))) {
+ PMC **to;
+ PMC **from = PMC_array(SELF);
+ INTVAL size = PMC_size(SELF);
+ Parrot_pmc_reuse(INTERP, SELF, new_type->vtable->base_type, 0);
+ GETATTR_ResizablePMCArray_pmc_array(INTERP, new_type, to);
+ PMC_size(new_type) = size;
+ PMC_array(new_type) = to;
+ }
+ 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);
+ INTVAL size = PMC_size(SELF);
+ GETATTR_FixedStringArray_str_array(INTERP, new_type, to);
+ Parrot_pmc_reuse(INTERP, SELF, new_type->vtable->base_type, 0);
+ for (i = 0; i < PMC_size(SELF); i++) {
+ to[i] = VTABLE_get_string(INTERP, from[i]);
+ }
+ PMC_size(new_type) = size;
+ }
+ 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);
+ INTVAL size = PMC_size(SELF);
+ GETATTR_FixedIntegerArray_int_array(INTERP, new_type, to);
+ Parrot_pmc_reuse(INTERP, SELF, new_type->vtable->base_type, 0);
+ for (i = 0; i < PMC_size(SELF); i++) {
+ to[i] = VTABLE_get_integer(INTERP, from[i]);
+ }
+ PMC_size(new_type) = size;
+ }
+ else {
+ Parrot_pmc_reuse(INTERP, SELF, new_type->vtable->base_type, 0);
+ retval = 0;
+ }
+
+ return retval;
+ }
+
+/*
+
=item C<FLOATVAL get_number()>
Returns the number of elements in the array.
View
5 src/pmc/resizablepmcarray.pmc
@@ -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
17 src/pmc/undef.pmc
@@ -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
127 t/op/morph.t
@@ -0,0 +1,127 @@
+#!./parrot
+# Copyright (C) 2014, Parrot Foundation.
+
+=head1 NAME
+
+t/op/morph.t - the morph opcode
+
+=head1 SYNOPSIS
+
+ % prove t/op/morph.t
+
+=head1 DESCRIPTION
+
+Tests most morph operations.
+
+morph objects to class, object
+morph class to class, object
+
+=cut
+
+.namespace[]
+
+.const int TESTS = 8
+
+# must set these up before the hll_map calls later
+.sub '__setup' :immediate
+ $P0 = subclass 'Integer', 'MyInt'
+ $P0 = subclass 'String', 'MyString'
+ $P0 = subclass 'Float', 'MyFloat'
+.end
+
+.sub 'main' :main
+ .include 'test_more.pir'
+
+ 'plan'(TESTS)
+ undef_morph_to_string()
+ undef_pmc_morph_to_string()
+ undef_pmc_morph_to_integer()
+ undef_pmc_morph_to_float()
+ string_pmc_morph_to_undef()
+
+ morph_class()
+ morph_obj()
+
+.end
+
+.sub undef_morph_to_string
+ new $P0, ['String']
+ new $P1, ['Undef']
+ set $P0, "foo"
+ concat $P1, $P0, $P0
+ is( $P1, 'foofoo', 'morphed to string' )
+.end
+
+.sub undef_pmc_morph_to_string
+ .local pmc pmc1
+ pmc1 = new ['Undef']
+ $S1 = pmc1
+ is( $S1, '', 'PMC Undef is empty string' )
+.end
+
+.sub undef_pmc_morph_to_integer
+ .local pmc pmc1
+ pmc1 = new ['Undef']
+ .local int int1
+ int1 = pmc1
+ is( int1, 0, 'PMC Undef as integer is zero' )
+
+ .local int int2
+ int2 = -7777777
+ int2 += int1
+ is( int2, -7777777, 'PMC Undef in addition is zero' )
+.end
+
+.sub undef_pmc_morph_to_float
+ .local pmc pmc1
+ pmc1 = new ['Undef']
+ .local int int1
+ int1 = pmc1
+ .local num float1
+ float1 = -7777777e-3
+ float1 += int1
+ is( float1, -7777.777000, 'PMC Undef morph to int then float' )
+.end
+
+.sub string_pmc_morph_to_undef
+ .local pmc pmc1
+ pmc1 = new ['String']
+ $P0 = get_class 'Undef'
+ morph pmc1, $P0
+ $S1 = typeof pmc1
+ is( $S1, 'Undef', 'PMC String morph to undef' )
+.end
+
+.sub morph_class
+ .local pmc obja, objb
+ $P0 = newclass 'Object1'
+ $P1 = newclass 'Object2'
+ obja = new $P0
+ objb = new $P1
+ morph obja, objb
+ $S1 = typeof obja
+ todo( $S1, 'Object2', 'morph class' )
+.end
+
+.sub morph_obj
+ .local pmc obja, objb
+ $P0 = newclass 'Object1'
+ $P1 = newclass 'Object2'
+ obja = new $P0
+ morph obja, $P1
+ $P2 = find_method obja, 'nameMe'
+ $S1 = obja.$P2()
+ todo( $S1, 'Object2', 'morph obj' )
+.end
+
+.namespace ['Object2']
+
+.sub 'nameMe' :method
+ .return("Object2")
+.end
+
+# Local Variables:
+# mode: pir
+# fill-column: 78
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
View
11 t/src/extend_vtable.t
@@ -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

No commit comments for this range

Something went wrong with that request. Please try again.