@@ -800,3 +800,45 @@ inline op nqp_get_sc_for_object(out PMC, in PMC) :base_core {
800
800
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
801
801
"Can only use nqp_get_sc_for_object with a SixModelObject");
802
802
}
803
+
804
+
805
+ /*
806
+
807
+ =item nqp_get_package_through_who
808
+
809
+ Takes a type object and uses its associated symbol table (in .WHO)
810
+ to look for a package within it. It will auto-vivify the package if
811
+ non exists.
812
+
813
+ =cut
814
+
815
+ */
816
+ inline op nqp_get_package_through_who(out PMC, in PMC, in STR) :base_core {
817
+ if ($2->vtable->base_type == smo_id) {
818
+ PMC *who = STABLE($2)->WHO;
819
+ PMC *pkg = VTABLE_get_pmc_keyed_str(interp, who, $3);
820
+ if (PMC_IS_NULL(pkg)) {
821
+ /* Create the package object. This is just like a call:
822
+ * pkg = KnowHOW.new_type(:name($3))
823
+ * XXX For now just create a KnowHOW; we can switch to a lighter
824
+ * package temp type later. */
825
+ PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
826
+ PMC *meth = VTABLE_find_method(interp, KnowHOW, Parrot_str_new(interp, "new_type", 0));
827
+ PMC *cappy = Parrot_pmc_new(interp, enum_class_CallContext);
828
+ VTABLE_push_pmc(interp, cappy, KnowHOW);
829
+ VTABLE_set_string_keyed_str(interp, cappy, Parrot_str_new(interp, "name", 0), $3);
830
+ Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
831
+ cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
832
+ Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
833
+ pkg = VTABLE_get_pmc_keyed_int(interp, cappy, 0);
834
+
835
+ /* Install it in the outer package's .WHO. */
836
+ VTABLE_set_pmc_keyed_str(interp, who, $3, pkg);
837
+ }
838
+ $1 = pkg;
839
+ }
840
+ else {
841
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
842
+ "Can only use nqp_get_package_through_who with a SixModelObject");
843
+ }
844
+ }
0 commit comments