-
Notifications
You must be signed in to change notification settings - Fork 2
/
plu_op.c
96 lines (77 loc) · 2.18 KB
/
plu_op.c
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
#include "plu_op.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "plu_debug.h"
#include "plu_global_state.h"
#include "plu_lua.h"
OP *
plu_pp_custom(pTHX)
{
dVAR; dSP;
plu_op_aux_t *aux;
int status;
aux = (plu_op_aux_t *)PL_op->op_targ;
status = plu_call_lua_func_via_registry(aTHX_ aux->func_registry_idx);
if (UNLIKELY( status != 0 )) {
SV *err = plu_get_lua_errmsg(aTHX);
lua_pop(PLU_lua_int, 1);
croak("%s", SvPVX(err));
}
/*if (aux->test != NOT_IN_PAD) {
SV *s = PAD_SVl(aux->test);
sv_setiv_mg(s, SvIV(s)+1);
}*/
/*PLU_DEBUG("Finished executing OP.\n");*/
RETURN;
}
/* Hook that will free the OP aux structure of our custom ops */
/* FIXME this doesn't appear to actually be called for all ops -
* specifically NOT for our custom OP. Is this because the
* custom OP isn't wired up correctly? */
void
plu_op_free_hook(pTHX_ OP *o)
{
if (PLU_orig_opfreehook != NULL)
PLU_orig_opfreehook(aTHX_ o);
/* printf("cleaning %s\n", OP_NAME(o)); */
if (o->op_ppaddr == plu_pp_custom) {
PLU_DEBUG("Cleaning up custom OP's plu_op_aux_t\n");
plu_op_aux_t *aux = (plu_op_aux_t *)o->op_targ;
Safefree(aux);
o->op_targ = 0; /* important or Perl will use it to access the pad */
}
}
OP *
plu_prepare_custom_op(pTHX_ const int lua_func_registry_idx)
{
OP *op;
plu_op_aux_t *aux;
NewOp(1101, op, 1, OP);
op->op_type = (OPCODE)OP_CUSTOM;
op->op_next = (OP *)op;
op->op_private = 0;
op->op_flags = 0;
/* Set it's implementation ptr */
op->op_ppaddr = plu_pp_custom;
/* Init aux struct */
Newx(aux, 1, plu_op_aux_t);
aux->func_registry_idx = lua_func_registry_idx;
aux->saved_op_targ = 0;
/* aux->saved_op_targ = origop->op_targ; */ /* save in case needed for sassign optimization */
/* It may turn out that op_targ is not safe to use for custom OPs because
* some core functions may meddle with it. But chances are it's fine.
* If not, we'll need to become extra-creative... */
op->op_targ = (PADOFFSET)PTR2UV(aux);
return op;
}
OP *
plu_prepare_null_op(pTHX)
{
OP *op;
op = newOP(OP_NULL, 0);
op->op_next = (OP *)op;
op->op_private = 0;
op->op_flags = 0;
return op;
}