Skip to content

Commit 3008506

Browse files
committed
First cut of package auto-viv using the new package scheme. Enabled just for variable accesses in lexical packages for now.
1 parent 46e3495 commit 3008506

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

src/NQP/Actions.pm

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,12 +1373,11 @@ class NQP::Actions is HLL::Actions {
13731373
elsif is_lexical(@name[0]) {
13741374
my $path := PAST::Var.new( :name(@name.shift()), :scope('lexical') );
13751375
for @name {
1376-
$path := PAST::Var.new(
1377-
:scope('keyed'),
1378-
PAST::Op.new( :pirop('get_who PP'), $path ),
1379-
~$_);
1376+
$path := PAST::Op.new(
1377+
:pirop('nqp_get_package_through_who PPs'),
1378+
$path, ~$_);
13801379
}
1381-
$lookup.unshift($path);
1380+
$lookup.unshift(PAST::Op.new(:pirop('get_who PP'), $path));
13821381
}
13831382
else {
13841383
# XXX Would really want this and then chase the symbol

src/ops/nqp.ops

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,3 +800,45 @@ inline op nqp_get_sc_for_object(out PMC, in PMC) :base_core {
800800
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
801801
"Can only use nqp_get_sc_for_object with a SixModelObject");
802802
}
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

Comments
 (0)