-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathPerl6.xs
115 lines (94 loc) · 3.65 KB
/
Perl6.xs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#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);
*/
}