Skip to content


Add --target=pbc and use for build #102

wants to merge 4 commits into from

2 participants


Adds a new option --target=pbc to the frontend. This is the first tiny step on the way to direct bytecode generation as envisioned by whiteknight.

The corresponding NQP changes can be found in the branch target-pbc of the main NQP repository, and the old Parrot-side infrastructure has been removed in whiteknight's branch eval_pmc.

Should not be merged into nom: please create a new branch instead.

Once someone pulls the trigger on parrot/parrot#934 , the code can be tested via perl --gen-parrot=eval_pmc --gen-nqp=target-pbc.


Are you certain that $precomp.main_sub() is always the same as the previous $precomp[0] ?

I'm not 100% certain, no. In my defense:

  • that's how whiteknight did it, and he hopefully knew what he was doing (instead of just cargo-coding like myself).
  • the build succeeds and all tests pass

Spectesting on Cygwin seems to result in additional failures with message

Dubious, test returned 1 (wstat 256, 0x100)

which is why I'm asking for a branch to be created so others can check I did not mess up.

@pmichaud Note that we're now always calling the main sub instead of invoking an eval PMC. As the eval PMC implicitly called the sub at index 0 as well, the change is at least consistent.

The main_sub member of the bytecode structure apparently gets initialized to -1, so somewhere some code gets executed that fixes it to return the first sub in absence of an explicit annotation.

I'll look into it some more tomorrow.

@pmichaud found it - see parrot-dev


@pmichaud I believe I've taken care of all of your complaints, so please take another look if you have a free minute.

The PackfileView PMC now comes with 2 additional methods first_sub_in_const_table() and single_sub_by_tag(). The former is the drop-in replacement for the old logic, is used right now but imo should go away long-term. The latter can only be used after tag generation has been added to the code generator. Right now, it's implemented in terms of subs_by_tag(), which should be fixed once it becomes more heavily used.

I don't think it's an immediate concern: I'd wait with switching to the new tag-based system until someone takes a shot at direct bytecode generation.


Now obsolete - see #106

@gerdr gerdr closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 17, 2013
  1. @gerdr

    migrate to PackfileView

    gerdr committed
  2. @gerdr
  3. @gerdr

    modify build to use --target=pbc

    gerdr committed
Commits on Feb 19, 2013
  1. @gerdr
This page is out of date. Refresh to see the latest.
6 .gitignore
@@ -8,9 +8,9 @@ Makefile
30 src/Perl6/
@@ -1203,33 +1203,35 @@ class Perl6::World is HLL::World {
- my $p6comp := pir::compreg__Ps('perl6');
- my $post := $$compunit);
- my $pir := $p6comp.pir($post);
- my $precomp := $p6comp.evalpmc($pir);
- $precomp[0].get_lexinfo.set_static_lexpad($slp);
- $precomp();
+ my $p6comp := pir::compreg__Ps('perl6');
+ my $post := $$compunit);
+ my $pir := $p6comp.pir($post);
+ my $pbc := $p6comp.pbc($pir);
+ my $mainline := $p6comp.init($pbc);
+ $mainline.get_lexinfo.set_static_lexpad($slp);
+ $mainline();
# Fix up Code object associations (including nested blocks).
# We un-stub any code objects for already-compiled inner blocks
# to avoid wasting re-compiling them, and also to help make
# parametric role outer chain work out. Also set up their static
# lexpads, if they have any.
- my int $num_subs := nqp::elems($precomp);
+ my @all_subs := $pbc.all_subs();
+ my int $num_subs := nqp::elems(@all_subs);
my int $i := 0;
while $i < $num_subs {
- my $subid := $precomp[$i].get_subid();
+ my $subid := @all_subs[$i].get_subid();
if nqp::existskey(%!sub_id_to_code_object, $subid) {
- pir::perl6_associate_sub_code_object__vPP($precomp[$i],
+ pir::perl6_associate_sub_code_object__vPP(@all_subs[$i],
- nqp::bindattr(%!sub_id_to_code_object{$subid}, $code_type, '$!do', $precomp[$i]);
+ nqp::bindattr(%!sub_id_to_code_object{$subid}, $code_type, '$!do', @all_subs[$i]);
if nqp::existskey(%!sub_id_to_static_lexpad, $subid) {
- $precomp[$i].get_lexinfo.set_static_lexpad(%!sub_id_to_static_lexpad{$subid});
+ @all_subs[$i].get_lexinfo.set_static_lexpad(%!sub_id_to_static_lexpad{$subid});
if nqp::existskey(%!sub_id_to_sc_idx, $subid) {
- pir::setprop__vPsP($precomp[$i], 'STATIC_CODE_REF', $precomp[$i]);
- self.update_root_code_ref(%!sub_id_to_sc_idx{$subid}, $precomp[$i]);
+ pir::setprop__vPsP(@all_subs[$i], 'STATIC_CODE_REF', @all_subs[$i]);
+ self.update_root_code_ref(%!sub_id_to_sc_idx{$subid}, @all_subs[$i]);
$i := $i + 1;
@@ -1239,7 +1241,7 @@ class Perl6::World is HLL::World {
# Return the Parrot Sub that maps to the thing we were originally
# asked to compile.
- $precomp[1]
+ @all_subs[1]
# Adds a constant value to the constants table. Returns PAST to do
6 src/core/
@@ -151,9 +151,9 @@ multi sub eval(Str $code, :$lang = 'perl6', PseudoStash :$context) {
my $compiler := pir::compreg__PS($lang);$lang).throw
if nqp::isnull($compiler);
- my $pbc := $compiler.compile($code, :outer_ctx($eval_ctx), :global(GLOBAL));
- nqp::atpos($pbc, 0).set_outer_ctx($eval_ctx);
- $pbc();
+ my $mainline := $compiler.compile($code, :outer_ctx($eval_ctx), :global(GLOBAL));
+ $mainline.set_outer_ctx($eval_ctx);
+ $mainline();
82 tools/build/
@@ -55,35 +55,21 @@ MANDIR = @mandir@
DOCDIR = @prefix@/share/doc
# files we create
-PERL6_PIR = src/gen/perl6.pir
PERL6_PBC = perl6.pbc
PERL6_EXE = perl6$(EXE)
-PERL6_ML = src/gen/perl6-moduleloader.pir
PERL6_ML_PBC = blib/Perl6/ModuleLoader.pbc
-PERL6_CF = src/gen/perl6-constantfolder.pir
PERL6_CF_PBC = blib/Perl6/ConstantFolder.pbc
-PERL6_W = src/gen/perl6-symboltable.pir
PERL6_W_PBC = blib/Perl6/World.pbc
-PERL6_G = src/gen/perl6-grammar.pir
PERL6_G_PBC = blib/Perl6/Grammar.pbc
-PERL6_OPS = src/gen/perl6-ops.pir
PERL6_OPS_PBC = blib/Perl6/Ops.pbc
-PERL6_A = src/gen/perl6-actions.pir
PERL6_A_PBC = blib/Perl6/Actions.pbc
-PERL6_O = src/gen/perl6-optimizer.pir
PERL6_O_PBC = blib/Perl6/Optimizer.pbc
-PERL6_P = src/gen/perl6-pod.pir
PERL6_P_PBC = blib/Perl6/Pod.pbc
-PERL6_C = src/gen/perl6-compiler.pir
PERL6_C_PBC = blib/Perl6/Compiler.pbc
-PERL6_M = src/gen/perl6-metamodel.pir
PERL6_M_PBC = blib/Perl6/Metamodel.pbc
-PERL6_B = src/gen/perl6-bootstrap.pir
PERL6_B_PBC = blib/Perl6/BOOTSTRAP.pbc
-SETTING_PIR = src/gen/CORE.setting.pir
SETTING_PBC = CORE.setting.pbc
-R_SETTING_PIR = src/gen/RESTRICTED.setting.pir
GROUP = perl6_group
OPS = perl6_ops
@@ -253,9 +239,9 @@ CLEANUPS = \
perl6.c \
perl6$(O) \
perl6_group.* \
- lib/Test.pir \
- lib/lib.pir \
- lib/Pod/To/Text.pir \
+ lib/Test.pbc \
+ lib/lib.pbc \
+ lib/Pod/To/Text.pbc \
rakudo_test_run.tar.gz \
src/gen/CORE.setting \
@@ -285,7 +271,7 @@ HARNESS_WITH_FUDGE = $(PERL) t/harness --fudge --keep-exit-code --icu=$(HAS_ICU)
STAGESTATS = @stagestats@
# the default target, TODO: make libraries in 'lib' a variable.
-all: check-versions $(PERL6_EXE) $(SETTING_PBC) $(R_SETTING_PBC) lib/lib.pir lib/Test.pir lib/Pod/To/Text.pir
+all: check-versions $(PERL6_EXE) $(SETTING_PBC) $(R_SETTING_PBC) lib/lib.pbc lib/Test.pbc lib/Pod/To/Text.pbc
# the install target
install: all
@@ -306,12 +292,12 @@ install: all
$(CP) lib/ $(DESTDIR)$(PERL6_LANG_DIR)/lib
- $(CP) lib/Test.pir $(DESTDIR)$(PERL6_LANG_DIR)/lib
+ $(CP) lib/Test.pbc $(DESTDIR)$(PERL6_LANG_DIR)/lib
$(CP) lib/lib.pm6 $(DESTDIR)$(PERL6_LANG_DIR)/lib
- $(CP) lib/lib.pir $(DESTDIR)$(PERL6_LANG_DIR)/lib
+ $(CP) lib/lib.pbc $(DESTDIR)$(PERL6_LANG_DIR)/lib
$(CP) lib/Pod/To/ $(DESTDIR)$(PERL6_LANG_DIR)/lib/Pod/To
- $(CP) lib/Pod/To/Text.pir $(DESTDIR)$(PERL6_LANG_DIR)/lib/Pod/To
+ $(CP) lib/Pod/To/Text.pbc $(DESTDIR)$(PERL6_LANG_DIR)/lib/Pod/To
@@ -336,86 +322,72 @@ $(PERL6_EXE): $(PERL6_PBC) $(PARROT_DLL_COPY)
# the complete compiler
$(PERL6_PBC): $(PERL6_G_PBC) $(PERL6_A_PBC) $(PERL6_C_PBC) $(PERL6_P_PBC) src/main.nqp
$(PERL) tools/build/ >src/gen/main-version.nqp
- $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pir --output=src/gen/perl6.pir \
+ $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pbc --output=$(PERL6_PBC) \
--combine src/main.nqp src/gen/main-version.nqp
- $(PARROT) $(PARROT_ARGS) -o $(PERL6_PBC) src/gen/perl6.pir
- $(NQP_EXE) --target=pir --output=$(PERL6_ML) --encoding=utf8 \
+ $(NQP_EXE) --target=pbc --output=$(PERL6_ML_PBC) --encoding=utf8 \
- $(NQP_EXE) --target=pir --output=$(PERL6_CF) --encoding=utf8 \
+ $(NQP_EXE) --target=pbc --output=$(PERL6_CF_PBC) --encoding=utf8 \
$(PERL6_W_PBC): $(NQP_EXE) $(PERL6_ML_PBC) src/Perl6/
- $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pir --output=$(PERL6_W) --encoding=utf8 \
+ $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pbc --output=$(PERL6_W_PBC) --encoding=utf8 \
$(PERL6_G_PBC): $(NQP_EXE) $(PERL6_W_PBC) $(PERL6_A_PBC) src/Perl6/ $(PERL6_P_PBC)
- $(NQP_EXE) --target=pir --output=$(PERL6_G) --encoding=utf8 \
+ $(NQP_EXE) --target=pbc --output=$(PERL6_G_PBC) --encoding=utf8 \
- $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pir --output=$(PERL6_OPS) --encoding=utf8 \
+ $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pbc --output=$(PERL6_OPS_PBC) --encoding=utf8 \
- $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pir --output=$(PERL6_A) --encoding=utf8 \
+ $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pbc --output=$(PERL6_A_PBC) --encoding=utf8 \
- $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pir --output=$(PERL6_O) --encoding=utf8 \
+ $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pbc --output=$(PERL6_O_PBC) --encoding=utf8 \
- $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pir --output=$(PERL6_P) --encoding=utf8 \
+ $(NQP_EXE) --vmlibs=perl6_group,perl6_ops --target=pbc --output=$(PERL6_P_PBC) --encoding=utf8 \
$(PERL6_C_PBC): $(NQP_EXE) $(DYNEXT_DYNPMC) $(DYNEXT_DYNOPS) $(PERL6_O_PBC) src/Perl6/Compiler.nqp
- $(NQP_EXE) --target=pir --output=$(PERL6_C) --encoding=utf8 \
+ $(NQP_EXE) --target=pbc --output=$(PERL6_C_PBC) --encoding=utf8 \
- $(NQP_EXE) --target=pir --output=$(PERL6_M) --encoding=utf8 \
+ $(NQP_EXE) --target=pbc --output=$(PERL6_M_PBC) --encoding=utf8 \
--vmlibs=perl6_ops src/gen/
- $(NQP_EXE) --target=pir --output=$(PERL6_B) --encoding=utf8 \
+ $(NQP_EXE) --target=pbc --output=$(PERL6_B_PBC) --encoding=utf8 \
--vmlibs=perl6_ops src/gen/
$(PERL) $(GEN_CAT) $(CORE_SOURCES) > src/gen/CORE.setting
@echo "The following step can take a long time, please be patient."
- ./$(PERL6_EXE) --setting=NULL --optimize=3 --target=pir --stagestats --output=$(SETTING_PIR) src/gen/CORE.setting
+ ./$(PERL6_EXE) --setting=NULL --optimize=3 --target=pbc --stagestats --output=$(SETTING_PBC) src/gen/CORE.setting
- ./$(PERL6_EXE) --target=pir $(STAGESTATS) --output=$(R_SETTING_PIR) $(R_SETTING_SRC)
+ ./$(PERL6_EXE) --target=pbc $(STAGESTATS) --output=$(R_SETTING_PBC) $(R_SETTING_SRC)
## testing targets
-lib/Test.pir: lib/ $(PERL6_EXE) $(SETTING_PBC)
- ./$(PERL6_EXE) --target=pir --output=lib/Test.pir lib/
+lib/Test.pbc: lib/ $(PERL6_EXE) $(SETTING_PBC)
+ ./$(PERL6_EXE) --target=pbc --output=lib/Test.pbc lib/
-lib/lib.pir: lib/lib.pm6 $(PERL6_EXE) $(SETTING_PBC)
- ./$(PERL6_EXE) --target=pir --output=lib/lib.pir lib/lib.pm6
+lib/lib.pbc: lib/lib.pm6 $(PERL6_EXE) $(SETTING_PBC)
+ ./$(PERL6_EXE) --target=pbc --output=lib/lib.pbc lib/lib.pm6
-lib/Pod/To/Text.pir: lib/Pod/To/ $(PERL6_EXE) $(SETTING_PBC)
- ./$(PERL6_EXE) --target=pir --output=lib/Pod/To/Text.pir lib/Pod/To/
+lib/Pod/To/Text.pbc: lib/Pod/To/ $(PERL6_EXE) $(SETTING_PBC)
+ ./$(PERL6_EXE) --target=pbc --output=lib/Pod/To/Text.pbc lib/Pod/To/
test : coretest
Something went wrong with that request. Please try again.