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, ruint encoding, 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));
60 stat->encoding = encoding;
65 stat->records = records;
66 if (stat->instacksize < size) {
67 stat->instackbuffer = r_realloc(stat->instackbuffer, (size + 2) * sizeof(rpainput_t));
68 stat->instacksize = size + 1;
69 stat->instack = &stat->instackbuffer[1];
70 r_memset(stat->instackbuffer, 0, sizeof(rpainput_t) * 2);
72 stat->ip.input = input;
74 RVM_CPUREG_SETL(stat->cpu, R_REC, 0);
75 RVM_CPUREG_SETU(stat->cpu, SP, 0);
76 RVM_CPUREG_SETU(stat->cpu, FP, 0);
77 RVM_CPUREG_SETU(stat->cpu, R_LOO, 0);
78 RVM_CPUREG_SETU(stat->cpu, R_TOP, -1);
80 RVM_CPUREG_SETL(stat->cpu, R_REC, (rlong)(r_array_length(stat->records) - 1));
86 void rpa_stat_cacheinvalidate(rpastat_t *stat)
88 rpa_cache_invalidate(stat->cache);
92 rlong rpa_stat_exec(rpastat_t *stat, rvm_asmins_t *prog, rword off, ruint encoding, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
99 rpa_stat_cacheinvalidate(stat);
100 rpa_stat_init(stat, encoding, input, start, end, records);
103 ret = rvm_cpu_exec_debug(stat->cpu, prog, off);
105 ret = rvm_cpu_exec(stat->cpu, prog, off);
108 if (!stat->cpu->error) {
109 if (stat->cpu->error) {
110 RPA_STAT_SETERROR_CODE(stat, stat->cpu->error);
113 * We should never get to here. Error have to be more
114 * specific and set at the places they are detected.
116 RPA_STAT_SETERROR_CODE(stat, RPA_E_EXECUTION);
121 ret = (rlong)RVM_CPUREG_GETL(stat->cpu, R0);
129 static rlong rpa_stat_exec_rid(rpastat_t *stat, rparule_t rid, ruint encoding, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
134 if ((topsiz = rpa_stat_exec(stat, rpa_dbex_executable(stat->dbex), rpa_dbex_executableoffset(stat->dbex, rid), encoding, input, start, end, records)) < 0) {
139 ptp = &stat->instack[topsiz];
140 return (ptp->input - input);
144 rlong rpa_stat_scan(rpastat_t *stat, rparule_t rid, ruint encoding, const rchar *input, const rchar *start, const rchar *end, const rchar **where)
148 while (input < end) {
149 ret = rpa_stat_exec_rid(stat, rid, encoding, input, start, end, NULL);
162 rlong rpa_stat_match(rpastat_t *stat, rparule_t rid, ruint encoding, const rchar *input, const rchar *start, const rchar *end)
164 return rpa_stat_exec_rid(stat, rid, encoding, input, start, end, NULL);
168 rlong rpa_stat_parse(rpastat_t *stat, rparule_t rid, ruint encoding, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
170 return rpa_stat_exec_rid(stat, rid, encoding, input, start, end, records);
174 rint rpa_stat_abort(rpastat_t *stat)
179 RPA_STAT_SETERROR_CODE(stat, RPA_E_USERABORT);
180 rvm_cpu_abort(stat->cpu);
185 rint rpa_stat_matchchr(rpastat_t *stat, rssize_t top, rulong wc)
188 rpainput_t *in = &stat->instack[top];
192 if (stat->encoding & RPA_ENCODING_ICASE) {
193 ret = (in->wc == wc || in->iwc == wc) ? 1 : 0;
195 ret = (in->wc == wc) ? 1 : 0;
201 rint rpa_stat_matchspchr(rpastat_t *stat, rssize_t top, rulong wc)
204 rpainput_t *in = &stat->instack[top];
226 ret = (in->wc == wc) ? 1 : 0;
231 rint rpa_stat_matchrng(rpastat_t *stat, rssize_t top, rulong wc1, rulong wc2)
234 rpainput_t *in = &stat->instack[top];
238 if (stat->encoding & RPA_ENCODING_ICASE) {
239 ret = ((in->wc >= wc1 && in->wc <= wc2) || (in->iwc >= wc1 && in->iwc <= wc2)) ? 1 : 0;
241 ret = ((in->wc >= wc1 && in->wc <= wc2)) ? 1 : 0;
247 static rint rpa_stat_utf8_getchar(ruint32 *pwc, rpastat_t *stat, const rchar *input)
249 return r_utf8_mbtowc(pwc, (const ruchar*)input, (const ruchar*)stat->end);
253 static rint rpa_stat_byte_getchar(ruint32 *pwc, rpastat_t *stat, const rchar *input)
255 if (input >= stat->end) {
256 *pwc = (unsigned int)0;
259 *pwc = *((const ruchar*)input);
264 static int rpa_stat_utf16_getchar(ruint32 *pwc, rpastat_t *stat, const rchar *input)
266 return r_utf16_mbtowc(pwc, (const ruchar*)input, (const ruchar*)stat->end);
270 rlong rpa_stat_shift(rpastat_t *stat, rssize_t top)
272 rpainput_t * ptp = &stat->instack[top];
278 if (top >= (rlong)stat->ip.serial) {
280 ptp->input = stat->ip.input;
281 if (ptp->input < stat->end) {
282 switch (stat->encoding & RPA_ENCODING_MASK) {
284 case RPA_ENCODING_UTF8:
285 inc = rpa_stat_utf8_getchar(&ptp->wc, stat, (const rchar*)stat->ip.input);
287 case RPA_ENCODING_UTF16LE:
288 inc = rpa_stat_utf16_getchar(&ptp->wc, stat, (const rchar*)stat->ip.input);
290 case RPA_ENCODING_BYTE:
291 inc = rpa_stat_byte_getchar(&ptp->wc, stat, (const rchar*)stat->ip.input);
294 if (stat->encoding & RPA_ENCODING_ICASE)
295 ptp->iwc = r_charicase(ptp->wc);
296 stat->ip.input += inc;
297 stat->ip.serial += 1;
300 ptp->wc = (ruint32)-1;
309 rlong rpa_stat_lasterror(rpastat_t *stat)
313 return stat->err.code;
317 rlong rpa_stat_lasterrorinfo(rpastat_t *stat, rpa_errinfo_t *errinfo)
319 if (!stat || !errinfo)
321 r_memcpy(errinfo, &stat->err, sizeof(rpa_errinfo_t));