Skip to content

Instantly share code, notes, and snippets.

@FROGGS
Created April 22, 2014 09:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FROGGS/3e5bee1ef8e122c9b6fe to your computer and use it in GitHub Desktop.
Save FROGGS/3e5bee1ef8e122c9b6fe to your computer and use it in GitHub Desktop.
diff --git a/build/gen-moar-runner.pl.in b/build/gen-moar-runner.pl.in
index 159fdca..44db932 100644
--- a/build/gen-moar-runner.pl.in
+++ b/build/gen-moar-runner.pl.in
@@ -8,16 +8,28 @@ use File::Spec;
my $install_to = shift @ARGV;
my $prefix = shift @ARGV;
-my $input_file = shift @ARGV;
+my $input_file;
my $lib_path_i = 0;
my $lib_paths = join "\n",
map { " instance->lib_path[@{[$lib_path_i++]}] = \"$_\";" } @ARGV;
-
+my $blocks = '';
+my $run_CUs = '';
+my $packed = 0;
my @source = <DATA>;
my $source = join '', @source;
+
+for (@ARGV) {
+ next unless /\.moarvm$/;
+ my ($block, $run_cu) = pack_moarvm_file($_);
+ $blocks .= $block;
+ $run_CUs .= $run_cu;
+}
+
+push @ARGV, '-e1' if $packed > 1;
+
open my $fh, ">", "$install_to.c"
or die "Could not open $install_to.c: $!";
-printf $fh $source, $input_file, $lib_paths, $lib_path_i;
+printf $fh $source, $blocks, $input_file, $lib_paths, $lib_path_i, $run_CUs;
close $fh
or die "Could not close $install_to.c: $!";
system("@cc@ @ccswitch@ @cflags@ @ccdef@MVM_TRACING=0 @ccdef@MVM_CGOTO=0 @objflags@ " .
@@ -32,12 +44,40 @@ system("@ld@ -o $install_to@exe@ @ldflags@ $install_to@obj@ -L$prefix/lib -lmoar
and die "Could not link $install_to: $!";
chmod 0755, "$install_to@exe@" if $^O ne 'MSWin32';
+sub pack_moarvm_file {
+ my $file = shift;
+ open my $if, "<", $file
+ or die "Could not open $file: $!";
+ binmode $if;
+ my @if = <$if>;
+ close $if
+ or die "Could not close $file: $!";
+ my @ords = map { ord } split '', join '', @if;
+ my $ords = join ',', @ords;
+ my @lines;
+ while (length $ords > 160) {
+ $ords =~ s/^(.{160,163},)//;
+ push @lines, $1;
+ }
+ push @lines, $ords;
+ $ords = join "\n", @lines;
+ my $block = sprintf "static MVMuint8 block%d[%d] = {\n%s };\n", $packed, scalar @ords, $ords;
+ my $run_cu = sprintf "MVM_vm_run_cu(instance, input_file, block%d, %d);\n", $packed, scalar @ords;
+ $input_file = $file unless $packed;
+ $packed++;
+ ($block, $run_cu)
+}
+
__DATA__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <moar.h>
+void MVM_vm_run_cu(MVMInstance *instance, const char *filename, MVMuint8 *block, MVMint64 size);
+
+%s
+
int main(int argc, char *argv[])
{
MVMInstance *instance = MVM_vm_create_instance();
@@ -51,9 +91,45 @@ int main(int argc, char *argv[])
%s
instance->lib_path[%d] = NULL;
- MVM_vm_run_file(instance, input_file);
+ %s
MVM_vm_destroy_instance(instance);
return EXIT_SUCCESS;
}
+
+/* This callback is passed to the interpreter code. It takes care of making
+ * the initial invocation. */
+static void toplevel_initial_invoke(MVMThreadContext *tc, void *data) {
+ /* Dummy, 0-arg callsite. */
+ static MVMCallsite no_arg_callsite = { NULL, 0, 0, 0 };
+
+ /* Create initial frame, which sets up all of the interpreter state also. */
+ MVM_frame_invoke(tc, (MVMStaticFrame *)data, &no_arg_callsite, NULL, NULL, NULL);
+}
+
+/* Loads bytecode from the specified file name and runs it. */
+void MVM_vm_run_cu(MVMInstance *instance, const char *filename, MVMuint8 *block, MVMint64 size) {
+ MVMStaticFrame *start_frame;
+
+ /* Map the compilation unit into memory and dissect it. */
+ MVMThreadContext *tc = instance->main_thread;
+ MVMCompUnit *cu = MVM_cu_from_bytes(tc, block, size);
+
+ MVMROOT(tc, cu, {
+ /* The call to MVM_string_utf8_decode() may allocate, invalidating the
+ location cu->body.filename */
+ MVMString *const str = MVM_string_utf8_decode(tc, instance->VMString, filename, strlen(filename));
+ cu->body.filename = str;
+
+ /* Run deserialization frame, if there is one. */
+ if (cu->body.deserialize_frame) {
+ MVM_interp_run(tc, &toplevel_initial_invoke, cu->body.deserialize_frame);
+ }
+ });
+
+ /* Run the frame marked main, or if there is none then fall back to the
+ * first frame. */
+ start_frame = cu->body.main_frame ? cu->body.main_frame : cu->body.frames[0];
+ MVM_interp_run(tc, &toplevel_initial_invoke, start_frame);
+}
diff --git a/tools/build/Makefile-Moar.in b/tools/build/Makefile-Moar.in
index ea99d92..2b8a80c 100644
--- a/tools/build/Makefile-Moar.in
+++ b/tools/build/Makefile-Moar.in
@@ -270,8 +270,8 @@ $(SETTING_MOAR): $(PERL6_MOAR) $(PERL6_B_MOAR) $(M_CORE_SOURCES)
$(R_SETTING_MOAR): $(PERL6_MOAR) $(SETTING_MOAR) $(R_SETTING_SRC)
$(M_RUN_PERL6) --target=mbc --output=$(R_SETTING_MOAR) $(R_SETTING_SRC)
-$(M_RUNNER): tools/build/create-moar-runner.pl $(PERL6_MOAR)
- $(PERL) tools/build/create-moar-runner.pl "$(MOAR)" perl6.moarvm perl6-m . "$(M_LIBPATH)" .
+$(M_RUNNER): $(PREFIX)/bin/gen-moar-runner.pl $(PERL6_MOAR)
+ $(PERL) $(PREFIX)/bin/gen-moar-runner.pl "perl6-m" "$(PREFIX)" "perl6.moarvm" "$(M_LIBPATH)" .
m-runner-default: $(M_RUNNER)
$(CP) $(M_RUNNER) perl6@runner_suffix@
@@ -280,8 +280,8 @@ $(PERL6_DEBUG_MOAR): src/perl6-debug.nqp $(PERL6_MOAR)
$(M_NQP) --target=mbc --output=$(PERL6_DEBUG_MOAR) \
--vmlibs=$(M_PERL6_OPS_DLL)=Rakudo_ops_init src/perl6-debug.nqp
-$(M_DEBUG_RUNNER): tools/build/create-moar-runner.pl $(PERL6_DEBUG_MOAR)
- $(PERL) tools/build/create-moar-runner.pl "$(MOAR)" perl6-debug.moarvm perl6-debug-m . "$(M_LIBPATH)" .
+$(M_DEBUG_RUNNER): $(PREFIX)/bin/gen-moar-runner.pl $(PERL6_DEBUG_MOAR)
+ $(PERL) $(PREFIX)/bin/gen-moar-runner.pl "perl6-debug-m" "$(PREFIX)" "perl6-debug.moarvm" "$(M_LIBPATH)" .
## testing targets
lib/Test.moarvm: lib/Test.pm $(PERL6_MOAR) $(SETTING_MOAR) $(M_RUNNER)
@@ -332,7 +332,7 @@ m-localtest_loud: m-all spectest_checkout t/localtest.data
m-sometests: m-all
@$(M_HARNESS_WITH_FUDGE) $(TESTFILES)
-m-install: m-all tools/build/create-moar-runner.pl
+m-install: m-all $(PREFIX)/bin/gen-moar-runner.pl
$(MKPATH) $(DESTDIR)$(PREFIX)/bin
$(MKPATH) $(DESTDIR)$(M_LIBPATH)/Perl6
$(CP) $(M_PERL6_LANG_OUTPUT) $(DESTDIR)$(M_LIBPATH)/Perl6
@@ -348,12 +348,12 @@ m-install: m-all tools/build/create-moar-runner.pl
$(CP) blib/lib.moarvm $(DESTDIR)$(PERL6_LANG_DIR)/lib
$(MKPATH) $(DESTDIR)$(PERL6_LANG_DIR)/lib/Pod/To
$(CP) blib/Pod/To/Text.moarvm $(DESTDIR)$(PERL6_LANG_DIR)/lib/Pod/To
- $(PERL) tools/build/create-moar-runner.pl "$(MOAR)" perl6.moarvm $(DESTDIR)$(PREFIX)/bin/perl6-m "$(PERL6_LANG_DIR)/runtime" "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
- $(PERL) tools/build/create-moar-runner.pl "$(MOAR)" perl6-debug.moarvm $(DESTDIR)$(PREFIX)/bin/perl6-debug-m "$(PERL6_LANG_DIR)/runtime" "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
+ $(PERL) $(PREFIX)/bin/gen-moar-runner.pl "$(DESTDIR)$(PREFIX)/bin/perl6-m" "$(PREFIX)" "$(DESTDIR)$(PERL6_LANG_DIR)/runtime/perl6.moarvm" "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
+ $(PERL) $(PREFIX)/bin/gen-moar-runner.pl "$(DESTDIR)$(PREFIX)/bin/perl6-debug-m" "$(PREFIX)" "$(DESTDIR)$(PERL6_LANG_DIR)/runtime/perl6-debug.moarvm" "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
$(CHMOD) 755 $(DESTDIR)$(PREFIX)/bin/perl6-m$(M_BAT)
m-runner-default-install: m-install
- $(PERL) tools/build/create-moar-runner.pl "$(MOAR)" perl6.moarvm $(DESTDIR)$(PREFIX)/bin/perl6-m "$(PERL6_LANG_DIR)/runtime" "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
+ $(PERL) $(PREFIX)/bin/gen-moar-runner.pl "$(DESTDIR)$(PREFIX)/bin/perl6-m" "$(PREFIX)" "$(DESTDIR)$(PERL6_LANG_DIR)/runtime/perl6.moarvm" "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
$(CP) $(DESTDIR)$(PREFIX)/bin/perl6-m$(M_BAT) $(DESTDIR)$(PREFIX)/bin/perl6$(M_BAT)
$(CHMOD) 755 $(DESTDIR)$(PREFIX)/bin/perl6$(M_BAT)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment