forked from xslate/p5-Text-Xslate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxslate.h
217 lines (160 loc) · 5.26 KB
/
xslate.h
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/* xslate.h */
#include "xshelper.h"
#if defined(__GNUC__) && !defined(TX_NO_DTC)
/* enable DTC optimization */
#define TX_DIRECT_THREADED_CODE
#endif
#define TX_RAW_CLASS "Text::Xslate::Type::Raw"
#define TX_PAIR_CLASS "Text::Xslate::Type::Pair"
#define TX_MACRO_CLASS "Text::Xslate::Type::Macro"
/* arbitrary initial buffer size */
#define TX_HINT_SIZE 200
/* max calling depth (execution/macrocall) */
#define TX_MAX_DEPTH 100
#define TXC(name) static void CAT2(TXCODE_, name)(pTHX_ tx_state_t* const txst PERL_UNUSED_DECL)
/* TXC_xxx macros provide the information of arguments, interpreted by tool/opcode.pl */
#define TXC_w_sv(n) TXC(n) /* has TX_op_arg_sv as a SV */
#define TXC_w_key(n) TXC(n) /* has TX_op_arg_sv as a keyword */
#define TXC_w_sviv(n) TXC(n) /* has TX_op_arg_sv able to SvIVX */
#define TXC_w_int(n) TXC(n) /* has TX_op_arg_iv */
#define TXC_w_var(n) TXC(n) /* has TX_op_arg_iv as a local variable index */
#define TXC_goto(n) TXC(n) /* has TX_op_arg_pc for goto */
#define TXARGf_SV ((U8)(0x01))
#define TXARGf_INT ((U8)(0x02))
#define TXARGf_KEY ((U8)(0x04))
#define TXARGf_VAR ((U8)(0x08))
#define TXARGf_PC ((U8)(0x10))
#define TXCODE_W_SV (TXARGf_SV)
#define TXCODE_W_SVIV (TXARGf_SV | TXARGf_INT)
#define TXCODE_W_KEY (TXARGf_SV | TXARGf_KEY)
#define TXCODE_W_INT (TXARGf_INT)
#define TXCODE_W_VAR (TXARGf_INT | TXARGf_VAR)
#define TXCODE_GOTO (TXARGf_PC)
/* TX_st and TX_op are valid only in opcodes */
#define TX_st (txst)
#define TX_pop() (*(PL_stack_sp--))
#define TX_frame_at(st, ix) ((AV*)AvARRAY((st)->frames)[ix])
#define TX_current_framex(st) TX_frame_at((st), (st)->current_frame)
#define TX_current_frame() TX_current_framex(TX_st)
#define TX_CATCH_ERROR() UNLIKELY(!!sv_true(ERRSV))
/* template object, stored in $self->{template}{$file} */
enum tx_tobj_ix {
TXo_MTIME,
TXo_CACHEPATH,
TXo_FULLPATH, /* TXo_FULLPATH must be the last one */
/* dependencies here */
TXo_least_size
};
/* vm execution frame object */
enum tx_frame_ix {
TXframe_NAME,
TXframe_OUTPUT,
TXframe_RETADDR,
TXframe_START_LVAR, /* TXframe_START_LVAR must be the last one */
/* local variables here */
TXframe_least_size = TXframe_START_LVAR
};
/* macro object */
enum tx_macro_ix {
TXm_NAME,
TXm_ADDR,
TXm_NARGS,
TXm_OUTER,
TXm_size,
};
/* for-loop variables */
enum tx_for_ix {
TXfor_ITEM,
TXfor_ITER,
TXfor_ARRAY,
};
struct tx_state_s;
struct tx_code_s;
struct tx_info_s;
typedef struct tx_state_s tx_state_t;
typedef struct tx_code_s tx_code_t;
typedef struct tx_info_s tx_info_t;
#define TX_op (TX_st->pc)
#define TX_PC2POS(st, p) ((UV)((p) - (st)->code))
#define TX_POS2PC(st, u) ((st)->code + (u))
typedef tx_code_t* tx_pc_t;
#define TX_RETURN_NEXT() STMT_START { TX_st->pc++; return; } STMT_END
#define TX_RETURN_PC(x) STMT_START { TX_st->pc = (x); return; } STMT_END
#ifdef TX_DIRECT_THREADED_CODE
typedef const void* tx_exec_t;
#define TX_RUNOPS(st) tx_runops(aTHX_ st)
#else /* TX_DIRECT_THREADED_CODE */
typedef void (*tx_exec_t)(pTHX_ tx_state_t* const);
#define TX_RUNOPS(st) STMT_START { \
while((st)->pc->exec_code != TXCODE_end) { \
CALL_FPTR((st)->pc->exec_code)(aTHX_ (st)); \
} \
} STMT_END
#endif /* TX_DIRECT_THREADED_CODE */
/* virtual machine state */
struct tx_state_s {
tx_pc_t pc; /* the program counter */
tx_code_t* code; /* compiled code */
U32 code_len;
SV* output;
/* registers */
SV* sa;
SV* sb;
SV* targ;
/* variables */
HV* vars; /* template variables */
/* stack frame */
AV* frames; /* see enum txframeo_ix */
I32 current_frame; /* current frame index */
SV** pad; /* AvARRAY(frame[current_frame]) + 3 */
HV* symbol; /* symbol table (e.g. name => \&body | [macro object]) */
U32 hint_size; /* suggested template size (bytes) */
AV* tmpl; /* template objects. see enum txtmplo_ix */
SV* engine; /* Text::Xslate instance */
tx_info_t* info; /* index -> an oinfo object */
};
/* opcode structure */
struct tx_code_s {
tx_exec_t exec_code;
union {
SV* sv;
IV iv;
tx_pc_t pc;
} u_arg;
};
/* opcode information */
struct tx_info_s {
U16 optype;
U16 line;
SV* file;
};
#define TX_VERBOSE_DEFAULT 1
void
tx_warn(pTHX_ tx_state_t* const, const char* const fmt, ...)
__attribute__format__(__printf__, pTHX_2, pTHX_3);
void
tx_error(pTHX_ tx_state_t* const, const char* const fmt, ...)
__attribute__format__(__printf__, pTHX_2, pTHX_3);
const char*
tx_neat(pTHX_ SV* const sv);
SV*
tx_call_sv(pTHX_ tx_state_t* const st, SV* const sv, I32 const flags, const char* const name);
SV*
tx_proccall(pTHX_ tx_state_t* const st, SV* const proc, const char* const name);
SV*
tx_mark_raw(pTHX_ SV* const str);
SV*
tx_unmark_raw(pTHX_ SV* const str);
int
tx_sv_is_array_ref(pTHX_ SV* const sv);
int
tx_sv_is_hash_ref(pTHX_ SV* const sv);
int
tx_sv_is_code_ref(pTHX_ SV* const sv);
/* builtin method stuff */
SV*
tx_methodcall(pTHX_ tx_state_t* const st, SV* const method);
SV*
tx_merge_hash(pTHX_ tx_state_t* const st, SV* base, SV* value);
void
tx_register_builtin_methods(pTHX_ HV* const hv);