Here's a patch which nearly gets t/pmc/packfiledirectory.t working fully.
I've added set_pmc_keyed() and set_pmc_keyed_str() to the PackfileDirectory
PMC. Unfortunately, this causes crashes when destroying the directory, as it
looks like I'm sharing memory in two places.
This test is a little dodgy as well, because it tries to add a segment which
already exists in the directory again with a different name. I'm not sure
that should work, but I couldn't get other approaches to work much better.
It's a starting point anyway.
-- c
=== src/pmc/packfiledirectory.pmc
==================================================================
--- src/pmc/packfiledirectory.pmc (revision 36934)
+++ src/pmc/packfiledirectory.pmc (local)
@@ -57,12 +57,15 @@
VTABLE PMC *get_pmc_keyed_int(INTVAL index) {
const PackFile_Directory * const pfd = PMC_data_typed(SELF, PackFile_Directory *);
PackFile_Segment *pfseg;
- PMC *rv;
- int pmc_type;
+ PMC *rv;
+ int pmc_type;
+
if (index < 0 || index >= (INTVAL)pfd->num_segments)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
- "PackfileDirectory: index out of bounds!");
+ "PackfileDirectory: index out of bounds!");
+
pfseg = pfd->segments[index];
+
switch (pfseg->type) {
case PF_DIR_SEG:
pmc_type = enum_class_PackfileDirectory;
@@ -80,7 +83,8 @@
pmc_type = enum_class_PackfileRawSegment;
break;
}
- rv = pmc_new(interp, pmc_type);
+
+ rv = pmc_new(interp, pmc_type);
PMC_data(rv) = pfseg;
return rv;
}
@@ -156,10 +160,32 @@
*/
VTABLE void set_pmc_keyed_str(STRING *name, PMC *segment) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED, "Not implemented yet.");
+ const PackFile_Directory * const pfd = PMC_data_typed(SELF, PackFile_Directory *);
+ PackFile_Segment * const add_seg = PMC_data(segment);
+
+ const int total = pfd->num_segments;
+ int i;
+
+ for (i = 0; i < total; i++) {
+ const PackFile_Segment * const pfseg = pfd->segments[i];
+
+ if (!Parrot_str_compare(interp, name,
+ Parrot_str_new_constant(interp, pfseg->name))) {
+ pfd->segments[i] = add_seg;
+ return;
+ }
+ }
+
+ add_seg->name = Parrot_str_to_cstring(interp, name);
+ PackFile_add_segment(interp, pfd, add_seg);
}
+ VTABLE void set_pmc_keyed(PMC *key, PMC *segment) {
+ STRING *s_key = VTABLE_get_string(interp, key);
+ VTABLE_set_pmc_keyed_str(interp, SELF, s_key, segment);
+ }
+
}
/*
=== t/pmc/packfiledirectory.t
==================================================================
--- t/pmc/packfiledirectory.t (revision 36934)
+++ t/pmc/packfiledirectory.t (local)
@@ -170,12 +170,12 @@
# PackfileDirectory.set_pmc_keyed_str
-pir_output_is( <<'CODE' . $get_uuid_pbc, <<'OUT', 'PackfileDirectory.set_pmc_keyed_str', todo => 'implement this' );
+pir_output_is( <<'CODE' . $get_uuid_pbc, <<'OUT', 'PackfileDirectory.set_pmc_keyed_str' );
.sub 'test' :main
.local pmc pf, pfdir
pf = _pbc()
pfdir = pf.'get_directory'()
- $P0 = pfdir[0]
+ $P0 = new [ 'PackfileRawSegment' ]
$S0 = 'BYTECODE_foo'
pfdir[$S0] = $P0
$I0 = elements pfdir
_______________________________________________
http://lists.parrot.org/mailman/listinfo/parrot-dev