fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / namespace.c
bloba6f46ed42316c5e6c7c9bf830ae5fab656a83b73
1 /*
2 Copyright (C) 2004-2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/namespace.c
9 =head1 DESCRIPTION
11 Common routines for storing and finding elements in namespaces
13 =cut
17 #include "parrot/parrot.h"
18 #include "namespace.str"
19 #include "pmc/pmc_sub.h"
20 #include "pmc/pmc_callcontext.h"
22 /* HEADERIZER HFILE: include/parrot/namespace.h */
23 /* HEADERIZER BEGIN: static */
24 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
26 PARROT_WARN_UNUSED_RESULT
27 PARROT_CAN_RETURN_NULL
28 static PMC * get_namespace_pmc(PARROT_INTERP, ARGIN(PMC *sub_pmc))
29 __attribute__nonnull__(1)
30 __attribute__nonnull__(2);
32 PARROT_WARN_UNUSED_RESULT
33 PARROT_CAN_RETURN_NULL
34 static PMC * internal_ns_keyed(PARROT_INTERP,
35 ARGIN(PMC *base_ns),
36 ARGIN(PMC *pmc_key),
37 int flags)
38 __attribute__nonnull__(1)
39 __attribute__nonnull__(2)
40 __attribute__nonnull__(3);
42 PARROT_WARN_UNUSED_RESULT
43 PARROT_CAN_RETURN_NULL
44 static PMC * internal_ns_keyed_key(PARROT_INTERP,
45 ARGIN(PMC *ns),
46 ARGIN(PMC *key),
47 int flags)
48 __attribute__nonnull__(1)
49 __attribute__nonnull__(2)
50 __attribute__nonnull__(3);
52 PARROT_WARN_UNUSED_RESULT
53 PARROT_CAN_RETURN_NULL
54 static PMC * internal_ns_keyed_str(PARROT_INTERP,
55 ARGIN(PMC *base_ns),
56 ARGIN(STRING *key),
57 int flags)
58 __attribute__nonnull__(1)
59 __attribute__nonnull__(2)
60 __attribute__nonnull__(3);
62 PARROT_WARN_UNUSED_RESULT
63 PARROT_CAN_RETURN_NULL
64 static PMC * internal_ns_maybe_create(PARROT_INTERP,
65 ARGIN(PMC *ns),
66 ARGIN(STRING *key),
67 int flags)
68 __attribute__nonnull__(1)
69 __attribute__nonnull__(2)
70 __attribute__nonnull__(3);
72 static void store_sub_in_multi(PARROT_INTERP,
73 ARGIN(PMC *sub_pmc),
74 ARGIN(PMC *ns))
75 __attribute__nonnull__(1)
76 __attribute__nonnull__(2)
77 __attribute__nonnull__(3);
79 #define ASSERT_ARGS_get_namespace_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
80 PARROT_ASSERT_ARG(interp) \
81 , PARROT_ASSERT_ARG(sub_pmc))
82 #define ASSERT_ARGS_internal_ns_keyed __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
83 PARROT_ASSERT_ARG(interp) \
84 , PARROT_ASSERT_ARG(base_ns) \
85 , PARROT_ASSERT_ARG(pmc_key))
86 #define ASSERT_ARGS_internal_ns_keyed_key __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
87 PARROT_ASSERT_ARG(interp) \
88 , PARROT_ASSERT_ARG(ns) \
89 , PARROT_ASSERT_ARG(key))
90 #define ASSERT_ARGS_internal_ns_keyed_str __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
91 PARROT_ASSERT_ARG(interp) \
92 , PARROT_ASSERT_ARG(base_ns) \
93 , PARROT_ASSERT_ARG(key))
94 #define ASSERT_ARGS_internal_ns_maybe_create __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
95 PARROT_ASSERT_ARG(interp) \
96 , PARROT_ASSERT_ARG(ns) \
97 , PARROT_ASSERT_ARG(key))
98 #define ASSERT_ARGS_store_sub_in_multi __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
99 PARROT_ASSERT_ARG(interp) \
100 , PARROT_ASSERT_ARG(sub_pmc) \
101 , PARROT_ASSERT_ARG(ns))
102 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
103 /* HEADERIZER END: static */
105 /* flags for internal_ns_keyed */
106 #define INTERN_NS_CREAT 1 /* I'm a fan of the classics */
110 =head1 Internal Static Functions
112 =over 4
114 =item C<static PMC * internal_ns_keyed_str(PARROT_INTERP, PMC *base_ns, STRING
115 *key, int flags)>
117 Looks up a nested NameSpace PMC starting from C<base_ns> and doing a relative
118 lookup. C<key> is a STRING containing the name of the NameSpace to look up.
119 Flags can be 0 or INTERN_NS_CREAT. In the former case, PMCNULL is returned
120 if the namespace is not found. In the later, a new namespace with the given
121 is created and returned if it is not found.
123 =cut
127 PARROT_WARN_UNUSED_RESULT
128 PARROT_CAN_RETURN_NULL
129 static PMC *
130 internal_ns_keyed_str(PARROT_INTERP, ARGIN(PMC *base_ns),
131 ARGIN(STRING *key), int flags)
133 ASSERT_ARGS(internal_ns_keyed_str)
134 PMC * const ns = VTABLE_get_pmc_keyed_str(interp, base_ns, key);
135 STRING * const namesp = CONST_STRING(interp, "NameSpace");
137 if (!PMC_IS_NULL(ns)
138 && (ns->vtable->base_type == enum_class_NameSpace
139 || VTABLE_isa(interp, ns, namesp)))
140 return ns;
142 return internal_ns_maybe_create(interp, base_ns, key, flags);
147 =item C<static PMC * internal_ns_keyed_key(PARROT_INTERP, PMC *ns, PMC *key, int
148 flags)>
150 Internal function to do keyed namespace lookup relative to a given namespace
151 PMC. The namespace to find is located by C<key> relative to C<ns>. C<flags>
152 determines what happens when an existing namespace is not found. 0 means
153 PMCNULL is returned, INTERN_NS_CREAT means a new namespace is created.
155 =cut
159 PARROT_WARN_UNUSED_RESULT
160 PARROT_CAN_RETURN_NULL
161 static PMC *
162 internal_ns_keyed_key(PARROT_INTERP, ARGIN(PMC *ns), ARGIN(PMC *key), int flags)
164 ASSERT_ARGS(internal_ns_keyed_key)
165 while (key) {
166 STRING * const part = VTABLE_get_string(interp, key);
167 PMC *sub_ns = VTABLE_get_pmc_keyed_str(interp, ns, part);
169 if (PMC_IS_NULL(sub_ns) || !VTABLE_isa(interp, sub_ns, CONST_STRING(interp, "NameSpace"))) {
170 sub_ns = internal_ns_maybe_create(interp, ns, part, flags);
172 if (PMC_IS_NULL(sub_ns))
173 return PMCNULL;
176 ns = sub_ns;
177 key = VTABLE_shift_pmc(interp, key);
180 return ns;
185 =item C<static PMC * internal_ns_keyed(PARROT_INTERP, PMC *base_ns, PMC
186 *pmc_key, int flags)>
188 Search for a namespace PMC starting from a base namespace C<base_ns> and
189 following C<pmc_key> to the nested namespace. C<pmc_key> can be a String,
190 a Key, or an array of strings (such as an ResizableStringArray, or a
191 ResizablePMCArray that contains Strings). Flags determines what we do if the
192 requested namespace is not found: 0 means we return PMCNULL, INTERN_NS_CREAT
193 means we create the new namespace and return it.
195 =cut
199 PARROT_WARN_UNUSED_RESULT
200 PARROT_CAN_RETURN_NULL
201 static PMC *
202 internal_ns_keyed(PARROT_INTERP, ARGIN(PMC *base_ns), ARGIN(PMC *pmc_key), int flags)
204 ASSERT_ARGS(internal_ns_keyed)
206 if (PMC_IS_TYPE(pmc_key, Key))
207 return internal_ns_keyed_key(interp, base_ns, pmc_key, flags);
208 else if (VTABLE_isa(interp, pmc_key, CONST_STRING(interp, "String"))) {
209 STRING * const str_key = VTABLE_get_string(interp, pmc_key);
210 return internal_ns_keyed_str(interp, base_ns, str_key, flags);
212 else {
213 /* array of strings */
214 STRING * const isans = CONST_STRING(interp, "NameSpace");
215 const INTVAL n = VTABLE_elements(interp, pmc_key);
216 INTVAL i;
217 PMC *ns = base_ns;
219 for (i = 0; i < n; ++i) {
220 STRING * const part = VTABLE_get_string_keyed_int(interp, pmc_key, i);
221 PMC *sub_ns = VTABLE_get_pmc_keyed_str(interp, ns, part);
223 if (PMC_IS_NULL(sub_ns) || !VTABLE_isa(interp, sub_ns, isans)) {
224 sub_ns = internal_ns_maybe_create(interp, ns, part, flags);
225 if (PMC_IS_NULL(sub_ns))
226 return PMCNULL;
228 ns = sub_ns;
230 return ns;
236 =item C<static PMC * internal_ns_maybe_create(PARROT_INTERP, PMC *ns, STRING
237 *key, int flags)>
239 Given a namespace PMC C<ns>, a STRING C<key> containing a name, and flags from
240 C<internal_ns_keyed> or C<internal_ns_keyed_str>, creates and returns a new
241 namespace with the given name as a child of the given namespace. This is an
242 internal function only.
244 =cut
248 PARROT_WARN_UNUSED_RESULT
249 PARROT_CAN_RETURN_NULL
250 static PMC *
251 internal_ns_maybe_create(PARROT_INTERP, ARGIN(PMC *ns), ARGIN(STRING *key), int flags)
253 ASSERT_ARGS(internal_ns_maybe_create)
255 /* TT #1220 - stop depending on typed namespace */
256 if (!(flags & INTERN_NS_CREAT))
257 return PMCNULL;
258 else {
259 const INTVAL type_id = Parrot_get_ctx_HLL_type(interp, enum_class_NameSpace);
260 /* TT #1221 - match HLL of enclosing namespace? */
261 PMC * const sub_ns = Parrot_pmc_new(interp, type_id);
263 if (PMC_IS_NULL(sub_ns))
264 return PMCNULL;
266 VTABLE_set_pmc_keyed_str(interp, ns, key, sub_ns);
267 return sub_ns;
273 =item C<static PMC * get_namespace_pmc(PARROT_INTERP, PMC *sub_pmc)>
275 Return the namespace PMC associated with the PMC C<sub>. If there is no
276 NameSpace associated with the sub, return it's HLL NameSpace PMC instead.
278 =cut
282 PARROT_WARN_UNUSED_RESULT
283 PARROT_CAN_RETURN_NULL
284 static PMC *
285 get_namespace_pmc(PARROT_INTERP, ARGIN(PMC *sub_pmc))
287 ASSERT_ARGS(get_namespace_pmc)
288 Parrot_Sub_attributes *sub;
289 PMC *nsname, *nsroot;
291 PMC_get_sub(interp, sub_pmc, sub);
292 nsname = sub->namespace_name;
293 nsroot = Parrot_get_HLL_namespace(interp, sub->HLL_id);
295 /* If we have a NULL, return the HLL namespace */
296 if (PMC_IS_NULL(nsname))
297 return nsroot;
298 /* If we have a String, do a string lookup */
299 else if (nsname->vtable->base_type == enum_class_String)
300 return Parrot_ns_make_namespace_keyed_str(interp, nsroot,
301 VTABLE_get_string(interp, nsname));
302 /* Otherwise, do a PMC lookup */
303 else
304 return Parrot_ns_make_namespace_keyed(interp, nsroot, nsname);
309 =item C<static void store_sub_in_multi(PARROT_INTERP, PMC *sub_pmc, PMC *ns)>
311 Adds the sub C<sub> into a multisub of the same name in the namespace C<ns>.
312 If no multisub by that name currently exists, we create one.
314 =cut
318 static void
319 store_sub_in_multi(PARROT_INTERP, ARGIN(PMC *sub_pmc), ARGIN(PMC *ns))
321 ASSERT_ARGS(store_sub_in_multi)
322 Parrot_Sub_attributes *sub;
323 STRING *ns_entry_name;
324 PMC *multisub;
326 PMC_get_sub(interp, sub_pmc, sub);
327 ns_entry_name = sub->ns_entry_name;
328 multisub = VTABLE_get_pmc_keyed_str(interp, ns, ns_entry_name);
330 /* is there an existing MultiSub PMC? or do we need to create one? */
331 if (PMC_IS_NULL(multisub)) {
332 multisub = Parrot_pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_MultiSub));
333 /* we have to push the sub onto the MultiSub before we try to store
334 it because storing requires information from the sub */
335 VTABLE_push_pmc(interp, multisub, sub_pmc);
336 VTABLE_set_pmc_keyed_str(interp, ns, ns_entry_name, multisub);
338 else
339 VTABLE_push_pmc(interp, multisub, sub_pmc);
344 =back
346 =head1 NameSpace API Functions
348 =over 4
350 =item C<PMC * Parrot_ns_get_namespace_keyed(PARROT_INTERP, PMC *base_ns, PMC
351 *pmc_key)>
353 Find the namespace relative to the namespace C<base_ns> with the key
354 C<pmc_key>, which may be a String, a Key, or an array of strings. Return
355 the namespace, or NULL if not found.
357 =cut
361 PARROT_EXPORT
362 PARROT_WARN_UNUSED_RESULT
363 PARROT_CAN_RETURN_NULL
364 PMC *
365 Parrot_ns_get_namespace_keyed(PARROT_INTERP, ARGIN(PMC *base_ns), ARGIN(PMC *pmc_key))
367 ASSERT_ARGS(Parrot_ns_get_namespace_keyed)
368 return internal_ns_keyed(interp, base_ns, pmc_key, 0);
373 =item C<PMC * Parrot_ns_get_namespace_keyed_str(PARROT_INTERP, PMC *base_ns,
374 STRING *str_key)>
376 Find the namespace relative to the namespace C<base_ns> with the string key
377 C<str_key>. Return the namespace, or NULL if not found.
379 =cut
383 PARROT_EXPORT
384 PARROT_WARN_UNUSED_RESULT
385 PARROT_CAN_RETURN_NULL
386 PMC *
387 Parrot_ns_get_namespace_keyed_str(PARROT_INTERP, ARGIN(PMC *base_ns),
388 ARGIN_NULLOK(STRING *str_key))
390 ASSERT_ARGS(Parrot_ns_get_namespace_keyed_str)
391 return internal_ns_keyed_str(interp, base_ns, str_key, 0);
396 =item C<PMC * Parrot_ns_make_namespace_keyed(PARROT_INTERP, PMC *base_ns, PMC
397 *pmc_key)>
399 Find, or create if necessary, the namespace relative to the namespace
400 C<base_ns> with the key C<pmc_key>, which may be a String, a Key, or an
401 array of strings. Return the namespace. Errors will result in exceptions.
403 =cut
407 PARROT_EXPORT
408 PARROT_WARN_UNUSED_RESULT
409 PARROT_CAN_RETURN_NULL
410 PMC *
411 Parrot_ns_make_namespace_keyed(PARROT_INTERP, ARGIN(PMC *base_ns),
412 ARGIN(PMC *pmc_key))
414 ASSERT_ARGS(Parrot_ns_make_namespace_keyed)
415 return internal_ns_keyed(interp, base_ns, pmc_key, INTERN_NS_CREAT);
420 =item C<PMC * Parrot_ns_make_namespace_keyed_str(PARROT_INTERP, PMC *base_ns,
421 STRING *str_key)>
423 Find, or create if necessary, the namespace relative to the namespace
424 C<base_ns> with the string key C<str_key>. Return the namespace. Errors
425 will result in exceptions.
427 =cut
431 PARROT_EXPORT
432 PARROT_WARN_UNUSED_RESULT
433 PARROT_CAN_RETURN_NULL
434 PMC *
435 Parrot_ns_make_namespace_keyed_str(PARROT_INTERP, ARGIN(PMC *base_ns),
436 ARGIN(STRING *str_key))
438 ASSERT_ARGS(Parrot_ns_make_namespace_keyed_str)
439 return internal_ns_keyed_str(interp, base_ns, str_key, INTERN_NS_CREAT);
444 =item C<PMC * Parrot_ns_make_namespace_autobase(PARROT_INTERP, PMC *key)>
446 Find, or create if necessary, a namespace with the key C<key>, which may be a
447 String, a Key, or an array of strings. If it is a String, then the lookup is
448 relative to the current namespace. Otherwise, it is relative to the current HLL
449 root namespace. Return the namespace. Errors will result in exceptions.
451 =cut
455 PARROT_EXPORT
456 PARROT_WARN_UNUSED_RESULT
457 PARROT_CAN_RETURN_NULL
458 PMC *
459 Parrot_ns_make_namespace_autobase(PARROT_INTERP, ARGIN_NULLOK(PMC *key))
461 ASSERT_ARGS(Parrot_ns_make_namespace_autobase)
462 PMC *base_ns;
463 if (VTABLE_isa(interp, key, CONST_STRING(interp, "String")))
464 base_ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
465 else
466 base_ns = VTABLE_get_pmc_keyed_int(interp, interp->HLL_namespace,
467 Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp)));
468 return Parrot_ns_make_namespace_keyed(interp, base_ns, key);
473 =item C<PMC * Parrot_ns_get_name(PARROT_INTERP, PMC *_namespace)>
475 Get the name of the namespace, as a ResizableStringArray. For instance, the
476 namespace Foo:Bar:Baz would return an RSA with three elements.
478 =cut
482 PARROT_EXPORT
483 PARROT_WARN_UNUSED_RESULT
484 PARROT_CAN_RETURN_NULL
485 PMC *
486 Parrot_ns_get_name(PARROT_INTERP, ARGIN(PMC *_namespace))
488 ASSERT_ARGS(Parrot_ns_get_name)
489 PMC *names;
490 STRING * const get_name = CONST_STRING(interp, "get_name");
491 Parrot_pcc_invoke_method_from_c_args(interp, _namespace, get_name, "->P", &names);
492 return names;
497 =item C<PMC * Parrot_ns_get_global(PARROT_INTERP, PMC *ns, STRING *globalname)>
499 Look up the global named C<globalname> in the namespace C<ns>. Return the
500 global, or return PMCNULL if C<ns> is null or if the global is not found.
502 Parrot_ns_get_global allows a null namespace without throwing an exception; it
503 simply returns PMCNULL in that case.
505 NOTE: At present the use of the {get, set}_global functions is mandatory due
506 to the wacky namespace typing of the default Parrot namespace.
507 Eventually it will be safe to just use the standard hash interface
508 (if desired).
510 =cut
514 PARROT_EXPORT
515 PARROT_WARN_UNUSED_RESULT
516 PARROT_CAN_RETURN_NULL
517 PMC *
518 Parrot_ns_get_global(PARROT_INTERP, ARGIN_NULLOK(PMC *ns), ARGIN_NULLOK(STRING *globalname))
520 ASSERT_ARGS(Parrot_ns_get_global)
521 if (PMC_IS_NULL(ns))
522 return PMCNULL;
524 return (PMC *)VTABLE_get_pointer_keyed_str(interp, ns, globalname);
529 =item C<void Parrot_ns_set_global(PARROT_INTERP, PMC *ns, STRING *globalname,
530 PMC *val)>
532 Set the global named C<globalname> in the namespace C<ns> to the value C<val>.
534 =cut
538 PARROT_EXPORT
539 void
540 Parrot_ns_set_global(PARROT_INTERP, ARGIN_NULLOK(PMC *ns),
541 ARGIN_NULLOK(STRING *globalname), ARGIN_NULLOK(PMC *val))
543 ASSERT_ARGS(Parrot_ns_set_global)
544 VTABLE_set_pmc_keyed_str(interp, ns, globalname, val);
550 =item C<PMC * Parrot_ns_find_namespace_global(PARROT_INTERP, PMC *ns, STRING
551 *globalname)>
553 Search the namespace PMC C<ns> for an object with name C<globalname>.
554 Return the object, or NULL if not found.
556 TT #1222 - For now this function prefers non-namespaces, it will eventually
557 entirely use the untyped interface.
559 =cut
563 PARROT_EXPORT
564 PARROT_WARN_UNUSED_RESULT
565 PARROT_CAN_RETURN_NULL
566 PMC *
567 Parrot_ns_find_namespace_global(PARROT_INTERP,
568 ARGIN_NULLOK(PMC *ns), ARGIN_NULLOK(STRING *globalname))
570 ASSERT_ARGS(Parrot_ns_find_namespace_global)
571 PMC *res;
573 if (PMC_IS_NULL(ns))
574 res = PMCNULL;
575 else {
577 * TT #1219 - we should be able to use 'get_pmc_keyed' here,
578 * but we can't because Parrot's default namespaces are not
579 * fully typed and there's a pseudo-typed interface that
580 * distinguishes 'get_pmc_keyed' from 'get_pointer_keyed';
581 * the former is for NS and the latter is for non-NS.
583 res = (PMC *)VTABLE_get_pointer_keyed_str(interp, ns, globalname);
586 return PMC_IS_NULL(res) ? NULL : res;
591 =item C<PMC * Parrot_ns_find_current_namespace_global(PARROT_INTERP, STRING
592 *globalname)>
594 Finds and returns the data time named C<globalname> in the current namespace.
596 =cut
600 PARROT_EXPORT
601 PARROT_WARN_UNUSED_RESULT
602 PARROT_CAN_RETURN_NULL
603 PMC *
604 Parrot_ns_find_current_namespace_global(PARROT_INTERP, ARGIN_NULLOK(STRING *globalname))
606 ASSERT_ARGS(Parrot_ns_find_current_namespace_global)
607 PMC * const ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
608 return Parrot_ns_find_namespace_global(interp, ns, globalname);
613 =item C<void Parrot_ns_store_global(PARROT_INTERP, PMC *ns, STRING *globalname,
614 PMC *val)>
616 Store the PMC C<val> into the namespace PMC C<ns> with name C<globalname>. If
617 the namespace is null, do nothing.
619 =cut
623 PARROT_EXPORT
624 void
625 Parrot_ns_store_global(PARROT_INTERP, ARGIN_NULLOK(PMC *ns),
626 ARGIN_NULLOK(STRING *globalname), ARGIN_NULLOK(PMC *val))
628 ASSERT_ARGS(Parrot_ns_store_global)
630 if (PMC_IS_NULL(ns))
631 return;
633 VTABLE_set_pmc_keyed_str(interp, ns, globalname, val);
638 =item C<PMC * Parrot_ns_find_global_from_op(PARROT_INTERP, PMC *ns, STRING
639 *globalname, void *next)>
641 If the global exists in the given namespace PMC, return it. If not, return
642 PMCNULL. Throw an exception if a NULL name is passed.
644 =cut
648 PARROT_EXPORT
649 PARROT_WARN_UNUSED_RESULT
650 PARROT_CANNOT_RETURN_NULL
651 PMC *
652 Parrot_ns_find_global_from_op(PARROT_INTERP, ARGIN(PMC *ns),
653 ARGIN_NULLOK(STRING *globalname), ARGIN_NULLOK(void *next))
655 ASSERT_ARGS(Parrot_ns_find_global_from_op)
656 if (STRING_IS_NULL(globalname))
657 Parrot_ex_throw_from_c_args(interp, next, EXCEPTION_GLOBAL_NOT_FOUND,
658 "Tried to get null global");
659 else {
660 PMC * const res = Parrot_ns_find_namespace_global(interp, ns, globalname);
661 if (!res)
662 return PMCNULL;
663 return res;
670 =item C<PMC * Parrot_ns_find_named_item(PARROT_INTERP, STRING *name, void
671 *next)>
673 TT #1223 - THIS IS BROKEN - it doesn't walk up the scopes yet
675 Find the given C<name> in lexicals, then the current namespace, then the HLL
676 root namespace, and finally Parrot builtins. If the name isn't found
677 anywhere, return PMCNULL.
679 =cut
683 PARROT_EXPORT
684 PARROT_WARN_UNUSED_RESULT
685 PARROT_CAN_RETURN_NULL
686 PMC *
687 Parrot_ns_find_named_item(PARROT_INTERP, ARGIN(STRING *name), SHIM(void *next))
689 ASSERT_ARGS(Parrot_ns_find_named_item)
690 PMC * const ctx = CURRENT_CONTEXT(interp);
691 PMC * const lex_pad = Parrot_find_pad(interp, name, ctx);
692 PMC * g = PMCNULL;
694 if (!PMC_IS_NULL(lex_pad)) {
695 g = VTABLE_get_pmc_keyed_str(interp, lex_pad, name);
697 /* TT #1223 - walk up the scopes! duh!! */
698 if (!PMC_IS_NULL(g))
699 return g;
702 g = Parrot_ns_find_current_namespace_global(interp, name);
703 if (!PMC_IS_NULL(g))
704 return g;
706 g = Parrot_ns_find_namespace_global(interp, Parrot_get_ctx_HLL_namespace(interp), name);
707 if (!PMC_IS_NULL(g))
708 return g;
709 return PMCNULL;
714 =item C<void Parrot_ns_store_sub(PARROT_INTERP, PMC *sub_pmc)>
716 Adds the PMC C<sub> into the current namespace. Adds the sub to a multi of the
717 same name if it's defined as a multi.
719 =cut
723 PARROT_EXPORT
724 void
725 Parrot_ns_store_sub(PARROT_INTERP, ARGIN(PMC *sub_pmc))
727 ASSERT_ARGS(Parrot_ns_store_sub)
728 const INTVAL cur_id = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
730 PMC *ns;
731 Parrot_Sub_attributes *sub;
733 /* store relative to HLL namespace */
734 PMC_get_sub(interp, sub_pmc, sub);
735 Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), sub->HLL_id);
737 ns = get_namespace_pmc(interp, sub_pmc);
739 /* attach a namespace to the sub for lookups */
740 sub->namespace_stash = ns;
742 /* store a :multi sub */
743 if (!PMC_IS_NULL(sub->multi_signature))
744 store_sub_in_multi(interp, sub_pmc, ns);
746 /* store other subs (as long as they're not :anon) */
747 else if (!(PObj_get_FLAGS(sub_pmc) & SUB_FLAG_PF_ANON)
748 || sub->vtable_index != -1) {
749 STRING * const ns_entry_name = sub->ns_entry_name;
750 PMC * const nsname = sub->namespace_name;
752 Parrot_ns_store_global(interp, ns, ns_entry_name, sub_pmc);
754 /* TT #1224:
755 TEMPORARY HACK - cache invalidation should be a namespace function
757 if (!PMC_IS_NULL(nsname)) {
758 STRING * const nsname_s = VTABLE_get_string(interp, nsname);
759 Parrot_invalidate_method_cache(interp, nsname_s);
763 /* restore HLL_id */
764 Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_id);
769 =back
771 =head1 SEE ALSO
773 F<include/parrot/namespace.h>
775 =cut
781 * Local variables:
782 * c-file-style: "parrot"
783 * End:
784 * vim: expandtab shiftwidth=4: