Skip to content

Commit

Permalink
Add a fallback resolver for BEGIN time run code objects.
Browse files Browse the repository at this point in the history
Ye olde implementation created a wrapper frame containing the lexical symbols
of all outer scopes. This is rather costly and blows up bytecode size. Instead,
we now use the VMs new capability to run a custom resolver when it cannot find
a lexical by itself.

This first implementation only gets us compile-time-known values, but it's a
start.
  • Loading branch information
niner authored and Stefan Seifert committed Jul 12, 2022
1 parent e818c69 commit 874becf
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions src/Raku/ast/code.rakumod
Expand Up @@ -99,7 +99,7 @@ class RakuAST::Code is RakuAST::Node {
my $code-obj := nqp::getcodeobj(nqp::curcode());
unless $precomp {
my $block := self.IMPL-QAST-BLOCK($context, :blocktype<declaration_static>);
$precomp := self.IMPL-COMPILE-DYNAMICALLY($block, $context);
$precomp := self.IMPL-COMPILE-DYNAMICALLY($resolver, $context, $block);
}
unless nqp::isnull($code-obj) {
return $code-obj(|@pos, |%named);
Expand Down Expand Up @@ -210,10 +210,9 @@ class RakuAST::Code is RakuAST::Node {
});
}

method IMPL-COMPILE-DYNAMICALLY(Mu $block, Mu $context) {
method IMPL-COMPILE-DYNAMICALLY(RakuAST::Resolver $resolver, RakuAST::IMPL::QASTContext $context, Mu $block) {
my $wrapper := QAST::Block.new(QAST::Stmts.new(), $block);
$wrapper.annotate('DYN_COMP_WRAPPER', 1);
$wrapper[0].push(QAST::Var.new(:name<$_>, :scope<lexical>, :decl<static>));

my $compunit := QAST::CompUnit.new(
:hll('Raku'),
Expand All @@ -223,6 +222,27 @@ class RakuAST::Code is RakuAST::Node {
);
my $comp := nqp::getcomp('Raku');
my $precomp := $comp.compile($compunit, :from<qast>, :compunit_ok(1));
nqp::dispatch(
'boot-syscall',
'set-compunit-resolver',
$precomp,
-> $name {
my $result := $resolver.resolve-lexical-in-outer($name);
if $result {
nqp::istype($result, RakuAST::CompileTimeValue)
?? $result.compile-time-value
!! Mu
}
else {
nqp::die("No lexical found with name $name via resolver");
}
},
-> $dyn-name {
my $dynamic-fallback := $resolver.resolve-lexical-in-outer('&DYNAMIC-FALLBACK');
my $without-star := nqp::replace($dyn-name, 1, 1, '');
$dynamic-fallback.compile-time-value()($dyn-name, $without-star)
}
);
my $mainline := $comp.backend.compunit_mainline($precomp);
$mainline();

Expand Down

0 comments on commit 874becf

Please sign in to comment.