Skip to content
Permalink
Browse files

Start of a C perl6 runner. Just a copy of moar atm.

  • Loading branch information...
patzim committed Jan 8, 2019
1 parent a11e9ab commit ed9b963d719dae4deac8ca291caa65d5a8d0395c
Showing with 336 additions and 6 deletions.
  1. +2 −0 .gitignore
  2. +17 −6 tools/build/Makefile-Moar.in
  3. +317 −0 tools/build/moar-runner.c
@@ -61,6 +61,8 @@ perl6-debug-j.bat
/perl6-lldb-m
perl6-m
perl6-m.bat
perl6-mc
perl6-mc.exe
perl6-debug-m
perl6-debug-m.bat
perl6-js
@@ -19,6 +19,8 @@ M_RUN_PERL6 = $(MOAR) --libpath="blib" --libpath="$(M_LIBPATH)" perl6.moarvm --n
M_BAT = @runner_suffix@
M_RUNNER = perl6-m@runner_suffix@

M_C_RUNNER = perl6-mc@exe@

# files we create
PERL6_MOAR = perl6.moarvm
PERL6_ML_MOAR = blib/Perl6/ModuleLoader.moarvm
@@ -214,6 +216,14 @@ $(M_VALGRIND_RUNNER): tools/build/create-moar-runner.p6 $(PERL6_MOAR) $(SETTING_
$(M_RUN_PERL6) tools/build/create-moar-runner.p6 "$(MOAR)" perl6.moarvm perl6-valgrind-m . "valgrind" --nqp-lib=blib norelocatable . blib "$(M_LIBPATH)"
-$(CHMOD) 755 $(M_VALGRIND_RUNNER)

$(M_C_RUNNER): tools/build/moar-runner.c
$(RM_F) $(M_C_RUNNER)
# Using only the pkgconfig moar includes does not work, because moar.h assumes all the specific includes below.
$(M_CC) @moar::ccshared@ $(M_CFLAGS) $(M_LDFLAGS) -I$(M_INCPATH) -I$(M_INCPATH)/moar \
-I$(M_INCPATH)/libatomic_ops -I$(M_INCPATH)/dyncall -I$(M_INCPATH)/moar -I$(M_INCPATH)/sha1 -I$(M_INCPATH)/tinymt -I$(M_INCPATH)/libtommath -I$(M_INCPATH)/libuv \
-L@moar::libdir@ -Wl,-z,origin,-rpath,'$$ORIGIN/../lib' -lmoar @moar::ccout@$@ tools/build/moar-runner.c


## testing targets
m-test : m-coretest$(HARNESS_TYPE)

@@ -288,7 +298,7 @@ m-localtest_loud: m-all spectest_checkout t/localtest.data
m-sometests: m-all
@$(M_HARNESS6_WITH_FUDGE) $(TESTFILES)

m-install: m-all tools/build/create-moar-runner.p6 tools/build/install-core-dist.p6 $(SETTING_MOAR)
m-install: m-all tools/build/create-moar-runner.p6 tools/build/install-core-dist.p6 $(SETTING_MOAR) $(M_C_RUNNER)
$(MKPATH) $(DESTDIR)$(PREFIX)/bin
$(MKPATH) $(DESTDIR)$(M_LIBPATH)/Perl6
$(M_RUN_CLEAN_TARGET_FILES) $(M_PERL6_LANG_OUTPUT) $(DESTDIR)/$(M_LIBPATH)/Perl6
@@ -305,15 +315,16 @@ m-install: m-all tools/build/create-moar-runner.p6 tools/build/install-core-dist
.@slash@$(M_RUNNER) tools/build/upgrade-repository.p6 $(DESTDIR)$(PERL6_LANG_DIR)/vendor
.@slash@$(M_RUNNER) tools/build/upgrade-repository.p6 $(DESTDIR)$(PERL6_LANG_DIR)/site
.@slash@$(M_RUNNER) tools/build/install-core-dist.p6 $(DESTDIR)$(PERL6_LANG_DIR)
$(M_RUN_PERL6) tools/build/create-moar-runner.p6 "$(MOAR)" perl6.moarvm $(DESTDIR)$(PREFIX)/bin/perl6-m "$(PERL6_LANG_DIR)/runtime" "" "" relocatable "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
#$(M_RUN_PERL6) tools/build/create-moar-runner.p6 "$(MOAR)" perl6.moarvm $(DESTDIR)$(PREFIX)/bin/perl6-m "$(PERL6_LANG_DIR)/runtime" "" "" relocatable "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
$(CP) $(M_C_RUNNER) $(DESTDIR)$(PREFIX)/bin/perl6-m@exe@
$(M_RUN_PERL6) tools/build/create-moar-runner.p6 "$(MOAR)" perl6-debug.moarvm $(DESTDIR)$(PREFIX)/bin/perl6-debug-m "$(PERL6_LANG_DIR)/runtime" "" "" relocatable "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
$(CHMOD) 755 $(DESTDIR)$(PREFIX)/bin/perl6-m$(M_BAT)
#$(CHMOD) 755 $(DESTDIR)$(PREFIX)/bin/perl6-m@exe@
@m_install@

m-runner-default-install: m-install
$(M_RUN_PERL6) tools/build/create-moar-runner.p6 "$(MOAR)" perl6.moarvm $(DESTDIR)$(PREFIX)/bin/perl6-m "$(PERL6_LANG_DIR)/runtime" "" "" relocatable "$(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)
#$(M_RUN_PERL6) tools/build/create-moar-runner.p6 "$(MOAR)" perl6.moarvm $(DESTDIR)$(PREFIX)/bin/perl6-m "$(PERL6_LANG_DIR)/runtime" "" "" relocatable "$(M_LIBPATH)" "$(PERL6_LANG_DIR)/lib" "$(PERL6_LANG_DIR)/runtime"
$(CP) $(DESTDIR)$(PREFIX)/bin/perl6-m@exe@ $(DESTDIR)$(PREFIX)/bin/perl6@exe@
#$(CHMOD) 755 $(DESTDIR)$(PREFIX)/bin/perl6@exe

manifest:
echo MANIFEST >MANIFEST
@@ -0,0 +1,317 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <moar.h>

#if MVM_TRACING
# define TRACING_OPT "[--tracing] "
# define TRACING_USAGE "\n --tracing output a line to stderr on every interpreter instr"
#else
# define TRACING_OPT ""
# define TRACING_USAGE ""
#endif

#ifdef HAVE_TELEMEH
# define TELEMEH_USAGE " MVM_TELEMETRY_LOG Log internal events at high precision to this file\n"
#else
# define TELEMEH_USAGE ""
#endif

#ifndef _WIN32
# include "signal.h"
#endif

#ifndef _WIN32
# include <unistd.h>
#else
# include <process.h>
#endif

#ifdef _WIN32
# define snprintf _snprintf
#endif

#if defined(_MSC_VER)
#define strtoll _strtoi64
#endif

/* flags need to be sorted alphabetically */

enum {
NOT_A_FLAG = -2,
UNKNOWN_FLAG = -1,

FLAG_CRASH,
FLAG_SUSPEND,
FLAG_DUMP,
FLAG_FULL_CLEANUP,
FLAG_HELP,
FLAG_TRACING,
FLAG_VERSION,

OPT_EXECNAME,
OPT_LIBPATH,
OPT_DEBUGPORT
};

static const char *const FLAGS[] = {
"--crash",
"--debug-suspend",
"--dump",
"--full-cleanup",
"--help",
"--tracing",
"--version",
};

static const char USAGE[] = "\
USAGE: moar [--crash] [--libpath=...] " TRACING_OPT "input.moarvm [program args]\n\
moar --dump input.moarvm\n\
moar --help\n\
\n\
--help display this message\n\
--dump dump the bytecode to stdout instead of executing\n\
--full-cleanup try to free all memory and exit cleanly\n\
--crash abort instead of exiting on unhandled exception\n\
--libpath specify path loadbytecode should search in\n\
--version show version information\n\
--debug-port=1234 listen for incoming debugger connections\n\
--debug-suspend pause execution at the entry point"
TRACING_USAGE
"\n\
\n\
The following environment variables are respected:\n\
\n\
MVM_SPESH_DISABLE Disables all dynamic optimization\n\
MVM_SPESH_INLINE_DISABLE Disables inlining\n\
MVM_SPESH_OSR_DISABLE Disables on-stack replacement\n\
MVM_SPESH_BLOCKING Blocks log-sending thread while specializer runs\n\
MVM_SPESH_LOG Specifies a dynamic optimizer log file\n\
MVM_SPESH_NODELAY Run dynamic optimization even for cold frames\n\
MVM_SPESH_LIMIT Limit the maximum number of specializations\n\
MVM_JIT_DISABLE Disables JITting to machine code\n\
MVM_JIT_EXPR_DISABLE Disable advanced 'expression' JIT\n\
MVM_JIT_DEBUG Add JIT debugging information to spesh log\n\
MVM_JIT_PERF_MAP Create a map file for the 'perf' profiler (linux only)\n\
MVM_JIT_DUMP_BYTECODE Dump bytecode in temporary directory\n\
MVM_SPESH_INLINE_LOG Dump details of inlining attempts to stderr\n\
MVM_CROSS_THREAD_WRITE_LOG Log unprotected cross-thread object writes to stderr\n\
MVM_COVERAGE_LOG Append (de-duped by default) line-by-line coverage messages to this file\n\
MVM_COVERAGE_CONTROL If set to 1, non-de-duping coverage started with nqp::coveragecontrol(1),\n\
if set to 2, non-de-duping coverage started right away\n"
TELEMEH_USAGE;

static int cmp_flag(const void *key, const void *value)
{
return strcmp(key, *(char **)value);
}

static int starts_with(const char *str, const char *want) {
size_t str_len = strlen(str);
size_t want_len = strlen(want);
return str_len < want_len
? 0
: strncmp(str, want, want_len) == 0;
}

static int parse_flag(const char *arg)
{
const char *const *found;

if (!arg || arg[0] != '-')
return NOT_A_FLAG;

found = bsearch(arg, FLAGS, sizeof FLAGS / sizeof *FLAGS, sizeof *FLAGS, cmp_flag);

if (found)
return (int)(found - FLAGS);
else if (starts_with(arg, "--libpath="))
return OPT_LIBPATH;
else if (starts_with(arg, "--execname="))
return OPT_EXECNAME;
else if (starts_with(arg, "--debug-port="))
return OPT_DEBUGPORT;
else
return UNKNOWN_FLAG;
}

#ifndef _WIN32
int main(int argc, char *argv[])
#else
int wmain(int argc, wchar_t *wargv[])
#endif
{
MVMInstance *instance;
const char *input_file;
const char *executable_name = NULL;
const char *lib_path[8];

#ifdef _WIN32
char **argv = MVM_UnicodeToUTF8_argv(argc, wargv);
#endif

int dump = 0;
int full_cleanup = 0;
int argi = 1;
int lib_path_i = 0;
int flag;

unsigned int interval_id;
char telemeh_inited = 0;

MVMuint32 debugserverport = 0;
int start_suspended = 0;

for (; (flag = parse_flag(argv[argi])) != NOT_A_FLAG; ++argi) {
switch (flag) {
case FLAG_CRASH:
MVM_crash_on_error();
continue;

case FLAG_DUMP:
dump = 1;
continue;

case FLAG_FULL_CLEANUP:
full_cleanup = 1;
continue;

case FLAG_HELP:
puts(USAGE);
return EXIT_SUCCESS;

#if MVM_TRACING
case FLAG_TRACING:
MVM_interp_enable_tracing();
continue;
#endif

case FLAG_SUSPEND:
start_suspended = 1;
continue;

case OPT_EXECNAME:
executable_name = argv[argi] + strlen("--execname=");
continue;

case OPT_LIBPATH:
if (lib_path_i == 7) { /* 0..7 == 8 */
fprintf(stderr, "ERROR: Only up to eight --libpath options are allowed.\n");
return EXIT_FAILURE;
}

lib_path[lib_path_i++] = argv[argi] + strlen("--libpath=");
continue;

case FLAG_VERSION: {
char *spesh_disable;
char *jit_disable;

printf("This is MoarVM version %s", MVM_VERSION);
if (MVM_jit_support()) {
printf(" built with JIT support");

spesh_disable = getenv("MVM_SPESH_DISABLE");
jit_disable = getenv("MVM_JIT_DISABLE");
if (spesh_disable && strlen(spesh_disable) != 0) {
printf(" (disabled via MVM_SPESH_DISABLE)");
} else if (jit_disable && strlen(jit_disable) != 0) {
printf(" (disabled via MVM_JIT_DISABLE)");
}
}
printf("\n");
return EXIT_SUCCESS;
}

case OPT_DEBUGPORT: {
MVMint64 port;
char *portstr = argv[argi] + strlen("--debugport=") + 1;
char *endptr;
port = strtoll(portstr, &endptr, 10);
if (*endptr != '\0') {
fprintf(stderr, "ERROR: Invalid characters in debug port flag: %s\n", portstr);
return EXIT_FAILURE;
}
if (port <= 1024 || 65535 < port) {
fprintf(stderr, "ERROR: debug server port out of range. We only accept ports above 1024 and below 65535. (got: %"PRIi64")\n", port);
return EXIT_FAILURE;
}
debugserverport = (MVMuint32)port;
break;
}

default:
fprintf(stderr, "ERROR: Unknown flag %s.\n\n%s\n", argv[argi], USAGE);
return EXIT_FAILURE;
}
}

#ifdef HAVE_TELEMEH
if (getenv("MVM_TELEMETRY_LOG")) {
char path[256];
FILE *fp;
snprintf(path, 255, "%s.%d", getenv("MVM_TELEMETRY_LOG"),
#ifdef _WIN32
_getpid()
#else
getpid()
#endif
);
fp = fopen(path, "w");
if (fp) {
MVM_telemetry_init(fp);
telemeh_inited = 1;
interval_id = MVM_telemetry_interval_start(0, "moarvm startup");
}
}
#endif

lib_path[lib_path_i] = NULL;

if (argi >= argc) {
fprintf(stderr, "ERROR: Missing input file.\n\n%s\n", USAGE);
return EXIT_FAILURE;
}

instance = MVM_vm_create_instance();
input_file = argv[argi++];

/* stash the rest of the raw command line args in the instance */
MVM_vm_set_clargs(instance, argc - argi, argv + argi);
MVM_vm_set_prog_name(instance, input_file);
MVM_vm_set_exec_name(instance, executable_name);
MVM_vm_set_lib_path(instance, lib_path_i, lib_path);

/* Ignore SIGPIPE by default, since we error-check reads/writes. This does
* not prevent users from setting up their own signal handler for SIGPIPE,
* which will take precedence over this ignore. */
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
#endif

if (debugserverport > 0) {
MVM_debugserver_init(instance->main_thread, debugserverport);

if (start_suspended) {
instance->main_thread->gc_status = MVMGCStatus_INTERRUPT | MVMSuspendState_SUSPEND_REQUEST;
}
}

if (dump) MVM_vm_dump_file(instance, input_file);
else MVM_vm_run_file(instance, input_file);

#ifdef HAVE_TELEMEH
if (getenv("MVM_TELEMETRY_LOG") && telemeh_inited) {
MVM_telemetry_interval_stop(0, interval_id, "moarvm teardown");
MVM_telemetry_finish();
}
#endif

if (full_cleanup) {
MVM_vm_destroy_instance(instance);
return EXIT_SUCCESS;
}
else {
MVM_vm_exit(instance);
}
}

0 comments on commit ed9b963

Please sign in to comment.
You can’t perform that action at this time.