Skip to content

Commit fd6f6b4

Browse files
committed
First round of compilation stage refactoring.
This separates the backend-independent stages from the backend-specific stages. The methods that relate to a backend's stages move into the Backend class. A new :from(...) parameter to .compile enables various places that did their own stage visiting, because they had a non-source start point, to just use .compile instead, which is a pleasant cleanup. Additionally, stage names are now properly validated.
1 parent 5df9fe9 commit fd6f6b4

File tree

4 files changed

+69
-38
lines changed

4 files changed

+69
-38
lines changed

src/HLL/Compiler.pm

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,36 @@ class HLL::Backend::Parrot {
7676
pir::interpinfo__Ii(pir::const::INTERPINFO_ACTIVE_PMCS),
7777
]);
7878
}
79+
80+
method stages() {
81+
'post pir evalpmc'
82+
}
83+
84+
method post($source, *%adverbs) {
85+
nqp::getcomp('QAST').post($source)
86+
}
87+
88+
method pirbegin() {
89+
".include 'cclass.pasm'\n"
90+
~ ".include 'except_severity.pasm'\n"
91+
~ ".include 'except_types.pasm'\n"
92+
~ ".include 'iglobals.pasm'\n"
93+
~ ".include 'interpinfo.pasm'\n"
94+
~ ".include 'iterator.pasm'\n"
95+
~ ".include 'sysinfo.pasm'\n"
96+
~ ".include 'stat.pasm'\n"
97+
~ ".include 'datatypes.pasm'\n"
98+
~ ".include 'libpaths.pasm'\n"
99+
}
100+
101+
method pir($source, *%adverbs) {
102+
self.pirbegin() ~ $source.pir()
103+
}
104+
105+
method evalpmc($source, *%adverbs) {
106+
my $compiler := nqp::getcomp('PIR');
107+
$compiler($source)
108+
}
79109
}
80110

81111
# Role specifying the default backend for this build.
@@ -103,7 +133,7 @@ class HLL::Compiler does HLL::Backend::Default {
103133
$!backend := self.default_backend();
104134

105135
# Default stages.
106-
@!stages := nqp::split(' ', 'start parse ast post pir evalpmc');
136+
@!stages := nqp::split(' ', 'start parse ast ' ~ $!backend.stages());
107137

108138
# Command options and usage.
109139
@!cmdoptions := nqp::split(' ', 'e=s help|h target=s trace|t=s encoding=s output|o=s combine version|v show-config verbose-config|V stagestats=s? ll-exception rxtrace nqpevent=s profile profile-compile');
@@ -417,20 +447,50 @@ class HLL::Compiler does HLL::Backend::Default {
417447
return self.dumper($r, $target, |%adverbs);
418448
}
419449
}
450+
451+
method exists_stage($stage) {
452+
my $found := 0;
453+
for self.stages() {
454+
if $_ eq $stage {
455+
return 1;
456+
}
457+
}
458+
return 0;
459+
}
420460

421-
method compile($source, *%adverbs) {
461+
method compile($source, :$from, *%adverbs) {
422462
my %*COMPILING<%?OPTIONS> := %adverbs;
423463

424464
my $target := nqp::lc(%adverbs<target>);
425465
my $result := $source;
426466
my $stderr := nqp::getstderr();
427467
my $stdin := nqp::getstdin();
428468
my $stagestats := %adverbs<stagestats>;
469+
unless $from eq '' || self.exists_stage($from) {
470+
nqp::die("Unknown compilation input '$_'");
471+
}
472+
unless $target eq '' || self.exists_stage($target) {
473+
nqp::die("Unknown compilation target '$_'");
474+
}
429475
for self.stages() {
476+
if $from ne '' {
477+
if $_ eq $from {
478+
$from := '';
479+
}
480+
next;
481+
}
430482
my $timestamp := nqp::time_n();
431-
$result := self."$_"($result, |%adverbs);
483+
if nqp::can(self, $_) {
484+
$result := self."$_"($result, |%adverbs);
485+
}
486+
elsif nqp::can($!backend, $_) {
487+
$result := $!backend."$_"($result, |%adverbs);
488+
}
489+
else {
490+
nqp::die("Unknown compilation stage '$_'");
491+
}
432492
my $diff := nqp::time_n() - $timestamp;
433-
if nqp::defined($stagestats) {
493+
if nqp::defined($stagestats) && $from eq '' {
434494
nqp::printfh($stderr, nqp::sprintf("Stage %-11s: %7.3f", [$_, $diff]));
435495
$!backend.force_gc() if nqp::bitand_i($stagestats, 0x4);
436496
nqp::printfh($stderr, $!backend.vmstat())
@@ -472,32 +532,6 @@ class HLL::Compiler does HLL::Backend::Default {
472532
$ast;
473533
}
474534

475-
method post($source, *%adverbs) {
476-
nqp::getcomp('QAST').post($source)
477-
}
478-
479-
method pirbegin() {
480-
".include 'cclass.pasm'\n"
481-
~ ".include 'except_severity.pasm'\n"
482-
~ ".include 'except_types.pasm'\n"
483-
~ ".include 'iglobals.pasm'\n"
484-
~ ".include 'interpinfo.pasm'\n"
485-
~ ".include 'iterator.pasm'\n"
486-
~ ".include 'sysinfo.pasm'\n"
487-
~ ".include 'stat.pasm'\n"
488-
~ ".include 'datatypes.pasm'\n"
489-
~ ".include 'libpaths.pasm'\n"
490-
}
491-
492-
method pir($source, *%adverbs) {
493-
self.pirbegin() ~ $source.pir()
494-
}
495-
496-
method evalpmc($source, *%adverbs) {
497-
my $compiler := nqp::getcomp('PIR');
498-
$compiler($source)
499-
}
500-
501535
method dumper($obj, $name, *%options) {
502536
if nqp::can($obj, 'dump') {
503537
nqp::print($obj.dump());

src/NQP/World.pm

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,9 @@ class NQP::World is HLL::World {
230230
my $stub_code := sub (*@args, *%named) {
231231
# Do the compilation.
232232
$past.unshift(self.libs());
233-
my $nqpcomp := nqp::getcomp('nqp');
234-
my $post := $nqpcomp.post(QAST::CompUnit.new( :hll('nqp'), $past ));
235-
my $pir := $nqpcomp.pir($post);
236-
my $compiled := $nqpcomp.evalpmc($pir);
233+
my $compiled := nqp::getcomp('nqp').compile(
234+
QAST::CompUnit.new( :hll('nqp'), $past ),
235+
:from<ast>);
237236

238237
# Fix up any code objects holding stubs with the real compiled thing.
239238
my $c := nqp::elems($compiled);

t/qast/pirt.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ sub is_pirt_result($producer, $expected, $desc) {
66
my $pirt := $producer();
77
my $pir := $pirt.pir();
88
#say($pir);
9-
my $pbc := QAST::Compiler.evalpmc($pir);
9+
my $pbc := nqp::getcomp('nqp').compile($pir, :from('pir'));
1010
ok($pbc() eq $expected, $desc);
1111
}
1212

t/qast/qast.t

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ plan(73);
55
# Following a test infrastructure.
66
sub compile_qast($qast) {
77
my $*QAST_BLOCK_NO_CLOSE := 1;
8-
my $pirt := QAST::Compiler.as_post($qast);
9-
my $pir := $pirt.pir();
10-
QAST::Compiler.evalpmc($pir);
8+
nqp::getcomp('nqp').compile($qast, :from('ast'));
119
}
1210
sub is_qast($qast, $value, $desc) {
1311
try {

0 commit comments

Comments
 (0)