[svn:parrot] r38009 - branches/packfile_revamp/src/pmc

bacek at svn.parrot.org bacek at svn.parrot.org
Fri Apr 10 05:30:19 UTC 2009


Author: bacek
Date: Fri Apr 10 05:30:18 2009
New Revision: 38009
URL: https://trac.parrot.org/parrot/changeset/38009

Log:
Refactor PackfileDirectory PMC to use Hash as main storage.

Modified:
   branches/packfile_revamp/src/pmc/packfiledirectory.pmc

Modified: branches/packfile_revamp/src/pmc/packfiledirectory.pmc
==============================================================================
--- branches/packfile_revamp/src/pmc/packfiledirectory.pmc	Fri Apr 10 05:29:56 2009	(r38008)
+++ branches/packfile_revamp/src/pmc/packfiledirectory.pmc	Fri Apr 10 05:30:18 2009	(r38009)
@@ -28,87 +28,146 @@
 #include "parrot/parrot.h"
 
 pmclass PackfileDirectory extends PackfileSegment {
+    /* Directory is a hash of Segments */
+    ATTR PMC *hash;
 
+/*
+
+=item C<void init()>
+
+Initialize PackfileDirectory.
+
+=cut
+
+*/
+    VTABLE void init() {
+        Parrot_PackfileDirectory_attributes * attrs =
+                mem_allocate_zeroed_typed(Parrot_PackfileDirectory_attributes);
+
+        attrs->hash = pmc_new(interp, enum_class_Hash);
+
+        PObj_custom_mark_destroy_SETALL(SELF);
+        PMC_data(SELF) = attrs;
+    }
 
 /*
 
-=item C<INTVAL elements()>
+=item C<void mark()>
 
-Get the number of elements in the array.
+Marks the object as live. 
 
 =cut
 
 */
-    VTABLE INTVAL elements() {
-        PackFile_Directory *pfd = PMC_data_typed(SELF, PackFile_Directory *);
-        return pfd->num_segments;
+
+    VTABLE void mark() {
+        Parrot_PackfileDirectory_attributes * attrs =
+                PARROT_PACKFILEDIRECTORY(SELF);
+
+        if (attrs->hash)
+            pobject_lives(interp, (PObj *)attrs->hash);
+    }
+
+/*
+
+=item C<void destroy()>
+
+Destroys the PMC and frees all allocated memory.
+
+=cut
+
+*/
+
+    VTABLE void destroy() {
+        Parrot_PackfileDirectory_attributes * attrs =
+                PARROT_PACKFILEDIRECTORY(SELF);
+
+        if (attrs) {
+            mem_sys_free(attrs);
+            PMC_data(SELF) = NULL;
+        }
     }
 
 
 /*
 
-=item C<PMC *get_pmc_keyed_int(INTVAL index)>
+=item C<void set_pointer(void *ptr)>
 
-Fetch a segment PMC from the array.
+Initialize PackfileDirectory from PackFile_Directory.
 
 =cut
 
 */
-    VTABLE PMC *get_pmc_keyed_int(INTVAL index)  {
-        const PackFile_Directory * const pfd = PMC_data_typed(SELF, PackFile_Directory *);
+
+    VTABLE void set_pointer(void *ptr) {
+        const PackFile_Directory * const pfd = (const PackFile_Directory *)ptr;
         PackFile_Segment *pfseg;
-        PMC              *rv;
+        PMC              *segment;
         int              pmc_type;
+        unsigned int     i;
+        STRING           *name;
+        PMC              *hash = PARROT_PACKFILEDIRECTORY(SELF)->hash;
+        
+        SUPER(ptr);
+
+        /* Iterate over elements and create corresponded PMCs */
+        for (i=0; i < pfd->num_segments; ++i) {
+            pfseg = pfd->segments[i];
+
+            switch (pfseg->type) {
+                case PF_DIR_SEG:
+                    pmc_type = enum_class_PackfileDirectory;
+                    break;
+                case PF_FIXUP_SEG:
+                    pmc_type = enum_class_PackfileFixupTable;
+                    break;
+                case PF_CONST_SEG:
+                    pmc_type = enum_class_PackfileConstantTable;
+                    break;
+                case PF_BYTEC_SEG:
+                case PF_UNKNOWN_SEG:
+                case PF_DEBUG_SEG:
+                default:
+                    pmc_type = enum_class_PackfileRawSegment;
+                    break;
+            }
+
+            segment = pmc_new(interp, pmc_type);
+            /* Initialize internal PMC structure */
+            VTABLE_set_pointer(interp, segment, pfseg);
 
-        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!");
-
-        pfseg = pfd->segments[index];
-
-        switch (pfseg->type) {
-            case PF_DIR_SEG:
-                pmc_type = enum_class_PackfileDirectory;
-                break;
-            case PF_FIXUP_SEG:
-                pmc_type = enum_class_PackfileFixupTable;
-                break;
-            case PF_CONST_SEG:
-                pmc_type = enum_class_PackfileConstantTable;
-                break;
-            case PF_BYTEC_SEG:
-            case PF_UNKNOWN_SEG:
-            case PF_DEBUG_SEG:
-            default:
-                pmc_type = enum_class_PackfileRawSegment;
-                break;
+            name    = Parrot_str_new(interp, pfseg->name, strlen(pfseg->name));
+            VTABLE_set_pmc_keyed_str(interp, hash, name, segment);
         }
+    }
+
+/*
+
+=item C<INTVAL elements()>
+
+Get the number of elements in the array.
+
+=cut
 
-        rv           = pmc_new(interp, pmc_type);
-        PMC_data(rv) = pfseg;
-        return rv;
+*/
+    VTABLE INTVAL elements() {
+        return VTABLE_elements(interp, PARROT_PACKFILEDIRECTORY(SELF)->hash);
     }
 
 
 /*
 
-=item C<STRING *get_string_keyed_int(INTVAL index)>
+=item C<PMC *get_iter()>
 
-Fetch a string containing the name of the specified segment PMC.
+Return a new iterator for the directory.
 
 =cut
 
 */
-    VTABLE STRING *get_string_keyed_int(INTVAL index)  {
-        const PackFile_Directory * const pfd = PMC_data_typed(SELF, PackFile_Directory *);
-        const PackFile_Segment *pfseg;
-        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!");
-        pfseg = pfd->segments[index];
-        return Parrot_str_new_constant(interp, pfseg->name);
-    }
 
+    VTABLE PMC *get_iter() {
+        return VTABLE_get_iter(interp, PARROT_PACKFILEDIRECTORY(SELF)->hash);
+    }
 
 /*
 
@@ -120,16 +179,8 @@
 
 */
     VTABLE PMC *get_pmc_keyed_str(STRING *name)  {
-        const PackFile_Directory * const pfd = PMC_data_typed(SELF, PackFile_Directory *);
-        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)))
-                return VTABLE_get_pmc_keyed_int(interp, SELF, i);
-        }
-        /* the specified segment name wasn't found. */
-        return PMCNULL;
+        return VTABLE_get_pmc_keyed_str(interp,
+                PARROT_PACKFILEDIRECTORY(SELF)->hash, name);
     }
 
 
@@ -144,8 +195,9 @@
 
 */
     VTABLE PMC *get_pmc_keyed(PMC *key) {
-        STRING * const s = VTABLE_get_string(INTERP, key);
-        return SELF.get_pmc_keyed_str(s);
+        STRING *s_key = VTABLE_get_string(interp, key);
+        return VTABLE_get_pmc_keyed_str(interp,
+                PARROT_PACKFILEDIRECTORY(SELF)->hash, s_key);
     }
 
 
@@ -158,29 +210,12 @@
 
 =cut
 
+TODO: check type
+
 */
     VTABLE void set_pmc_keyed_str(STRING *name, PMC *segment)  {
-        PackFile_Directory * const pfd = PMC_data_typed(SELF, PackFile_Directory *);
-        PackFile_Segment *add_seg = PMC_data_typed(segment, PackFile_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))) {
-                    add_seg->pf = pfd->base.pf;
-                    add_seg->name = pfseg->name;
-                    pfd->segments[i] = add_seg;
-                return;
-            }
-        }
-
-        add_seg->name = Parrot_str_to_cstring(interp, name);
-        add_seg->pf = pfd->base.pf;
-        PackFile_add_segment(interp, pfd, add_seg);
+        VTABLE_set_pmc_keyed_str(interp,
+            PARROT_PACKFILEDIRECTORY(SELF)->hash, name, segment);
     }
 
     VTABLE void set_pmc_keyed(PMC *key, PMC *segment)  {


More information about the parrot-commits mailing list