Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

212 lines (156 sloc) 5.274 kb
/* 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);
/* builtin method stuff */
SV*
tx_methodcall(pTHX_ tx_state_t* const st, SV* const method);
void
tx_register_builtin_methods(pTHX_ HV* const hv);
Jump to Line
Something went wrong with that request. Please try again.