develooper Front page | perl.cvs.parrot | Postings from December 2008

[svn:parrot] r33593 - trunk/src

From:
chromatic
Date:
December 6, 2008 23:44
Subject:
[svn:parrot] r33593 - trunk/src
Message ID:
20081207074443.38BEDCB9AF@x12.develooper.com
Author: chromatic
Date: Sat Dec  6 23:44:42 2008
New Revision: 33593

Modified:
   trunk/src/global.c

Log:
[src] Refactored internal namespace lookup and creation functions.  There are
more functions now, but they're saner, because they don't have to keep checking
whether they're operating on a STRING, a Key, a String PMC, or an array PMC
containing String PMCs.

Modified: trunk/src/global.c
==============================================================================
--- trunk/src/global.c	(original)
+++ trunk/src/global.c	Sat Dec  6 23:44:42 2008
@@ -33,11 +33,41 @@
 PARROT_CAN_RETURN_NULL
 static PMC * internal_ns_keyed(PARROT_INTERP,
     ARGIN(PMC *base_ns),
-    ARGIN_NULLOK(PMC *pmc_key),
-    ARGIN_NULLOK(STRING *str_key),
+    ARGIN(PMC *pmc_key),
     int flags)
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static PMC * internal_ns_keyed_key(PARROT_INTERP,
+    ARGIN(PMC *ns),
+    ARGIN(PMC *key),
+    int flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static PMC * internal_ns_keyed_str(PARROT_INTERP,
+    ARGIN(PMC *base_ns),
+    ARGIN(STRING *key),
+    int flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static PMC * internal_ns_maybe_create(PARROT_INTERP,
+    ARGIN(PMC *ns),
+    ARGIN(STRING *key),
+    int flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
 
 static void store_sub_in_multi(PARROT_INTERP,
     ARGIN(PMC *sub),
@@ -58,9 +88,9 @@
 
 =item C<static PMC * internal_ns_keyed>
 
-internal_ns_keyed: Internal function to do keyed namespace lookup
-relative to a given namespace PMC.  Understands STRINGs, String PMCs,
-Key pmcs, and array PMCs containing strings.
+internal_ns_keyed: Internal function to do keyed namespace lookup relative to a
+given namespace PMC.  Understands String, Key, and array PMCs containing
+strings.
 
 =cut
 
@@ -69,73 +99,143 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static PMC *
-internal_ns_keyed(PARROT_INTERP, ARGIN(PMC *base_ns), ARGIN_NULLOK(PMC *pmc_key),
-        ARGIN_NULLOK(STRING *str_key), int flags)
+internal_ns_keyed(PARROT_INTERP, ARGIN(PMC *base_ns), ARGIN(PMC *pmc_key), int flags)
 {
-    PMC *ns, *sub_ns;
+    PMC *sub_ns;
+    PMC *ns = base_ns;
     INTVAL i, n;
     static const INTVAL max_intval = (INTVAL)((~(UINTVAL)0) >> 1); /*2s comp*/
 
-    ns = base_ns;
-
-    if (str_key)
-        n = 1;
-    else if (pmc_key->vtable->base_type == enum_class_String) {
-        str_key = VTABLE_get_string(interp, pmc_key);
-        n = 1;
+    if (pmc_key->vtable->base_type == enum_class_String) {
+        STRING *str_key = VTABLE_get_string(interp, pmc_key);
+        return internal_ns_keyed_str(interp, base_ns, str_key, flags);
     }
+
     else if (pmc_key->vtable->base_type == enum_class_Key)
-        n = max_intval;         /* we don't yet know how big the key is */
+        return internal_ns_keyed_key(interp, base_ns, pmc_key, flags);
     else
         n = VTABLE_elements(interp, pmc_key); /* array of strings */
 
     for (i = 0; i < n; ++i) {
         STRING *part;
+        if (!pmc_key)
+            Parrot_ex_throw_from_c_args(interp, NULL, 1,
+                "Passed a NULL pmc_key into VTABLE_get_string_keyed_int");
 
-        if (str_key)
-            part = str_key;
-        else if (n == max_intval) {
-            if (!pmc_key)
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                    "Trying to use a NULL PMC as a key");
+        part   = VTABLE_get_string_keyed_int(interp, pmc_key, i);
+        sub_ns = VTABLE_get_pmc_keyed_str(interp, ns, part);
 
-            part    = VTABLE_get_string(interp, pmc_key);
-            pmc_key = key_next(interp, pmc_key);
+        if (PMC_IS_NULL(sub_ns) || !VTABLE_isa(interp, sub_ns, CONST_STRING(interp, "NameSpace"))) {
+            sub_ns = internal_ns_maybe_create(interp, ns, part, flags);
 
-            if (!pmc_key)
-                n = i + 1;      /* now we know how big the key is */
+            if (PMC_IS_NULL(sub_ns))
+                return PMCNULL;
         }
-        else {
-            if (!pmc_key)
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                    "Passed a NULL pmc_key into VTABLE_get_string_keyed_int");
 
-            part = VTABLE_get_string_keyed_int(interp, pmc_key, i);
-        }
+        ns = sub_ns;
+    }
 
-        sub_ns = VTABLE_get_pmc_keyed_str(interp, ns, part);
+    return ns;
+}
 
-        if (PMC_IS_NULL(sub_ns)
-            /* RT#46157 - stop depending on typed namespace */
-            || sub_ns->vtable->base_type != enum_class_NameSpace)
-        {
-            if (!(flags & INTERN_NS_CREAT))
-                return PMCNULL;
 
-            /* RT#46159 - match HLL of enclosing namespace? */
-            sub_ns = pmc_new(interp,
-                             Parrot_get_ctx_HLL_type(interp,
-                                                     enum_class_NameSpace));
+/*
+
+=item C<static PMC * internal_ns_keyed_str>
+
+Internal function to do keyed namespace lookup relative to a given namespace
+PMC.  Understands STRINGs.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static PMC *
+internal_ns_keyed_str(PARROT_INTERP, ARGIN(PMC *base_ns),
+    ARGIN(STRING *key), int flags)
+{
+    PMC *ns = VTABLE_get_pmc_keyed_str(interp, base_ns, key);
+
+    if (!PMC_IS_NULL(ns) && VTABLE_isa(interp, ns, CONST_STRING(interp, "NameSpace")))
+        return ns;
+
+    return internal_ns_maybe_create(interp, base_ns, key, flags);
+}
+
+/*
+
+=item C<static PMC * internal_ns_keyed_key>
+
+Internal function to do keyed namespace lookup relative to a given namespace
+PMC.  Understands Key PMCs.  Used from C<internal_ns_keyed>.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static PMC *
+internal_ns_keyed_key(PARROT_INTERP, ARGIN(PMC *ns), ARGIN(PMC *key), int flags)
+{
+    while (key) {
+        STRING *part   = VTABLE_get_string(interp, key);
+        PMC    *sub_ns = VTABLE_get_pmc_keyed_str(interp, ns, part);
+
+        if (PMC_IS_NULL(sub_ns) || !VTABLE_isa(interp, sub_ns, CONST_STRING(interp, "NameSpace"))) {
+            sub_ns = internal_ns_maybe_create(interp, ns, part, flags);
+
             if (PMC_IS_NULL(sub_ns))
                 return PMCNULL;
-            VTABLE_set_pmc_keyed_str(interp, ns, part, sub_ns);
         }
-        ns = sub_ns;
-    } /* for */
+
+        ns  = sub_ns;
+        key = key_next(interp, key);
+    }
 
     return ns;
 }
 
+
+/*
+
+=item C<static PMC * internal_ns_maybe_create>
+
+Given the a namespace PMC, a STRING containing a name, and flags from
+C<internal_ns_keyed> or C<internal_ns_keyed_str>, creates and returns a new
+namespace with the given name in the given namespace.  This is an internal
+function only.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static PMC *
+internal_ns_maybe_create(PARROT_INTERP, ARGIN(PMC *ns), ARGIN(STRING *key), int flags)
+{
+    PMC *sub_ns;
+
+    /* RT #46157 - stop depending on typed namespace */
+    if (!(flags & INTERN_NS_CREAT))
+        return PMCNULL;
+
+    /* RT #46159 - match HLL of enclosing namespace? */
+    sub_ns = pmc_new(interp, Parrot_get_ctx_HLL_type(interp,
+                                                 enum_class_NameSpace));
+
+    if (PMC_IS_NULL(sub_ns))
+        return PMCNULL;
+
+    VTABLE_set_pmc_keyed_str(interp, ns, key, sub_ns);
+
+    return sub_ns;
+}
+
+
 /*
 
 =item C<PMC * Parrot_get_namespace_keyed>
@@ -154,7 +254,7 @@
 PMC *
 Parrot_get_namespace_keyed(PARROT_INTERP, ARGIN(PMC *base_ns), ARGIN_NULLOK(PMC *pmc_key))
 {
-    return internal_ns_keyed(interp, base_ns, pmc_key, NULL, 0);
+    return internal_ns_keyed(interp, base_ns, pmc_key, 0);
 }
 
 /*
@@ -175,7 +275,7 @@
 Parrot_get_namespace_keyed_str(PARROT_INTERP, ARGIN(PMC *base_ns),
         ARGIN_NULLOK(STRING *str_key))
 {
-    return internal_ns_keyed(interp, base_ns, PMCNULL, str_key, 0);
+    return internal_ns_keyed_str(interp, base_ns, str_key, 0);
 }
 
 /*
@@ -197,7 +297,7 @@
 Parrot_make_namespace_keyed(PARROT_INTERP, ARGIN(PMC *base_ns),
         ARGIN_NULLOK(PMC *pmc_key))
 {
-    return internal_ns_keyed(interp, base_ns, pmc_key, NULL, INTERN_NS_CREAT);
+    return internal_ns_keyed(interp, base_ns, pmc_key, INTERN_NS_CREAT);
 }
 
 /*
@@ -219,7 +319,7 @@
 Parrot_make_namespace_keyed_str(PARROT_INTERP, ARGIN(PMC *base_ns),
         ARGIN_NULLOK(STRING *str_key))
 {
-    return internal_ns_keyed(interp, base_ns, NULL, str_key, INTERN_NS_CREAT);
+    return internal_ns_keyed_str(interp, base_ns, str_key, INTERN_NS_CREAT);
 }
 
 
@@ -371,7 +471,7 @@
 Search the namespace PMC C<ns> for an object with name C<globalname>.
 Return the object, or NULL if not found.
 
-RT#46161 - For now this function prefers non-namespaces, it will eventually
+RT #46161 - For now this function prefers non-namespaces, it will eventually
 entirely use the untyped interface.
 
 =cut
@@ -395,7 +495,7 @@
         res = PMCNULL;
     else {
         /*
-         * RT#46163 - we should be able to use 'get_pmc_keyed' here,
+         * RT #46163 - we should be able to use 'get_pmc_keyed' here,
          * but we can't because Parrot's default namespaces are not
          * fully typed and there's a pseudo-typed interface that
          * distinguishes 'get_pmc_keyed' from 'get_pointer_keyed';
@@ -435,7 +535,7 @@
 an array of namespace name strings, or a string PMC, for an object
 with name C<globalname>.  Return the object, or NULL if not found.
 
-RT#46161 - For now this function prefers non-namespaces, it will eventually
+RT #46161 - For now this function prefers non-namespaces, it will eventually
 entirely use the untyped interface.
 
 =cut
@@ -463,7 +563,7 @@
 C<str_key> is NULL, for an object with name C<globalname>.  Return the
 object, or NULL if not found.
 
-RT#46161 - For now this function prefers non-namespaces, it will eventually
+RT #46161 - For now this function prefers non-namespaces, it will eventually
 entirely use the untyped interface.
 
 =cut
@@ -529,7 +629,7 @@
                           CONTEXT(interp)->current_namespace,
                           globalname, val);
 
-    /* RT#46165 - method cache invalidation should occur */
+    /* RT #46165 - method cache invalidation should occur */
 }
 
 /*
@@ -540,7 +640,7 @@
 which may be a key PMC, an array of namespace name strings, or a
 string PMC, with name C<globalname>.
 
-RT#46161 - For now this function prefers non-namespaces, it will eventually
+RT #46161 - For now this function prefers non-namespaces, it will eventually
 entirely use the untyped interface.
 
 =cut
@@ -555,7 +655,7 @@
     PMC *ns;
 
     /*
-     * RT#46167 - temporary hack to notice when key is actually a string, so that
+     * RT #46167 - temporary hack to notice when key is actually a string, so that
      * the legacy logic for invalidating method cache will be called; this is
      * not good enough but it avoids regressesions for now
      */
@@ -571,7 +671,7 @@
 
     Parrot_store_global_n(interp, ns, globalname, val);
 
-    /* RT#46165 - method cache invalidation should occur */
+    /* RT #46165 - method cache invalidation should occur */
 }
 
 /*
@@ -596,7 +696,7 @@
 
     Parrot_store_global_n(interp, ns, globalname, val);
 
-    /* RT#46169 - method cache invalidation should be a namespace function */
+    /* RT #46169 - method cache invalidation should be a namespace function */
     Parrot_invalidate_method_cache(interp, str_key, globalname);
 }
 
@@ -637,7 +737,7 @@
 
 =item C<PMC * Parrot_find_name_op>
 
-RT#46171 - THIS IS BROKEN - it doesn't walk up the scopes yet
+RT #46171 - THIS IS BROKEN - it doesn't walk up the scopes yet
 
 Find the given C<name> in lexicals, then the current namespace, then the HLL
 root namespace, and finally Parrot builtins.  If the name isn't found
@@ -662,7 +762,7 @@
     else
         g = VTABLE_get_pmc_keyed_str(interp, lex_pad, name);
 
-    /* RT#46171 - walk up the scopes!  duh!! */
+    /* RT #46171 - walk up the scopes!  duh!! */
 
     if (PMC_IS_NULL(g))
         g = Parrot_find_global_cur(interp, name);



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About