RPA Toolkit
added state information for optimized compilation and multiple rpa callback fixes.
authorMartin Stoilov <martin@rpasearch.com>
Mon, 17 Jan 2011 00:21:36 +0000 (16:21 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Mon, 17 Jan 2011 00:21:36 +0000 (16:21 -0800)
30 files changed:
rgrep/rpagrep.c
rgrep/rpagrep.h
rgrep/unix/main.c
rlib/build/linux/x86_64/Makefile
rlib/rarray.c
rlib/rarray.h
rlib/rcarray.c
rlib/rcarray.h
rpa/build/linux/x86_64/Makefile
rpa/rpacbrecord.h
rpa/rpadbex.c
rpa/rpadbexpriv.c
rpa/rpamatchlist.c
rpa/rpamatchlist.h
rpa/rpamnode.c
rpa/rpastat.c
rpa/rpastat.h
rvm/build/linux/x86_64/Makefile
rvm/rvmcpu.c
rvm/rvmcpu.h
rvm/rvmreg.h
rvm/rvmscope.c
rvm/rvmscope.h
tests/build/linux/robject-tests.mk
tests/build/linux/x86_64/Makefile
tests/ecma262.rpa
tests/rpagen-test.c
tests/speed-test.c [new file with mode: 0644]
tests/test.js
tests/test.php [new file with mode: 0644]

index 6dd2848..c4f7e3d 100644 (file)
@@ -391,15 +391,19 @@ static int rpa_callback_output(const char *name, void *userdata, const char *inp
 {
        rpa_grep_t *pGrep = (rpa_grep_t *)userdata;
 
+       if (reason & RPA_REASON_START)
+               rpa_grep_output_utf8_string(pGrep, "START ");
+       if (reason & RPA_REASON_MATCHED)
+               rpa_grep_output_utf8_string(pGrep, "MATCHED ");
+       if (reason & RPA_REASON_END)
+               rpa_grep_output_utf8_string(pGrep, "END ");
+       rpa_grep_output_utf8_string(pGrep, name);
+
        if (reason & RPA_REASON_MATCHED) {
-               rpa_grep_output_utf8_string(pGrep, name);
                rpa_grep_output_utf8_string(pGrep, ": ");
                rpa_grep_output(pGrep, input, size, pGrep->encoding);
-               rpa_grep_output_utf8_string(pGrep, "\n");
-       } else if (reason & RPA_REASON_START) {
-
        }
-
+       rpa_grep_output_utf8_string(pGrep, "\n");
 
        return size;
 }
@@ -411,6 +415,12 @@ void rpa_grep_setup_callback(rpa_grep_t *pGrep, rpa_buffer_t *pattern)
 }
 
 
+void rpa_grep_setup_matched_callback(rpa_grep_t *pGrep, rpa_buffer_t *pattern)
+{
+       rpa_dbex_add_callback(pGrep->hDbex, pattern->s, RPA_REASON_MATCHED, rpa_callback_output, pGrep);
+}
+
+
 void rpa_grep_dump_pattern_tree(rpa_grep_t *pGrep, rpa_buffer_t *pattern)
 {
        rpa_pattern_handle hPattern = rpa_dbex_get_pattern(pGrep->hDbex, pattern->s);
index 93ba3a8..ccbc5d9 100644 (file)
@@ -70,6 +70,7 @@ void rpa_grep_output(rpa_grep_t *pGrep, const char *s, unsigned long size, unsig
 void rpa_grep_output_utf8_string(rpa_grep_t *pGrep, const char *s);
 void rpa_grep_output_utf16_string(rpa_grep_t *pGrep, const unsigned short *s);
 void rpa_grep_setup_callback(rpa_grep_t *pGrep, rpa_buffer_t *pattern);
+void rpa_grep_setup_matched_callback(rpa_grep_t *pGrep, rpa_buffer_t *pattern);
 void rpa_grep_dump_pattern_tree(rpa_grep_t *pGrep, rpa_buffer_t *pattern);
 
 
index fa1ba7c..522e462 100644 (file)
@@ -45,6 +45,7 @@ int usage(int argc, const char *argv[])
                fprintf(stderr, "\t-e patterns         execute pattern\n");
                fprintf(stderr, "\t-f patternfile      read the patterns from a file, the last pattern will be executed\n");
                fprintf(stderr, "\t-c printpatterns    print these patterns when there is a match.\n");
+               fprintf(stderr, "\t-C printpatterns    print these patterns at START MATCH END.\n");
                fprintf(stderr, "\t-i                  ignore case.\n");                
                fprintf(stderr, "\t-m                  match from the beginning.\n");           
                fprintf(stderr, "\t-p                  parse the stream.\n");           
@@ -93,11 +94,23 @@ int main(int argc, const char *argv[])
                                rpa_buffer_t pattern;
                                pattern.s = (char*)argv[i];
                                pattern.size = strlen(argv[i]);                 
+                               rpa_grep_setup_matched_callback(pGrep, &pattern);
+                       }
+               }
+       }
+
+       for (i = 1; i < argc; i++) {
+               if (strcmp(argv[i], "-C") == 0) {
+                       if (++i < argc) {
+                               rpa_buffer_t pattern;
+                               pattern.s = (char*)argv[i];
+                               pattern.size = strlen(argv[i]);
                                rpa_grep_setup_callback(pGrep, &pattern);
                        }
                }
        }
 
+
        for (i = 1; i < argc; i++) {
                if (strcmp(argv[i], "-f") == 0) {
                        if (++i < argc) {
@@ -164,7 +177,7 @@ int main(int argc, const char *argv[])
                if (argv[i][0] != '-') {
                        ++scanned;
                        rpa_grep_scan_path(pGrep, argv[i]);
-               } else if (argv[i][1] == 'e' || argv[i][1] == 'f' || argv[i][1] == 'c'){
+               } else if (argv[i][1] == 'e' || argv[i][1] == 'f' || argv[i][1] == 'c' || argv[i][1] == 'C'){
                        ++i;
                }
                
index 785a672..a2c8f9f 100644 (file)
@@ -10,10 +10,15 @@ LD = ld
 
 ifeq ($(BLDCFG), release)
 CFLAGS := -fPIC -O3
+else 
+ifeq ($(BLDCFG), profile)
+CFLAGS := -fPIC -O0 -pg -Wall 
+CFLAGS += -DR_DEBUG_MEMALLOC
 else
 CFLAGS := -fPIC -O0 -g -Wall 
 CFLAGS += -DR_DEBUG_MEMALLOC
 endif
+endif
 
 ifeq ($(CCBLD), yes)
 CFLAGS += -fprofile-arcs -ftest-coverage
index 3b373fc..e220fa9 100644 (file)
@@ -78,7 +78,7 @@ rint r_array_add(rarray_t *array, rconstpointer data)
 }
 
 
-rint r_array_remove(rarray_t *array)
+rint r_array_removelast(rarray_t *array)
 {
        r_array_setlength(array, r_array_length(array) - 1);
        return r_array_length(array);
index 7c636f6..efa0f75 100644 (file)
@@ -28,16 +28,19 @@ struct rarray_s {
 #define r_array_length(__array__) ((__array__)->len)
 #define r_array_empty(__array__) ((r_array_length(__array__)) ? 0 : 1)
 #define r_array_last(__array__, __type__) (r_array_index(__array__, (__array__)->len - 1, __type__))
+#define r_array_inclast(__array__, __type__) (*((__type__*)(r_array_lastslot(__array__))) += 1)
+#define r_array_declast(__array__, __type__) (*((__type__*)(r_array_lastslot(__array__))) -= 1)
+
 #define r_array_index(__array__, __index__, __type__) (((__type__*)(void*)(__array__)->data)[__index__])
 #define r_array_slot(__array__, __index__) (((ruint8*)(__array__)->data) + (__array__)->elt_size * (__index__))
-#define r_array_lastslot(__array__) r_array_slot(__array__, r_array_length(__array__) - 1)
+#define r_array_lastslot(__array__) (r_array_length(__array__) ? r_array_slot(__array__, r_array_length(__array__) - 1) : NULL)
 #define r_array_push(__array__, __val__, __type__) do {__type__ __v__ = (__type__)__val__; r_array_add(__array__, &__v__); } while(0)
 #define r_array_pop(__array__, __type__) (r_array_index(__array__, (__array__)->len ? --(__array__)->len : 0, __type__))
 
 robject_t *r_array_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint elt_size);
 rarray_t *r_array_create(ruint elt_size);
 rint r_array_add(rarray_t *array, rconstpointer data);
-rint r_array_remove(rarray_t *array);
+rint r_array_removelast(rarray_t *array);
 rint r_array_insert(rarray_t *array, ruint index, rconstpointer data);
 rint r_array_replace(rarray_t *array, ruint index, rconstpointer data);
 void r_array_setlength(rarray_t *array, ruint len);
index 99c7576..c4b30df 100644 (file)
@@ -1,7 +1,7 @@
 #include "rcarray.h"
 #include "rmem.h"
 
-#define MIN_CARRAY_LEN 2
+#define MIN_CARRAY_LEN 2048
 
 
 
@@ -112,7 +112,21 @@ rint r_carray_add(rcarray_t *carray, rconstpointer data)
 void r_carray_setlength(rcarray_t *carray, ruint len)
 {
        r_carray_checkexpand(carray, len);
-       carray->len = len;
+       r_carray_length(carray) = len;
+}
+
+
+void r_carray_inclength(rcarray_t *carray)
+{
+       r_carray_checkexpand(carray, r_carray_length(carray) + 1);
+       r_carray_length(carray) += 1;
+}
+
+
+void r_carray_declength(rcarray_t *carray)
+{
+       if (r_carray_length(carray))
+               r_carray_length(carray) -= 1;
 }
 
 
index 3812e61..847cb87 100644 (file)
@@ -26,11 +26,11 @@ struct rcarray_s {
        ruint elt_size;
        r_carray_callback oncleanup;
        r_carray_callback oncopy;
-       rpointer *user;
+       rpointer *userdata;
 };
 
-#define r_carray_size(__carray__) ((__carray__)->alloc_size)
-#define r_carray_length(__carray__) ((__carray__)->len)
+#define r_carray_size(__carray__) (__carray__)->alloc_size
+#define r_carray_length(__carray__) (__carray__)->len
 #define r_carray_empty(__carray__) ((r_carray_length(__carray__)) ? 0 : 1)
 #define r_carray_slot(__carray__, __index__)(((rchar*)r_array_index((__carray__)->array, (__index__) >> R_CARRAY_CHUNKBITS, rpointer)) + ((__index__) & R_CARRAY_CHUNKMASK) * (__carray__)->elt_size)
 #define r_carray_index(__carray__, __index__, __type__) *((__type__*)r_carray_slot(__carray__, __index__))
@@ -40,6 +40,8 @@ rcarray_t *r_carray_create(ruint elt_size);
 rint r_carray_replace(rcarray_t *carray, ruint index, rconstpointer data);
 rint r_carray_add(rcarray_t *carray, rconstpointer data);
 void r_carray_setlength(rcarray_t *carray, ruint len);
+void r_carray_inclength(rcarray_t *carray);
+void r_carray_inclength(rcarray_t *carray);
 void *r_carray_slot_expand(rcarray_t *carray, ruint index);
 
 /*
index 85120be..fb42c57 100644 (file)
@@ -8,11 +8,16 @@ CC = gcc
 AR = ar
 LD = ld
 
+
 ifeq ($(BLDCFG), release)
 CFLAGS := -fPIC -O3
 else
+ifeq ($(BLDCFG), profile)
+CFLAGS := -fPIC -O0 -pg -Wall -DDEBUG
+else
 CFLAGS := -fPIC -O0 -g -Wall -DDEBUG
 endif
+endif
 
 ifeq ($(CCBLD), yes)
 CFLAGS += -fprofile-arcs -ftest-coverage
index 628bc65..a7c0457 100644 (file)
@@ -35,6 +35,7 @@ typedef struct rpa_cbrecord_s {
        rpa_mnode_t *mnode;
        const char *input;
        unsigned int size;
+       unsigned int reason;
 } rpa_cbrecord_t;
 
 
index f3e99e9..4651fbb 100644 (file)
@@ -63,7 +63,7 @@ void rpa_dbex_close_do(rpa_dbex_handle hDbex)
 void rpa_dbex_close(rpa_dbex_handle hDbex)
 {
        rpa_dbex_close_do(hDbex);
-       rpa_dbex_connect_callbacks(hDbex);
+//     rpa_dbex_connect_callbacks(hDbex);
 }
 
 
index d357577..fd4de9b 100644 (file)
@@ -121,31 +121,54 @@ error:
 }
 
 
-void rpa_mnode_connect_callback_dontuse(rpa_dbex_handle hDbex, rpa_mnode_t *mnode)
+void rpa_dbex_set_nlist_callbackptr(rpa_dbex_handle hDbex, rpa_match_nlist_t *nlistmatch)
 {
-       int ret = 0;
+       rpa_dbex_t strdbex;
+       rpa_pattern_handle hDefault;
        rpa_varlink_t *pCallback;
-       const char *name = (void*)0;
-       int size = name ? r_strlen(name) : 0;
-
-       if (!mnode || (mnode->flags & RPA_MNODE_NOCONNECT) || !mnode->match || !mnode->match->name)
-               return;
-       name = mnode->match->name;
-       size = mnode->match->namesiz;
-       for (pCallback = rpa_dbex_prev_callback(hDbex, 0); pCallback; pCallback = rpa_dbex_prev_callback(hDbex, pCallback)) {
+       const char *name;
+       int namelen, ret;
+       rpa_match_t *match = (rpa_match_t*)nlistmatch;
+
+       for (pCallback = rpa_dbex_next_callback(hDbex, 0); pCallback; pCallback = rpa_dbex_next_callback(hDbex, pCallback)) {
                rpa_callbackdata_t *pCbData = (rpa_callbackdata_t *)pCallback->var.v.ptr;
-               ret = rpa_dbex_strmatch(name, pCbData->namematch);
-               if (size && ret == size) {
-                       if (mnode->flags & RPA_MNODE_CALLBACK) {
-                               mnode->flags |= pCbData->reason;
-                               ((rpa_mnode_callback_t*)mnode)->matched_callback = rpa_common_callback;
-                               ((rpa_mnode_callback_t*)mnode)->userdata = pCallback;
+               if (pCbData->exact) {
+                       if (match->namesiz == pCbData->namematchsiz && r_strncmp(pCbData->namematch, match->name, match->namesiz) == 0) {
+                               nlistmatch->callback = (void*)pCallback;
+                       }
+               } else {
+                       rpa_dbex_init(&strdbex, 16);
+                       rpa_dbex_open(&strdbex);
+                       if (rpa_dbex_load_string(&strdbex, pCbData->namematch) < 0) {
+                               rpa_dbex_cleanup(&strdbex);
+                               continue;
                        }
-                       return;
+                       rpa_dbex_close_do(&strdbex);
+                       hDefault = rpa_dbex_default_pattern(&strdbex);
+                       name = match->name;
+                       namelen = match->namesiz;
+                       ret = rpa_stat_match_lite(&strdbex.stat, hDefault, name, name, name + namelen);
+                       if (namelen && ret == namelen && !nlistmatch->callback) {
+                               nlistmatch->callback = (void*)pCallback;
+                       }
+                       rpa_dbex_cleanup(&strdbex);
                }
-       }       
+       }
+}
 
 
+void rpa_dbex_mnode_connect(rpa_dbex_handle hDbex, rpa_mnode_callback_t *cbmnode)
+{
+       rpa_varlink_t *pCallback;
+       rpa_match_nlist_t *nlistmatch = (rpa_match_nlist_t *)((rpa_mnode_t*)cbmnode)->match;
+       pCallback = (rpa_varlink_t *)nlistmatch->callback;
+
+       if (pCallback) {
+               rpa_callbackdata_t *pCbData = (rpa_callbackdata_t *)pCallback->var.v.ptr;
+               ((rpa_mnode_t*)cbmnode)->flags |= pCbData->reason;
+               cbmnode->matched_callback = rpa_common_callback;
+               cbmnode->userdata = pCallback;
+       }
 }
 
 
@@ -421,8 +444,10 @@ rpa_varlink_t *rpa_dbex_create_mnode_callback(rpa_dbex_handle hDbex, rpa_match_t
        pVarLinkMnodePtr->var.userdata4 = (rpa_word_t)MATCH_CLASS_MNODEPTR;
        pVarLinkMnodePtr->var.finalize = rpa_var_class_destroy;
        rpa_list_addt(&hDbex->treehead, &pVarLinkMnodePtr->lnk);
-       if ((((rpa_mnode_t *)pCbMnode)->flags & RPA_MNODE_NOCONNECT) == 0)
+       if ((((rpa_mnode_t *)pCbMnode)->flags & RPA_MNODE_NOCONNECT) == 0) {
                rpa_list_addt(&hDbex->callbackmnodes, &pCbMnode->cblink);
+               rpa_dbex_mnode_connect(hDbex, pCbMnode);
+       }
        return pVarLinkMnodePtr;
 }
 
@@ -568,14 +593,17 @@ static rpa_word_t rpa_vmcb_create_ragnelist_matchptr(rpa_vm_t *vm)
 rpa_varlink_t *rpa_dbex_create_nlist_matchptr(rpa_dbex_handle hDbex, const char *name, unsigned int size, rpa_matchfunc_t match_function_id)
 {
        rpa_varlink_t *pVarLinkListMatchPtr;
+       rpa_match_nlist_t *nlistmatch;
 
        pVarLinkListMatchPtr = rpa_varlink_create(RPA_VAR_PTR, "NLIST");
        if (!pVarLinkListMatchPtr)
                return (void*)0;
-       if ((pVarLinkListMatchPtr->var.v.ptr = (void*) rpa_match_nlist_create_namesize(name, size, match_function_id)) == (void*)0) {
+       nlistmatch = (rpa_match_nlist_t *)rpa_match_nlist_create_namesize(name, size, match_function_id);
+       if ((pVarLinkListMatchPtr->var.v.ptr = (void*) nlistmatch) == (void*)0) {
                rpa_varlink_destroy(pVarLinkListMatchPtr);
                return (void*)0;
        }
+       rpa_dbex_set_nlist_callbackptr(hDbex, nlistmatch);
        pVarLinkListMatchPtr->var.userdata4 = (rpa_word_t)MATCH_CLASS_NAMEDMATCHPTR;
        pVarLinkListMatchPtr->var.finalize = rpa_var_class_destroy;
        rpa_list_addt(&hDbex->treehead, &pVarLinkListMatchPtr->lnk);
index cd1f923..8fc2eca 100644 (file)
@@ -159,12 +159,12 @@ int rpa_match_list_best_alt(rpa_match_t *match, rpa_stat_t *stat, const char *in
        rpa_list_t *pos;
        rpa_mnode_t *hcur, *best = NULL;
        int ret, mret = 0;
-       unsigned char cbdisable = stat->cbdisable;
+       unsigned char cbmod = stat->cbmod;
 
        /*
         * Disable callbacks while looking for the best match
         */
-       stat->cbdisable = 1;
+       stat->cbmod = RPA_CB_DISABLED;
        head = &((rpa_match_list_t *)match)->head;
        rpa_list_for_each(pos, head) {
                hcur = rpa_list_entry(pos, rpa_mnode_t, mlink);
@@ -178,7 +178,7 @@ int rpa_match_list_best_alt(rpa_match_t *match, rpa_stat_t *stat, const char *in
        /*
         * Restore the original state
         */
-       stat->cbdisable = cbdisable;
+       stat->cbmod = cbmod;
        if (best)
                mret = stat->ntable[best->flags & RPA_MNODEFUNC_MASK](best, stat, input);
 
index 0361dd2..8579010 100644 (file)
@@ -40,6 +40,7 @@ typedef struct rpa_match_list_s {
 typedef struct rpa_match_nlist_s {
        rpa_match_list_t base;
        unsigned char loopy;
+       void *callback;
 } rpa_match_nlist_t;
 
 rpa_match_t * rpa_match_list_create(const char *name, rpa_matchfunc_t match_function_id);
index 9f79261..dd39dc3 100644 (file)
@@ -28,7 +28,7 @@
 #include "rpadbex.h"
 
 
-#define RPA_MCACHE_SET(_c_, _m_, _i_, _r_, _d_) do {(_c_)->match = (_m_); (_c_)->input = (_i_); (_c_)->ret = (_r_); (_c_)->cbdisable = (_d_);} while (0)
+#define RPA_MCACHE_SET(_c_, _m_, _i_, _r_, _d_) do {(_c_)->match = (_m_); (_c_)->input = (_i_); (_c_)->ret = (_r_); (_c_)->cbmod = (_d_); rpa_cbset_reset(&(_c_)->cbset, 0); } while (0)
 #define RPA_MCACHE_CBSET(_c_, _m_, _i_, _r_, _d_, _o_, _s_) \
        do { \
                rpa_cbrecord_t *cbrec; \
@@ -290,7 +290,7 @@ int rpa_mnode_exec_callback(rpa_mnode_t *mnode, rpa_stat_t *stat, const char *in
 
        if (input >= stat->end)
                return -1;
-       if (stat->cbdisable)
+       if (stat->cbmod)
                return size;
        if ( ((rpa_mnode_callback_t*)mnode)->matched_callback && (reason & mnode->flags))
                ret = ((rpa_mnode_callback_t*)mnode)->matched_callback(mnode, stat, input, size, (reason & mnode->flags));
@@ -304,7 +304,7 @@ int rpa_mnode_record_callback(rpa_mnode_t *mnode, rpa_stat_t *stat, const char *
 
        if (input >= stat->end)
                return -1;
-       if (stat->cbdisable)
+       if (stat->cbmod)
                return size;
        if (mnode->flags & RPA_MNODE_SYNCRONOUS)
                return rpa_mnode_exec_callback(mnode, stat, input, size, reason);
@@ -313,6 +313,7 @@ int rpa_mnode_record_callback(rpa_mnode_t *mnode, rpa_stat_t *stat, const char *
                        cbrec->mnode = mnode;
                        cbrec->input = input;
                        cbrec->size = size;
+                       cbrec->reason = reason;
                }
        }
        return size;
@@ -418,12 +419,12 @@ int rpa_mnode_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char *i
        rpa_word_t hash = 0;
        rpa_mcache_t *ncache = NULL;
        rpa_mcache_t *mcache = NULL;
-       unsigned char cbdisable = stat->cbdisable;
+       unsigned char cbmod = stat->cbmod;
 
        if (mnode->flags & RPA_MNODE_NOCONNECT) {
-               stat->cbdisable = 1;
+               stat->cbmod = RPA_CB_DISABLED;
        }
-       hash = RPA_MCACHEHASH(match, input, stat->cbdisable);
+       hash = RPA_MCACHEHASH(match, input, stat->cbmod);
        mcache = &stat->mcache[hash];
        ncache = &stat->ncache[hash];
 
@@ -448,9 +449,9 @@ int rpa_mnode_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char *i
                ret = rpa_mnode_plain(mnode, stat, input);
                if (stat->usecache) {
                        if (ret > 0)
-                               RPA_MCACHE_SET(mcache, match, input, ret, stat->cbdisable);
+                               RPA_MCACHE_SET(mcache, match, input, ret, stat->cbmod);
                        else
-                               RPA_MCACHE_SET(ncache, match, input, ret, stat->cbdisable);
+                               RPA_MCACHE_SET(ncache, match, input, ret, stat->cbmod);
                }
        }
        if (ret <= 0) {
@@ -461,7 +462,7 @@ int rpa_mnode_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char *i
        ret = rpa_mnode_exec_callback(mnode, stat, input, ret, RPA_REASON_END|RPA_REASON_MATCHED);
 
 end:
-       stat->cbdisable = cbdisable;
+       stat->cbmod = cbmod;
        if (ret <= 0)
                return -1;
        return ret;
@@ -622,7 +623,7 @@ void rpa_mcache_cbset(rpa_stat_t *stat, rpa_mcache_t *_c_, rpa_match_t *_m_, con
 {
        rpa_cbrecord_t *cbrec;
        rpa_word_t _off_;
-       RPA_MCACHE_SET((_c_), (_m_), (_i_), (_r_), stat->cbdisable);
+       RPA_MCACHE_SET((_c_), (_m_), (_i_), (_r_), stat->cbmod);
        rpa_cbset_reset(&(_c_)->cbset, 0);
        if ((_s_) > 0) {
                if (rpa_cbset_check_space_min(&(_c_)->cbset, (_s_) + 1) < 0) {
@@ -646,16 +647,21 @@ int rpa_mnode_p_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char
        rpa_word_t hash = 0;
        rpa_mcache_t *mcache = NULL;
        rpa_mcache_t *ncache = NULL;
-       rpa_word_t cboff, cboffset_now = (rpa_word_t)-1, cboffset_before = rpa_cbset_getpos(&stat->cbset);
-       unsigned char cbdisable = stat->cbdisable;
+       rpa_word_t cboff, cboffset_now = (rpa_word_t)-1, cboffset_before = (rpa_word_t)-1;
+       unsigned char cbmod = stat->cbmod;
 
        if (mnode->flags & RPA_MNODE_NOCONNECT) {
-               stat->cbdisable = 1;
+               stat->cbmod = RPA_CB_DISABLED;
        }
-       hash = RPA_MCACHEHASH(match, input, stat->cbdisable);
+       hash = RPA_MCACHEHASH(match, input, stat->cbmod);
        mcache = &stat->mcache[hash];
        ncache = &stat->ncache[hash];
 
+       ret = rpa_mnode_record_callback(mnode, stat, input, (unsigned int) (stat->end - input), RPA_REASON_START);
+       if (!ret)
+               goto end;
+
+       cboffset_before = rpa_cbset_getpos(&stat->cbset);
        if (((rpa_match_nlist_t*)match)->loopy) {
                ret = rpa_mnode_p_plain_loop_detect(mnode, stat, input);
        } else if (ncache->match == match && ncache->input == input) {
@@ -665,7 +671,7 @@ int rpa_mnode_p_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char
                 */
                ret = -1;
                goto end;
-       } else if (mcache->match == match && mcache->input == input && mcache->cbdisable == stat->cbdisable) {
+       } else if (mcache->match == match && mcache->input == input && mcache->cbmod == stat->cbmod) {
                rpa_cbrecord_t *cbrec;
                rpa_word_t lastoff = rpa_cbset_getpos(&mcache->cbset);
                for (cboff = 1; cboff <= lastoff; cboff++) {
@@ -687,27 +693,31 @@ int rpa_mnode_p_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char
                         */
                        if (ret > 0) {
                                cboffset_now = rpa_cbset_getpos(&stat->cbset);
-                               RPA_MCACHE_CBSET(mcache, match, input, ret, stat->cbdisable, cboffset_before, cboffset_now - cboffset_before);
+                               RPA_MCACHE_CBSET(mcache, match, input, ret, stat->cbmod, cboffset_before, cboffset_now - cboffset_before);
                                /*
                                 * If the callbacks are not disabled we can also set the cache for the cases when they are disabled.
                                 */
-                               if (!stat->cbdisable)
+                               if (!stat->cbmod) {
+                                       ASSERT(&stat->mcache[RPA_MCACHEHASH(match, input, 1)] != mcache);
                                        RPA_MCACHE_SET(&stat->mcache[RPA_MCACHEHASH(match, input, 1)], match, input, ret, 1);
+                               }
                        } else {
-                               RPA_MCACHE_SET(ncache, match, input, ret, stat->cbdisable);
+                               RPA_MCACHE_SET(ncache, match, input, ret, stat->cbmod);
                        }
                }
        }
 
+end:
        if (ret > 0) {
-               ret = rpa_mnode_record_callback(mnode, stat, input, ret, RPA_REASON_START|RPA_REASON_END|RPA_REASON_MATCHED);
+               ret = rpa_mnode_record_callback(mnode, stat, input, ret, RPA_REASON_END|RPA_REASON_MATCHED);
+       } else {
+               ret = rpa_mnode_record_callback(mnode, stat, input, 0, RPA_REASON_END);
        }
 
-end:
        /*
         * Restore the original state
         */
-       stat->cbdisable = cbdisable;
+       stat->cbmod = cbmod;
        if (ret <= 0) {
                return -1;
        }
index 8f5aee7..361fe6f 100644 (file)
@@ -446,11 +446,8 @@ static int rpa_stat_play_cbset(rpa_stat_t *stat, const char *input, unsigned int
 
        for (off = 1; off <= cbset->off; off++) {
                rpa_cbrecord_t *cbrec = &cbset->data[off];
-               ret = rpa_mnode_exec_callback(cbrec->mnode, stat, cbrec->input, cbrec->size, RPA_REASON_START);
-               if (!ret)
-                       return 0;
-               ret = rpa_mnode_exec_callback(cbrec->mnode, stat, cbrec->input, cbrec->size, RPA_REASON_MATCHED | RPA_REASON_END);
-               if (!ret)
+               ret = rpa_mnode_exec_callback(cbrec->mnode, stat, cbrec->input, cbrec->size, cbrec->reason);
+               if (cbrec->size && !ret)
                        return 0;
        }
        return size;
index 33dd203..d16a108 100644 (file)
@@ -59,10 +59,16 @@ typedef struct rpa_mcache_s {
        const char *input;
        rpa_cbset_t cbset;
        int ret;
-       int cbdisable;
+       int cbmod;
 } rpa_mcache_t;
 
 
+typedef enum {
+       RPA_CB_DEFAULT = 0,
+       RPA_CB_DISABLED,
+} rap_cbmod_t;
+
+
 struct rpa_stat_s {
        rpa_dbex_t *hDbex;
        /* 
@@ -90,7 +96,7 @@ struct rpa_stat_s {
        int (*getchar)(unsigned int *pwc, rpa_stat_t *stat, const char *input);
        const char *where;
        unsigned char usecache; 
-       unsigned char cbdisable;
+       rap_cbmod_t cbmod;
 };
 
 
index ba71a89..dc78299 100644 (file)
@@ -11,8 +11,12 @@ LD = ld
 ifeq ($(BLDCFG), release)
 CFLAGS := -fPIC -O3
 else
+ifeq ($(BLDCFG), profile)
+CFLAGS := -fPIC -O0 -pg -Wall 
+else
 CFLAGS := -fPIC -O0 -g -Wall 
 endif
+endif
 
 ifeq ($(CCBLD), yes)
 CFLAGS += -fprofile-arcs -ftest-coverage
index 1b057a2..9b1bcdd 100644 (file)
@@ -38,6 +38,7 @@ static const char *stropcalls[] = {
        "RVM_ASR",
        "RVM_SWI",
        "RVM_SWIID",
+       "RVM_CALL",
        "RVM_MOV",
        "RVM_INC",
        "RVM_DEC",
@@ -136,8 +137,6 @@ static const char *stropcalls[] = {
        "RVM_ADDRA",
        "RVM_ELDA",
        "RVM_ESTA",
-       "RVM_ELDS",
-       "RVM_ESTS",
        "UNKNOWN",
        "UNKNOWN",
        "UNKNOWN",
@@ -162,7 +161,6 @@ static void rvm_op_b(rvmcpu_t *cpu, rvm_asmins_t *ins)
                pc += RVM_CPUREG_GETU(cpu, ins->op2);
        if (ins->op3 != XX)
                pc += RVM_CPUREG_GETU(cpu, ins->op3);
-//     RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
        RVM_CPUREG_INCIP(cpu, PC, pc - 1);
 }
 
@@ -178,7 +176,6 @@ static void rvm_op_beq(rvmcpu_t *cpu, rvm_asmins_t *ins)
                        pc += RVM_CPUREG_GETU(cpu, ins->op2);
                if (ins->op3 != XX)
                        pc += RVM_CPUREG_GETU(cpu, ins->op3);
-//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -195,7 +192,6 @@ static void rvm_op_bneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
                        pc += RVM_CPUREG_GETU(cpu, ins->op2);
                if (ins->op3 != XX)
                        pc += RVM_CPUREG_GETU(cpu, ins->op3);
-//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -212,7 +208,6 @@ static void rvm_op_bleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
                        pc += RVM_CPUREG_GETU(cpu, ins->op2);
                if (ins->op3 != XX)
                        pc += RVM_CPUREG_GETU(cpu, ins->op3);
-//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -228,7 +223,6 @@ static void rvm_op_bgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
                        pc += RVM_CPUREG_GETU(cpu, ins->op2);
                if (ins->op3 != XX)
                        pc += RVM_CPUREG_GETU(cpu, ins->op3);
-//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -246,7 +240,6 @@ static void rvm_op_bles(rvmcpu_t *cpu, rvm_asmins_t *ins)
                        pc += RVM_CPUREG_GETU(cpu, ins->op2);
                if (ins->op3 != XX)
                        pc += RVM_CPUREG_GETU(cpu, ins->op3);
-//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -263,7 +256,6 @@ static void rvm_op_bgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
                        pc += RVM_CPUREG_GETU(cpu, ins->op2);
                if (ins->op3 != XX)
                        pc += RVM_CPUREG_GETU(cpu, ins->op3);
-//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -292,7 +284,7 @@ static void rvm_op_bl(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_exit(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-
+       cpu->abort = 1;
 }
 
 
@@ -629,6 +621,19 @@ static void rvm_op_swiid(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
+static void rvm_op_call(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+
+       if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_SWIID) {
+               RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
+               rvm_op_swiid(cpu, ins);
+       } else {
+               rvm_op_bl(cpu, ins);
+       }
+}
+
+
 static void rvm_op_sub(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) - RVM_CPUREG_GETU(cpu, ins->op3));
@@ -762,59 +767,62 @@ static void rvm_op_push(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rword sp = RVM_CPUREG_GETU(cpu, SP) + 1;
 
-       r_carray_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, ins->op1));
+       RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, ins->op1));
        RVM_CPUREG_SETU(cpu, SP, sp);
 }
 
 
+static void rvm_op_lds(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
+
+       RVM_CPUREG_SET(cpu, ins->op1, RVM_STACK_READ(cpu->stack, sp));
+}
+
+
 static void rvm_op_sts(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
 
-       r_carray_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, ins->op1));
+       RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, ins->op1));
 }
 
 
 static void rvm_op_pushm(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       int n, i;
+       rword n, i = 0;
        rword bits = RVM_CPUREG_GETU(cpu, ins->op1);
        rword sp = RVM_CPUREG_GETU(cpu, SP);
 
-       for (i = 0, n = 0; bits && n < RLST; n++) {
-               if (((rword)(1 << n)) & bits) {
-                       i += 1;
+       if (!(bits & ((1<<(RVM_REGS_NUM / 2)) - 1)))
+               i = RVM_REGS_NUM / 2;
+       for (;bits && i < RLST; i++) {
+               n = 1 << i;
+               if (n & bits) {
                        sp += 1;
-                       r_carray_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, n));
-                       bits &= ~(1<<n);
+                       RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, i));
+                       bits &= ~n;
                }
        }
-       RVM_CPUREG_SETU(cpu, SP, RVM_CPUREG_GETU(cpu, SP) + i);
-}
-
-
-static void rvm_op_pop(rvmcpu_t *cpu, rvm_asmins_t *ins)
-{
-       rword sp = RVM_CPUREG_GETU(cpu, SP);
-
-       RVM_CPUREG_SET(cpu, ins->op1, r_carray_index(cpu->stack, sp, rvmreg_t));
-       if (ins->op1 != SP)
-               RVM_CPUREG_SETU(cpu, SP, sp - 1);
+       RVM_CPUREG_SETU(cpu, SP, sp);
 }
 
 
 static void rvm_op_popm(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       int n;
+       int n, i = RLST - 1;
        rword bits = RVM_CPUREG_GETU(cpu, ins->op1);
        rword savedbits = bits;
        rword sp = RVM_CPUREG_GETU(cpu, SP);
 
-       for (n = RLST - 1; bits && n >= 0; n--) {
-               if (((rword)(1 << n)) & bits) {
-                       RVM_CPUREG_SET(cpu, n, r_carray_index(cpu->stack, sp, rvmreg_t));
+       if (!(bits & ~((1 << (RVM_REGS_NUM / 2)) - 1)))
+               i = RVM_REGS_NUM / 2 - 1;
+       for (; bits && i >= 0; i--) {
+               n = 1 << i;
+               if (n & bits) {
+                       RVM_CPUREG_SET(cpu, i, RVM_STACK_READ(cpu->stack, sp));
                        sp -= 1;
-                       bits &= ~(1<<n);
+                       bits &= ~n;
                }
        }
        if (!(((rword)(1 << SP)) & savedbits))
@@ -822,11 +830,13 @@ static void rvm_op_popm(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
-static void rvm_op_lds(rvmcpu_t *cpu, rvm_asmins_t *ins)
+static void rvm_op_pop(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
+       rword sp = RVM_CPUREG_GETU(cpu, SP);
 
-       RVM_CPUREG_SET(cpu, ins->op1, r_carray_index(cpu->stack, sp, rvmreg_t));
+       RVM_CPUREG_SET(cpu, ins->op1, RVM_STACK_READ(cpu->stack, sp));
+       if (ins->op1 != SP)
+               RVM_CPUREG_SETU(cpu, SP, sp - 1);
 }
 
 
@@ -836,7 +846,7 @@ static void rvm_op_addrs(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
        RVM_CPUREG_CLEAR(cpu, ins->op1);
        RVM_CPUREG_SETTYPE(cpu, ins->op1, RVM_DTYPE_POINTER);
-       RVM_CPUREG_SETP(cpu, ins->op1, r_carray_slot_expand(cpu->stack, sp));
+       RVM_CPUREG_SETP(cpu, ins->op1, RVM_STACK_ADDR(cpu->stack, sp));
 }
 
 
@@ -1423,7 +1433,7 @@ static void rvm_op_abort(rvmcpu_t *cpu, rvm_asmins_t *ins)
        RVM_ABORT(cpu, RVM_CPUREG_GETU(cpu, ins->op1));
 }
 
-
+#if 0
 static void rvm_op_elds(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        ruint index = RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3);
@@ -1436,7 +1446,7 @@ static void rvm_op_ests(rvmcpu_t *cpu, rvm_asmins_t *ins)
        ruint index = RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3);
        *RVM_STACK_ADDR(cpu, index) = RVM_CPUREG_GET(cpu, ins->op1);
 }
-
+#endif
 
 static rvm_cpu_op ops[] = {
        rvm_op_exit,            // RVM_EXT
@@ -1445,6 +1455,7 @@ static rvm_cpu_op ops[] = {
        rvm_op_asr,                     // RVM_ASR
        rvm_op_swi,                     // RVM_SWI
        rvm_op_swiid,           // RVM_SWIID
+       rvm_op_call,            // RVM_CALL
        rvm_op_mov,                     // RVM_MOV
        rvm_op_inc,                     // RVM_INC
        rvm_op_dec,                     // RVM_DEC
@@ -1545,8 +1556,6 @@ static rvm_cpu_op ops[] = {
        rvm_op_addra,           // RVM_ADDRA
        rvm_op_elda,            // RVM_ELDA
        rvm_op_esta,            // RVM_ESTA
-       rvm_op_elds,            // RVM_ELDS
-       rvm_op_ests,            // RVM_ESTS
        (void*) 0,
        (void*) 0,
        (void*) 0,
@@ -1568,8 +1577,9 @@ rvmcpu_t *rvm_cpu_create()
                return ((void*)0);
        r_memset(cpu, 0, sizeof(*cpu));
        cpu->switables = r_array_create(sizeof(rvm_switable_t*));
-       cpu->stack = r_carray_create(sizeof(rvmreg_t));
-       cpu->stack->user = (void*)cpu;
+//     cpu->stack = r_carray_create(sizeof(rvmreg_t));
+       cpu->stack = r_malloc(4 * 1024 *sizeof(rvmreg_t));
+       cpu->data = r_carray_create(sizeof(rvmreg_t));
        cpu->opmap = rvm_opmap_create();
        cpu->gc = rvm_gc_create();
        rvm_op_binary_init(cpu->opmap);
@@ -1583,16 +1593,18 @@ rvmcpu_t *rvm_cpu_create()
 
 void rvm_cpu_destroy(rvmcpu_t *cpu)
 {
-       r_object_destroy((robject_t*)cpu->switables);
-       r_object_destroy((robject_t*)cpu->stack);
-       rvm_opmap_destroy(cpu->opmap);
        rvm_gc_deallocate_all(cpu->gc);
        rvm_gc_destroy(cpu->gc);
+       r_object_destroy((robject_t*)cpu->switables);
+//     r_object_destroy((robject_t*)cpu->stack);
+       r_free(cpu->stack);
+       r_object_destroy((robject_t*)cpu->data);
+       rvm_opmap_destroy(cpu->opmap);
        r_free(cpu);
 }
 
 
-rint rvm_cpu_dbgarg_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off, rint debug)
+rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
 {
        rvm_asmins_t *pi;
        rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
@@ -1613,25 +1625,41 @@ rint rvm_cpu_dbgarg_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off, rint debu
                        RVM_REG_ASSIGNFLAGS(regda, (pi->type >= RVM_DTYPE_STRING) ? RVM_INFOBIT_ROBJECT : 0);
                }
                ops[pi->opcode](cpu, pi);
-               if (debug)
-                       rvm_cpu_dumpregs(pi, cpu);
-               if (cpu->abort)
-                       return -1;
                RVM_REG_INCIP(regpc, 1);
-       } while (pi->opcode);
+       } while (!cpu->abort);
+       if (cpu->error)
+               return -1;
        return 0;
 }
 
 
-rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
-{
-       return rvm_cpu_dbgarg_exec(cpu, prog, off, 0);
-}
-
-
 rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
 {
-       return rvm_cpu_dbgarg_exec(cpu, prog, off, 1);
+       rvm_asmins_t *pi;
+       rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
+       rvmreg_t *regpc = RVM_CPUREG_PTR(cpu, PC);
+
+       RVM_CPUREG_SETIP(cpu, PC, prog + off);
+       cpu->abort = 0;
+       cpu->error = 0;
+       do {
+               pi = RVM_REG_GETIP(regpc);
+               if (pi->da) {
+                       if (pi->type == RVM_DTYPE_DOUBLE) {
+                               RVM_REG_SETD(regda, pi->data.d);
+                       } else {
+                               RVM_REG_SETU(regda, pi->data.u);
+                       }
+                       RVM_REG_SETTYPE(regda, pi->type);
+                       RVM_REG_ASSIGNFLAGS(regda, (pi->type >= RVM_DTYPE_STRING) ? RVM_INFOBIT_ROBJECT : 0);
+               }
+               ops[pi->opcode](cpu, pi);
+               rvm_cpu_dumpregs(pi, cpu);
+               RVM_REG_INCIP(regpc, 1);
+       } while (!cpu->abort);
+       if (cpu->error)
+               return -1;
+       return 0;
 }
 
 
@@ -1681,6 +1709,7 @@ rvm_asmins_t rvm_asmp(rword opcode, rword op1, rword op2, rword op3, rpointer da
        a.op2 = (ruint8)op2;
        a.op3 = (ruint8)op3;
        a.data.u = (rword)data;
+       a.type = RVM_DTYPE_POINTER;
        if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
                a.da = 1;
        return a;
index 9642b55..7aa09cf 100644 (file)
@@ -40,6 +40,7 @@ enum {
        RVM_ASR,                /* Arithmetic shift right: op1 = op2 >> op3, preserve the signed bit */
        RVM_SWI,
        RVM_SWIID,
+       RVM_CALL,               /* if op1 is of type RVM_DTYPE_SWIID, then invoke RVM_SWIID, otherwise invoke RVM_BL */
        RVM_MOV,
        RVM_INC,                /* INC: op1 = op1 + 1 */
        RVM_DEC,                /* DEC: op1 = op1 - 1 */
@@ -111,11 +112,11 @@ enum {
        RVM_TYPE,               /* Type: op1 = typeof(op2) */
        RVM_SETTYPE,    /* Type: op1.type = op2 */
        RVM_EMOV,
-       RVM_EADD,               /* Add: op1 = op2 + op3 */
-       RVM_ESUB,               /* Subtract: op1 = op2 - op3 */
-       RVM_EMUL,               /* Multiply: op1 = op2 * op3 */
-       RVM_EDIV,               /* Divide: op1 = op2 / op3 */
-       RVM_EMOD,               /* Modulo: op1 = op2 % op3 */
+       RVM_EADD,               /* Add: op1 = op2 + op3, update the status register */
+       RVM_ESUB,               /* Subtract: op1 = op2 - op3, update the status register */
+       RVM_EMUL,               /* Multiply: op1 = op2 * op3, update the status register */
+       RVM_EDIV,               /* Divide: op1 = op2 / op3, update the status register */
+       RVM_EMOD,               /* Modulo: op1 = op2 % op3, update the status register */
        RVM_ELSL,               /* Logical Shift Left: op1 = op2 << op3, update the status register */
        RVM_ELSR,               /* Logical Shift Right: op1 = op2 >> op3, update the status register */
        RVM_ELSRU,              /* Logical Unsigned Shift Right: op1 = op2 >>> op3, update the status register */
@@ -126,12 +127,12 @@ enum {
        RVM_ELAND,              /* Logical AND: op1 = op2 && op3, update status register */
        RVM_ELOR,               /* Logical OR: op1 = op2 || op3, update the status register */
        RVM_ELNOT,              /* Logical NOT: op1 = !op2, update the status register */
-       RVM_EEQ,                /* op1 = op2 == op3 ? 1 : 0 */
-       RVM_ENOTEQ,             /* op1 = op2 != op3 ? 1 : 0 */
-       RVM_EGREAT,             /* op1 = op2 > op3 ? 1 : 0 */
-       RVM_EGREATEQ,   /* op1 = op2 >= op3 ? 1 : 0 */
-       RVM_ELESS,              /* op1 = op2 < op3 ? 1 : 0 */
-       RVM_ELESSEQ,    /* op1 = op2 <= op3 ? 1 : 0 */
+       RVM_EEQ,                /* op1 = op2 == op3 ? 1 : 0, update the status register */
+       RVM_ENOTEQ,             /* op1 = op2 != op3 ? 1 : 0, update the status register */
+       RVM_EGREAT,             /* op1 = op2 > op3 ? 1 : 0, update the status register */
+       RVM_EGREATEQ,   /* op1 = op2 >= op3 ? 1 : 0, update the status register */
+       RVM_ELESS,              /* op1 = op2 < op3 ? 1 : 0, update the status register */
+       RVM_ELESSEQ,    /* op1 = op2 <= op3 ? 1 : 0, update the status register */
 
        RVM_ECMP,               /* Compare: status register is updated based on the result: op1 - op2 */
        RVM_ECMN,               /* Compare Negative: status register is updated based on the result: op1 + op2 */
@@ -140,9 +141,6 @@ enum {
        RVM_ADDRA,              /* op1 is the destination memory, op2 is the array, op3 is the offset */
        RVM_ELDA,               /* op1 is the destination, op2 is the array, op3 is the offset */
        RVM_ESTA,               /* op1 is the source, op2 is the array, op3 is the offset */
-       RVM_ELDS,               /* op1 is the destination, load the value from stack at offset op2 + op3 */
-       RVM_ESTS,               /* op1 is the source, store the value on stack at offset op2 + op3  */
-
 };
 
 
@@ -165,7 +163,7 @@ do { \
         RVM_STATUS_CLRBIT(cpu, b); \
 } while (0)
 
-#define RVM_OPERAND_BITS 5
+#define RVM_OPERAND_BITS 4
 #define RVM_REGS_NUM (1 << RVM_OPERAND_BITS)
 #define R0 0
 #define R1 1
@@ -200,19 +198,27 @@ do { \
 #define R30 30
 #define R31 31
 
-#define FP R26
-#define SP R27
-#define LR R28
-#define PC R29
-#define DA R30         /* The DA register should never be modified manually, otherwise the result is undefined */
-#define XX R31
-#define RLST XX
+#define RLST (RVM_REGS_NUM - 1)
+#define FP (RLST - 5)
+#define SP (RLST - 4)
+#define LR (RLST - 3)
+#define PC (RLST - 2)
+#define DA (RLST - 1)                          /* The DA register should never be modified manually, otherwise the result is undefined */
+#define XX (RLST)
+
 
 #define RVM_STACK_CHUNK 256
 #define RVM_ABORT(__cpu__, __e__) do { __cpu__->error = (__e__); (__cpu__)->abort = 1; ASSERT(0); return; } while (0)
 #define BIT(__shiftby__) (1 << (__shiftby__))
-
-
+#define BITR(__f__, __l__, __r__) (((__r__) >= (__f__) && (__r__) <= (__l__)) ? BIT(__r__) : 0)
+#define BITS(__f__, __l__)  (BITR(__f__, __l__, R0)) | (BITR(__f__, __l__, R1)) | (BITR(__f__, __l__, R2)) | (BITR(__f__, __l__, R3)) | \
+                                                       (BITR(__f__, __l__, R4)) | (BITR(__f__, __l__, R5)) | (BITR(__f__, __l__, R6)) | (BITR(__f__, __l__, R7)) | \
+                                                       (BITR(__f__, __l__, R8)) | (BITR(__f__, __l__, R9)) | (BITR(__f__, __l__, R10)) | (BITR(__f__, __l__, R11)) | \
+                                                       (BITR(__f__, __l__, R12)) | (BITR(__f__, __l__, R13)) | (BITR(__f__, __l__, R14)) | (BITR(__f__, __l__, R15)) | \
+                                                       (BITR(__f__, __l__, R16)) | (BITR(__f__, __l__, R17)) | (BITR(__f__, __l__, R18)) | (BITR(__f__, __l__, R19)) | \
+                                                       (BITR(__f__, __l__, R20)) | (BITR(__f__, __l__, R21)) | (BITR(__f__, __l__, R22)) | (BITR(__f__, __l__, R23)) | \
+                                                       (BITR(__f__, __l__, R24)) | (BITR(__f__, __l__, R25)) | (BITR(__f__, __l__, R26)) | (BITR(__f__, __l__, R27)) | \
+                                                       (BITR(__f__, __l__, R28)) | (BITR(__f__, __l__, R29)) | (BITR(__f__, __l__, R30)) | (BITR(__f__, __l__, R31))
 
 #define RVM_OPCODE_BITS 8
 #define RVM_SWI_TABLE_BITS 10
@@ -224,6 +230,16 @@ do { \
 #define RVM_ASMINS_SWI(__opcode__) ((__opcode__) >> RVM_OPCODE_BITS)
 #define RVM_OPSWI(__id__) (((__id__) << RVM_OPCODE_BITS) | RVM_SWI)
 
+//#define RVM_STACK_WRITE(__s__, __sp__, __p__) r_carray_replace((__s__), (__sp__), (rconstpointer)(__p__));
+//#define RVM_STACK_READ(__s__, __sp__) r_carray_index((__s__), (__sp__), rvmreg_t)
+//#define RVM_STACK_ADDR(__s__, __sp__) r_carray_slot_expand((__s__), (__sp__))
+
+
+#define RVM_STACK_WRITE(__s__, __sp__, __p__) do { r_memcpy(((rvmreg_t*)(__s__)) + (__sp__), (__p__), sizeof(rvmreg_t)); } while(0)
+#define RVM_STACK_READ(__s__, __sp__) *RVM_STACK_ADDR(__s__, __sp__)
+#define RVM_STACK_ADDR(__s__, __sp__) (((rvmreg_t*)(__s__)) + (__sp__))
+
+
 #define RVM_E_DIVZERO          (1)
 #define RVM_E_ILLEGAL          (2)
 #define RVM_E_CAST                     (3)
@@ -268,7 +284,9 @@ struct rvmcpu_s {
        rword error;
        rword abort;
        rarray_t *switables;
-       rcarray_t *stack;
+//     rcarray_t *stack;
+       void *stack;
+       rcarray_t *data;
        struct rvm_opmap_s *opmap;
        void *userdata;
        rvm_gc_t *gc;
@@ -280,7 +298,6 @@ void rvm_cpu_destroy(rvmcpu_t * vm);
 rint rvm_cpu_addswitable(rvmcpu_t * cpu, rvm_switable_t *switalbe);
 rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off);
 rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off);
-rint rvm_cpu_dbgarg_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off, rint debug);
 rint rvm_cpu_getswi(rvmcpu_t *cpu, const rchar *swiname, rsize_t size);
 rint rvm_cpu_getswi_s(rvmcpu_t *cpu, const rchar *swiname);
 void rvm_relocate(rvm_asmins_t *code, rsize_t size);
index 35e02ee..18f1a09 100644 (file)
@@ -8,6 +8,7 @@
 #include "rcarray.h"
 #include "rstring.h"
 
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -35,9 +36,6 @@ extern "C" {
 #define RVM_INFOBIT_LAST (1 << 15)
 #define RVM_INFOBIT_ALL (RVM_INFOBIT_ROBJECT | RVM_INFOBIT_LAST)
 
-#define r_carray_rvmregslot(__carray__, __index__)((rvmreg_t*)(((rchar*)r_array_index((__carray__)->array, (__index__) >> R_CARRAY_CHUNKBITS, rpointer)) + ((__index__) & R_CARRAY_CHUNKMASK) * sizeof(rvmreg_t)))
-#define RVM_STACK_ADDR(__cpu__, __off__) ((rvmreg_t*)r_carray_rvmregslot((__cpu__)->stack, (__off__) ))
-#define RVM_SPOFF_ADDR(__cpu__, __spoff__) RVM_STACK_ADDR(__cpu__, (RVM_CPUREG_GETU(__cpu__, SP) - (__spoff__)))
 
 #define RVM_CPUREG_R_PTR(__cpu__, __r__) (&(__cpu__)->r[(__r__)])
 #define RVM_CPUREG_PTR(__cpu__, __r__) RVM_CPUREG_R_PTR(__cpu__, __r__)
@@ -51,10 +49,12 @@ extern "C" {
 
 #define RVM_REG_TSTFLAG(__r__, __flag__) ((__r__)->flags & (__flag__)) ? TRUE : FALSE
 #define RVM_REG_SETFLAG(__r__, __flag__) do { (__r__)->flags |= (__flag__); } while (0)
+#define RVM_REG_GETFLAGS(__r__) (__r__)->flags
 #define RVM_REG_CLRFLAG(__r__, __flag__) do { (__r__)->flags &= ~(__flag__); } while (0)
-#define RVM_REG_ASSIGNFLAGS(__r__, __flags__) do { (__r__)->flags = ~(__flags__); } while (0)
+#define RVM_REG_ASSIGNFLAGS(__r__, __flags__) do { (__r__)->flags = (__flags__); } while (0)
 #define RVM_CPUREG_TSTFLAG(__cpu__, __r__, __flag__) RVM_REG_TSTFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
 #define RVM_CPUREG_SETFLAG(__cpu__, __r__, __flag__) RVM_REG_SETFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
+#define RVM_CPUREG_GETFLAGS(__cpu__, __r__) RVM_REG_GETFLAGS(RVM_CPUREG_PTR(__cpu__, __r__))
 #define RVM_CPUREG_CLRFLAG(__cpu__, __r__, __flag__) RVM_REG_CLRFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
 #define RVM_CPUREG_ASSIGNFLAGS(__cpu__, __r__, __flags__) RVM_REG_ASSIGNFLAGS(RVM_CPUREG_PTR(__cpu__, __r__), __flags__)
 
index 0766759..dc13ef4 100644 (file)
@@ -71,8 +71,7 @@ void rvm_scope_push(rvm_scope_t* scope)
 void rvm_scope_pop(rvm_scope_t* scope)
 {
        ruint scopelen = r_array_index(scope->scopestack, r_array_length(scope->scopestack) - 1, ruint);
-//     r_array_setlength(scope->scopestack, r_array_length(scope->scopestack));
-       r_array_remove(scope->scopestack);
+       r_array_removelast(scope->scopestack);
        r_array_setlength(scope->varstack, scopelen);
 //     r_printf("SCOPE FRAME: %d, POP: %d\n", r_array_length(scope->scopestack), scopelen);
 }
@@ -84,7 +83,7 @@ void rvm_scope_addoffset(rvm_scope_t *scope, const rchar *name, ruint namesize,
 
        vmap.name = rvm_scope_addname(scope, name, namesize);
        vmap.data.offset = off;
-       vmap.datatype = r_array_empty(scope->scopestack) ? VARMAP_DATATYPE_OFFSET : VARMAP_DATATYPE_FPOFFSET;
+       vmap.datatype = VARMAP_DATATYPE_OFFSET;
        r_array_add(scope->varstack, &vmap);
 }
 
index acdc641..4819a52 100644 (file)
@@ -11,8 +11,7 @@ extern "C" {
 #endif
 
 #define VARMAP_DATATYPE_OFFSET 0
-#define VARMAP_DATATYPE_FPOFFSET 1
-#define VARMAP_DATATYPE_PTR 2
+#define VARMAP_DATATYPE_PTR 1
 
 
 typedef struct rvm_varmap_s {
index f91b46b..3853230 100644 (file)
@@ -27,6 +27,7 @@ TESTS   += $(OUTDIR)/scope-test
 TESTS   += $(OUTDIR)/rhash-test
 TESTS   += $(OUTDIR)/rvm-test
 TESTS   += $(OUTDIR)/loop-test
+TESTS   += $(OUTDIR)/speed-test
 TESTS   += $(OUTDIR)/memalloc-test
 TESTS   += $(OUTDIR)/asm-cast
 TESTS   += $(OUTDIR)/asm-add
index 2488010..5ea6812 100644 (file)
@@ -9,8 +9,12 @@ AR = ar
 ifeq ($(BLDCFG), release)
 CFLAGS = -O3
 else
+ifeq ($(BLDCFG), profile)
+CFLAGS = -O0 -pg
+else
 CFLAGS = -g -O0 -Wall 
 endif
+endif
 
 ifeq ($(CCBLD), yes)
 CFLAGS += -fprofile-arcs -ftest-coverage
index 27a61eb..3683844 100644 (file)
@@ -111,14 +111,16 @@ SingleStringCharacter                     ::= '\\' <:EscapeSequence:> |
                                                                <:LineContinuation:> |
                                                                <:SourceCharacter:> - (['] | '\\' | <:LineTerminator:>)
 
+BracketExpressionOp                            ::= '(' <S>? <:Expression:> <S>? ')'
+
 PrimaryExpression                              ::= 'this' | 
                                                                '(' <S>? <:Expression:> <S>? ')' |
                                                                <:LiteralOp:> |
                                                                (<;SwiIdExist;> & <:SwiId:>) |
                                                                <:IdentifierOp:>
-                                                               
+                                                       
 ValPrimaryExpression                   ::= 'this' | 
-                                                               '(' <S>? <:Expression:> <S>? ')' |
+                                                                       <:BracketExpressionOp:> |
                                                                <:LiteralOp:> |
                                                                (<;SwiIdExist;> & <:SwiId:>) |
                                                                <:ValIdentifierOp:>
@@ -146,7 +148,7 @@ MemberExpressionIndexBaseOp         ::= <:MemberExpression:>
 MemberExpressionIndexOp                        ::= <:MemberExpressionIndexBaseOp:> <S>? '[' <:S:>? <:Expression:> <:S:>? ']'
 MemberExpression                               ::= <:MemberExpressionIndexOp:>  |
                                                                        <:MemberExpression:> '.' <:IdentifierName:> |
-                                                                       <:NewKeyword:> <S>? <:MemberExpression:> <S>? <:Arguments:> |
+                                                                       <:NewKeyword:> <S>? <:MemberExpression:> <S>? <:ArgumentsOp:> |
                                                                        <:FunctionExpression:> |
                                                                        <:PrimaryExpression:>
 
@@ -157,7 +159,7 @@ NewExpression                                       ::= <:NewArrayExpression:> |
 
 
 FunctionCallName                               ::= <:CallExpression:> | <:MemberExpression:>
-CallExpressionOp                               ::= <:FunctionCallName:> <S>? <:Arguments:>
+CallExpressionOp                               ::= <:FunctionCallName:> <S>? <:ArgumentsOp:>
 CallExpressionIndexBaseOp              ::= <:CallExpression:>
 CallExpressionIndexOp                  ::= <:CallExpressionIndexBaseOp:> <S>? '[' <S>? <:Expression:> <S>? ']'
 
@@ -165,7 +167,7 @@ CallExpression                                      ::= <:CallExpressionIndexOp:> |
                                                                        <:CallExpression:> '.' <:IdentifierName:> |
                                                                        <:CallExpressionOp:>
 
-Arguments                                              ::= '(' <S>? ')' |
+ArgumentsOp                                            ::= '(' <S>? ')' |
                                                                '(' <S>? <:ArgumentList:> <S>? ')'
 ArgumentList                                   ::= <:ArgumentList:> <S>? ',' <S>? <:AssignmentExpression:> |
                                                                        <:AssignmentExpression:>
@@ -183,7 +185,7 @@ ValMemberExpressionIndexBaseOp      ::= <:ValMemberExpression:>
 ValMemberExpressionIndexOp             ::= <:ValMemberExpressionIndexBaseOp:> <S>? '[' <:S:>? <:Expression:> <:S:>? ']'
 ValMemberExpression                            ::= <:ValMemberExpressionIndexOp:>  |
                                                                        <:ValMemberExpression:> '.' <:IdentifierName:> |
-                                                                       <:NewKeyword:> <S>? <:ValMemberExpression:> <S>? <:Arguments:> |
+                                                                       <:NewKeyword:> <S>? <:ValMemberExpression:> <S>? <:ArgumentsOp:> |
                                                                        <:ValFunctionExpression:> |
                                                                        <:ValPrimaryExpression:>
 
@@ -194,7 +196,7 @@ ValNewExpression                            ::= <:NewArrayExpression:> |
 
 
 ValFunctionCallName                            ::= <:ValCallExpression:> | <:ValMemberExpression:>
-ValCallExpressionOp                            ::= <:ValFunctionCallName:> <S>? <:Arguments:>
+ValCallExpressionOp                            ::= <:ValFunctionCallName:> <S>? <:ArgumentsOp:>
 ValCallExpressionIndexBaseOp   ::= <:ValCallExpression:>
 ValCallExpressionIndexOp               ::= <:ValCallExpressionIndexBaseOp:> <S>? '[' <S>? <:Expression:> <S>? ']'
 
@@ -211,16 +213,15 @@ PostfixOperator                           ::= '++' | '--'
 PostfixExpressionOp                    ::= <:LeftHandSideExpression:> <:PostfixOperator:>
 PostfixExpressionValOp                 ::= <:ValLeftHandSideExpression:>
 PostfixExpression                              ::= <:PostfixExpressionOp:> |
-                                                                       <:PostfixExpressionValOp:>
+                                                                       <:PostfixExpressionValOp:> 
 
 PrefixOperator                                         ::= <:PostfixOperator:>
 PrefixExpressionOp                             ::= <:PrefixOperator:> <:LeftHandSideExpression:>
 PrefixExpression                               ::= <:PrefixExpressionOp:>
 
 # 11.4 Unary Operators
-NegativeOperator                               ::= ('-' - '--')
-UnaryOperatorOpcode                            ::= '~' | '!'
-UnaryOperator                          ::= 'delete' | 'void' | 'typeof' | ('+' - '++') | <:UnaryOperatorOpcode:> | <:NegativeOperator:>
+UnaryOperatorOpcode                            ::= '~' | '!' | ('+' - '++') | ('-' - '--') | 'delete' | 'void' | 'typeof'
+UnaryOperator                          ::= <:UnaryOperatorOpcode:>
 UnaryExpressionOp                      ::=     <S>? <:UnaryOperator:> <S>? <:UnaryExpression:>
 UnaryExpression                                ::=     <:UnaryExpressionOp:> | <:PrefixExpression:> | <:PostfixExpression:>
 
@@ -293,13 +294,6 @@ IterationDo                                                        ::= <:DoKeyword:> <S>? <:Statement:> <S>? <:WhileExpression:>
 IterationStatement                                     ::= <:IterationWhile:> |
                                                                        <:IterationDo:>
 
-
-## 11.12 Conditional Operator ( ? : )
-#ConditionalExpression                         ::= <:LogicalORExpression:> ( <S>? '?' <S>? <:AssignmentExpression:> <S>? ':' <S>? <:AssignmentExpression:> )?
-#ValueOfExpression                             ::= <:NewArrayExpression:> |
-#                                                                      <:Expression:>
-
-
 # 11.12 Conditional Operator ( ? : )
 #ConditionalExpression         ::= <:LogicalORExpression:> ( <S>? '?' <S>? <:AssignmentExpression:> <S>? ':' <S>? <:AssignmentExpression:> )?
 #ConditionalExpressionNoIn::=<:LogicalORExpressionNoIn:> ( <S>? '?' <S>? <:AssignmentExpression:> <S>? ':' <S>? <:AssignmentExpressionNoIn:> )?
@@ -308,25 +302,25 @@ ConditionalExpression     ::= <:LogicalORExpression:>
 
 # 11.13 Assignment Operators
 LeftHandSideExpressionPush             ::= <:LeftHandSideExpression:>
+IdentifierAddressPush                  ::= <:Identifier:>
 AssignmentExpressionOp                         ::= <:LeftHandSideExpressionPush:> <S>? <:AssignmentOperator:> <S>? <:AssignmentExpression:>
-#AssignmentExpressionOp                        ::= (<LeftHandSideExpression> <S>? <AssignmentOperator> <S>? <AssignmentExpression>) & 
-#                                                                      (<LeftHandSideExpression> <S>? <AssignmentOperator> <S>? <:AssignmentExpression:>) &
-#                                                                      (<LeftHandSideExpression> <S>? <:AssignmentOperator:> <S>? <AssignmentExpression>) &
-#                                                                      (<:LeftHandSideExpression:> <S>? <AssignmentOperator> <S>? <AssignmentExpression>)
-
-AssignmentExpression                   ::= <:AssignmentExpressionOp:> | <:ConditionalExpression:>
+AssignmentExpression                   ::= <:AssignmentExpressionOp:> | 
+                                                                       <:ConditionalExpression:>
 
-AssignmentExpressionNoIn::= <:LeftHandSideExpression:> <S>? <:AssignmentOperator:> <S>? <:AssignmentExpressionNoIn:> | <:ConditionalExpressionNoIn:>
-AssignmentOperator     ::= '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '>>>=' | '&=' | '^=' | '|='
+AssignmentExpressionNoIn               ::= <:LeftHandSideExpression:> <S>? <:AssignmentOperator:> <S>? <:AssignmentExpressionNoIn:> | <:ConditionalExpressionNoIn:>
+AssignmentOperator                             ::= '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '>>>=' | '&=' | '^=' | '|='
 
 
 # 11.14 Comma Operator         ( , )
 Expression             ::= <:AssignmentExpression:> ( <S>? ',' <S>? <:AssignmentExpression:> )*
 ExpressionNoIn         ::= <:AssignmentExpressionNoIn:> ( <S>? ',' <S>? <:AssignmentExpressionNoIn:> )*
 
+#Print statement;
+PrintOp                                                        ::= '%'print'%'
 
 # 12 Statements
-Statement                                              ::= <:Block:> |
+Statement                                              ::= <:PrintOp:> |
+                                                                       <:Block:> |
                                                                <:Comment:> |
                                                                <:VariableStatement:> |
                                                                <:EmptyStatement:> |
@@ -400,7 +394,6 @@ SourceElements                                      ::= (<S>? <:SourceElement:>)+
 SourceElement                                          ::= <:FunctionDeclaration:> |
                                                                        <:Statement:>
 Program                                                        ::= <:SourceElements:>
-ProgramInit                                            ::= <:SourceCharacter:>
 # The root rule, it is anonymous
 <:Program:>
        
index 1f4f0b9..e9e67a9 100644 (file)
@@ -51,6 +51,16 @@ typedef struct rvm_codespan_s {
 } rvm_codespan_t;
 
 
+typedef struct rvm_costat_s rvm_costat_t;
+
+struct rvm_costat_s {
+       ruint binaryop;
+       ruint level;
+       ruint dirty;
+       ruint funcalls;
+       rvm_costat_t *root;
+};
+
 typedef struct rvm_compiler_s {
        rpa_dbex_handle dbex;
        rvm_codegen_t *cg;
@@ -60,12 +70,122 @@ typedef struct rvm_compiler_s {
        rarray_t *fundecl;
        rarray_t *opcodes;
        rarray_t *codespan;
+       rarray_t *varmap;
+       rarray_t *stat;
        rvmcpu_t *cpu;
        rboolean optimized;
 } rvm_compiler_t;
 
+
+
+#define RVM_SAVEDREGS_FIRST 4
+#define RVM_SAVEDREGS_MAX (RLST - (RLST - FP) - RVM_SAVEDREGS_FIRST - 1)
+
+
 void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co);
 
+rvm_costat_t *rvm_costat_current(rvm_compiler_t *co)
+{
+       return (rvm_costat_t *)r_array_lastslot(co->stat);
+}
+
+
+ruint rvm_costat_getdebth(rvm_compiler_t *co)
+{
+       return r_array_length(co->stat);
+}
+
+ruint rvm_costat_getlevel(rvm_compiler_t *co)
+{
+       if (!rvm_costat_current(co))
+               return 0;
+       return rvm_costat_current(co)->level;
+}
+
+
+void rvm_costat_inclevel(rvm_compiler_t *co)
+{
+       rvm_costat_current(co)->level += 1;
+       if (rvm_costat_current(co)->level > rvm_costat_current(co)->root->dirty)
+               rvm_costat_current(co)->root->dirty = rvm_costat_current(co)->level;
+}
+
+void rvm_costat_declevel(rvm_compiler_t *co)
+{
+       rvm_costat_current(co)->level -= 1;
+}
+
+
+ruint rvm_costat_getbinaryop(rvm_compiler_t *co)
+{
+       if (!rvm_costat_current(co))
+               return 0;
+       return rvm_costat_current(co)->binaryop;
+}
+
+
+void rvm_costat_incbinaryop(rvm_compiler_t *co)
+{
+       rvm_costat_current(co)->binaryop += 1;
+}
+
+
+void rvm_costat_decbinaryop(rvm_compiler_t *co)
+{
+       rvm_costat_current(co)->binaryop -= 1;
+}
+
+/*
+ruint rvm_costat_getfuncalls(rvm_compiler_t *co)
+{
+       if (!rvm_costat_current(co))
+               return 0;
+       return rvm_costat_current(co)->root->funcalls;
+}
+
+
+void rvm_costat_incfuncalls(rvm_compiler_t *co)
+{
+       rvm_costat_current(co)->root->funcalls += 1;
+}
+
+
+void rvm_costat_decfuncalls(rvm_compiler_t *co)
+{
+       rvm_costat_current(co)->root->funcalls -= 1;
+}
+*/
+
+ruint rvm_costat_getdirty(rvm_compiler_t *co)
+{
+       if (!rvm_costat_current(co))
+               return 0;
+       return rvm_costat_current(co)->root->dirty;
+}
+
+
+void rvm_costat_push(rvm_compiler_t *co)
+{
+       rvm_costat_t stat = *rvm_costat_current(co);
+       stat.binaryop = 0;
+       r_array_add(co->stat, &stat);
+}
+
+
+void rvm_costat_pushroot(rvm_compiler_t *co)
+{
+       rvm_costat_t stat;
+       r_memset(&stat, 0, sizeof(stat));
+       r_array_add(co->stat, &stat);
+       rvm_costat_current(co)->root = rvm_costat_current(co);
+}
+
+void rvm_costat_pop(rvm_compiler_t *co)
+{
+       r_array_removelast(co->stat);
+}
+
+
 
 rvm_compiler_t *rvm_compiler_create(rpa_dbex_handle dbex)
 {
@@ -78,8 +198,10 @@ rvm_compiler_t *rvm_compiler_create(rpa_dbex_handle dbex)
        co->opcodes = r_array_create(sizeof(ruint));
        co->fp = r_array_create(sizeof(rword));
        co->funcall = r_array_create(sizeof(rvm_funcall_t));
+       co->stat = r_array_create(sizeof(rvm_costat_t));
        co->fundecl = r_array_create(sizeof(rvm_fundecl_t));
        co->codespan = r_array_create(sizeof(rvm_codespan_t));
+       co->varmap = r_array_create(sizeof(rvm_varmap_t*));
        r_array_push(co->fp, 0, rword);
        co->dbex = dbex;
        return co;
@@ -92,10 +214,12 @@ void rvm_compiler_destroy(rvm_compiler_t *co)
                rvm_codegen_destroy(co->cg);
                rvm_scope_destroy(co->scope);
                r_object_destroy((robject_t*) co->opcodes);
+               r_object_destroy((robject_t*) co->stat);
                r_object_destroy((robject_t*) co->fp);
                r_object_destroy((robject_t*) co->funcall);
                r_object_destroy((robject_t*) co->fundecl);
                r_object_destroy((robject_t*) co->codespan);
+               r_object_destroy((robject_t*) co->varmap);
                r_free(co);
        }
 }
@@ -120,52 +244,24 @@ static void rvm_swi_negative(rvmcpu_t *cpu, rvm_asmins_t *ins)
 static void rvm_swi_eadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rvmreg_t *res = RVM_CPUREG_PTR(cpu, R0);
-       rvmreg_t *arg1 = (rvmreg_t *)r_carray_slot(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
-       rvmreg_t *arg2 = (rvmreg_t *)r_carray_slot(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 2);
+       rvmreg_t *arg1 = (rvmreg_t *)RVM_STACK_ADDR(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
+       rvmreg_t *arg2 = (rvmreg_t *)RVM_STACK_ADDR(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 2);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_ADD, cpu, res, arg1, arg2);
 }
 
-static void rvm_swi_eless(rvmcpu_t *cpu, rvm_asmins_t *ins)
-{
-       rvmreg_t *res = RVM_SPOFF_ADDR(cpu, 1);
-       rvmreg_t *arg2 = RVM_SPOFF_ADDR(cpu, 0);
-
-       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LESS, cpu, res, res, arg2);
-       RVM_CPUREG_SETU(cpu, SP, RVM_CPUREG_GETU(cpu, SP) - 1);
-}
-
-
-static void rvm_swi_bnonzero(rvmcpu_t *cpu, rvm_asmins_t *ins)
-{
-       rvmreg_t *arg = RVM_SPOFF_ADDR(cpu, 0);
-
-       if (RVM_REG_GETU(arg))
-               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
-       RVM_CPUREG_SETU(cpu, SP, RVM_CPUREG_GETU(cpu, SP) - 1);
-}
-
-
-static void rvm_swi_identifiervalue(rvmcpu_t *cpu, rvm_asmins_t *ins)
-{
-       RVM_CPUREG_SET(cpu, ins->op1, *r_carray_rvmregslot(cpu->stack, RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3)));
-}
-
 
 static rvm_switable_t switable[] = {
                {"none", test_swi_none},
                {"RVM_SWI_NEG", rvm_swi_negative},
                {"rvm_swi_eadd", rvm_swi_eadd},
-               {"rvm_swi_eless", rvm_swi_eless},
-               {"rvm_swi_bnonzero", rvm_swi_bnonzero},
-               {"rvm_swi_identifiervalue", rvm_swi_identifiervalue},
                {NULL, NULL},
 };
 
 
 static void rvm_js_print(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *r = (rvmreg_t *)r_carray_slot(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
+       rvmreg_t *r = (rvmreg_t *)RVM_STACK_ADDR(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
 
        if (rvm_reg_gettype(r) == RVM_DTYPE_UNSIGNED)
                r_printf("%lu\n", RVM_REG_GETU(r));
@@ -194,9 +290,19 @@ static rvm_switable_t switable_js[] = {
 
 inline int codegen_print_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
+       rvm_compiler_t *co = (rvm_compiler_t *)userdata;
+
        if (parseinfo) {
+               if (reason & RPA_REASON_START)
+                       fprintf(stdout, "START ");
+               if (reason & RPA_REASON_MATCHED)
+                       fprintf(stdout, "MATCHED ");
+               if (reason & RPA_REASON_END)
+                       fprintf(stdout, "END ");
                fprintf(stdout, "%s: ", name);
-               fwrite(input, sizeof(char), size, stdout);
+               if (!(reason & RPA_REASON_START))
+                               fwrite(input, sizeof(char), size, stdout);
+               fprintf(stdout, " (debth: %d, level: %d, binaryop: %d, dirty: %d)", rvm_costat_getdebth(co), rvm_costat_getlevel(co), rvm_costat_getbinaryop(co), rvm_costat_getdirty(co));
                fprintf(stdout, "\n");
                fflush(stdout);
        }
@@ -218,6 +324,15 @@ int codegen_opcode_unary_callback(const char *name, void *userdata, const char *
 
        if (r_stringncmp("-", input, size))
                r_array_push(co->opcodes, RVM_OPSWI(rvm_cpu_getswi_s(co->cpu, "RVM_SWI_NEG")), ruint);
+       else if (r_stringncmp("+", input, size))
+               r_array_push(co->opcodes, RVM_NOP, ruint);
+       else if (r_stringncmp("delete", input, size))
+               r_array_push(co->opcodes, RVM_NOP, ruint);
+       else if (r_stringncmp("void", input, size))
+               r_array_push(co->opcodes, RVM_NOP, ruint);
+       else if (r_stringncmp("typeof", input, size))
+               r_array_push(co->opcodes, RVM_NOP, ruint);
+
        else
                r_array_push(co->opcodes, RVM_ABORT, ruint);
 
@@ -234,32 +349,54 @@ int codegen_opcode_callback(const char *name, void *userdata, const char *input,
                r_array_push(co->opcodes, RVM_EADD, ruint);
        else if (r_stringncmp("+", input,  size))
                r_array_push(co->opcodes, RVM_EADD, ruint);
+       else if (r_stringncmp("+=", input,  size))
+               r_array_push(co->opcodes, RVM_EADD, ruint);
        else if (r_stringncmp("--", input,  size))
                r_array_push(co->opcodes, RVM_ESUB, ruint);
        else if (r_stringncmp("-", input,  size))
                r_array_push(co->opcodes, RVM_ESUB, ruint);
+       else if (r_stringncmp("-=", input,  size))
+               r_array_push(co->opcodes, RVM_ESUB, ruint);
        else if (r_stringncmp("*", input,  size))
                r_array_push(co->opcodes, RVM_EMUL, ruint);
+       else if (r_stringncmp("*=", input,  size))
+               r_array_push(co->opcodes, RVM_EMUL, ruint);
        else if (r_stringncmp("/", input,  size))
                r_array_push(co->opcodes, RVM_EDIV, ruint);
+       else if (r_stringncmp("/=", input,  size))
+               r_array_push(co->opcodes, RVM_EDIV, ruint);
        else if (r_stringncmp("%", input,  size))
                r_array_push(co->opcodes, RVM_EMOD, ruint);
+       else if (r_stringncmp("%=", input,  size))
+               r_array_push(co->opcodes, RVM_EMOD, ruint);
        else if (r_stringncmp("&&", input,  size))
                r_array_push(co->opcodes, RVM_ELAND, ruint);
        else if (r_stringncmp("||", input,  size))
                r_array_push(co->opcodes, RVM_ELOR, ruint);
        else if (r_stringncmp("&", input,  size))
                r_array_push(co->opcodes, RVM_EAND, ruint);
+       else if (r_stringncmp("&=", input,  size))
+               r_array_push(co->opcodes, RVM_EAND, ruint);
        else if (r_stringncmp("|", input,  size))
                r_array_push(co->opcodes, RVM_EORR, ruint);
+       else if (r_stringncmp("|=", input,  size))
+               r_array_push(co->opcodes, RVM_EORR, ruint);
        else if (r_stringncmp("^", input,  size))
                r_array_push(co->opcodes, RVM_EXOR, ruint);
+       else if (r_stringncmp("^=", input,  size))
+               r_array_push(co->opcodes, RVM_EXOR, ruint);
        else if (r_stringncmp(">>", input,  size))
                r_array_push(co->opcodes, RVM_ELSR, ruint);
+       else if (r_stringncmp(">>=", input,  size))
+               r_array_push(co->opcodes, RVM_ELSR, ruint);
        else if (r_stringncmp("<<", input,  size))
                r_array_push(co->opcodes, RVM_ELSL, ruint);
+       else if (r_stringncmp("<<=", input,  size))
+               r_array_push(co->opcodes, RVM_ELSL, ruint);
        else if (r_stringncmp(">>>", input,  size))
                r_array_push(co->opcodes, RVM_ELSRU, ruint);
+       else if (r_stringncmp(">>>=", input,  size))
+               r_array_push(co->opcodes, RVM_ELSRU, ruint);
        else if (r_stringncmp("<=", input,  size))
                r_array_push(co->opcodes, RVM_ELESSEQ, ruint);
        else if (r_stringncmp(">=", input,  size))
@@ -280,6 +417,8 @@ int codegen_opcode_callback(const char *name, void *userdata, const char *input,
                r_array_push(co->opcodes, RVM_ELNOT, ruint);
        else if (r_stringncmp("~", input,  size))
                r_array_push(co->opcodes, RVM_ENOT, ruint);
+       else if (r_stringncmp("=", input,  size))
+               r_array_push(co->opcodes, RVM_NOP, ruint);
        else
                r_array_push(co->opcodes, RVM_ABORT, ruint);
 
@@ -292,53 +431,28 @@ int codegen_binary_asmop_callback(const char *name, void *userdata, const char *
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
-       ruint opcode = r_array_pop(co->opcodes, ruint);
-       rvm_asmins_t * last = rvm_codegen_getcode(co->cg, off - 1);
 
-       if (co->optimized && last->opcode == RVM_PUSH && last->op1 == R1) {
-               rvm_codegen_setcodesize(co->cg, off - 1);
-               off = rvm_codegen_getcodesize(co->cg);
+       if (reason & RPA_REASON_START) {
+               rvm_costat_inclevel(co);
+               rvm_costat_incbinaryop(co);
+       } else if (reason & RPA_REASON_MATCHED) {
+               ruint op1;
+               ruint opcode = r_array_pop(co->opcodes, ruint);
 
-               last = rvm_codegen_getcode(co->cg, off - 1);
-               if (last->opcode == RVM_MOV && last->op1 == R1 && last->op2 == DA) {
-                       rvm_asmins_t binop = *last;
-                       binop.opcode = opcode;
-                       binop.op1 = R0;
-                       binop.op2 = R0;
-                       binop.op3 = DA;
-                       rvm_codegen_setcodesize(co->cg, off - 1);
-                       off = rvm_codegen_getcodesize(co->cg);
-
-                       last = rvm_codegen_getcode(co->cg, off - 1);
-                       if (last->opcode == RVM_PUSH && last->op1 == R0) {
-                               rvm_codegen_setcodesize(co->cg, off - 1);
-                       } else {
-                               rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
-                       }
-                       rvm_codegen_addins(co->cg, binop);
-                       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
+               if (rvm_costat_getlevel(co) < RVM_SAVEDREGS_MAX) {
+                       op1 = rvm_costat_getlevel(co) + RVM_SAVEDREGS_FIRST - 1;
                } else {
-                       rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
-                       rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, R1, 0));
-                       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
+                       rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
+                       op1 = R1;
                }
-       } else if (co->optimized && last->opcode == RVM_PUSH && last->op1 == R0) {
-               rvm_codegen_setcodesize(co->cg, off - 1);
-               off = rvm_codegen_getcodesize(co->cg);
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
-               rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, R1, 0));
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
-       } else  {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
-               rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, R1, 0));
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
+               rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, op1, R0, 0));
+               rvm_costat_declevel(co);
+               rvm_costat_decbinaryop(co);
+       } else if (reason & RPA_REASON_END) {
+               rvm_costat_declevel(co);
+               rvm_costat_decbinaryop(co);
        }
 
-
-
-
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
 
@@ -346,26 +460,30 @@ int codegen_binary_asmop_callback(const char *name, void *userdata, const char *
 }
 
 
-int codegen_unary_asmop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_valop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
-       ruint opcode = r_array_pop(co->opcodes, ruint);
+       rvm_asmins_t *last = rvm_codegen_getcode(co->cg, off - 1);
 
-       if (co->optimized) {
-               rvm_asmins_t * last = rvm_codegen_getcode(co->cg, off - 1);
-               if (last->opcode == RVM_PUSH && last->op1 == R0) {
-                       rvm_codegen_setcodesize(co->cg, off - 1);
-                       off = rvm_codegen_getcodesize(co->cg);
+       if ((reason & RPA_REASON_START) && rvm_costat_getbinaryop(co)) {
+               if (rvm_costat_getlevel(co) < RVM_SAVEDREGS_MAX) {
+                       if (co->optimized && last->op1 == R0 && (last->opcode == RVM_MOV || last->opcode == RVM_LDRR ||
+                                       last->opcode == RVM_LDS || (last->opcode >= RVM_EADD && last->opcode <= RVM_ELESSEQ))) {
+                               last->op1 = rvm_costat_getlevel(co) + RVM_SAVEDREGS_FIRST - 1;
+                               off -= 1;
+                       } else {
+                               rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, rvm_costat_getlevel(co) + RVM_SAVEDREGS_FIRST - 1, R0, XX, 0));
+                       }
                } else {
-                       rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
+                       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
                }
+       }
+
+
+       if (reason & RPA_REASON_MATCHED) {
 
-       } else {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
        }
-       rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -374,17 +492,11 @@ int codegen_unary_asmop_callback(const char *name, void *userdata, const char *i
 }
 
 
-int codegen_postfixexpressionvalop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_conditionalexp_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
 
-//     rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
-//     rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_POINTER));
-//     rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
-//     rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
-
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
 
@@ -392,57 +504,54 @@ int codegen_postfixexpressionvalop_callback(const char *name, void *userdata, co
 }
 
 
-int codegen_push_r0_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_unary_asmop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
-       rvm_asmins_t *last = rvm_codegen_getcode(co->cg, off - 1);
+       ruint op1 = rvm_costat_getlevel(co) ? RVM_SAVEDREGS_FIRST - 1 + rvm_costat_getlevel(co) : R0;
 
-       if (co->optimized && last->opcode == RVM_MOV && last->op1 == R0 && last->op2 == R1) {
-               rvm_codegen_setcodesize(co->cg, off - 1);
-               off = rvm_codegen_getcodesize(co->cg);
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R1, XX, XX, 0));
-       } else {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
+       if (reason & RPA_REASON_START) {
+       }
+
+       if (reason & RPA_REASON_MATCHED) {
+               ruint opcode = r_array_pop(co->opcodes, ruint);
+               rvm_codegen_addins(co->cg, rvm_asm(opcode, op1, op1, XX, 0));
+       }
+
+       if (reason & RPA_REASON_END) {
        }
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
-
        return size;
 }
 
 
-int codegen_push_r1_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_costate_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
 
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R1, XX, XX, 0));
+       if (reason & RPA_REASON_START) {
+               rvm_costat_push(co);
+       }
+
+       if (reason & RPA_REASON_END) {
+               rvm_costat_pop(co);
+       }
+
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
-
        return size;
 }
 
 
-int codegen_pop_r0_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_push_r0_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
 
-       if (co->optimized) {
-               rvm_asmins_t * last = rvm_codegen_getcode(co->cg, off - 1);
-               if (last->opcode == RVM_PUSH && last->op1 == R0) {
-                       rvm_codegen_setcodesize(co->cg, off - 1);
-                       off = rvm_codegen_getcodesize(co->cg);
-               } else {
-                       rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
-               }
-
-       } else {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
-       }
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -451,12 +560,12 @@ int codegen_pop_r0_callback(const char *name, void *userdata, const char *input,
 }
 
 
-int codegen_literalop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_integer_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
 
-       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R0, R1, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R0, DA, XX, r_strtol(input, NULL, 10)));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -465,12 +574,12 @@ int codegen_literalop_callback(const char *name, void *userdata, const char *inp
 }
 
 
-int codegen_integer_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_printop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
 
-       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R1, DA, XX, r_strtol(input, NULL, 10)));
+       rvm_codegen_addins(co->cg, rvm_asmd(RVM_PRN, R0, DA, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -484,7 +593,7 @@ int codegen_double_callback(const char *name, void *userdata, const char *input,
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
 
-       rvm_codegen_addins(co->cg, rvm_asmd(RVM_MOV, R1, DA, XX, r_strtod(input, NULL)));
+       rvm_codegen_addins(co->cg, rvm_asmd(RVM_MOV, R0, DA, XX, r_strtod(input, NULL)));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -500,7 +609,7 @@ int codegen_string_callback(const char *name, void *userdata, const char *input,
 
        rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R1, DA, XX, (void*)input));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R2, DA, XX, size));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCSTR, R1, R1, R2, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCSTR, R0, R1, R2, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -509,32 +618,43 @@ int codegen_string_callback(const char *name, void *userdata, const char *input,
 }
 
 
-int codegen_programinit_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_program_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        ruint off;
 
-       off = rvm_codegen_getcodesize(co->cg);
+       if (reason & RPA_REASON_START) {
+               off = rvm_codegen_getcodesize(co->cg);
+               rvm_costat_pushroot(co);
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
+       } else {
+               rvm_codegen_replaceins(co->cg, 0, rvm_asm(RVM_MOV, FP, SP, XX, 0));
+               rvm_codegen_replaceins(co->cg, 1, rvm_asm(RVM_ADD, SP, SP, DA, r_array_pop(co->fp, rword)));
+               off = rvm_codegen_getcodesize(co->cg);
+               if (debuginfo)
+                       rvm_codegen_addins(co->cg, rvm_asm(RVM_PRN, R0, XX, XX, 0));
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
+       }
+
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
 
+       if (reason & RPA_REASON_END) {
+               rvm_costat_pop(co);
+       }
        return size;
 }
 
 
-int codegen_program_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+int codegen_opinit_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
-       ruint off;
-
-       rvm_codegen_replaceins(co->cg, 0, rvm_asm(RVM_MOV, FP, SP, XX, 0));
-       rvm_codegen_replaceins(co->cg, 1, rvm_asm(RVM_ADD, SP, SP, DA, r_array_pop(co->fp, rword)));
+       rulong off = rvm_codegen_getcodesize(co->cg);
 
-       off = rvm_codegen_getcodesize(co->cg);
-       if (debuginfo)
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_PRN, R0, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -547,8 +667,13 @@ int codegen_opassign_callback(const char *name, void *userdata, const char *inpu
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
+       ruint opcode = r_array_pop(co->opcodes, ruint);
 
        rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
+       if (opcode != RVM_NOP) {
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R2, R1, XX, 0));
+               rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R2, R0, 0));
+       }
        rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
@@ -566,9 +691,9 @@ int codegen_oppostfix_callback(const char *name, void *userdata, const char *inp
 
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, DA, 1));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(opcode, R2, R0, DA, 1));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R2, R1, XX, 0));
+
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -587,7 +712,6 @@ int codegen_opprefix_callback(const char *name, void *userdata, const char *inpu
        rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, DA, 1));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -632,9 +756,6 @@ int codegen_memberexpressionbase_callback(const char *name, void *userdata, cons
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
 
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_POINTER));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));   // Array Address
        rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));   // Array -> On Stack
 
@@ -678,35 +799,6 @@ int codegen_offset_to_ptr_callback(const char *name, void *userdata, const char
 }
 
 
-int codegen_identifiervalue_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
-{
-       rvm_compiler_t *co = (rvm_compiler_t *)userdata;
-       rulong off = rvm_codegen_getcodesize(co->cg);
-       rvm_varmap_t *v = rvm_scope_lookup(co->scope, input, size);
-
-       if (!v) {
-               fprintf(stdout, "ERROR: undefined variable: ");
-               fwrite(input, sizeof(char), size, stdout);
-               fprintf(stdout, "\n");
-               rpa_dbex_abort(co->dbex);
-               return 0;
-       }
-
-       if (v->datatype == VARMAP_DATATYPE_FPOFFSET) {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_ELDS, R0, FP, DA, v->data.offset));
-       } else {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_ELDS, R0, DA, XX, v->data.offset));
-       }
-
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));   // Push it on the stack
-
-       codegen_print_callback(name, userdata, input, size, reason, start, end);
-       codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
-
-       return size;
-}
-
-
 int codegen_swiidexist_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
@@ -746,10 +838,10 @@ int codegen_opidentifier_callback(const char *name, void *userdata, const char *
        rvm_varmap_t *v = rvm_scope_lookup(co->scope, input, size);
 
        if (v) {
-               if (v->datatype == VARMAP_DATATYPE_FPOFFSET) {
+               if (v->datatype == VARMAP_DATATYPE_OFFSET) {
                        rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
                } else {
-                       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, DA, XX, v->data.offset));
+                       rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
                }
                codegen_print_callback(name, userdata, input, size, reason, start, end);
                codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -772,10 +864,10 @@ int codegen_validentifierop_callback(const char *name, void *userdata, const cha
        rvm_varmap_t *v = rvm_scope_lookup(co->scope, input, size);
 
        if (v) {
-               if (v->datatype == VARMAP_DATATYPE_FPOFFSET) {
+               if (v->datatype == VARMAP_DATATYPE_OFFSET) {
                        rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, FP, DA, v->data.offset));
                } else {
-                       rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, DA, XX, v->data.offset));
+                       rvm_codegen_addins(co->cg, rvm_asmp(RVM_LDRR, R0, DA, XX, v->data.ptr));
                }
                codegen_print_callback(name, userdata, input, size, reason, start, end);
                codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -788,7 +880,6 @@ int codegen_validentifierop_callback(const char *name, void *userdata, const cha
        fprintf(stdout, "\n");
        rpa_dbex_abort(co->dbex);
        return 0;
-
 }
 
 
@@ -805,17 +896,22 @@ int codegen_varalloc_to_ptr_callback(const char *name, void *userdata, const cha
                return 0;
        }
 
-       r_array_push(co->fp, r_array_pop(co->fp, rword) + 1, rword);
-       rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
+       if (rvm_scope_count(co->scope)) {
+               r_array_inclast(co->fp, rword);
+               rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
+       } else {
+               rvm_scope_addpointer(co->scope, input, size, r_carray_slot_expand(co->cpu->data, r_carray_length(co->cpu->data)));
+               r_carray_inclength(co->cpu->data);
+       }
        v = rvm_scope_tiplookup(co->scope, input, size);
 
-       if (v->datatype == VARMAP_DATATYPE_FPOFFSET) {
+       if (v->datatype == VARMAP_DATATYPE_OFFSET) {
                rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
        } else {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, DA, XX, v->data.offset));
+               rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
        }
-
        rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
+
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
 
@@ -836,8 +932,13 @@ int codegen_varalloc_callback(const char *name, void *userdata, const char *inpu
                return 0;
        }
 
-       r_array_push(co->fp, r_array_pop(co->fp, rword) + 1, rword);
-       rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
+       if (rvm_scope_count(co->scope)) {
+               r_array_inclast(co->fp, rword);
+               rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
+       } else {
+               rvm_scope_addpointer(co->scope, input, size, r_carray_slot_expand(co->cpu->data, r_carray_length(co->cpu->data)));
+               r_carray_inclength(co->cpu->data);
+       }
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -846,8 +947,6 @@ int codegen_varalloc_callback(const char *name, void *userdata, const char *inpu
 }
 
 
-
-
 int codegen_newarraysize_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
@@ -855,7 +954,6 @@ int codegen_newarraysize_callback(const char *name, void *userdata, const char *
 
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCARR, R0, R1, XX, 0));
-//     rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -930,34 +1028,6 @@ int codegen_funcallparameter_callback(const char *name, void *userdata, const ch
 }
 
 
-int codegen_funcallexpression_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
-{
-       rvm_compiler_t *co = (rvm_compiler_t *)userdata;
-       rulong off = rvm_codegen_getcodesize(co->cg);
-       rvm_funcall_t *funcall = r_array_empty(co->funcall) ? NULL : (rvm_funcall_t *) r_array_slot(co->funcall, r_array_length(co->funcall) - 1);
-
-
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, FP, SP, DA, funcall->params));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, DA, XX, funcall->params));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_STS, R1, FP, DA, -3));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, FP, DA, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_SWIID));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 5));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_SWIID, R0, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, SP, FP, DA, 1));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 2));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BL, R0, DA, XX, -rvm_codegen_getcodesize(co->cg)));
-
-       r_array_remove(co->funcall);
-       codegen_print_callback(name, userdata, input, size, reason, start, end);
-       codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
-
-       return size;
-}
-
-
 int codegen_funcallname_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
@@ -972,17 +1042,12 @@ int codegen_funcallname_callback(const char *name, void *userdata, const char *i
         * and FP will point there. After the call we save the LR at that spot
         * as we don't need the RO anymore.
         */
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_POINTER));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));
+//     rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
+//     rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_POINTER));
+//     rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
+//     rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));
 
-       /*
-        * R1 is just a place holder, we will write the number of args passed
-        * later when we find out the number
-        */
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, DA, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R1)|BIT(FP)|BIT(SP)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
@@ -992,6 +1057,27 @@ int codegen_funcallname_callback(const char *name, void *userdata, const char *i
 }
 
 
+int codegen_funcallexpression_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
+{
+       rvm_compiler_t *co = (rvm_compiler_t *)userdata;
+       rulong off = rvm_codegen_getcodesize(co->cg);
+       rvm_funcall_t *funcall = r_array_empty(co->funcall) ? NULL : (rvm_funcall_t *) r_array_slot(co->funcall, r_array_length(co->funcall) - 1);
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, FP, SP, DA, funcall->params));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R1, FP, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_STS, LR, FP, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_CALL, R1, DA, XX, -rvm_codegen_getcodesize(co->cg)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(FP,LR)));
+
+       r_array_removelast(co->funcall);
+       codegen_print_callback(name, userdata, input, size, reason, start, end);
+       codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
+
+       return size;
+}
+
+
 int codegen_fundeclparameter_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
@@ -1007,7 +1093,7 @@ int codegen_fundeclparameter_callback(const char *name, void *userdata, const ch
        }
 
        fundecl->params += 1;
-       r_array_push(co->fp, r_array_pop(co->fp, rword) + 1, rword);
+       r_array_inclast(co->fp, rword);
        rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -1020,23 +1106,24 @@ int codegen_fundeclname_callback(const char *name, void *userdata, const char *i
 {
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
-       rvm_fundecl_t fundecl = {input, size, 0, off, 0};
+       rvm_fundecl_t fundecl = {input, size, 0, off};
        rint ret;
 
        ret = codegen_varalloc_callback(name, userdata, input, size, reason, start, end);
        if (ret == 0)
                return ret;
 
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, 0));    /* Will be re-written later */
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, DA, R0, XX, 0));   /* Will be re-written later */
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));              /* Will be re-written later */
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, SP, FP, DA, 0));    /* Will be re-written later */
        rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
+//     rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
 
        r_array_push(co->fp, 0, rword);
        r_array_add(co->fundecl, &fundecl);
        rvm_scope_push(co->scope);
+       rvm_costat_pushroot(co);
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -1072,28 +1159,30 @@ int codegen_fundecl_callback(const char *name, void *userdata, const char *input
        /*
         * Function end, we first define the function end
         */
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xeeeeeeee));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(PC)));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xeeeeeeee));
+       if (rvm_costat_getdirty(co))
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(RVM_SAVEDREGS_FIRST, RVM_SAVEDREGS_FIRST+ rvm_costat_getdirty(co) - 1)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
 
+       /*
+        * the number of arguments passed is = SP - FP
+        */
        fundecl->codesize = rvm_codegen_getcodesize(co->cg) - fundecl->codestart;
-
-
-       if (fname->datatype == VARMAP_DATATYPE_FPOFFSET) {
+       if (fname->datatype == VARMAP_DATATYPE_OFFSET) {
                rvm_codegen_replaceins(co->cg, fundecl->codestart + 0, rvm_asm(RVM_ADDRS, R0, FP, DA, fname->data.offset));
        } else {
-               rvm_codegen_replaceins(co->cg, fundecl->codestart + 0, rvm_asm(RVM_ADDRS, R0, DA, XX, fname->data.offset));
+               rvm_codegen_replaceins(co->cg, fundecl->codestart + 0, rvm_asmp(RVM_MOV, R0, DA, XX, fname->data.ptr));
        }
        rvm_codegen_replaceins(co->cg, fundecl->codestart + 1, rvm_asm(RVM_STRR, DA, R0, XX, fundecl->codestart + 3));
        rvm_codegen_replaceins(co->cg, fundecl->codestart + 2, rvm_asm(RVM_B, DA, XX, XX, fundecl->codesize - 2));
-       rvm_codegen_replaceins(co->cg, fundecl->codestart + 3, rvm_asm(RVM_STS, LR, FP, DA, 0));
-       rvm_codegen_replaceins(co->cg, fundecl->codestart + 4, rvm_asm(RVM_ADD, SP, FP, DA, fp));
+       rvm_codegen_replaceins(co->cg, fundecl->codestart + 3, rvm_asm(RVM_ADD, SP, FP, DA, fp));
+       if (rvm_costat_getdirty(co))
+               rvm_codegen_replaceins(co->cg, fundecl->codestart + 4, rvm_asm(RVM_PUSHM, DA, XX, XX, BITS(RVM_SAVEDREGS_FIRST, RVM_SAVEDREGS_FIRST + rvm_costat_getdirty(co) - 1)));
 
        fundecl->codesize = rvm_codegen_getcodesize(co->cg) - fundecl->codestart;
        fundecl->params = r_array_last(co->fp, rword);
 
-       r_array_remove(co->fundecl);
+       r_array_removelast(co->fundecl);
+       rvm_costat_pop(co);
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
 
@@ -1106,8 +1195,9 @@ int codegen_opreturn_callback(const char *name, void *userdata, const char *inpu
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
 
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(PC)));
+       if (rvm_costat_getdirty(co))
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(RVM_SAVEDREGS_FIRST, RVM_SAVEDREGS_FIRST + rvm_costat_getdirty(co) - 1)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
 
        codegen_print_callback(name, userdata, input, size, reason, start, end);
        codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
@@ -1209,9 +1299,16 @@ int codegen_iterationdo_callback(const char *name, void *userdata, const char *i
        rvm_compiler_t *co = (rvm_compiler_t *)userdata;
        rulong off = rvm_codegen_getcodesize(co->cg);
        rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
+       rvm_asmins_t *last = rvm_codegen_getcode(co->cg, off - 1);
 
+       if (last->op1 == R0 && last->opcode >= RVM_EADD && last->opcode <= RVM_ELESSEQ) {
+               /*
+                * Nothing to do, the status register will be updated.
+                */
+       } else {
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
+       }
 
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
        cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, -cs.codesize));
        rvm_codemap_poploopblock(co->cg->codemap);
@@ -1380,18 +1477,19 @@ void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co)
 
        rpa_dbex_open(dbex);
 
-       rpa_dbex_add_callback_exact(dbex, "BitwiseANDOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "BitwiseXOROp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "BitwiseOROp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "AdditiveExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "BitwiseANDOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "BitwiseXOROp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "BitwiseOROp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "AdditiveExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
 
-       rpa_dbex_add_callback_exact(dbex, "MultiplicativeExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "ShiftExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "EqualityExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "RelationalExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "LogicalOROp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "LogicalANDOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "MultiplicativeExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "ShiftExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "EqualityExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "RelationalExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "LogicalOROp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "LogicalANDOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
 
+       rpa_dbex_add_callback_exact(dbex, "AssignmentOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
        rpa_dbex_add_callback_exact(dbex, "EqualityOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
        rpa_dbex_add_callback_exact(dbex, "RelationalOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
        rpa_dbex_add_callback_exact(dbex, "AdditiveOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
@@ -1404,8 +1502,8 @@ void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co)
        rpa_dbex_add_callback_exact(dbex, "LogicalOROperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
        rpa_dbex_add_callback_exact(dbex, "LogicalNotOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
        rpa_dbex_add_callback_exact(dbex, "BitwiseNotOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "UnaryOperatorOpcode", RPA_REASON_MATCHED, codegen_opcode_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "NegativeOperator", RPA_REASON_MATCHED, codegen_opcode_unary_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "UnaryOperatorOpcode", RPA_REASON_MATCHED, codegen_opcode_unary_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "PrintOp", RPA_REASON_MATCHED, codegen_printop_callback, co);
 
 
        rpa_dbex_add_callback_exact(dbex, "PostfixOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
@@ -1413,11 +1511,10 @@ void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co)
        rpa_dbex_add_callback_exact(dbex, "PrefixExpressionOp", RPA_REASON_MATCHED, codegen_opprefix_callback, co);
 
 
-       rpa_dbex_add_callback_exact(dbex, "UnaryExpressionOp", RPA_REASON_MATCHED, codegen_unary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "LogicalNotExpressionOp", RPA_REASON_MATCHED, codegen_unary_asmop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "BitwiseNotExpressionOp", RPA_REASON_MATCHED, codegen_unary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "UnaryExpressionOp", RPA_REASON_ALL, codegen_unary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "LogicalNotExpressionOp", RPA_REASON_ALL, codegen_unary_asmop_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "BitwiseNotExpressionOp", RPA_REASON_ALL, codegen_unary_asmop_callback, co);
 
-       rpa_dbex_add_callback_exact(dbex, "LiteralOp", RPA_REASON_MATCHED, codegen_literalop_callback, co);
        rpa_dbex_add_callback_exact(dbex, "DecimalIntegerLiteral", RPA_REASON_MATCHED, codegen_integer_callback, co);
        rpa_dbex_add_callback_exact(dbex, "DecimalNonIntegerLiteral", RPA_REASON_MATCHED, codegen_double_callback, co);
        rpa_dbex_add_callback_exact(dbex, "BlockBegin", RPA_REASON_MATCHED, codegen_scopepush_callback, co);
@@ -1426,16 +1523,12 @@ void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co)
        rpa_dbex_add_callback_exact(dbex, "DoKeyword", RPA_REASON_MATCHED, codegen_dokeyword_callback, co);
        rpa_dbex_add_callback_exact(dbex, "IterationDo", RPA_REASON_MATCHED, codegen_iterationdo_callback, co);
 
-
-
        rpa_dbex_add_callback_exact(dbex, "sqstring", RPA_REASON_MATCHED, codegen_string_callback, co);
        rpa_dbex_add_callback_exact(dbex, "dqstring", RPA_REASON_MATCHED, codegen_string_callback, co);
        rpa_dbex_add_callback_exact(dbex, "DoubleStringCharacters", RPA_REASON_MATCHED, codegen_string_callback, co);
        rpa_dbex_add_callback_exact(dbex, "SingleStringCharacters", RPA_REASON_MATCHED, codegen_string_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "ProgramInit", RPA_REASON_MATCHED, codegen_programinit_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "Program", RPA_REASON_MATCHED, codegen_program_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "Initialiser", RPA_REASON_MATCHED, codegen_opassign_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "AssignmentEq", RPA_REASON_MATCHED, codegen_opassign_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "Program", RPA_REASON_START|RPA_REASON_MATCHED, codegen_program_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "Initialiser", RPA_REASON_MATCHED, codegen_opinit_callback, co);
        rpa_dbex_add_callback_exact(dbex, "AssignmentExpressionOp", RPA_REASON_MATCHED, codegen_opassign_callback, co);
 
        rpa_dbex_add_callback_exact(dbex, "VariableAllocate", RPA_REASON_MATCHED, codegen_varalloc_callback, co);
@@ -1447,12 +1540,8 @@ void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co)
        rpa_dbex_add_callback_exact(dbex, "SwiIdExist", RPA_REASON_MATCHED, codegen_swiidexist_callback, co);
 
        rpa_dbex_add_callback_exact(dbex, "IdentifierOp", RPA_REASON_MATCHED, codegen_opidentifier_callback, co);
-
        rpa_dbex_add_callback_exact(dbex, "ValIdentifierOp", RPA_REASON_MATCHED, codegen_validentifierop_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "PostfixExpressionValOp", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
-
-//     rpa_dbex_add_callback_exact(dbex, "AssignmentOperator", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
-
+       rpa_dbex_add_callback_exact(dbex, "PostfixExpressionValOp", RPA_REASON_ALL, codegen_valop_callback, co);
 
        rpa_dbex_add_callback_exact(dbex, "LeftHandSideExpressionPush", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
        rpa_dbex_add_callback_exact(dbex, "LiteralPushOp", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
@@ -1470,14 +1559,16 @@ void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co)
        rpa_dbex_add_callback_exact(dbex, "ValCallExpressionIndexBaseOp", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
        rpa_dbex_add_callback_exact(dbex, "ValCallExpressionIndexOp", RPA_REASON_MATCHED, codegen_arrayelementvalue_callback, co);
 
-       rpa_dbex_add_callback_exact(dbex, "ConditionalExpression", RPA_REASON_MATCHED, codegen_pop_r0_callback, co);
-       rpa_dbex_add_callback_exact(dbex, "IdentifierValueOp", RPA_REASON_MATCHED, codegen_identifiervalue_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "ConditionalExpression", RPA_REASON_MATCHED, codegen_conditionalexp_callback, co);
 
-       rpa_dbex_add_callback_exact(dbex, "ValueOfExpression", RPA_REASON_MATCHED, codegen_pop_r0_callback, co);
        rpa_dbex_add_callback_exact(dbex, "NewArraySize", RPA_REASON_MATCHED, codegen_newarraysize_callback, co);
        rpa_dbex_add_callback_exact(dbex, "NewArrayNoSize", RPA_REASON_MATCHED, codegen_newarraynosize_callback, co);
        rpa_dbex_add_callback_exact(dbex, "compile_error", RPA_REASON_MATCHED, codegen_compile_error_callback, co);
 
+//     rpa_dbex_add_callback_exact(dbex, "ValCallExpression", RPA_REASON_ALL, codegen_costate_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "ArgumentsOp", RPA_REASON_ALL, codegen_costate_callback, co);
+       rpa_dbex_add_callback_exact(dbex, "BracketExpressionOp", RPA_REASON_ALL, codegen_costate_callback, co);
+
        rpa_dbex_add_callback_exact(dbex, "FunctionName", RPA_REASON_MATCHED, codegen_fundeclname_callback, co);
        rpa_dbex_add_callback_exact(dbex, "FunctionDefinition", RPA_REASON_MATCHED, codegen_fundeclsignature_callback, co);
        rpa_dbex_add_callback_exact(dbex, "FunctionDeclaration", RPA_REASON_MATCHED, codegen_fundecl_callback, co);
diff --git a/tests/speed-test.c b/tests/speed-test.c
new file mode 100644 (file)
index 0000000..6ba698e
--- /dev/null
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "common.h"
+#include "rvmoperator.h"
+
+
+static void rvm_eadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_ADD, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+//     fprintf(stdout, "%s %ld\n", __FUNCTION__, RVM_CPUREG_GETU(cpu, ins->op1));
+}
+
+
+static void rvm_callback_two(rvmcpu_t *vm, rvm_asmins_t *ins)
+{
+       fprintf(stdout, "%s\n", __FUNCTION__);
+}
+
+
+static rvm_switable_t calltable[] = {
+       {"rvm_callback_two", rvm_callback_two},
+       {"rvm_eadd", rvm_eadd},
+       {NULL, NULL},
+};
+
+       
+int main(int argc, char *argv[])
+{
+       rlong i, iter = 1;
+       ruint ret = 0;
+       ruint off = 0;
+       rvm_asmins_t vmcode[256];
+       rvmcpu_t *vm = rvm_cpu_create();
+
+       if (argc > 1) {
+               iter = atol(argv[1]);
+       }
+
+       rvm_cpu_addswitable(vm, calltable);
+       rvm_cpu_addswitable(vm, common_calltable);
+
+       vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 0);
+       for (i = 0; i < 25; i++)
+               vmcode[off++] = rvm_asm(RVM_NOP, XX, XX, XX, 0);
+       for (i = 0; i < 15; i++)
+               vmcode[off++] = rvm_asm(RVM_NOP, XX, XX, XX, BIT(R5));
+       for (i = 0; i < 15; i++)
+               vmcode[off++] = rvm_asm(RVM_NOP, XX, XX, XX, BIT(R5));
+       for (i = 0; i < 5; i++)
+               vmcode[off++] = rvm_asm(RVM_NOP, XX, XX, XX, 0);
+       for (i = 0; i < 5; i++)
+               vmcode[off++] = rvm_asm(RVM_NOP, XX, XX, XX, 0);
+
+       vmcode[off++] = rvm_asm(RVM_ADD, R0, R0, DA, 1);
+       vmcode[off++] = rvm_asm(RVM_CMP, R0, DA, XX, iter);
+       vmcode[off++] = rvm_asm(RVM_BLES, DA, XX, XX, -45);
+       vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
+       vmcode[off++] = rvm_asm(RVM_EXT, R0, XX, XX, 0);
+
+
+       rvm_relocate(vmcode, off);
+       ret = rvm_cpu_exec(vm, vmcode, 0);
+       fprintf(stdout, "R0 = %ld (%ld operations)\n", (unsigned long) RVM_CPUREG_GETU(vm, R0), (unsigned long)RVM_CPUREG_GETU(vm, R5));
+       rvm_cpu_destroy(vm);
+       return 0;
+}
index 58731bc..e984e59 100644 (file)
@@ -1,7 +1,11 @@
 var a = 2; 
 
+function mul(a,b) {
+       return a*b;
+}
+
 function add (a, b) {
-       return a + b;
+       return 2*(a+mul(2,b)-b) - (a+mul(2,b)-b);
 }
 
 function sub (a, b) {
@@ -9,14 +13,19 @@ function sub (a, b) {
 }
 
 
-if ( (a == 4) ) 
-{
-       a=3;
-       a=4;
-} else if (a==2) {
-       a=5;
-       a=10;
-} 
+function iter() {
+       var i = 0;
+
+       do {
+               i = add(i,1.001);
+       } while (i < 2000000);
+       print(i);
+}
 
+var i = 0;
 
-print(add(a, sub(3,2)));
+do {
+       i = add(i,1.001);
+} while (i < 2000000);
+print(i);
+iter();
diff --git a/tests/test.php b/tests/test.php
new file mode 100644 (file)
index 0000000..0292186
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+       function mul($a, $b)
+       {
+               return $a*$b;
+       }
+
+       function add($a, $b)
+       {
+               return 2 * ($a + mul(2, $b) - $b) - ($a + mul(2, $b) - $b);
+       }
+
+       function iter() {
+               $i = 0;
+               do {
+                       $i = add($i, 1.001);
+               } while ($i < 2000000);
+               echo($i . "\n");
+       }
+
+       $i = 0;
+       do {
+          $i = add($i, 1.001);
+       } while ($i < 2000000);
+
+       echo($i . "\n");
+       iter();
+
+
+?>