if (!hStat)
return -1;
rpa_stat_cachedisable(hStat, pGrep->disablecache);
- rpa_stat_encodingset(hStat, pGrep->encoding);
+ rpa_stat_setencoding(hStat, pGrep->encoding);
hStat->debug = pGrep->execdebug;
ret = rpa_stat_match(hStat, pGrep->hPattern, input, start, end);
if (ret > 0) {
rpa_grep_output_utf8_string(pGrep, "\n");
}
pGrep->cachehit = hStat->cache->hit;
- pGrep->orphrecords = r_array_length(hStat->orphans);
- pGrep->emitstacksize = r_array_length(hStat->emitstack);
-
rpa_stat_destroy(hStat);
return 0;
}
int rpa_grep_parse(rpa_grep_t *pGrep, const char* buffer, unsigned long size)
{
+ rlong ret;
rlong i;
rchar location[128];
rpastat_t *hStat;
- rarray_t *records = NULL;
+ rarray_t *records = rpa_record_array();
rparecord_t *prec;
const char *input = buffer, *start = buffer, *end = buffer + size;
if (!hStat)
return -1;
rpa_stat_cachedisable(hStat, pGrep->disablecache);
- rpa_stat_encodingset(hStat, pGrep->encoding);
+ rpa_stat_setencoding(hStat, pGrep->encoding);
hStat->debug = pGrep->execdebug;
- rpa_stat_parse(hStat, pGrep->hPattern, input, start, end, &records);
- if (records) {
+ ret = rpa_stat_parse(hStat, pGrep->hPattern, input, start, end, records);
+ if (ret < 0) {
+ rpa_errinfo_t err;
+ rpa_stat_lasterrorinfo(hStat, &err);
+ if (err.code) {
+ r_snprintf(location, sizeof(location), "Parse Error: Code: %ld", err.code);
+ rpa_grep_output_utf8_string(pGrep, location);
+ }
+ if (err.ruleid) {
+ r_snprintf(location, sizeof(location), ", Rule UID: %ld", err.ruleid);
+ rpa_grep_output_utf8_string(pGrep, location);
+ }
+ if (*err.name) {
+ r_snprintf(location, sizeof(location), ", Name: %s", err.name);
+ rpa_grep_output_utf8_string(pGrep, location);
+ }
+ if (err.offset) {
+ r_snprintf(location, sizeof(location), " at Offset: %ld", err.offset);
+ rpa_grep_output_utf8_string(pGrep, location);
+ }
+ rpa_grep_output_utf8_string(pGrep, "\n");
+
+ } else {
if (pGrep->greptype == RPA_GREPTYPE_PARSE) {
for (i = 0; i < r_array_length(records); i++) {
prec = (rparecord_t *)r_array_slot(records, i);
}
}
- r_array_destroy(records);
}
+ r_array_destroy(records);
pGrep->cachehit = hStat->cache->hit;
- pGrep->orphrecords = r_array_length(hStat->orphans);
- pGrep->emitstacksize = r_array_length(hStat->emitstack);
-
rpa_stat_destroy(hStat);
return 0;
}
hStat = rpa_stat_create(pGrep->hDbex, 0);
if (!hStat)
return -1;
- rpa_stat_encodingset(hStat, pGrep->encoding);
+ rpa_stat_setencoding(hStat, pGrep->encoding);
rpa_stat_cachedisable(hStat, pGrep->disablecache);
hStat->debug = pGrep->execdebug;
pGrep->cachehit = hStat->cache->hit;
- pGrep->orphrecords = r_array_length(hStat->orphans);
again:
ret = rpa_stat_scan(hStat, pGrep->hPattern, input, start, end, &matched);
pGrep->cachehit += hStat->cache->hit;
- pGrep->orphrecords += r_array_length(hStat->orphans);
if (ret > 0) {
if (!displayed) {
input = matched + ret;
goto again;
}
-
- pGrep->emitstacksize = r_array_length(hStat->emitstack);
rpa_stat_destroy(hStat);
return 0;
}
hStat = rpa_stat_create(pGrep->hDbex, 0);
if (!hStat)
return -1;
- rpa_stat_encodingset(hStat, pGrep->encoding);
+ rpa_stat_setencoding(hStat, pGrep->encoding);
hStat->debug = pGrep->execdebug;
again:
unsigned long scanmilisec;
unsigned long usedstack;
unsigned long cachehit;
- unsigned long orphrecords;
- unsigned long emitstacksize; // Must be ZERO, if not something is going wrong
unsigned int icase;
unsigned int encoding;
unsigned int greptype;
milsec = 1;
minutes = milsec/60000;
sec = (milsec%60000)/1000.0;
- fprintf(stdout, "\ntime: %0ldm%1.3fs, %ld KB (%ld KB/sec), stack: %ld KB, memory: %ld KB (leaked %ld Bytes), cachehit: %ld, "
- "orphan records: %ld, emitstacksize: %ld\n",
+ fprintf(stdout, "\ntime: %0ldm%1.3fs, %ld KB (%ld KB/sec), stack: %ld KB, memory: %ld KB (leaked %ld Bytes), cachehit: %ld \n",
minutes, sec, sckb, 1000*sckb/milsec, pGrep->usedstack / 1000, (rlong)r_debug_get_maxmem()/1000, (rlong)r_debug_get_allocmem(),
- pGrep->cachehit, pGrep->orphrecords, pGrep->emitstacksize);
+ pGrep->cachehit);
}
rpa_grep_destroy(pGrep);
#!emit sqstring
#!emitid SyntaxError UID_SYNTAXERROR 1
-#!emitid FunctionSyntaxError UID_FUNCTIONSYNTAXERROR 1
-#!emitid BlockSyntaxError UID_BLOCKSYNTAXERROR 1
-#!emitid GlobalSyntaxError UID_GLOBALSYNTAXERROR 1
-#!emitid IndexSyntaxError UID_INDEXSYNTAXERROR 1
-#!emitid MultiplicativeSyntaxError UID_MULTIPLICATIVESYNTAXERROR 1
-#!emitid AdditiveSyntaxError UID_ADDITIVESYNTAXERROR 1
#!emitid AdditiveOperator UID_BINARYOPERATOR 2
#!emitid AdditiveOperator UID_ADDITIVEOPERATOR 2
#!emitid MultiplicativeOperator UID_MULTIPLICATIVEOPERATOR 2
#!emitid DoWhileExpressionCompare UID_DOWHILEEXPRESSIONCOMPARE 59
#!emitid Program UID_PROGRAM 60
+#!abort AbortIfNotSC
+#!abort AbortIfNotMultiplicativeExpression
+
# 6 Source Text
SourceCharacter ::= .
SC ::= <S>? ';' <S>?
COMMA ::= <S>? ',' <S>?
EQ ::= <S>? '=' <S>?
+AbortIfNotSC ::= <SC>
# 7.4 Comments
Comment ::= <MultiLineComment> | <SingleLineComment>
# 11.2 Left-Hand-Side Expressions
-IndexSyntaxError ::= '[' (. - <SC>)*
+LSB ::= <S>? '[' <S>?
+RSB ::= <S>? ']' <S>?
MemberExpressionBase ::= <MemberExpression>
-MemberExpressionIndexOp ::= <MemberExpressionBase> <S>? (('[' <S>? <Expression> <S>? ']' <S>?) | <IndexSyntaxError>)
+MemberExpressionIndexOp ::= <MemberExpressionBase> <LSB> <Expression> <RSB>
MemberExpressionDotOp ::= <MemberExpressionBase> '.' <IdentifierName>
MemberExpression ::= <MemberExpressionIndexOp> |
# 11.5 Multiplicative Operators
-MultiplicativeSyntaxError ::= <MultiplicativeOperator>
MultiplicativeOperator ::= '*' | '/' | '%'
-MultiplicativeExpressionOp ::= <MultiplicativeExpression> <S>? ((<MultiplicativeOperator> <S>? <UnaryExpression>) | <MultiplicativeSyntaxError>)
+MultiplicativeExpressionOp ::= <MultiplicativeExpression> <S>? <MultiplicativeOperator> <S>? <UnaryExpression>
MultiplicativeExpression ::= <MultiplicativeExpressionOp> |
<UnaryExpression>
# 11.6 Additive Operators
-AdditiveSyntaxError ::= <AdditiveOperator>
AdditiveOperator ::= '+' | '-'
-AdditiveExpressionOp ::= <AdditiveExpression> <S>? ((<AdditiveOperator> <S>? <MultiplicativeExpression>) | <AdditiveSyntaxError>)
+AbortIfNotMultiplicativeExpression ::= <MultiplicativeExpression>
+AdditiveExpressionOp ::= <AdditiveExpression> <S>? <AdditiveOperator> <S>? <AbortIfNotMultiplicativeExpression>
AdditiveExpression ::= <AdditiveExpressionOp> |
<MultiplicativeExpression>
<SwitchStatementOp>
# 12.1 Block
-Block ::= <S>? '{' <S>? <StatementList>? <S>? ('}' | <BlockSyntaxError>) <S>?
+Block ::= <S>? '{' <S>? <StatementList>? <S>? '}' <S>?
StatementList ::= (<S>? <Statement>)+
# 12.2 Variable Statement
-VariableStatement ::= 'var' <S>? <VariableDeclarationList> <SC>
+VariableStatement ::= 'var' <S>? <VariableDeclarationList> <AbortIfNotSC>
VariableDeclarationList ::= <VariableDeclaration> (<COMMA> <VariableDeclaration> )*
VariableAllocate ::= <IdentifierNoEmit>
VariableAllocateAndInit ::= <IdentifierNoEmit>
EmptyStatement ::= <SC>
# 12.4 Expression Statement
-ExpressionStatement ::= (<Expression> - ('function' | '{')) <SC>
+ExpressionStatement ::= (<Expression> - ('function' | '{')) <AbortIfNotSC>
# 12.5 The if Statement
# 12.6 Iteration Statements
# 12.6a Iteration do ... while()
DoWhileExpressionCompare ::= <Expression>
-IterationDo ::= 'do' <S>? <Statement> <S>? 'while' <S>? '(' <S>? <DoWhileExpressionCompare> <S>? ')' (<S>? ';')
+IterationDo ::= 'do' <S>? <Statement> <S>? 'while' <S>? '(' <S>? <DoWhileExpressionCompare> <S>? ')' <AbortIfNotSC>
# 12.6b Iteration while()
WhileExpressionCompare ::= <Expression>
<IterationDo>
# 12.9 The return Statement
-ReturnOp ::= ('return' - 'return' <IdentifierPart>) <WhiteSpace>* <AssignmentExpression>? (<S>? ';')
-ReturnStatement ::= ('return' - 'return' <IdentifierPart>) <WhiteSpace>* <AssignmentExpression>? (<S>? ';')
+ReturnOp ::= ('return' - 'return' <IdentifierPart>) <WhiteSpace>* <AssignmentExpression>? <AbortIfNotSC>
+ReturnStatement ::= ('return' - 'return' <IdentifierPart>) <WhiteSpace>* <AssignmentExpression>? <AbortIfNotSC>
# The Break Statement
BreakOp ::= 'break' - 'break' <IdentifierPart>
-BreakStatement ::= <S>? <BreakOp> <SC>
+BreakStatement ::= <S>? <BreakOp> <AbortIfNotSC>
# The Continue Statement
ContinueOp ::= 'continue' - 'continue' <IdentifierPart>
-ContinueStatement ::= <S>? <ContinueOp> <SC>
+ContinueStatement ::= <S>? <ContinueOp> <AbortIfNotSC>
# 13 Function Definition
FunctionName ::= <IdentifierNoEmit>
-FunctionDeclaration ::= ('function'-'function'<IdentifierPart>)<S>?<FunctionName><S>?'('<S>?<FormalParameterList>?<S>?')'<S>?'{'<S>?<FunctionBody>?<S>? ('}' | <FunctionSyntaxError>)
-FunctionExpression ::= ('function'-'function'<IdentifierPart>)<S>?<FunctionName>?<S>?'('<S>?<FormalParameterList>?<S>?')'<S>?'{'<S>?<FunctionBody>?<S>?('}' | <FunctionSyntaxError>)
+FunctionDeclaration ::= ('function'-'function'<IdentifierPart>)<S>?<FunctionName><S>?'('<S>?<FormalParameterList>?<S>?')'<S>?'{'<S>?<FunctionBody>?<S>?'}'
+FunctionExpression ::= ('function'-'function'<IdentifierPart>)<S>?<FunctionName>?<S>?'('<S>?<FormalParameterList>?<S>?')'<S>?'{'<S>?<FunctionBody>?<S>?'}'
FormalParameterList ::= <FunctionParameter> ( <S>? ',' <S>? <FunctionParameter> )*
FunctionParameter ::= <IdentifierNoEmit>
-# FunctionBody ::= <SourceElements>
-FunctionBody ::= (<S>? (<SourceElement> ))+
-FunctionDeclarationStatement ::= ('function' - 'function' <IdentifierPart>)<S>?<FunctionName><S>?'('<S>?<FormalParameterList>?<S>?')' <SC>
+FunctionBody ::= <SourceElements>
+FunctionDeclarationStatement ::= ('function' - 'function' <IdentifierPart>)<S>?<FunctionName><S>?'('<S>?<FormalParameterList>?<S>?')' <AbortIfNotSC>
# FunctionName ::= <IdentifierNoEmit>
# FunctionNameLookupAlloc ::= <IdentifierNoEmit>
# FunctionExpression ::= ('function' - 'function'<IdentifierPart>)<S>?<FunctionName>?<S>?'('<S>?<FormalParameterList>?<S>?')'<S>?'{'<S>?<FunctionBody>?<S>?'}'
# FunctionParameter ::= <Identifier>
# FormalParameterList ::= <FunctionParameter> ( <S>? ',' <S>? <FunctionParameter> )*
-# FunctionDefinitionStatement ::= ('function' - 'function' <IdentifierPart>)<S>?<FunctionNameLookupAlloc><S>?'('<S>?<FormalParameterList>?<S>?')' <SC>
+# FunctionDefinitionStatement ::= ('function' - 'function' <IdentifierPart>)<S>?<FunctionNameLookupAlloc><S>?'('<S>?<FormalParameterList>?<S>?')' <AbortIfNotSC>
# FunctionBody ::= <SourceElements>
# 14 Program
-BlockSyntaxError ::= (. - '}')+ '}'
-FunctionSyntaxError ::= (. - '}')+ '}'
-GlobalSyntaxError ::= (. - <SC>)+
-
SourceElements ::= (<S>? <SourceElement>)+
SourceElement ::= <FunctionDeclaration> |
<Statement>
-Program ::= <SourceElements> | <GlobalSyntaxError>
+Program ::= <SourceElements>
# The root rule, it is anonymous
<Program>
jse->cpu = rvm_cpu_create_default();
jse->co = rjs_compiler_create(jse->cpu);
jse->cgs = r_array_create(sizeof(rvm_codegen_t*));
+ jse->errors = r_array_create(sizeof(rjs_error_t));
rvm_cpu_addswitable(jse->cpu, "rjsswitable", rjsswitable);
if (!jse->pa || !jse->cpu || !jse->co || !jse->cgs)
goto error;
}
}
r_array_destroy(jse->cgs);
+ r_array_destroy(jse->errors);
rjs_parser_destroy(jse->pa);
rvm_cpu_destroy(jse->cpu);
rjs_compiler_destroy(jse->co);
}
-static rint rjs_engine_parse(rjs_engine_t *jse, const rchar *script, rsize_t size, rarray_t **records)
+static rint rjs_engine_parse(rjs_engine_t *jse, const rchar *script, rsize_t size, rarray_t *records)
{
rlong res = 0;
- res = rjs_parser_exec(jse->pa, script, size, records);
+ rjs_error_t error;
+
+ r_memset(&error, 0, sizeof(error));
+ res = rjs_parser_exec(jse->pa, script, size, records, &error);
+ if (res < 0)
+ r_array_add(jse->errors, &error);
return res;
}
rint rjs_engine_compile(rjs_engine_t *jse, const rchar *script, rsize_t size)
{
rvm_codegen_t *topcg = NULL;
- rarray_t *records = NULL;
+ rarray_t *records = rpa_record_array();
jse->co->debug = jse->debugcompile;
- if (rjs_engine_parse(jse, script, size, &records) < 0) {
+ if (rjs_engine_parse(jse, script, size, records) < 0) {
goto err;
}
rint rjs_engine_dumpast(rjs_engine_t *jse, const rchar *script, rsize_t size)
{
- rarray_t *records = NULL;
- if (rjs_engine_parse(jse, script, size, &records) < 0) {
+ rarray_t *records = rpa_record_array();
+ if (rjs_engine_parse(jse, script, size, records) < 0) {
return -1;
#include "rvmcpu.h"
#include "rjsparser.h"
#include "rjscompiler.h"
+#include "rjserror.h"
+
typedef struct rjs_engine_s {
rjs_parser_t *pa;
rjs_compiler_t *co;
rarray_t *cgs;
+ rarray_t *errors;
rvmcpu_t *cpu;
rlong debugcompile:1;
rlong debugexec:1;
}
-void rjs_compiler_adderror(rjs_compiler_t *co, rlong code, const rchar *script, rlong scriptsize)
+void rjs_compiler_adderror(rjs_compiler_t *co, rlong code, const rchar *script)
{
- rjs_coerror_t error;
- error.code = code;
- error.script = script;
- error.scriptsize = scriptsize;
- r_array_add(co->errors, &error);
+ /*
+ * Not used for now. I should probably get rid of this altogether.
+ */
}
goto end;
}
- rjs_compiler_adderror(co, RJS_ERROR_UNDEFINED, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_UNDEFINED, prec->input);
return 0;
}
*/
ctx = rjs_compiler_getctx(co, RJS_COCTX_FUNCTION);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTION, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTION, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
return 0;
}
R_ASSERT(ctx);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
if (!ctx) {
- rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
return 0;
}
R_ASSERT(ctx);
rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
prec = (rparecord_t *)r_array_slot(records, rec);
rjs_compiler_debughead(co, records, rec);
- rjs_compiler_adderror(co, RJS_ERROR_SYNTAX, prec->input, prec->inputsiz);
+ rjs_compiler_adderror(co, RJS_ERROR_SYNTAX, prec->input);
rjs_compiler_debugtail(co, records, rec);
return 0;
}
co->scope = rvm_scope_create();
co->coctx = r_array_create(sizeof(rjs_coctx_t *));
- co->errors = r_array_create(sizeof(rjs_coerror_t));
co->cpu = cpu;
r_memset(co->handlers, 0, sizeof(co->handlers));
if (co) {
rvm_scope_destroy(co->scope);
r_array_destroy(co->coctx);
- r_array_destroy(co->errors);
r_free(co->temp);
co->cpu = NULL;
r_free(co);
}
co->cg = cg;
- r_array_setlength(co->errors, 0);
for (i = 0; i >= 0; i = rpa_recordtree_next(records, i, RPA_RECORD_START)) {
if (rjs_compiler_playrecord(co, records, i) < 0)
/*
return -1;
}
- if (r_array_length(co->errors)) {
- /*
- * TBD
- */
- return -1;
- }
-
if (rvm_codegen_relocate(co->cg, &labelerr) < 0) {
/*
* TBD
#include "rvmcpu.h"
#include "rjsuids.h"
#include "rparecord.h"
+#include "rjserror.h"
#define RJS_COMPILER_NHANDLERS 128
#define RJS_COMPILER_CODEGENKEEP (1 << 0)
#define RJS_COCTX_ITERATION (1 << 5)
#define RJS_COCTX_OPERATION (1 << 5)
-#define RJS_ERROR_NONE 0
-#define RJS_ERROR_UNDEFINED 1
-#define RJS_ERROR_SYNTAX 2
-#define RJS_ERROR_NOTAFUNCTION 3
-#define RJS_ERROR_NOTAFUNCTIONCALL 4
-#define RJS_ERROR_NOTALOOP 5
-#define RJS_ERROR_NOTAIFSTATEMENT 6
typedef struct rjs_coctx_s {
rulong type;
} rjs_coctx_iteration_t;
-typedef struct rjs_coerror_s {
- rlong code;
- const rchar *script;
- rlong scriptsize;
-} rjs_coerror_t;
-
typedef struct rjs_compiler_s rjs_compiler_t;
typedef rint (*RJS_COMPILER_RH)(rjs_compiler_t *co, rarray_t *records, rlong rec);
rvm_codegen_t *cg;
rvm_scope_t *scope;
rarray_t *coctx;
- rarray_t *errors;
rchar *temp;
rlong headoff;
rlong opcode;
--- /dev/null
+#ifndef _RJSERROR_H_
+#define _RJSERROR_H_
+
+
+#define RJS_ERRORTYPE_NONE 0
+#define RJS_ERRORTYPE_SYNTAX 1
+#define RJS_ERRORTYPE_RUNTIME 2
+
+
+#define RJS_ERROR_NONE 0
+#define RJS_ERROR_UNDEFINED 1
+#define RJS_ERROR_SYNTAX 2
+#define RJS_ERROR_NOTAFUNCTION 3
+#define RJS_ERROR_NOTAFUNCTIONCALL 4
+#define RJS_ERROR_NOTALOOP 5
+#define RJS_ERROR_NOTAIFSTATEMENT 6
+
+
+typedef struct rjs_error_s {
+ rlong type;
+ rlong error;
+ rlong offset;
+ rlong line;
+ rlong lineoffset;
+} rjs_error_t;
+
+
+#endif /* RJSERROR_H_ */
void rjs_display_errors(rjs_engine_t *jse, rstr_t *script)
{
- rlong line = 0;
rlong i;
- rjs_coerror_t *err;
-
- for (i = 0; i < r_array_length(jse->co->errors); i++) {
- err = (rjs_coerror_t *)r_array_slot(jse->co->errors, i);
- line = jrs_offset2line(script->str, (rlong)(err->script - script->str));
- fprintf(stdout, "Line: %ld (%ld, %ld), Error Code: %ld, ", (rlong)line, (rlong)(err->script - script->str), (rlong)err->scriptsize, err->code);
- fprintf(stdout, "%s: ", errormsg[err->code]);
- fwrite(err->script, sizeof(rchar), err->scriptsize, stdout);
+ rjs_error_t *err;
+
+ for (i = 0; i < r_array_length(jse->errors); i++) {
+ err = (rjs_error_t *)r_array_slot(jse->errors, i);
+ fprintf(stdout, "Line: %ld (%ld, %ld), Error Code: %ld, ", (rlong)err->line, err->offset, err->lineoffset, err->error);
+ fprintf(stdout, "%s: ", errormsg[err->error]);
+ fwrite(script->str + err->lineoffset, sizeof(rchar), err->offset - err->lineoffset, stdout);
fprintf(stdout, "\n");
}
}
}
end:
- if (jse->co && r_array_length(jse->co->errors))
+ if (jse && r_array_length(jse->errors))
rjs_display_errors(jse, script);
rjs_engine_destroy(jse);
if (unmapscript)
#include "rmem.h"
#include "rjsrules.h"
#include "rjsparser.h"
+#include "rjserror.h"
void rjs_parser_dbex_error(rjs_parser_t *parser)
}
-rlong rjs_parser_exec(rjs_parser_t *parser, const rchar *script, rsize_t size, rarray_t **ast)
+rlong jrs_parser_offset2line(const rchar *script, rlong offset)
+{
+ rlong line = 1;
+ const rchar *ptr;
+
+ for (line = 1, ptr = script + offset; ptr >= script; --ptr) {
+ if (*ptr == '\n')
+ line += 1;
+ }
+
+ return line;
+}
+
+
+rlong jrs_parser_offset2lineoffset(const rchar *script, rlong offset)
+{
+ rlong lineoffset = 0;
+ const rchar *ptr;
+
+ for (lineoffset = 0, ptr = script + offset; ptr > script; --ptr) {
+ if (*ptr == '\n')
+ break;
+ lineoffset += 1;
+ }
+ return offset - lineoffset;
+}
+
+
+rlong rjs_parser_exec(rjs_parser_t *parser, const rchar *script, rsize_t size, rarray_t *ast, rjs_error_t *error)
{
rlong res = 0;
rpastat_t *stat = rpa_stat_create(parser->dbex, 4096);
res = rpa_stat_parse(stat, rpa_dbex_last(parser->dbex), script, script, script + size, ast);
+ if (res < 0 && error) {
+ rpa_errinfo_t rpaerror;
+ rpa_stat_lasterrorinfo(stat, &rpaerror);
+ if (rpaerror.code == RPA_E_RULEABORT) {
+ error->type = RJS_ERRORTYPE_SYNTAX;
+ error->error = RJS_ERROR_SYNTAX;
+ error->offset = rpaerror.offset;
+ error->line = jrs_parser_offset2line(script, error->offset);
+ error->lineoffset = jrs_parser_offset2lineoffset(script, error->offset);
+ }
+ }
rpa_stat_destroy(stat);
return res;
}
#include "rarray.h"
#include "rvmcpu.h"
#include "rpa.h"
+#include "rjserror.h"
typedef struct rjs_parser_s {
rjs_parser_t *rjs_parser_create();
void rjs_parser_destroy(rjs_parser_t *parser);
-rlong rjs_parser_exec(rjs_parser_t *parser, const rchar *script, rsize_t size, rarray_t **ast);
+rlong rjs_parser_exec(rjs_parser_t *parser, const rchar *script, rsize_t size, rarray_t *ast, rjs_error_t *error);
#ifdef __cplusplus
cache->entry[bucket].recsize = size;
cache->entry[bucket].serial = cache->serial;
r_array_setlength(cacherecords, 0);
- for (i = 0; i < size; i++) {
- r_array_add(cacherecords, r_array_slot(records, startrec + i));
+ if (records) {
+ for (i = 0; i < size; i++) {
+ r_array_add(cacherecords, r_array_slot(records, startrec + i));
+ }
}
-
}
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R3, R0, XX, 0)); // |
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, R_OTP, XX, 0)); // |
rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, exp.loopidx, rvm_asm(RVM_B, DA, XX, XX, 0)); // |
- rvm_codegen_redefinelabel_default(co->cg, exp.failidx); // |
+ rvm_codegen_redefinelabel_default(co->cg, exp.failidx); // |
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_REC, R1, XX, 0)); // <-------------------------------------
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));
rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_BGRE, DA, XX, XX, 3));
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));
- rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
+ if (exp.rulepref && (exp.rulepref->flags & RPA_RFLAG_ABORTONFAIL)) {
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_ABORT, DA, R_OTP, R0, 0));
+ } else {
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
+ }
rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, R_TOP, R_TOP, R3, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
return 0;
rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_REC, R1, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));
+ if (exp.rulepref && (exp.rulepref->flags & RPA_RFLAG_ABORTONFAIL)) {
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_ABORT, DA, R_OTP, R0, 0));
+ }
rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
rvm_codegen_redefinelabel_default(co->cg, exp.endidx);
rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, LR, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_OTP, R_TOP, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RPA_SETCACHE, DA, R_REC, R_REC, exp.start));
+ if (exp.rulepref && (exp.rulepref->flags & RPA_RFLAG_ABORTONFAIL)) {
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_ABORT, DA, R_OTP, R0, 0));
+ }
rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
return 0;
}
rpa_compiler_t *co;
rpa_parser_t *pa;
rarray_t *records;
+ rarray_t *temprecords;
rharray_t *rules;
rarray_t *recstack;
rarray_t *inlinestack;
static rparecord_t *rpa_dbex_record(rpadbex_t *dbex, rlong rec);
static rint rpa_dbex_rulename(rpadbex_t *dbex, rlong rec, const rchar **name, rsize_t *namesize);
static rint rpa_parseinfo_loopdetect(rpadbex_t *dbex, rlong parent, rlong loopto);
-static rlong rpa_dbex_play_recordhandler(rpadbex_t *dbex, rlong rec);
-static rlong rpa_dbex_play_recordhandlers(rpadbex_t *dbex, rlong rec, rlong nrecs);
static rlong rpa_dbex_firstinlined(rpadbex_t *dbex);
static rint rpa_dbex_findinlined(rpadbex_t *dbex, rlong startrec);
static rint rpa_dbex_playchildrecords(rpadbex_t *dbex, rlong rec);
}
+static rint rpa_dbex_rh_abort(rpadbex_t *dbex, rlong rec)
+{
+ const rchar *name = NULL;
+ rsize_t namesize;
+ rarray_t *records = dbex->records;
+ rparecord_t *prec;
+
+ rec = rpa_recordtree_get(records, rec, RPA_RECORD_START);
+ prec = rpa_dbex_record(dbex, rec);
+ R_ASSERT(prec);
+ rpa_dbex_debug_recordhead(dbex, rec);
+ if (rpa_dbex_rulename(dbex, rec, &name, &namesize) < 0) {
+ return -1;
+ }
+ rpa_compiler_rulepref_set_flag(dbex->co, name, namesize, RPA_RFLAG_ABORTONFAIL);
+ rpa_dbex_debug_recordtail(dbex, rec);
+ if (rpa_dbex_playchildrecords(dbex, rec) < 0)
+ return -1;
+ rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+ prec = rpa_dbex_record(dbex, rec);
+ R_ASSERT(prec);
+ rpa_dbex_debug_recordhead(dbex, rec);
+ rpa_dbex_debug_recordtail(dbex, rec);
+ return 0;
+}
+
+
static rint rpa_dbex_rh_emit(rpadbex_t *dbex, rlong rec)
{
const rchar *name = NULL;
dbex->co = rpa_compiler_create();
dbex->pa = rpa_parser_create();
dbex->records = r_array_create(sizeof(rparecord_t));
+ dbex->temprecords = r_array_create(sizeof(rparecord_t));
dbex->rules = r_harray_create(sizeof(rpa_ruleinfo_t));
dbex->recstack = r_array_create(sizeof(rulong));
dbex->inlinestack = r_array_create(sizeof(rulong));
dbex->handlers[RPA_PRODUCTION_REQOP] = rpa_dbex_rh_exp;
dbex->handlers[RPA_PRODUCTION_MINOP] = rpa_dbex_rh_minexp;
dbex->handlers[RPA_PRODUCTION_DIRECTIVEEMIT] = rpa_dbex_rh_emit;
+ dbex->handlers[RPA_PRODUCTION_DIRECTIVEABORT] = rpa_dbex_rh_abort;
dbex->handlers[RPA_PRODUCTION_DIRECTIVENOEMIT] = rpa_dbex_rh_noemit;
dbex->handlers[RPA_PRODUCTION_DIRECTIVEEMITALL] = rpa_dbex_rh_emitall;
dbex->handlers[RPA_PRODUCTION_DIRECTIVEEMITNONE] = rpa_dbex_rh_emitnone;
rpa_parser_destroy(dbex->pa);
r_harray_destroy(dbex->rules);
r_array_destroy(dbex->records);
+ r_array_destroy(dbex->temprecords);
r_array_destroy(dbex->recstack);
r_array_destroy(dbex->inlinestack);
r_free(dbex->handlers);
}
-static void rpa_dbex_copyrecords(rpadbex_t *dbex, rarray_t *records)
+static void rpa_dbex_copyrecords(rpadbex_t *dbex)
{
rint i;
+ rarray_t *records = dbex->temprecords;
+
for (i = rpa_recordtree_get(records, 0, RPA_RECORD_START); i >= 0; i = rpa_recordtree_next(records, i, RPA_RECORD_START))
rpa_recordtree_walk(records, i, 0, rpa_dbex_copy_handler, dbex);
}
RPA_DBEX_SETERRINFO_CODE(dbex, RPA_E_NOTOPEN);
return -1;
}
- if ((ret = rpa_parser_load(dbex->pa, rules, size)) < 0) {
+ r_array_setlength(dbex->temprecords, 0);
+ if ((ret = rpa_parser_load(dbex->pa, rules, size, dbex->temprecords)) < 0) {
return -1;
}
RPA_DBEX_SETERRINFO_OFFSET(dbex, ret);
return -1;
}
- rpa_dbex_copyrecords(dbex, dbex->pa->stat->records);
+ rpa_dbex_copyrecords(dbex);
return ret;
}
}
-static rlong rpa_dbex_play_recordhandler(rpadbex_t *dbex, rlong rec)
-{
- rparecord_t *prec = (rparecord_t *) r_array_slot(dbex->records, rec);
- rpa_dbex_recordhandler handler = dbex->handlers[prec->ruleuid];
- if (handler) {
- if (handler(dbex, rec) < 0)
- return -1;
- }
- return 0;
-}
-
-
-static rlong rpa_dbex_play_recordhandlers(rpadbex_t *dbex, rlong rec, rlong nrecs)
-{
- rparecord_t *prec;
- rlong i, res = 0;
-
- for (i = rec; i < rec + nrecs; i++) {
- prec = (rparecord_t *) r_array_slot(dbex->records, i);
-
- if (prec->ruleuid == RPA_PRODUCTION_MINOP && (prec->type & RPA_RECORD_START)) {
- rlong lastchild = rpa_recordtree_lastchild(dbex->records, i, RPA_RECORD_START);
- rlong firstchild = rpa_recordtree_firstchild(dbex->records, i, RPA_RECORD_START);
- if (firstchild < 0 || lastchild < 0 || firstchild == lastchild)
- return -1;
- if ((res = rpa_dbex_play_recordhandler(dbex, i)) < 0)
- return -1;
- if ((res = rpa_dbex_play_recordhandlers(dbex, lastchild, rpa_recordtree_size(dbex->records, lastchild))) < 0)
- return -1;
- if ((res = rpa_dbex_play_recordhandlers(dbex, firstchild, lastchild - firstchild)) < 0)
- return -1;
- if ((res = rpa_dbex_play_recordhandler(dbex, rpa_recordtree_get(dbex->records, i, RPA_RECORD_END))) < 0)
- return -1;
- i += rpa_recordtree_size(dbex->records, i) - 1;
- continue;
- }
-
- if (rpa_dbex_play_recordhandler(dbex, i) < 0)
- return -1;
- }
-
- return i;
-}
-
-
static rint rpa_dbex_compile_rule(rpadbex_t *dbex, rparule_t rid)
{
rlong codeoff;
#define RPA_E_UNRESOLVED_SYMBOL 1007
#define RPA_E_PARAM 1008
+#define RPA_E_EXECUTION 2000
#define RPA_E_USERABORT 2001
+#define RPA_E_RULEABORT 2002
/**
* \typedef rpaerror_t
}
-rlong rpa_parser_load(rpa_parser_t *pa, const rchar *prods, rsize_t size)
+rlong rpa_parser_load(rpa_parser_t *pa, const rchar *prods, rsize_t size, rarray_t *records)
{
rlong ret = 0;
rpa_compiler_t *co = pa->co;
rpastat_t *stat = pa->stat;
- rpa_stat_init(stat, prods, prods, prods + size);
rpa_stat_cachedisable(stat, 0);
-
- if (rpa_stat_exec(stat, rvm_codegen_getcode(co->cg, 0), pa->main) < 0)
+ if (rpa_stat_exec(stat, rvm_codegen_getcode(co->cg, 0), pa->main, prods, prods, prods + size, records) < 0)
return -1;
ret = (rlong)RVM_CPUREG_GETL(stat->cpu, R0);
if (ret < 0)
}
-rlong rpa_parser_load_s(rpa_parser_t *pa, const rchar *prods)
+rlong rpa_parser_load_s(rpa_parser_t *pa, const rchar *prods, rarray_t *records)
{
- return rpa_parser_load(pa, prods, r_strlen(prods));
+ return rpa_parser_load(pa, prods, r_strlen(prods), records);
}
rpa_compiler_branch_end(co);
rpa_compiler_branch_begin(co, RPA_MATCH_NONE);
+ rpa_compiler_reference_nan_s(co, "abort");
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rpa_compiler_branch_end(co);
+
+
+ rpa_compiler_branch_begin(co, RPA_MATCH_NONE);
rpa_compiler_reference_nan_s(co, "emitid");
rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rpa_compiler_branch_end(co);
}
+static void rpa_production_directive_abort(rpa_parser_t *pa)
+{
+ rpa_compiler_t *co = pa->co;
+
+ rpa_compiler_rulepref_set_ruleuid_flags_s(co, "abort", RPA_PRODUCTION_DIRECTIVEABORT, RPA_RFLAG_EMITRECORD);
+ rpa_compiler_rule_begin_s(co, "abort");
+
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, '#'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rpa_compiler_reference_opt_s(co, "space");
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, '!'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rpa_compiler_reference_opt_s(co, "space");
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'b'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'o'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'r'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 't'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rpa_compiler_reference_nan_s(co, "space");
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rpa_compiler_reference_nan_s(co, "rulename");
+
+ rpa_compiler_rule_end(co);
+}
+
+
static void rpa_production_directive_emitall(rpa_parser_t *pa)
{
rpa_compiler_t *co = pa->co;
rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'A', 'Z'));
rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, '_'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+
rpa_compiler_class_end(co);
rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, '0', '9'));
rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, '_'));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
rpa_compiler_class_end(co);
rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rpa_production_directive_emit(pa);
rpa_production_directive_noemit(pa);
rpa_production_directive_emitid(pa);
+ rpa_production_directive_abort(pa);
rpa_production_directives(pa);
rpa_production_char(pa);
rpa_production_clsnum(pa);
RPA_PRODUCTION_DIRECTIVENOEMIT,
RPA_PRODUCTION_DIRECTIVEEMITNONE,
RPA_PRODUCTION_DIRECTIVEEMITALL,
+ RPA_PRODUCTION_DIRECTIVEABORT,
RPA_PRODUCTION_DIRECTIVEEMITID,
rpa_parser_t *rpa_parser_create();
void rpa_parser_destroy(rpa_parser_t *pa);
-rlong rpa_parser_load(rpa_parser_t *pa, const rchar *prods, rsize_t size);
-rlong rpa_parser_load_s(rpa_parser_t *pa, const rchar *prods);
+rlong rpa_parser_load(rpa_parser_t *pa, const rchar *prods, rsize_t size, rarray_t *records);
+rlong rpa_parser_load_s(rpa_parser_t *pa, const rchar *prods, rarray_t *records);
#ifdef __cplusplus
}
r_printf(" %s\n", buffer);
return;
}
+
+
+rarray_t *rpa_record_array()
+{
+ rarray_t *records;
+
+ records = r_array_create(sizeof(rparecord_t));
+ return records;
+}
rlong rpa_record_getusertype(rarray_t *records, rlong rec);
rint rpa_record_optchar(rparecord_t *prec, rint defc);
rint rpa_record_loopchar(rparecord_t *prec, rint defc);
+rarray_t *rpa_record_array();
#ifdef __cplusplus
}
#endif
#include "rcharconv.h"
-#define RPA_STAT_SETERROR_CODE(__s__, __e__) do { (__s__)->error = __e__; } while (0)
-
-
rpastat_t *rpa_stat_create(rpadbex_t *dbex, rulong stacksize)
{
rpastat_t *stat = (rpastat_t *) r_zmalloc(sizeof(*stat));
return NULL;
}
stat->dbex = dbex;
- stat->records = r_array_create(sizeof(rparecord_t));
- stat->emitstack = r_array_create(sizeof(rlong));
- stat->orphans = r_array_create(sizeof(rlong));
stat->cpu->userdata1 = stat;
-
return stat;
}
if (stat) {
if (stat->instack)
r_free(stat->instackbuffer);
- r_array_destroy(stat->records);
- r_array_destroy(stat->emitstack);
- r_array_destroy(stat->orphans);
rpavm_cpu_destroy(stat->cpu);
rpa_cache_destroy(stat->cache);
r_free(stat);
}
-rint rpa_stat_init(rpastat_t *stat, const rchar *input, const rchar *start, const rchar *end)
+rint rpa_stat_init(rpastat_t *stat, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
{
rulong size;
if (input < start || input > end) {
return -1;
}
+ r_memset(&stat->err, 0, sizeof(stat->err));
size = end - start;
stat->start = start;
stat->end = end;
stat->input = input;
- stat->error = 0;
- r_array_setlength(stat->orphans, 0);
- r_array_setlength(stat->emitstack, 0);
stat->cache->hit = 0;
+ stat->records = records;
if (stat->instacksize < size) {
stat->instackbuffer = r_realloc(stat->instackbuffer, (size + 2) * sizeof(rpainput_t));
stat->instacksize = size + 1;
}
stat->ip.input = input;
stat->ip.serial = 0;
+ RVM_CPUREG_SETL(stat->cpu, R_REC, 0);
+ RVM_CPUREG_SETU(stat->cpu, SP, 0);
+ RVM_CPUREG_SETU(stat->cpu, FP, 0);
+ RVM_CPUREG_SETU(stat->cpu, R_LOO, 0);
+ RVM_CPUREG_SETU(stat->cpu, R_TOP, -1);
+ if (stat->records) {
+ RVM_CPUREG_SETL(stat->cpu, R_REC, (rlong)(r_array_length(stat->records) - 1));
+ }
return 0;
}
}
-rint rpa_stat_encodingset(rpastat_t *stat, ruint encoding)
+rint rpa_stat_setencoding(rpastat_t *stat, ruint encoding)
{
if (!stat) {
return -1;
}
-static rparecord_t *rpa_stat_nextrecord(rpastat_t *stat, rparecord_t *cur)
-{
- if (r_array_empty(stat->records))
- return NULL;
- if (cur == NULL) {
- return (rparecord_t *)r_array_slot(stat->records, 0);
- }
- if (cur >= (rparecord_t *)r_array_lastslot(stat->records) || cur < (rparecord_t *)r_array_slot(stat->records, 0))
- return NULL;
- R_ASSERT(cur->next);
- cur = (rparecord_t *)r_array_slot(stat->records, cur->next);
- if (cur->type == RPA_RECORD_TAIL)
- return NULL;
- return cur;
-}
-
-
-static void rpa_stat_fixrecords(rpastat_t *stat)
-{
- rarray_t *records;
- rparecord_t *cur = (rparecord_t *)r_array_slot(stat->records, 0);
-
- return;
- cur = rpa_stat_nextrecord(stat, cur);
- if (!cur) {
- /*
- * There are no records
- */
- r_array_setlength(stat->records, 0);
- return;
- }
- records = (rarray_t *)r_array_create(sizeof(rparecord_t));
- while (cur) {
- r_array_add(records, cur);
- cur = rpa_stat_nextrecord(stat, cur);
- }
- r_array_destroy(stat->records);
- stat->records = records;
-}
-
-
-
-rlong rpa_stat_exec(rpastat_t *stat, rvm_asmins_t *prog, rword off)
+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)
{
rlong ret;
return -1;
}
rpa_stat_cacheinvalidate(stat);
- r_array_setlength(stat->records, 0);
- RVM_CPUREG_SETU(stat->cpu, SP, 0);
- RVM_CPUREG_SETU(stat->cpu, FP, 0);
- RVM_CPUREG_SETL(stat->cpu, R_REC, -1);
- RVM_CPUREG_SETU(stat->cpu, R_LOO, 0);
- RVM_CPUREG_SETU(stat->cpu, R_TOP, -1);
+ rpa_stat_init(stat, input, start, end, records);
if (stat->debug) {
ret = rvm_cpu_exec_debug(stat->cpu, prog, off);
} else {
ret = rvm_cpu_exec(stat->cpu, prog, off);
}
if (ret < 0) {
- if (stat->cpu->error == RVM_E_USERABORT)
- RPA_STAT_SETERROR_CODE(stat, RPA_E_USERABORT);
- else
- RPA_STAT_SETERROR_CODE(stat, stat->cpu->error);
- r_array_setlength(stat->records, 0);
+ if (!stat->cpu->error) {
+ if (stat->cpu->error) {
+ RPA_STAT_SETERROR_CODE(stat, stat->cpu->error);
+ } else {
+ /*
+ * We should never get to here. Error have to be more
+ * specific and set at the places they are detected.
+ */
+ RPA_STAT_SETERROR_CODE(stat, RPA_E_EXECUTION);
+ }
+ }
return -1;
}
- rpa_stat_fixrecords(stat);
ret = (rlong)RVM_CPUREG_GETL(stat->cpu, R0);
if (ret < 0) {
- r_array_setlength(stat->records, 0);
return 0;
}
return ret;
}
-static rlong rpa_stat_exec_noinit(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end)
+static rlong rpa_stat_exec_rid(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
{
rlong topsiz = 0;
rpainput_t *ptp;
- rpa_stat_init(stat, input, start, end);
- if ((topsiz = rpa_stat_exec(stat, rpa_dbex_executable(stat->dbex), rpa_dbex_executableoffset(stat->dbex, rid))) < 0) {
+ if ((topsiz = rpa_stat_exec(stat, rpa_dbex_executable(stat->dbex), rpa_dbex_executableoffset(stat->dbex, rid), input, start, end, records)) < 0) {
return -1;
}
if (topsiz <= 0)
{
rlong ret;
- if (!stat) {
- return -1;
- }
while (input < end) {
- ret = rpa_stat_exec_noinit(stat, rid, input, start, end);
+ ret = rpa_stat_exec_rid(stat, rid, input, start, end, NULL);
if (ret < 0)
return -1;
if (ret > 0) {
rlong rpa_stat_match(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end)
{
- if (!stat) {
- return -1;
- }
-
- return rpa_stat_exec_noinit(stat, rid, input, start, end);
+ return rpa_stat_exec_rid(stat, rid, input, start, end, NULL);
}
-rlong rpa_stat_parse(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, rarray_t **records)
+rlong rpa_stat_parse(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, rarray_t *records)
{
- rint res = 0;
-
- if (!stat) {
- return -1;
- }
-
- res = rpa_stat_exec_noinit(stat, rid, input, start, end);
- if (res > 0 && !r_array_empty(stat->records) && records) {
- *records = stat->records;
- stat->records = r_array_create(sizeof(rparecord_t));
- }
- return res;
+ return rpa_stat_exec_rid(stat, rid, input, start, end, records);
}
if (!stat) {
return -1;
}
-
+ RPA_STAT_SETERROR_CODE(stat, RPA_E_USERABORT);
rvm_cpu_abort(stat->cpu);
return 0;
}
return top;
}
+
+
+rlong rpa_stat_lasterror(rpastat_t *stat)
+{
+ if (!stat)
+ return -1;
+ return stat->err.code;
+}
+
+
+rlong rpa_stat_lasterrorinfo(rpastat_t *stat, rpa_errinfo_t *errinfo)
+{
+ if (!stat || !errinfo)
+ return -1;
+ r_memcpy(errinfo, &stat->err, sizeof(rpa_errinfo_t));
+ return 0;
+}
void rpa_stat_destroy(rpastat_t *stat);
-rint rpa_stat_encodingset(rpastat_t *stat, ruint encoding);
rlong rpa_stat_scan(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, const rchar **where);
+rlong rpa_stat_parse(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, rarray_t *records);
rlong rpa_stat_match(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end);
-rlong rpa_stat_parse(rpastat_t *stat, rparule_t rid, const rchar *input, const rchar *start, const rchar *end, rarray_t **records);
+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);
rint rpa_stat_abort(rpastat_t *stat);
-rlong rpa_stat_exec(rpastat_t *stat, rvm_asmins_t *prog, rword off);
+rint rpa_stat_setencoding(rpastat_t *stat, ruint encoding);
+
+
+/**
+ * \brief Return the error code of the last occurred error.
+ *
+ * \param dbex Pointer to \ref rpadbex_t object.
+ * \return The error code of the last occurred error. If this function fails the
+ * return value is negative.
+ */
+rlong rpa_stat_lasterror(rpastat_t *stat);
+
+/**
+ * \brief Get error information for the last occurred error.
+ *
+ * \param dbex Pointer to \ref rpadbex_t object.
+ * \param errinfo Pointer to \ref rpa_errinfo_t buffer that will be
+ * filled with the error information. This parameter cannot be NULL.
+ * \return Return 0 if the function is successful or negative otherwise. If this function fails the
+ * return value is negative.
+ */
+rlong rpa_stat_lasterrorinfo(rpastat_t *stat, rpa_errinfo_t *errinfo);
#ifdef __cplusplus
extern "C" {
#endif
+#define RPA_STAT_SETERROR_CODE(__d__, __e__) do { (__d__)->err.code = __e__; } while (0)
+#define RPA_STAT_SETERRINFO_OFFSET(__d__, __o__) do { (__d__)->err.offset = __o__; (__d__)->err.mask |= RPA_ERRINFO_OFFSET; } while (0)
+#define RPA_STAT_SETERRINFO_RULEUID(__d__, __r__) do { (__d__)->err.ruleid = __r__; (__d__)->err.mask |= RPA_ERRINFO_RULEID; } while (0)
+#define RPA_STAT_SETERRINFO_NAME(__d__, __n__, __s__) do { \
+ (__d__)->err.mask |= RPA_ERRINFO_NAME; \
+ r_memset((__d__)->err.name, 0, sizeof((__d__)->err.name)); \
+ r_strncpy((__d__)->err.name, __n__, R_MIN(__s__, (sizeof((__d__)->err.name) - 1))); } while (0)
struct rpastat_s {
rpadbex_t *dbex;
const rchar *input;
const rchar *start;
const rchar *end;
- ruint error;
+ rpa_errinfo_t err;
ruint encoding;
ruint debug;
rarray_t *records;
- rarray_t *emitstack;
- rarray_t *orphans;
rpainput_t *instackbuffer;
rpainput_t *instack; /* instack = &instackbuffer[1]; This allows R_TOP = -1, without any additional checks */
rulong instacksize;
rvmcpu_t *cpu;
};
-rint rpa_stat_init(rpastat_t *stat, const rchar *input, const rchar *start, const rchar *end);
+rint rpa_stat_init(rpastat_t *stat, const rchar *input, const rchar *start, const rchar *end, rarray_t *records);
void rpa_stat_cachedisable(rpastat_t *stat, ruint disable);
void rpa_stat_cacheinvalidate(rpastat_t *stat);
rint rpa_stat_matchchr(rpastat_t *stat, rssize_t top, rulong wc);
static void rpavm_swi_emittail(rvmcpu_t *cpu, rvm_asmins_t *ins)
{
- rparecord_t *rec;
rpastat_t *stat = (rpastat_t *)cpu->userdata1;
rlong index = RVM_CPUREG_GETL(cpu, R_REC);
- index = r_array_replace(stat->records, index + 1, NULL);
- RVM_CPUREG_SETL(cpu, R_REC, index);
- rec = (rparecord_t *)r_array_slot(stat->records, index);
- rec->type = RPA_RECORD_TAIL;
- r_array_setlength(stat->records, index);
+ if (stat->records)
+ r_array_setlength(stat->records, index + 1);
+}
+
+
+static void rpavm_swi_abort(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+ rpa_ruledata_t *ruledata = RVM_CPUREG_GETP(cpu, ins->op1);
+ rstr_t name = {(rchar*)ruledata + ruledata->name, ruledata->namesize};
+ rpastat_t *stat = (rpastat_t *)cpu->userdata1;
+ rlong index = RVM_CPUREG_GETL(cpu, R_REC);
+ rword tp = RVM_CPUREG_GETU(cpu, ins->op2);
+
+
+ if (stat->records)
+ r_array_setlength(stat->records, index + 1);
+ RPA_STAT_SETERROR_CODE(stat, RPA_E_RULEABORT);
+ RPA_STAT_SETERRINFO_RULEUID(stat, ruledata->ruleuid);
+ if (name.str) {
+ RPA_STAT_SETERRINFO_NAME(stat, name.str, name.size);
+ }
+ if (stat->instack[tp].input) {
+ RPA_STAT_SETERRINFO_OFFSET(stat, stat->instack[tp].input - stat->start);
+ }
+ rvm_cpu_abort(cpu);
}
if (stat->debug)
r_printf("%ld: %s, %s, tp = %ld\n", RVM_CPUREG_GETU(cpu, FP), "START", name.str, tp);
- if (!(ruledata->flags & RPA_RFLAG_EMITRECORD))
+ if (!stat->records || !(ruledata->flags & RPA_RFLAG_EMITRECORD))
return;
index = r_array_replace(stat->records, index + 1, NULL);
if (stat->debug)
r_printf("%ld: %s, %s, tp = %ld, tplen = %ld\n", RVM_CPUREG_GETU(cpu, FP), "END ", name.str, tp, tplen);
- if (!(ruledata->flags & RPA_RFLAG_EMITRECORD))
+ if (!stat->records || !(ruledata->flags & RPA_RFLAG_EMITRECORD))
return;
index = r_array_replace(stat->records, index + 1, NULL);
}
-static void rpavm_swi_getnextrec(rvmcpu_t *cpu, rvm_asmins_t *ins)
-{
- rpastat_t *stat = (rpastat_t *)cpu->userdata1;
- rlong rec = RVM_CPUREG_GETL(cpu, ins->op2);
-
- rparecord_t *prec = (rparecord_t *)r_array_slot(stat->records, rec);
-
-// r_printf("%s, rec = %ld, next = %ld\n", __FUNCTION__, rec, prec->next);
- RVM_CPUREG_SETL(cpu, ins->op1, prec->next);
-}
-
-
static void rpavm_swi_setcache(rvmcpu_t *cpu, rvm_asmins_t *ins)
{
rpastat_t *stat = (rpastat_t *)cpu->userdata1;
if (r0 > 0) {
if (entry->recsize) {
long i;
- r_array_setlength(stat->records, RVM_CPUREG_GETL(cpu, R_REC) + 1);
- for (i = 0; i < r_array_length(entry->records); i++) {
- r_array_add(stat->records, r_array_slot(entry->records, i));
+ if (stat->records) {
+ r_array_setlength(stat->records, RVM_CPUREG_GETL(cpu, R_REC) + 1);
+ for (i = 0; i < r_array_length(entry->records); i++) {
+ r_array_add(stat->records, r_array_slot(entry->records, i));
+ }
}
RVM_CPUREG_SETL(cpu, R_REC, r_array_length(stat->records) - 1);
}
{"RPA_EMITSTART", rpavm_swi_emitstart},
{"RPA_EMITEND", rpavm_swi_emitend},
{"RPA_EMITTAIL", rpavm_swi_emittail},
- {"RPA_GETNEXTREC", rpavm_swi_getnextrec},
+ {"RPA_ABORT", rpavm_swi_abort},
{"RPA_PRNINFO", rpavm_swi_prninfo},
{NULL, NULL},
};
#define RPA_INLINE_REF (1<<5)
#define RPA_LOOP_INDERECTION 1024
#define RPA_RFLAG_EMITRECORD (1 << 0)
+#define RPA_RFLAG_ABORTONFAIL (1 << 2)
#define R_REC (TP - 3)
#define R_LOO (TP - 2)
#define RPA_EMITSTART RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 16))
#define RPA_EMITEND RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 17))
#define RPA_EMITTAIL RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 18))
-#define RPA_GETNEXTREC RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 19))
+#define RPA_ABORT RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 19))
#define RPA_PRNINFO RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 20))
-
-//#define RPA_GETRECLEN RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 19))
-//#define RPA_SETRECLEN RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 20))
-//#define RPA_GETCURREC RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 21))
-//#define RPA_SETCURREC RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 22))
-
-
typedef struct rpainput_s {
const rchar *input;
ruint32 wc;
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+30);
+ rpa_stat_init(stat, teststr, teststr, teststr+30, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+3);
+ rpa_stat_init(stat, teststr, teststr, teststr+3, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+3);
+ rpa_stat_init(stat, teststr, teststr, teststr+3, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
stat = rpa_stat_create(NULL, 4096);
rvm_cpu_addswitable(stat->cpu, "common_table", common_calltable);
- rpa_stat_init(stat, teststr, teststr, teststr+12);
+ rpa_stat_init(stat, teststr, teststr, teststr+12, NULL);
mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));