Browse files

[PMC] Made nested UnManagedStructs independent of each other, per RT …

…#31292.

This unTODOes one test.

git-svn-id: https://svn.parrot.org/parrot/trunk@36918 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
1 parent 6822f5c commit 63c275b8cd998116ce578fad243c797e6bdbd99c @chromatic chromatic committed Feb 21, 2009
Showing with 83 additions and 45 deletions.
  1. +24 −1 src/pmc/managedstruct.pmc
  2. +40 −27 src/pmc/unmanagedstruct.pmc
  3. +19 −17 t/pmc/nci.t
View
25 src/pmc/managedstruct.pmc
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2001-2007, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
$Id$
=head1 DESCRIPTION
@@ -101,6 +101,29 @@ Destroys the struct, freeing the allocated memory.
return;
}
+
+/*
+
+=item C<PMC * clone()>
+
+Creates a clone of this PMC; clones any unmanaged memory it holds too. Note
+that the latter is only a shallow copy, as there's no general way of knowing
+how to clone I<that> data.
+
+=cut
+
+*/
+
+ VTABLE PMC *clone() {
+ PMC *dest = pmc_new_init(interp, SELF->vtable->base_type,
+ PMC_pmc_val(SELF));
+
+ if (PMC_data(SELF))
+ memmove(PMC_data(dest), PMC_data(SELF), PMC_int_val(SELF));
+
+ return dest;
+ }
+
}
/*
View
67 src/pmc/unmanagedstruct.pmc
@@ -160,14 +160,13 @@ char_offset_key(PARROT_INTERP, PMC *pmc, PMC *key, int *type)
if (*type == enum_type_struct_ptr || *type == enum_type_struct) {
/* the struct PMC is hanging off the initializer element
- * as property "_struct"
- */
+ * as property "_struct" */
PMC * const ptr = VTABLE_get_pmc_keyed_int(interp, init, ix);
init = VTABLE_getprop(interp, ptr, CONST_STRING(interp, "_struct"));
- PARROT_ASSERT(init &&
- (init->vtable->base_type == enum_class_UnManagedStruct ||
- init->vtable->base_type == enum_class_ManagedStruct));
+ PARROT_ASSERT(init
+ && (init->vtable->base_type == enum_class_UnManagedStruct
+ || init->vtable->base_type == enum_class_ManagedStruct));
/* array of structs */
if (max > 1) {
@@ -182,24 +181,25 @@ char_offset_key(PARROT_INTERP, PMC *pmc, PMC *key, int *type)
p += offs * count;
}
+
if (init->vtable->base_type == enum_class_UnManagedStruct) {
/* now point PMC_data of this struct to the real data */
if (*type == enum_type_struct_ptr) {
/* that is either a pointer */
PARROT_ASSERT((PTR2INTVAL(p) & (PARROT_PTR_ALIGNMENT - 1)) == 0);
PMC_data(init) = *(void**)p;
}
- else {
- /* or just an offset for nested structs */
+
+ /* or just an offset for nested structs */
+ else
PMC_data(init) = p;
- }
}
- else if (init->vtable->base_type == enum_class_ManagedStruct &&
- *type == enum_type_struct_ptr) {
+ else if (init->vtable->base_type == enum_class_ManagedStruct
+ && *type == enum_type_struct_ptr) {
/* a nested struct pointer belonging to us
* p is the location of the struct pointer in the
- * outer struct, the inner is at PMC_data(init)
- */
+ * outer struct, the inner is at PMC_data(init) */
+
PARROT_ASSERT((PTR2INTVAL(p) & (PARROT_PTR_ALIGNMENT - 1)) == 0);
*(void **)p = PMC_data(init);
}
@@ -216,6 +216,7 @@ char_offset_key(PARROT_INTERP, PMC *pmc, PMC *key, int *type)
return p + count * size;
}
+
/*
=item C<static INTVAL
@@ -521,8 +522,8 @@ set_string(PARROT_INTERP, char *p, int type, STRING *value)
calc_align(PARROT_INTERP, PMC *pmc, PMC *type_pmc,
int type, size_t offs)>
-Alignment of contained structures is the alignment of the
-biggest item in that C<struct>.
+Alignment of contained structures is the alignment of the biggest item in that
+C<struct>.
i386: C<long long> or C<double> is aligned on 4.
@@ -542,8 +543,7 @@ calc_align(PARROT_INTERP, PMC *pmc, PMC *type_pmc,
if (type == enum_type_struct || type == enum_type_struct_ptr) {
/* a nested structs alignment is the biggest item in it
- * so go through that struct and check
- */
+ * so go through that struct and check */
nested = VTABLE_getprop(interp, type_pmc, CONST_STRING(interp, "_struct"));
nested_init = PMC_pmc_val(nested);
}
@@ -587,8 +587,8 @@ calc_align(PARROT_INTERP, PMC *pmc, PMC *type_pmc,
=item C<static size_t
calc_offsets(PARROT_INTERP, PMC *pmc, PMC *value, size_t toff)>
-Calculates the offsets for the C<struct>. See C<init_pmc()> for a
-description of C<*value>.
+Calculates the offsets for the C<struct>. See C<init_pmc()> for a description
+of C<*value>.
=cut
@@ -597,8 +597,10 @@ description of C<*value>.
static size_t
calc_offsets(PARROT_INTERP, PMC *pmc, PMC *value, size_t toff)
{
- INTVAL i, n = (size_t)VTABLE_elements(interp, value);
- int size;
+ STRING *_struct = CONST_STRING(interp, "_struct");
+ INTVAL n = (size_t)VTABLE_elements(interp, value);
+ INTVAL i;
+ int size;
if (n % 3)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
@@ -611,25 +613,36 @@ calc_offsets(PARROT_INTERP, PMC *pmc, PMC *value, size_t toff)
int offs = (int)VTABLE_get_integer_keyed_int(interp, value, i + 2);
if (type < enum_first_type || type >= enum_last_type)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "Illegal type in initializer for struct");
+ Parrot_ex_throw_from_c_args(interp, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Illegal type in initializer for struct");
if (count <= 0) {
count = 1;
- VTABLE_set_integer_keyed_int(interp, value, i+1, count);
+ VTABLE_set_integer_keyed_int(interp, value, i + 1, count);
}
if (offs <= 0) {
offs = toff = calc_align(interp, pmc, type_pmc, type, toff);
- VTABLE_set_integer_keyed_int(interp, value, i+2, offs);
+ VTABLE_set_integer_keyed_int(interp, value, i + 2, offs);
}
else
toff = offs;
if (type == enum_type_struct) {
- PMC *nested = VTABLE_getprop(interp, type_pmc, CONST_STRING(interp, "_struct"));
+ PMC *nested = VTABLE_getprop(interp, type_pmc, _struct);
size = VTABLE_get_integer(interp, nested);
}
+ else if (type == enum_type_struct_ptr) {
+ PMC *nested = VTABLE_getprop(interp, type_pmc, _struct);
+
+ /* must clone this struct so as not to share its memory */
+ if (nested->vtable->base_type == enum_class_ManagedStruct)
+ VTABLE_setprop(interp, type_pmc, _struct,
+ VTABLE_clone(interp, nested));
+
+ size = data_types[type - enum_first_type].size;
+ }
else
size = data_types[type - enum_first_type].size;
@@ -739,8 +752,8 @@ Returns whether the two C<struct>s are equivalent.
*/
VTABLE INTVAL is_equal(PMC *value) {
- return (SELF->vtable == value->vtable &&
- PMC_data(SELF) == PMC_data(value));
+ return (SELF->vtable == value->vtable
+ && PMC_data(SELF) == PMC_data(value));
}
/*
View
36 t/pmc/nci.t
@@ -2134,7 +2134,7 @@ Triple: 6
Sum: 12
OUTPUT
- pasm_output_is( <<'CODE', <<'OUTPUT', 'nci_vpii - nested structs' );
+pasm_output_is( <<'CODE', <<'OUTPUT', 'nci_vpii - nested structs' );
.include "datatypes.pasm"
new P8, 'OrderedHash'
@@ -2156,16 +2156,15 @@ OUTPUT
push P6, 0
new P5, 'ManagedStruct', P6
- set P9[ 'y' ], 200
+ set P5[ 'nested'; 'y' ], 200
set P5[ 'x' ], 100
set I0, P5[ 'x' ]
set I1, P5[ 'nested'; 'y' ]
print "Old X: "
- print I0
- print "\nOld Y: "
- print I1
- print "\n"
+ say I0
+ print "Old Y: "
+ say I1
set_args "0,0,0", P5, 1, 2
loadlib P1, "libnci_test"
@@ -2176,15 +2175,13 @@ OUTPUT
set P6, P5[ 'nested' ]
set I1, P6[ 'y' ]
print "X: "
- print I0
- print "\nY: "
- print I1
- print "\n"
+ say I0
+ print "Y: "
+ say I1
# extract struct
set P6, P5[ 'nested' ]
set I1, P6[ 'y' ]
- print I1
- print "\n"
+ say I1
end
CODE
Old X: 100
@@ -2536,7 +2533,7 @@ CODE
OUTPUT
pir_output_is(
- << 'CODE', << 'OUTPUT', 'nested structs should be independent', todo => 'RT #31292' );
+ << 'CODE', << 'OUTPUT', 'nested structs should be independent' );
.include 'datatypes.pasm'
.sub 'test' :main
@@ -2563,6 +2560,7 @@ pir_output_is(
.local pmc nci_func
nci_func = dlfunc libnci_test, 'nci_vpii', 'vpii'
+ print_values( outer )
nci_func( outer, 1, 100 )
print_values( outer )
@@ -2574,6 +2572,7 @@ pir_output_is(
nci_func( other, 2, 200 )
print_values( outer )
+ print_values( other )
.end
.sub 'print_values'
@@ -2583,10 +2582,9 @@ pir_output_is(
x = outer['x']
y = outer[ 'nested'; 'y' ]
print "X: "
- print x
- print "\nY: "
- print y
- print "\n"
+ say x
+ print "Y: "
+ say y
.end
.sub 'make_outer_struct'
@@ -2611,10 +2609,14 @@ pir_output_is(
.return( outer )
.end
CODE
+X: 0
+Y: 0
X: 1
Y: 100
X: 1
Y: 100
+X: 2
+Y: 200
OUTPUT
pir_output_is( << 'CODE', << 'OUTPUT', "arity" );

0 comments on commit 63c275b

Please sign in to comment.