#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include <moar.h>
#include "Perl6.h"
#ifdef PERL_IMPLICIT_CONTEXT
#define create_p6 p5_callback(my_perl)
#else
#define create_p6 p5_callback(NULL)
#endif
SV *(*p5_callback)(PerlInterpreter *);
MVMInstance *instance;
MVMCompUnit *cu;
/* Points to the current opcode. */
MVMuint8 *cur_op = NULL;
/* The current frame's bytecode start. */
MVMuint8 *bytecode_start = NULL;
/* Points to the base of the current register set for the frame we
* are presently in. */
MVMRegister *reg_base = NULL;
SV *perl6;
const char *filename = PERL6_INSTALL_PATH "/runtime/perl6.moarvm";
static void toplevel_initial_invoke(MVMThreadContext *tc, void *data) {
/* Create initial frame, which sets up all of the interpreter state also. */
MVM_frame_dispatch_zero_args(tc, ((MVMStaticFrame *)data)->body.static_code);
}
void init_inline_perl6_new_callback(SV *(*new_p5_callback)(PerlInterpreter *)) {
p5_callback = new_p5_callback;
}
char *library_location, *helper_path;
const char *raw_clargs[2];
const char *lib_path[3] = {
NQP_LIBDIR,
PERL6_INSTALL_PATH "/lib",
PERL6_INSTALL_PATH "/runtime",
};
MODULE = Inline::Perl6 PACKAGE = Inline::Perl6
void setup_library_location(path, helper)
char *path
char *helper
CODE:
raw_clargs[0] = helper_path = helper;
raw_clargs[1] = library_location = path;
void
initialize()
CODE:
MVM_crash_on_error();
instance = MVM_vm_create_instance();
/* stash the rest of the raw command line args in the instance */
MVM_vm_set_prog_name(instance, PERL6_INSTALL_PATH "/runtime/perl6.moarvm");
MVM_vm_set_exec_name(instance, PERL6_EXECUTABLE);
MVM_vm_set_lib_path(instance, 3, (const char **)lib_path);
MVM_vm_set_clargs(instance, 0, NULL);
/* Map the compilation unit into memory and dissect it. */
MVMThreadContext *tc = instance->main_thread;
cu = MVM_cu_map_from_file(tc, filename, 0);
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) {
MVMint8 spesh_enabled_orig = tc->instance->spesh_enabled;
tc->instance->spesh_enabled = 0;
MVM_interp_run(tc, &toplevel_initial_invoke, cu->body.deserialize_frame, NULL);
tc->instance->spesh_enabled = spesh_enabled_orig;
}
});
MVM_vm_set_clargs(instance, 2, raw_clargs);
instance->clargs = NULL; /* clear cache */
MVM_interp_run(tc, &toplevel_initial_invoke, cu->body.main_frame, NULL);
/* Stash addresses of current op, register base and SC deref base
* in the TC; this will be used by anything that needs to switch
* the current place we're interpreting. */
tc->interp_cur_op = &cur_op;
tc->interp_bytecode_start = &bytecode_start;
tc->interp_reg_base = ®_base;
tc->interp_cu = &cu;
toplevel_initial_invoke(tc, cu->body.main_frame);
mark_thread_blocked(tc);
perl6 = create_p6;
void
p6_destroy()
CODE:
if (perl6 != NULL) {
SvREFCNT_dec(perl6);
perl6 = NULL;
/* Disabled due to crashes. Also moarvm itself doesn't do this by default.
MVM_vm_destroy_instance(instance);
*/
}