RPA Toolkit
RJS prop access changes... continued.
authorMartin Stoilov <martin@rpasearch.com>
Fri, 26 Aug 2011 05:04:20 +0000 (22:04 -0700)
committerMartin Stoilov <martin@rpasearch.com>
Fri, 26 Aug 2011 05:04:20 +0000 (22:04 -0700)
rjs/rjs.c
rjs/rjs.h
rjs/rjscompiler.c
rvm/rvmcpu.c
rvm/rvmreg.c
rvm/rvmreg.h

index 9c57bb4..b7efb52 100644 (file)
--- a/rjs/rjs.c
+++ b/rjs/rjs.c
@@ -351,6 +351,8 @@ static long rjs_op_mapproplookup(rmap_t *map, rvmcpu_t *cpu, rvm_asmins_t *ins)
        long index = -1;
        rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
+       if (!map)
+               return -1;
        if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_SIGNED || RVM_REG_GETTYPE(arg3) == RVM_DTYPE_UNSIGNED) {
                index = r_map_lookup_l(map, -1, (long)RVM_REG_GETL(arg3));
        } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_DOUBLE) {
@@ -373,13 +375,75 @@ static long rjs_op_stringproplookup(rstring_t *str, rvmcpu_t *cpu, rvm_asmins_t
                index = RVM_REG_GETL(arg3);
        } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_DOUBLE) {
                index = (long)RVM_REG_GETD(arg3);
-       } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_STRING) {
-               index = r_strtol(((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.str, NULL, 10);
        }
+
+       if (index >= str->s.size)
+               index = -1;
        return index;
 }
 
 
+static void rjs_op_propget(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       long index = -1;
+       rmap_t *map;
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+
+       if (rvm_reg_gettype(arg2) == RVM_DTYPE_MAP) {
+               rmap_t *map = (rmap_t*)RVM_REG_GETP(arg2);
+               index = rjs_op_mapproplookup(map, cpu, ins);
+               if (index >= 0) {
+                       *arg1 = *((rvmreg_t*)r_map_value(map, index));
+                       return;
+               }
+       } else if (rvm_reg_gettype(arg2) == RVM_DTYPE_STRING) {
+               rstring_t *str = (rstring_t*)RVM_REG_GETP(arg2);
+               index = rjs_op_stringproplookup(str, cpu, ins);
+               if (index >= 0) {
+                       rstring_t * allocstr = r_string_create_strsize(&str->s.str[index], 1);
+                       r_gc_add(cpu->gc, (robject_t*)allocstr);
+                       rvm_reg_setstring(arg1, allocstr);
+                       return;
+               }
+       }
+
+       map = rjs_engine_get(cpu)->props[rvm_reg_gettype(arg2)];
+       index = rjs_op_mapproplookup(map, cpu, ins);
+       if (index >= 0) {
+               rvmreg_t *val = (rvmreg_t*)r_map_value(map, index);
+               if (RVM_REG_GETTYPE(val) == RVM_DTYPE_PROPHANDLER) {
+                       ((rvmcpu_op)RVM_REG_GETP(val))(cpu, ins);
+               } else {
+                       *arg1 = *val;
+               }
+               return;
+       }
+       rvm_reg_setundef(arg1);
+}
+
+
+static void rjs_op_propset(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       long index = -1;
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rmap_t *map = (rmap_t*)RVM_REG_GETP(arg2);
+       rpointer value = NULL;
+
+       if (rvm_reg_gettype(arg2) == RVM_DTYPE_MAP) {
+               index = rjs_op_mapproplookupadd(map, cpu, ins);
+               value = r_map_value(map, index);
+       }
+       if (!value) {
+               value = &rjs_engine_get(cpu)->scratch;
+       }
+       RVM_REG_CLEAR(arg1);
+       RVM_REG_SETTYPE(arg1, RVM_DTYPE_POINTER);
+       RVM_REG_SETP(arg1, value);
+}
+
+
 static void rjs_op_proplookup(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        long index = -1;
@@ -395,7 +459,7 @@ static void rjs_op_proplookup(rvmcpu_t *cpu, rvm_asmins_t *ins)
                rstring_t *str = (rstring_t*)RVM_REG_GETP(arg2);
                index = rjs_op_stringproplookup(str, cpu, ins);
                if (index < 0) {
-                       index = rjs_op_mapproplookup(RJS_CPU2JSE(cpu)->props[RVM_DTYPE_STRING], cpu, ins);
+                       index = rjs_op_mapproplookup(rjs_engine_get(cpu)->props[RVM_DTYPE_STRING], cpu, ins);
                        if (index >= 0)
                                globalprop = TRUE;
                }
@@ -447,7 +511,7 @@ static void rjs_op_propldr(rvmcpu_t *cpu, rvm_asmins_t *ins)
        } else if (rvm_reg_gettype(arg2) == RVM_DTYPE_STRING) {
                rstring_t *s = (rstring_t*)RVM_REG_GETP(arg2);
                if (RVM_REG_TSTFLAG(arg1, RVM_INFOBIT_GLOBAL)) {
-                       rmap_t *a = RJS_CPU2JSE(cpu)->props[RVM_DTYPE_STRING];
+                       rmap_t *a = rjs_engine_get(cpu)->props[RVM_DTYPE_STRING];
                        value = r_map_value(a, index);
                        if (value) {
                                *arg1 = *((rvmreg_t*)value);
@@ -879,7 +943,7 @@ static void rjs_string_length(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rvmreg_t *r = NULL;
        rstring_t *src;
 
-       r = (rvmreg_t *) RVM_CPUREG_PTR(cpu, TP);
+       r = (rvmreg_t *) RVM_CPUREG_PTR(cpu, ins->op2);
        if (rvm_reg_gettype(r) != RVM_DTYPE_STRING)
                RJS_SWI_ABORT(rjs_engine_get(cpu), NULL);
        src = (rstring_t *)RVM_REG_GETP(r);
@@ -892,7 +956,6 @@ rjs_engine_t *rjs_engine_create()
 {
        rvmcpu_t *cpu;
        rvmreg_t *tp;
-       rvmreg_t tmp;
        rjs_engine_t *jse = (rjs_engine_t *) r_zmalloc(sizeof(*jse));
 
        jse->pa = rjs_parser_create();
@@ -946,6 +1009,8 @@ rjs_engine_t *rjs_engine_create()
        rvm_cpu_setophandler(cpu, RJS_PROPPREV, "RJS_PROPPREV", rjs_op_propprev);
        rvm_cpu_setophandler(cpu, RJS_STRALLOC, "RJS_STRALLOC", rjs_op_stralloc);
        rvm_cpu_setophandler(cpu, RJS_MAPALLOC, "RJS_MAPALLOC", rjs_op_mapalloc);
+       rvm_cpu_setophandler(cpu, RJS_PROPGET, "RJS_PROPGET", rjs_op_propget);
+       rvm_cpu_setophandler(cpu, RJS_PROPSET, "RJS_PROPSET", rjs_op_propset);
 
        cpu->userdata2 = rjs_opmap_create();
        rjs_op_binary_init(RJS_USERDATA2MAP(cpu->userdata2));
@@ -953,14 +1018,8 @@ rjs_engine_t *rjs_engine_create()
        rjs_op_not_init(RJS_USERDATA2MAP(cpu->userdata2));
        rjs_op_logicnot_init(RJS_USERDATA2MAP(cpu->userdata2));
 
-
-       jse->props[RVM_DTYPE_STRING] = r_map_create(sizeof(rvmreg_t), 3);
-       tmp = rvm_reg_create_swi(rvm_cpu_swilookup_s(cpu, "rjsswitable", "string.ltrim"));
-       r_map_add_s(jse->props[RVM_DTYPE_STRING], "ltrim", &tmp);
-       tmp = rvm_reg_create_swi(rvm_cpu_swilookup_s(cpu, "rjsswitable", "string.length"));
-       r_map_add_s(jse->props[RVM_DTYPE_STRING], "length", &tmp);
-       r_gc_add(jse->cpu->gc, (robject_t*)jse->props[RVM_DTYPE_STRING]);
-
+       rjs_set_ophandler(jse, RVM_DTYPE_STRING, "ltrim", rjs_string_ltrim);
+       rjs_set_prophandler(jse, RVM_DTYPE_STRING, "length", rjs_string_length);
        return jse;
 error:
        rjs_engine_destroy(jse);
@@ -1345,5 +1404,34 @@ void rjs_engine_abort(rjs_engine_t *jse, rjs_error_t *error)
 
 rjs_engine_t *rjs_engine_get(rvmcpu_t *cpu)
 {
-       return (rjs_engine_t *)cpu->userdata1;
+       return RJS_CPU2JSE(cpu);
+}
+
+
+static void rjs_set_handler(rjs_engine_t *jse, unsigned long type, const char *name, rconstpointer handler, unsigned long handlertype)
+{
+       rmap_t *map;
+       rvmreg_t r;
+
+       if (type >= RVM_DTYPE_SIZE)
+               return;
+       if (!jse->props[type])
+               jse->props[type] = r_map_create(sizeof(rvmreg_t), 3);
+       map = jse->props[type];
+       r_memset(&r, 0, sizeof(r));
+       RVM_REG_SETP(&r, handler);
+       RVM_REG_SETTYPE(&r, handlertype);
+       r_map_add_s(map, name, &r);
+}
+
+
+void rjs_set_prophandler(rjs_engine_t *jse, unsigned long type, const char *name, rconstpointer handler)
+{
+       rjs_set_handler(jse, type, name, handler, RVM_DTYPE_PROPHANDLER);
+}
+
+
+void rjs_set_ophandler(rjs_engine_t *jse, unsigned long type, const char *name, rconstpointer handler)
+{
+       rjs_set_handler(jse, type, name, handler, RVM_DTYPE_OPHANDLER);
 }
index e3c9ff2..62898fc 100644 (file)
--- a/rjs/rjs.h
+++ b/rjs/rjs.h
@@ -37,6 +37,7 @@ extern "C" {
 typedef struct rjs_engine_s {
        rjs_parser_t *pa;
        rjs_compiler_t *co;
+       rvmreg_t scratch;
        rarray_t *cgs;
        rarray_t *errors;
        rmap_t *props[RVM_DTYPE_SIZE];
@@ -91,9 +92,11 @@ typedef struct rjs_engine_s {
 #define RJS_PROPDEL                    RVM_USER162             /* Delete Property */
 #define RJS_PROPNEXT           RVM_USER163
 #define RJS_PROPPREV           RVM_USER164
-#define RJS_STRALLOC           RVM_USER165             /* Allocate string in op1, op2 is pointer (char*) to string, op3 is the size */
-#define RJS_ARRALLOC           RVM_USER166             /* Allocate array in op1, op2 is the size */
-#define RJS_MAPALLOC           RVM_USER167             /* Allocate array in op1, op2 is the size */
+#define RJS_PROPGET                    RVM_USER165
+#define RJS_PROPSET                    RVM_USER166
+#define RJS_STRALLOC           RVM_USER167             /* Allocate string in op1, op2 is pointer (char*) to string, op3 is the size */
+#define RJS_ARRALLOC           RVM_USER168             /* Allocate array in op1, op2 is the size */
+#define RJS_MAPALLOC           RVM_USER169             /* Allocate array in op1, op2 is the size */
 
 #define RJS_GPKEY_NONE 0
 #define RJS_GPKEY_TYPES 1
@@ -117,6 +120,8 @@ rvmreg_t *rjs_engine_args_exec_s(rjs_engine_t *jse, const char *script, unsigned
 rvmreg_t *rjs_engine_exec_s(rjs_engine_t *jse, const char *script);
 void rjs_engine_abort(rjs_engine_t *jse, rjs_error_t *error);
 rjs_engine_t *rjs_engine_get(rvmcpu_t *cpu);
+void rjs_set_prophandler(rjs_engine_t *jse, unsigned long type, const char *name, rconstpointer handler);
+void rjs_set_ophandler(rjs_engine_t *jse, unsigned long type, const char *name, rconstpointer handler);
 
 #ifdef __cplusplus
 }
index 5329443..1fe9ad2 100644 (file)
@@ -800,15 +800,23 @@ int rjs_compiler_rh_memberexpressiondotop(rjs_compiler_t *co, rarray_t *records,
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rjs_compiler_record_lastofkind(co, records, rec)) {
+               rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPSET, R0, R1, R2, 0));        // R1 Array
+
+#if 0
                rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPLKUPADD, R0, R1, R2, 0));    // Get the offset of the element at offset R0
                rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPADDR, R0, R1, R0, 0));       // Get the address of the element at offset R0
+#endif
 
        } else {
+               rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPGET, R0, R1, R2, 0));        // Get the property
+
+#if 0
                rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPLKUP, R0, R1, R2, 0));       // Get the offset of the element at offset R0
                if (ctx && ctx->type == RJS_COCTX_DELETE)
                        rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPDEL, R0, R1, R0, 0));                // Get the result of deletion in R0
                else
                        rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPLDR, R0, R1, R0, 0));                // Get the value of the element at offset R0
+#endif
        }
        rjs_compiler_debugtail(co, records, rec);
        return 0;
@@ -833,16 +841,23 @@ int rjs_compiler_rh_memberexpressionindexop(rjs_compiler_t *co, rarray_t *record
        rjs_compiler_debughead(co, records, rec);
        if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rjs_compiler_record_lastofkind(co, records, rec)) {
                rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly an Array
+#if 0
                rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPLKUPADD, R0, R1, R0, 0));    // R1 Array
                rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPADDR, R0, R1, R0, 0));       // Get the address of the element at offset R0
+#endif
+               rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPSET, R0, R1, R0, 0));        // R1 Array
 
        } else {
                rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly an Array
+               rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPGET, R0, R1, R0, 0));        // R1 Array
+#if 0
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly an Array
                rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPLKUP, R0, R1, R0, 0));       // R1 Array
                if (ctx && ctx->type == RJS_COCTX_DELETE)
                        rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPDEL, R0, R1, R0, 0));                // Get the result of deletion in R0
                else
                        rvm_codegen_addins(co->cg, rvm_asm(RJS_PROPLDR, R0, R1, R0, 0));                // Get the value of the element at offset R0
+#endif
        }
        rjs_compiler_debugtail(co, records, rec);
        return 0;
index 6274ab0..a7695dc 100644 (file)
@@ -603,6 +603,8 @@ static void rvm_op_call(rvmcpu_t *cpu, rvm_asmins_t *ins)
                rvm_op_swiid(cpu, ins);
        } else if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_FUNCTION) {
                rvm_op_bxl(cpu, ins);
+       } else if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_OPHANDLER) {
+               ((rvmcpu_op)RVM_REG_GETP(arg1))(cpu, ins);
        } else {
                RVM_ABORT(cpu, RVM_E_NOTFUNCTION);
        }
index 7bdb3fb..fcd90ae 100644 (file)
@@ -227,6 +227,30 @@ rvmreg_t rvm_reg_create_signed(rword l)
 }
 
 
+rvmreg_t rvm_reg_create_pointer(rpointer p)
+{
+       rvmreg_t r;
+       rvm_reg_setpointer(&r, p);
+       return r;
+
+}
+
+rvmreg_t rvm_reg_create_ophandler(rpointer p)
+{
+       rvmreg_t r;
+       rvm_reg_setophandler(&r, p);
+       return r;
+}
+
+
+rvmreg_t rvm_reg_create_prophandler(rpointer p)
+{
+       rvmreg_t r;
+       rvm_reg_setprophandler(&r, p);
+       return r;
+}
+
+
 void rvm_reg_cleanup(rvmreg_t *reg)
 {
        RVM_REG_CLEAR(reg);
@@ -327,6 +351,22 @@ void rvm_reg_setpointer(rvmreg_t *r, rpointer p)
 }
 
 
+void rvm_reg_setophandler(rvmreg_t *r, rpointer p)
+{
+       r_memset(r, 0, sizeof(*r));
+       RVM_REG_SETP(r, p);
+       RVM_REG_SETTYPE(r, RVM_DTYPE_OPHANDLER);
+}
+
+
+void rvm_reg_setprophandler(rvmreg_t *r, rpointer p)
+{
+       r_memset(r, 0, sizeof(*r));
+       RVM_REG_SETP(r, p);
+       RVM_REG_SETTYPE(r, RVM_DTYPE_PROPHANDLER);
+}
+
+
 int rvm_reg_str2num(rvmreg_t *dst, const rvmreg_t *src)
 {
        char *dptr, *lptr;
index e660594..a520118 100644 (file)
@@ -52,7 +52,9 @@ extern "C" {
 #define RVM_DTYPE_MAP 12
 #define RVM_DTYPE_FUNCTION 13
 #define RVM_DTYPE_SWIID 14
-#define RVM_DTYPE_USER 16
+#define RVM_DTYPE_OPHANDLER 15
+#define RVM_DTYPE_PROPHANDLER 16
+#define RVM_DTYPE_USER 17
 #define RVM_DTYPE_SIZE (1 << 5)
 #define RVM_DTYPE_MASK (RVM_DTYPE_SIZE - 1)
 #define RVM_DTYPE_MAX (RVM_DTYPE_MASK)
@@ -167,6 +169,9 @@ rvmreg_t rvm_reg_create_double(double d);
 rvmreg_t rvm_reg_create_signed(rword l);
 rvmreg_t rvm_reg_create_pair(ruint32 p1, ruint32 p2);
 rvmreg_t rvm_reg_create_strptr(char *s, unsigned int size);
+rvmreg_t rvm_reg_create_pointer(rpointer p);
+rvmreg_t rvm_reg_create_ophandler(rpointer p);
+rvmreg_t rvm_reg_create_prophandler(rpointer p);
 rvmreg_type_t rvm_reg_gettype(const rvmreg_t *r);
 rboolean rvm_reg_tstflag(const rvmreg_t *r, ruint16 flag);
 void rvm_reg_init(rvmreg_t *reg);
@@ -181,6 +186,8 @@ void rvm_reg_setboolean(rvmreg_t *r, rboolean b);
 void rvm_reg_setsigned(rvmreg_t *r, rword l);
 void rvm_reg_setdouble(rvmreg_t *r, double d);
 void rvm_reg_setpointer(rvmreg_t *r, rpointer p);
+void rvm_reg_setophandler(rvmreg_t *r, rpointer p);
+void rvm_reg_setprophandler(rvmreg_t *r, rpointer p);
 void rvm_reg_setpair(rvmreg_t *r, ruint32 p1, ruint32 p2);
 void rvm_reg_setstrptr(rvmreg_t *r, char *s, unsigned int size);
 void rvm_reg_setstring(rvmreg_t *r, rstring_t *ptr);