return RVM_ENOT;
else if (r_stringncmp("!", input, size))
return RVM_ELNOT;
+ else
+ return RVM_NOP;
return -1;
}
}
+int rjs_compiler_rh_unaryexpressiondelete(rjs_compiler_t *co, rarray_t *records, long rec)
+{
+ rparecord_t *prec;
+ rjs_coctx_operation_t ctx;
+
+ r_memset(&ctx, 0, sizeof(ctx));
+ ctx.base.type = RJS_COCTX_DELETE;
+ r_array_push(co->coctx, &ctx, rjs_coctx_t*);
+
+ prec = (rparecord_t *)r_array_slot(records, rec);
+ rjs_compiler_debughead(co, records, rec);
+ rjs_compiler_debugtail(co, records, rec);
+ if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+ goto error;
+ rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+ prec = (rparecord_t *)r_array_slot(records, rec);
+ rjs_compiler_debughead(co, records, rec);
+ rjs_compiler_debugtail(co, records, rec);
+ r_array_removelast(co->coctx);
+ return 0;
+
+error:
+ r_array_removelast(co->coctx);
+ return -1;
+}
+
+
int rjs_compiler_rh_assignmentexpressionop(rjs_compiler_t *co, rarray_t *records, long rec)
{
rparecord_t *prec;
} else {
rvm_codegen_addins(co->cg, rvm_asm(RVM_MAPLKUP, R0, R1, R2, 0)); // Get the offset of the element at offset R0
- rvm_codegen_addins(co->cg, rvm_asm(RVM_MAPLDR, R0, R1, R0, 0)); // Get the value of the element at offset R0
+ if (ctx && ctx->type == RJS_COCTX_DELETE)
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_MAPDEL, R0, R1, R0, 0)); // Get the result of deletion in R0
+ else
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_MAPLDR, R0, R1, R0, 0)); // Get the value of the element at offset R0
}
rjs_compiler_debugtail(co, records, rec);
return 0;
} else {
rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0)); // Supposedly an Array
rvm_codegen_addins(co->cg, rvm_asm(RVM_MAPLKUP, R0, R1, R0, 0)); // R1 Array
- rvm_codegen_addins(co->cg, rvm_asm(RVM_MAPLDR, R0, R1, R0, 0)); // Get the value of the element at offset R0
+ if (ctx && ctx->type == RJS_COCTX_DELETE)
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_MAPDEL, R0, R1, R0, 0)); // Get the result of deletion in R0
+ else
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_MAPLDR, R0, R1, R0, 0)); // Get the value of the element at offset R0
}
rjs_compiler_debugtail(co, records, rec);
return 0;
}
+int rjs_compiler_rh_iterationforin(rjs_compiler_t *co, rarray_t *records, long rec)
+{
+ rparecord_t *prec;
+ rjs_coctx_iteration_t ctx;
+
+ r_memset(&ctx, 0, sizeof(ctx));
+ ctx.base.type = RJS_COCTX_ITERATION;
+ ctx.start = rvm_codegen_getcodesize(co->cg);
+ ctx.iterationidx = rvm_codegen_invalid_addlabel_s(co->cg, NULL);
+ ctx.continueidx = rvm_codegen_invalid_addlabel_s(co->cg, NULL);
+ ctx.endidx = rvm_codegen_invalid_addlabel_s(co->cg, NULL);
+ r_array_push(co->coctx, &ctx, rjs_coctx_t*);
+ rvm_scope_push(co->scope);
+ prec = (rparecord_t *)r_array_slot(records, rec);
+ rjs_compiler_debughead(co, records, rec);
+ rjs_compiler_debugtail(co, records, rec);
+
+ if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+ goto error;
+
+ rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+ prec = (rparecord_t *)r_array_slot(records, rec);
+ rjs_compiler_debughead(co, records, rec);
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx.iterationidx, rvm_asm(RVM_B, DA, XX, XX, 0));
+ rvm_codegen_redefinelabel_default(co->cg, ctx.endidx);
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_SUB, SP, SP, DA, 3));
+ rjs_compiler_debugtail(co, records, rec);
+ rvm_scope_pop(co->scope);
+ r_array_removelast(co->coctx);
+ return 0;
+
+error:
+ rvm_scope_pop(co->scope);
+ r_array_removelast(co->coctx);
+ return -1;
+}
+
+
+int rjs_compiler_rh_forininit(rjs_compiler_t *co, rarray_t *records, long rec)
+{
+ rjs_coctx_iteration_t *ctx = (rjs_coctx_iteration_t *)rjs_compiler_getctx(co, RJS_COCTX_ITERATION);
+ rparecord_t *prec;
+ prec = (rparecord_t *)r_array_slot(records, rec);
+ rjs_compiler_debughead(co, records, rec);
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_PUSH, DA, XX, XX, -1));
+ rjs_compiler_debugtail(co, records, rec);
+
+ if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+ goto error;
+
+ rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+ prec = (rparecord_t *)r_array_slot(records, rec);
+ rjs_compiler_debughead(co, records, rec);
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R0, R0, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_CMP, R0, DA, XX, RVM_DTYPE_JSOBJECT));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx->endidx, rvm_asm(RVM_BNEQ, DA, XX, XX, 0));
+ rvm_codegen_redefinelabel_default(co->cg, ctx->iterationidx);
+ rvm_codegen_redefinelabel_default(co->cg, ctx->continueidx);
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_LDS, R0, SP, DA, -2));
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_LDS, R1, SP, DA, 0));
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_LDS, R2, SP, DA, -1));
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_MAPNEXT, R0, R1, R0, 0));
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_CMP, R0, DA, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_STS, R0, SP, DA, -2));
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_MAPKEYLDR, R0, R1, R0, 0));
+ rvm_codegen_addins(co->cg, rvm_asml(RVM_STRR, R0, R2, XX, 0));
+ rjs_compiler_debugtail(co, records, rec);
+ return 0;
+
+error:
+ return -1;
+}
+
+
int rjs_compiler_rh_iterationwhile(rjs_compiler_t *co, rarray_t *records, long rec)
{
rparecord_t *prec;
co->handlers[UID_ITERATIONDO] = rjs_compiler_rh_iterationdo;
co->handlers[UID_ITERATIONWHILE] = rjs_compiler_rh_iterationwhile;
co->handlers[UID_ITERATIONFOR] = rjs_compiler_rh_iterationfor;
+ co->handlers[UID_ITERATIONFORIN] = rjs_compiler_rh_iterationforin;
+ co->handlers[UID_FORININIT] = rjs_compiler_rh_forininit;
co->handlers[UID_DOWHILEEXPRESSIONCOMPARE] = rjs_compiler_rh_dowhileexpressioncompare;
co->handlers[UID_WHILEEXPRESSIONCOMPARE] = rjs_compiler_rh_forexpressioncompare;
co->handlers[UID_FOREXPRESSIONCOMPARE] = rjs_compiler_rh_forexpressioncompare;
co->handlers[UID_THIS] = rjs_compiler_rh_this;
co->handlers[UID_NEWEXPRESSIONCALL] = rjs_compiler_rh_newexpressioncall;
co->handlers[UID_UNARYEXPRESSIONOP] = rjs_compiler_rh_unaryexpressionop;
+ co->handlers[UID_UNARYEXPRESSIONDELETE] = rjs_compiler_rh_unaryexpressiondelete;
co->handlers[UID_BINARYOPERATOR] = rjs_compiler_rh_binaryoperator;
co->handlers[UID_UNARYOPERATOR] = rjs_compiler_rh_unaryoperator;
co->handlers[UID_BREAKSTATEMENT] = rjs_compiler_rh_break;
"STA",
"MAPALLOC",
"MAPADDR",
+ "MAPKEYLDR",
"MAPLDR",
"MAPSTR",
+ "MAPDEL",
"MAPLKUP",
"MAPADD",
"MAPLKUPADD",
- "UNKNOWN",
+ "MAPNEXT",
+ "MAPPREV",
"UNKNOWN",
"UNKNOWN",
"UNKNOWN",
}
+static void rvm_op_mapdel(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+ int ret;
+ long index;
+ rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+ rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+ rvmreg_t tmp = rvm_reg_create_signed(0);
+ rmap_t *a = NULL;
+
+ rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
+ index = (long)RVM_REG_GETL(&tmp);
+ if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
+ RVM_ABORT(cpu, RVM_E_NOTOBJECT);
+ a = (rmap_t*)RVM_REG_GETP(arg2);
+ ret = r_map_delete(a, index);
+ rvm_reg_setboolean(arg1, ret == 0 ? 1 : 0);
+}
+
+
static void rvm_op_mapaddr(rvmcpu_t *cpu, rvm_asmins_t *ins)
{
rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
}
+static void rvm_op_mapkeyldr(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+ rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+ rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+ rvmreg_t tmp = rvm_reg_create_signed(0);
+ rmap_t *a = NULL;
+ rstring_t *key;
+ long index;
+
+ rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
+ index = (long)RVM_REG_GETL(&tmp);
+ if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
+ RVM_ABORT(cpu, RVM_E_NOTOBJECT);
+ a = (rmap_t*)RVM_REG_GETP(arg2);
+ key = r_map_key(a, index);
+ if (!key) {
+ RVM_REG_CLEAR(arg1);
+ RVM_REG_SETTYPE(arg1, RVM_DTYPE_UNDEF);
+ } else {
+ rvm_reg_setstring(arg1, key);
+ }
+}
+
+
+static void rvm_op_mapnext(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+ rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+ rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+ rvmreg_t tmp = rvm_reg_create_signed(0);
+ rmap_t *a = NULL;
+ long index;
+
+ rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
+ index = (long)RVM_REG_GETL(&tmp);
+ if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
+ RVM_ABORT(cpu, RVM_E_NOTOBJECT);
+ a = (rmap_t*)RVM_REG_GETP(arg2);
+ if (index < 0)
+ index = r_map_first(a);
+ else
+ index = r_map_next(a, index);
+ RVM_REG_CLEAR(arg1);
+ RVM_REG_SETTYPE(arg1, RVM_DTYPE_SINGED);
+ RVM_REG_SETL(arg1, index);
+}
+
+
+static void rvm_op_mapprev(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+ rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+ rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+ rvmreg_t tmp = rvm_reg_create_signed(0);
+ rmap_t *a = NULL;
+ long index;
+
+ rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
+ index = (long)RVM_REG_GETL(&tmp);
+ if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
+ RVM_ABORT(cpu, RVM_E_NOTOBJECT);
+ a = (rmap_t*)RVM_REG_GETP(arg2);
+ if (index < 0)
+ index = r_map_last(a);
+ else
+ index = r_map_prev(a, index);
+ RVM_REG_CLEAR(arg1);
+ RVM_REG_SETTYPE(arg1, RVM_DTYPE_SINGED);
+ RVM_REG_SETL(arg1, index);
+}
+
+
static void rvm_op_mapstr(rvmcpu_t *cpu, rvm_asmins_t *ins)
{
rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
rvm_op_sta, // RVM_STA
rvm_op_mapalloc, // RVM_MAPALLOC
rvm_op_mapaddr, // RVM_MAPADDR,
+ rvm_op_mapkeyldr, // RVM_MAPKEYLDR,
rvm_op_mapldr, // RVM_MAPLDR,
rvm_op_mapstr, // RVM_MAPSTR,
+ rvm_op_mapdel, // RVM_MAPDEL,
rvm_op_maplookup, // RVM_MAPLKUP,
rvm_op_mapadd, // RVM_MAPADD,
rvm_op_maplookupadd,// RVM_MAPLKUPADD,
+ rvm_op_mapnext, // RVM_MAPNEXT,
+ rvm_op_mapprev, // RVM_MAPPREV,
(void*) 0,
(void*) 0,
(void*) 0,