3 #include "rpastatpriv.h"
4 #include "rvmcodegen.h"
10 rpastat_t *rpa_stat_create(rpadbex_t *dbex, rulong stacksize)
12 rpastat_t *stat = (rpastat_t *) r_zmalloc(sizeof(*stat));
14 stacksize = RPA_DEFAULT_STACKSIZE;
15 stat->cpu = rpavm_cpu_create(stacksize);
16 stat->cache = rpa_cache_create();
22 stat->cpu->userdata1 = stat;
27 void rpa_stat_destroy(rpastat_t *stat)
31 r_free(stat->instackbuffer);
32 rpavm_cpu_destroy(stat->cpu);
33 rpa_cache_destroy(stat->cache);
39 void rpa_stat_cachedisable(rpastat_t *stat, ruint disable)
41 rpa_cache_disable(stat->cache, disable);
45 rint rpa_stat_init(rpastat_t *stat, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
55 if (input < start || input > end) {
58 r_memset(&stat->err, 0, sizeof(stat->err));
64 stat->records = records;
65 if (stat->instacksize < size) {
66 stat->instackbuffer = r_realloc(stat->instackbuffer, (size + 2) * sizeof(rpainput_t));
67 stat->instacksize = size + 1;
68 stat->instack = &stat->instackbuffer[1];
69 r_memset(stat->instackbuffer, 0, sizeof(rpainput_t) * 2);
71 stat->ip.input = input;
73 RVM_CPUREG_SETL(stat->cpu, R_REC, 0);
74 RVM_CPUREG_SETU(stat->cpu, SP, 0);
75 RVM_CPUREG_SETU(stat->cpu, FP, 0);
76 RVM_CPUREG_SETU(stat->cpu, R_LOO, 0);
77 RVM_CPUREG_SETU(stat->cpu, R_TOP, -1);
79 RVM_CPUREG_SETL(stat->cpu, R_REC, (rlong)(r_array_length(stat->records) - 1));
85 void rpa_stat_cacheinvalidate(rpastat_t *stat)
87 rpa_cache_invalidate(stat->cache);
91 rint rpa_stat_setencoding(rpastat_t *stat, ruint encoding)
97 stat->encoding = encoding;
102 rlong rpa_stat_exec(rpastat_t *stat, rvm_asmins_t *prog, rword off, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
109 rpa_stat_cacheinvalidate(stat);
110 rpa_stat_init(stat, input, start, end, records);
112 ret = rvm_cpu_exec_debug(stat->cpu, prog, off);
114 ret = rvm_cpu_exec(stat->cpu, prog, off);
117 if (!stat->cpu->error) {
118 if (stat->cpu->error) {
119 RPA_STAT_SETERROR_CODE(stat, stat->cpu->error);
122 * We should never get to here. Error have to be more
123 * specific and set at the places they are detected.
125 RPA_STAT_SETERROR_CODE(stat, RPA_E_EXECUTION);
130 ret = (rlong)RVM_CPUREG_GETL(stat->cpu, R0);
138 static rlong rpa_stat_exec_rid(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
143 if ((topsiz = rpa_stat_exec(stat, rpa_dbex_executable(stat->dbex), rpa_dbex_executableoffset(stat->dbex, rid), input, start, end, records)) < 0) {
148 ptp = &stat->instack[topsiz];
149 return (ptp->input - input);
153 rlong rpa_stat_scan(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, const rchar **where)
157 while (input < end) {
158 ret = rpa_stat_exec_rid(stat, rid, input, start, end, NULL);
171 rlong rpa_stat_match(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end)
173 return rpa_stat_exec_rid(stat, rid, input, start, end, NULL);
177 rlong rpa_stat_parse(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
179 return rpa_stat_exec_rid(stat, rid, input, start, end, records);
183 rint rpa_stat_abort(rpastat_t *stat)
188 RPA_STAT_SETERROR_CODE(stat, RPA_E_USERABORT);
189 rvm_cpu_abort(stat->cpu);
194 rint rpa_stat_matchchr(rpastat_t *stat, rssize_t top, rulong wc)
197 rpainput_t *in = &stat->instack[top];
201 if (stat->encoding & RPA_ENCODING_ICASE) {
202 ret = (in->wc == wc || in->iwc == wc) ? 1 : 0;
204 ret = (in->wc == wc) ? 1 : 0;
210 rint rpa_stat_matchspchr(rpastat_t *stat, rssize_t top, rulong wc)
213 rpainput_t *in = &stat->instack[top];
235 ret = (in->wc == wc) ? 1 : 0;
240 rint rpa_stat_matchrng(rpastat_t *stat, rssize_t top, rulong wc1, rulong wc2)
243 rpainput_t *in = &stat->instack[top];
247 if (stat->encoding & RPA_ENCODING_ICASE) {
248 ret = ((in->wc >= wc1 && in->wc <= wc2) || (in->iwc >= wc1 && in->iwc <= wc2)) ? 1 : 0;
250 ret = ((in->wc >= wc1 && in->wc <= wc2)) ? 1 : 0;
256 static rint rpa_stat_utf8_getchar(ruint32 *pwc, rpastat_t *stat, const rchar *input)
258 return r_utf8_mbtowc(pwc, (const ruchar*)input, (const ruchar*)stat->end);
262 static rint rpa_stat_byte_getchar(ruint32 *pwc, rpastat_t *stat, const rchar *input)
264 if (input >= stat->end) {
265 *pwc = (unsigned int)0;
268 *pwc = *((const ruchar*)input);
273 static int rpa_stat_utf16_getchar(ruint32 *pwc, rpastat_t *stat, const rchar *input)
275 return r_utf16_mbtowc(pwc, (const ruchar*)input, (const ruchar*)stat->end);
279 rlong rpa_stat_shift(rpastat_t *stat, rssize_t top)
281 rpainput_t * ptp = &stat->instack[top];
287 if (top >= (rlong)stat->ip.serial) {
289 ptp->input = stat->ip.input;
290 if (ptp->input < stat->end) {
291 switch (stat->encoding & RPA_ENCODING_MASK) {
293 case RPA_ENCODING_UTF8:
294 inc = rpa_stat_utf8_getchar(&ptp->wc, stat, (const rchar*)stat->ip.input);
296 case RPA_ENCODING_UTF16LE:
297 inc = rpa_stat_utf16_getchar(&ptp->wc, stat, (const rchar*)stat->ip.input);
299 case RPA_ENCODING_BYTE:
300 inc = rpa_stat_byte_getchar(&ptp->wc, stat, (const rchar*)stat->ip.input);
303 if (stat->encoding & RPA_ENCODING_ICASE)
304 ptp->iwc = r_charicase(ptp->wc);
305 stat->ip.input += inc;
306 stat->ip.serial += 1;
309 ptp->wc = (ruint32)-1;
318 rlong rpa_stat_lasterror(rpastat_t *stat)
322 return stat->err.code;
326 rlong rpa_stat_lasterrorinfo(rpastat_t *stat, rpa_errinfo_t *errinfo)
328 if (!stat || !errinfo)
330 r_memcpy(errinfo, &stat->err, sizeof(rpa_errinfo_t));