2 #include "rjscompiler.h"
6 rint rjs_compiler_playreversechildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec);
7 static rint rjs_compiler_playrecord(rjs_compiler_t *co, rarray_t *records, rlong rec);
8 static rint rjs_compiler_playchildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec);
11 void rjs_compiler_debughead(rjs_compiler_t *co, rarray_t *records, rlong rec)
13 rvm_codegen_setsource(co->cg, rec);
15 rparecord_t *prec = (rparecord_t *) r_array_slot(records, rec);
16 co->headoff = rvm_codegen_getcodesize(co->cg);
17 if (prec->type & RPA_RECORD_START) {
18 rpa_record_dump(records, rec);
25 void rjs_compiler_debugtail(rjs_compiler_t *co, rarray_t *records, rlong rec)
27 rvm_codegen_setsource(co->cg, rec);
29 rparecord_t *prec = (rparecord_t *) r_array_slot(records, rec);
30 rvm_asm_dump(rvm_codegen_getcode(co->cg, co->headoff), rvm_codegen_getcodesize(co->cg) - co->headoff);
31 if (prec->type & RPA_RECORD_END) {
32 rpa_record_dump(records, rec);
39 void rjs_compiler_adderror(rjs_compiler_t *co, rlong code, rparecord_t *prec)
41 co->error->type = RJS_ERRORTYPE_SYNTAX;
42 co->error->error = code;
43 co->error->script = co->script;
44 co->error->offset = prec->input - co->script;
45 co->error->size = prec->inputsiz;
46 co->error->line = rjs_parser_offset2line(co->script, co->error->offset);
47 co->error->lineoffset = rjs_parser_offset2lineoffset(co->script, co->error->offset);
52 static const rchar *rjs_compiler_record2str(rjs_compiler_t *co, rarray_t *records, rlong rec)
54 rparecord_t *prec = (rparecord_t *)r_array_slot(records, rpa_recordtree_get(records, rec, RPA_RECORD_END));
55 rsize_t size = 16; /* Min size */
57 if (prec && prec->inputsiz) {
58 size = prec->inputsiz + 1;
60 co->temp = r_realloc(co->temp, size);
61 r_memset(co->temp, 0, size);
62 if (prec->input && prec->inputsiz)
63 r_memcpy(co->temp, prec->input, prec->inputsiz);
68 static rlong rjs_compiler_record_parentuid(rjs_compiler_t *co, rarray_t *records, rlong rec)
70 rlong parent = rpa_recordtree_parent(records, rec, RPA_RECORD_START);
74 return rpa_record_getruleuid(records, parent);
78 static rlong rjs_compiler_record_lastofkind(rjs_compiler_t *co, rarray_t *records, rlong rec)
80 rlong uid = rpa_record_getruleuid(records, rec);
83 for (i = rpa_recordtree_next(records, rec, RPA_RECORD_START) ; i >= 0; i = rpa_recordtree_next(records, i, RPA_RECORD_START)) {
84 if (rpa_record_getruleuid(records, i) == uid)
91 static rlong rjs_compiler_record2identifer(rjs_compiler_t *co, rarray_t *records, rlong rec)
93 rvm_varmap_t *v = NULL;
94 rjs_coctx_t *ctx = NULL;
95 rparecord_t *prec = (rparecord_t *)r_array_slot(records, rec);
98 * First lets find out if we are within a function definition or
99 * this is a global variable.
101 ctx = rjs_compiler_getctx(co, RJS_COCTX_FUNCTION | RJS_COCTX_GLOBAL);
104 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
107 * TBD: Temporary here
110 r_printf("ERROR: Identifier already defined: %s\n", rjs_compiler_record2str(co, records, rec));
114 if ( ctx->type == RJS_COCTX_FUNCTION ) {
115 rjs_coctx_function_t *functx = (rjs_coctx_function_t *)ctx;
116 functx->stackallocs += 1;
117 rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, functx->stackallocs);
119 if (rvm_scope_count(co->scope)) {
120 rjs_coctx_global_t *globalctx = (rjs_coctx_global_t *)ctx;
121 globalctx->stackallocs += 1;
122 rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, globalctx->stackallocs);
127 rvm_scope_addpointer(co->scope, prec->input, prec->inputsiz, rvm_cpu_alloc_global(co->cpu));
130 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
131 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
132 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
134 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
141 rjs_coctx_t *rjs_compiler_getctx(rjs_compiler_t *co, rulong type)
146 for (i = r_array_length(co->coctx) - 1; i >= 0; i--) {
147 ctx = r_array_index(co->coctx, i, rjs_coctx_t*);
148 if (ctx->type & type)
155 rjs_coctx_t *rjs_compiler_gettopctx(rjs_compiler_t *co)
157 rlong len = r_array_length(co->coctx);
160 return r_array_index(co->coctx, len - 1, rjs_coctx_t*);
165 rlong rjs_compiler_record2opcode(rparecord_t *prec)
167 const rchar *input = prec->input;
168 rsize_t size = prec->inputsiz;
170 if (r_stringncmp("++", input, size))
172 else if (r_stringncmp("+", input, size))
174 else if (r_stringncmp("+=", input, size))
176 else if (r_stringncmp("--", input, size))
178 else if (r_stringncmp("-", input, size))
180 else if (r_stringncmp("-=", input, size))
182 else if (r_stringncmp("*", input, size))
184 else if (r_stringncmp("*=", input, size))
186 else if (r_stringncmp("/", input, size))
188 else if (r_stringncmp("/=", input, size))
190 else if (r_stringncmp("%", input, size))
192 else if (r_stringncmp("%=", input, size))
194 else if (r_stringncmp("&&", input, size))
196 else if (r_stringncmp("||", input, size))
198 else if (r_stringncmp("&", input, size))
200 else if (r_stringncmp("&=", input, size))
202 else if (r_stringncmp("|", input, size))
204 else if (r_stringncmp("|=", input, size))
206 else if (r_stringncmp("^", input, size))
208 else if (r_stringncmp("^=", input, size))
210 else if (r_stringncmp(">>", input, size))
212 else if (r_stringncmp(">>=", input, size))
214 else if (r_stringncmp("<<", input, size))
216 else if (r_stringncmp("<<=", input, size))
218 else if (r_stringncmp(">>>", input, size))
220 else if (r_stringncmp(">>>=", input, size))
222 else if (r_stringncmp("<=", input, size))
224 else if (r_stringncmp(">=", input, size))
226 else if (r_stringncmp("<", input, size))
228 else if (r_stringncmp(">", input, size))
230 else if (r_stringncmp("===", input, size))
232 else if (r_stringncmp("==", input, size))
234 else if (r_stringncmp("!==", input, size))
236 else if (r_stringncmp("!=", input, size))
238 else if (r_stringncmp("!", input, size))
240 else if (r_stringncmp("~", input, size))
242 else if (r_stringncmp("=", input, size))
249 rlong rjs_compiler_record2unaryopcode(rparecord_t *prec)
251 const rchar *input = prec->input;
252 rsize_t size = prec->inputsiz;
254 if (r_stringncmp("+", input, size))
256 else if (r_stringncmp("-", input, size))
258 else if (r_stringncmp("~", input, size))
260 else if (r_stringncmp("!", input, size))
267 rint rjs_compiler_rh_program(rjs_compiler_t *co, rarray_t *records, rlong rec)
269 rjs_coctx_global_t ctx;
271 rlong mainidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__main", 0);
272 rlong allocsidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__allocs", 0);
275 r_memset(&ctx, 0, sizeof(ctx));
276 ctx.base.type = RJS_COCTX_GLOBAL;
277 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
279 prec = (rparecord_t *)r_array_slot(records, rec);
280 rjs_compiler_debughead(co, records, rec);
281 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, mainidx, rvm_asm(RVM_B, DA, XX, XX, 0));
282 start = rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
283 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_DEFAULT, allocsidx, rvm_asm(RVM_ADD, SP, FP, DA, 0));
284 rjs_compiler_debugtail(co, records, rec);
286 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
289 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
290 prec = (rparecord_t *)r_array_slot(records, rec);
291 rvm_codegen_redefinepointer(co->cg, allocsidx, (rpointer)ctx.stackallocs);
292 rjs_compiler_debughead(co, records, rec);
293 rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
294 rvm_codegen_redefinelabel_default(co->cg, mainidx);
295 rvm_codegen_addins(co->cg, rvm_asm(RVM_BL, DA, XX, XX, start - rvm_codegen_getcodesize(co->cg)));
296 rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
297 rjs_compiler_debugtail(co, records, rec);
298 r_array_removelast(co->coctx);
302 r_array_removelast(co->coctx);
307 rint rjs_compiler_rh_varalloc(rjs_compiler_t *co, rarray_t *records, rlong rec)
310 prec = (rparecord_t *)r_array_slot(records, rec);
311 rjs_compiler_debughead(co, records, rec);
312 rjs_compiler_debugtail(co, records, rec);
314 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
317 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
318 prec = (rparecord_t *)r_array_slot(records, rec);
319 rjs_compiler_debughead(co, records, rec);
320 if (rjs_compiler_record2identifer(co, records, rec) < 0)
322 rjs_compiler_debugtail(co, records, rec);
327 rint rjs_compiler_rh_varallocinit(rjs_compiler_t *co, rarray_t *records, rlong rec)
330 prec = (rparecord_t *)r_array_slot(records, rec);
331 rjs_compiler_debughead(co, records, rec);
332 rjs_compiler_debugtail(co, records, rec);
334 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
337 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
338 prec = (rparecord_t *)r_array_slot(records, rec);
339 rjs_compiler_debughead(co, records, rec);
340 if (rjs_compiler_record2identifer(co, records, rec) < 0)
342 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
343 rjs_compiler_debugtail(co, records, rec);
348 rint rjs_compiler_rh_initializer(rjs_compiler_t *co, rarray_t *records, rlong rec)
351 prec = (rparecord_t *)r_array_slot(records, rec);
352 rjs_compiler_debughead(co, records, rec);
353 rjs_compiler_debugtail(co, records, rec);
355 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
358 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
359 prec = (rparecord_t *)r_array_slot(records, rec);
360 rjs_compiler_debughead(co, records, rec);
361 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
362 rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
363 rjs_compiler_debugtail(co, records, rec);
368 rint rjs_compiler_rh_identifier(rjs_compiler_t *co, rarray_t *records, rlong rec)
373 prec = (rparecord_t *)r_array_slot(records, rec);
374 rjs_compiler_debughead(co, records, rec);
375 rjs_compiler_debugtail(co, records, rec);
377 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
380 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
381 prec = (rparecord_t *)r_array_slot(records, rec);
382 rjs_compiler_debughead(co, records, rec);
383 v = rvm_scope_lookup(co->scope, prec->input, prec->inputsiz);
386 * Let see if this is a swiid
388 if ((swiid = rvm_cpu_swilookup(co->cpu, NULL, prec->input, prec->inputsiz)) >= 0) {
389 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, swiid));
390 rvm_codegen_addins(co->cg, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_SWIID));
394 rjs_compiler_adderror(co, RJS_ERROR_UNDEFINED, prec);
398 if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rpa_recordtree_next(records, rec, RPA_RECORD_START) == -1) {
400 * If this is the last child of UID_LEFTHANDSIDEEXPRESSIONADDR
402 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
403 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
405 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
408 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
409 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, FP, DA, v->data.offset));
411 rvm_codegen_addins(co->cg, rvm_asmp(RVM_LDRR, R0, DA, XX, v->data.ptr));
415 rjs_compiler_debugtail(co, records, rec);
420 rint rjs_compiler_rh_expression(rjs_compiler_t *co, rarray_t *records, rlong rec)
423 prec = (rparecord_t *)r_array_slot(records, rec);
424 rjs_compiler_debughead(co, records, rec);
425 rjs_compiler_debugtail(co, records, rec);
427 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
430 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
431 prec = (rparecord_t *)r_array_slot(records, rec);
432 rjs_compiler_debughead(co, records, rec);
433 rjs_compiler_debugtail(co, records, rec);
438 rint rjs_compiler_rh_lefthandsideexpression(rjs_compiler_t *co, rarray_t *records, rlong rec)
441 prec = (rparecord_t *)r_array_slot(records, rec);
442 rjs_compiler_debughead(co, records, rec);
443 rjs_compiler_debugtail(co, records, rec);
445 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
448 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
449 prec = (rparecord_t *)r_array_slot(records, rec);
450 rjs_compiler_debughead(co, records, rec);
451 rjs_compiler_debugtail(co, records, rec);
456 rint rjs_compiler_rh_lefthandsideexpressionaddr(rjs_compiler_t *co, rarray_t *records, rlong rec)
459 prec = (rparecord_t *)r_array_slot(records, rec);
460 rjs_compiler_debughead(co, records, rec);
461 rjs_compiler_debugtail(co, records, rec);
463 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
466 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
467 prec = (rparecord_t *)r_array_slot(records, rec);
468 rjs_compiler_debughead(co, records, rec);
469 rvm_codegen_addins(co->cg, rvm_asmp(RVM_PUSH, R0, XX, XX, 0));
470 rjs_compiler_debugtail(co, records, rec);
475 rint rjs_compiler_rh_decimalintegerliteral(rjs_compiler_t *co, rarray_t *records, rlong rec)
478 prec = (rparecord_t *)r_array_slot(records, rec);
479 rjs_compiler_debughead(co, records, rec);
480 rjs_compiler_debugtail(co, records, rec);
482 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
485 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
486 prec = (rparecord_t *)r_array_slot(records, rec);
487 rjs_compiler_debughead(co, records, rec);
488 rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R0, DA, XX, r_strtol(prec->input, NULL, 10)));
489 rjs_compiler_debugtail(co, records, rec);
494 rint rjs_compiler_rh_decimalnonintegerliteral(rjs_compiler_t *co, rarray_t *records, rlong rec)
497 prec = (rparecord_t *)r_array_slot(records, rec);
498 rjs_compiler_debughead(co, records, rec);
499 rjs_compiler_debugtail(co, records, rec);
501 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
504 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
505 prec = (rparecord_t *)r_array_slot(records, rec);
506 rjs_compiler_debughead(co, records, rec);
507 rvm_codegen_addins(co->cg, rvm_asmd(RVM_MOV, R0, DA, XX, r_strtod(prec->input, NULL)));
509 rjs_compiler_debugtail(co, records, rec);
514 rint rjs_compiler_rh_stringcharacters(rjs_compiler_t *co, rarray_t *records, rlong rec)
517 prec = (rparecord_t *)r_array_slot(records, rec);
519 rjs_compiler_debughead(co, records, rec);
520 rjs_compiler_debugtail(co, records, rec);
522 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
525 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
526 prec = (rparecord_t *)r_array_slot(records, rec);
527 rjs_compiler_debughead(co, records, rec);
528 co->stringcharacters.str = (rchar*)prec->input;
529 co->stringcharacters.size = prec->inputsiz;
530 rjs_compiler_debugtail(co, records, rec);
535 rint rjs_compiler_rh_stringliteral(rjs_compiler_t *co, rarray_t *records, rlong rec)
538 prec = (rparecord_t *)r_array_slot(records, rec);
540 rjs_compiler_debughead(co, records, rec);
541 co->stringcharacters.str = NULL;
542 co->stringcharacters.size = 0;
543 rjs_compiler_debugtail(co, records, rec);
545 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
548 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
549 prec = (rparecord_t *)r_array_slot(records, rec);
550 rjs_compiler_debughead(co, records, rec);
551 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R1, DA, XX, co->stringcharacters.str));
552 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R2, DA, XX, co->stringcharacters.size));
553 rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCSTR, R0, R1, R2, 0));
554 rjs_compiler_debugtail(co, records, rec);
559 rint rjs_compiler_rh_binaryexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
562 rjs_coctx_operation_t ctx;
564 r_memset(&ctx, 0, sizeof(ctx));
565 ctx.base.type = RJS_COCTX_OPERATION;
566 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
568 prec = (rparecord_t *)r_array_slot(records, rec);
569 rjs_compiler_debughead(co, records, rec);
570 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
571 rjs_compiler_debugtail(co, records, rec);
572 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
574 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
575 prec = (rparecord_t *)r_array_slot(records, rec);
576 rjs_compiler_debughead(co, records, rec);
577 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
578 rvm_codegen_addins(co->cg, rvm_asm(ctx.opcode, R0, R1, R0, 0));
579 rjs_compiler_debugtail(co, records, rec);
580 r_array_removelast(co->coctx);
584 r_array_removelast(co->coctx);
589 rint rjs_compiler_rh_unaryexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
592 rjs_coctx_operation_t ctx;
594 r_memset(&ctx, 0, sizeof(ctx));
595 ctx.base.type = RJS_COCTX_OPERATION;
596 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
598 prec = (rparecord_t *)r_array_slot(records, rec);
599 rjs_compiler_debughead(co, records, rec);
600 rjs_compiler_debugtail(co, records, rec);
601 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
603 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
604 prec = (rparecord_t *)r_array_slot(records, rec);
605 rjs_compiler_debughead(co, records, rec);
606 rvm_codegen_addins(co->cg, rvm_asm(ctx.opcode, R0, R0, XX, 0));
607 rjs_compiler_debugtail(co, records, rec);
608 r_array_removelast(co->coctx);
612 r_array_removelast(co->coctx);
617 rint rjs_compiler_rh_assignmentexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
620 rjs_coctx_operation_t ctx;
622 r_memset(&ctx, 0, sizeof(ctx));
623 ctx.base.type = RJS_COCTX_OPERATION;
624 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
626 prec = (rparecord_t *)r_array_slot(records, rec);
627 rjs_compiler_debughead(co, records, rec);
628 rjs_compiler_debugtail(co, records, rec);
629 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
631 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
632 prec = (rparecord_t *)r_array_slot(records, rec);
633 rjs_compiler_debughead(co, records, rec);
634 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
635 if (ctx.opcode != RVM_NOP) {
636 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R2, R1, XX, 0));
637 rvm_codegen_addins(co->cg, rvm_asm(ctx.opcode, R0, R2, R0, 0));
639 rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
640 rjs_compiler_debugtail(co, records, rec);
641 r_array_removelast(co->coctx);
644 r_array_removelast(co->coctx);
649 rint rjs_compiler_rh_newarrayexpression(rjs_compiler_t *co, rarray_t *records, rlong rec)
652 prec = (rparecord_t *)r_array_slot(records, rec);
653 rjs_compiler_debughead(co, records, rec);
654 rjs_compiler_debugtail(co, records, rec);
655 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
657 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
658 prec = (rparecord_t *)r_array_slot(records, rec);
659 rjs_compiler_debughead(co, records, rec);
660 rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCOBJ, R0, DA, XX, 0));
661 rjs_compiler_debugtail(co, records, rec);
666 rint rjs_compiler_rh_memberexpressiondotop(rjs_compiler_t *co, rarray_t *records, rlong rec)
668 rjs_coctx_t *ctx = rjs_compiler_gettopctx(co);
671 prec = (rparecord_t *)r_array_slot(records, rec);
672 rjs_compiler_debughead(co, records, rec);
673 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0)); // Supposedly an Array
674 rjs_compiler_debugtail(co, records, rec);
675 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
677 if (ctx && ctx->type == RJS_COCTX_FUNCTIONCALL)
678 ((rjs_coctx_functioncall_t *)ctx)->setthis = 1;
679 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
680 prec = (rparecord_t *)r_array_slot(records, rec);
681 rjs_compiler_debughead(co, records, rec);
682 if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rjs_compiler_record_lastofkind(co, records, rec)) {
683 rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUPADD, R0, R1, R2, 0)); // Get the offset of the element at offset R0
684 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDROBJH, R0, R1, R0, 0)); // Get the address of the element at offset R0
687 rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUP, R0, R1, R2, 0)); // Get the offset of the element at offset R0
688 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDOBJH, R0, R1, R0, 0)); // Get the value of the element at offset R0
690 rjs_compiler_debugtail(co, records, rec);
695 rint rjs_compiler_rh_memberexpressionindexop(rjs_compiler_t *co, rarray_t *records, rlong rec)
698 prec = (rparecord_t *)r_array_slot(records, rec);
699 rjs_compiler_debughead(co, records, rec);
700 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0)); // Supposedly an Array
701 rjs_compiler_debugtail(co, records, rec);
703 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
705 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
706 prec = (rparecord_t *)r_array_slot(records, rec);
707 rjs_compiler_debughead(co, records, rec);
708 if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rjs_compiler_record_lastofkind(co, records, rec)) {
709 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0)); // Supposedly an Array
710 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDROBJN, R0, R1, R0, 0)); // Get the address of the element at offset R0
713 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0)); // Supposedly an Array
714 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDOBJN, R0, R1, R0, 0)); // Get the value of the element at offset R0
716 rjs_compiler_debugtail(co, records, rec);
721 rint rjs_compiler_rh_functiondeclaration(rjs_compiler_t *co, rarray_t *records, rlong rec)
723 rjs_coctx_function_t ctx;
725 rlong start, execidx, endidx, allocsidx;
727 r_memset(&ctx, 0, sizeof(ctx));
728 ctx.base.type = RJS_COCTX_FUNCTION;
730 prec = (rparecord_t *)r_array_slot(records, rec);
731 rjs_compiler_debughead(co, records, rec);
732 start = rvm_codegen_getcodesize(co->cg);
733 endidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__funend", start);
734 execidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__funexec", start);
735 allocsidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__allocs", start);
737 if (rpa_record_getruleuid(records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START)) == UID_FUNCTIONNAME) {
738 if (rjs_compiler_record2identifer(co, records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START)) < 0)
740 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
742 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_JUMP, execidx, rvm_asm(RVM_MOV, R0, DA, XX, 0));
743 rvm_codegen_addins(co->cg, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_FUNCTION));
744 if (rpa_record_getruleuid(records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START)) == UID_FUNCTIONNAME) {
745 rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
747 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, endidx, rvm_asm(RVM_B, DA, XX, XX, 0));
748 rvm_codegen_redefinelabel_default(co->cg, execidx);
749 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_DEFAULT, allocsidx, rvm_asm(RVM_ADD, SP, FP, DA, 0));
751 rjs_compiler_debugtail(co, records, rec);
753 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
754 rvm_scope_push(co->scope);
755 if (rjs_compiler_playchildrecords(co, records, rec) < 0) {
756 rvm_scope_pop(co->scope);
759 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
760 prec = (rparecord_t *)r_array_slot(records, rec);
761 rjs_compiler_debughead(co, records, rec);
762 rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
763 rvm_codegen_redefinelabel_default(co->cg, endidx);
764 rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
765 rvm_codegen_redefinepointer(co->cg, allocsidx, (rpointer)ctx.stackallocs);
766 rjs_compiler_debugtail(co, records, rec);
768 co->cg->userdata = RJS_COMPILER_CODEGENKEEP;
769 rvm_scope_pop(co->scope);
770 r_array_removelast(co->coctx);
774 r_array_removelast(co->coctx);
779 rint rjs_compiler_rh_functionparameter(rjs_compiler_t *co, rarray_t *records, rlong rec)
781 rjs_coctx_t *ctx = NULL;
782 rjs_coctx_function_t *functx = NULL;
786 prec = (rparecord_t *)r_array_slot(records, rec);
787 rjs_compiler_debughead(co, records, rec);
789 * First lets find out if we are within a function definition or
790 * this is a global variable.
792 ctx = rjs_compiler_getctx(co, RJS_COCTX_FUNCTION);
794 rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTION, prec);
798 functx = (rjs_coctx_function_t *)ctx;
799 rjs_compiler_debugtail(co, records, rec);
801 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
804 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
805 prec = (rparecord_t *)r_array_slot(records, rec);
806 rjs_compiler_debughead(co, records, rec);
807 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
810 * TBD: Temporary here
813 r_printf("ERROR: Identifier already defined: %s\n", rjs_compiler_record2str(co, records, rec));
817 functx->stackallocs += 1;
818 rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, functx->stackallocs);
820 rjs_compiler_debugtail(co, records, rec);
825 rint rjs_compiler_rh_functioncall(rjs_compiler_t *co, rarray_t *records, rlong rec)
828 rjs_coctx_functioncall_t ctx;
830 r_memset(&ctx, 0, sizeof(ctx));
831 ctx.base.type = RJS_COCTX_FUNCTIONCALL;
832 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
834 prec = (rparecord_t *)r_array_slot(records, rec);
835 rjs_compiler_debughead(co, records, rec);
836 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(TP)|BIT(FP)|BIT(SP)|BIT(LR)));
837 rjs_compiler_debugtail(co, records, rec);
840 * Important: Function call has two children FunctionCallName, Arguments
841 * We evaluate them in reverse order, first we evaluate the Arguments and push them on the
842 * stack, than we evaluate the FunctionCallName -> R0. When we make the call we assume the
843 * result of the FunctionCallName will be in R0.
845 if (rjs_compiler_playreversechildrecords(co, records, rec) < 0)
848 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
849 prec = (rparecord_t *)r_array_slot(records, rec);
850 rjs_compiler_debughead(co, records, rec);
852 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, TP, R1, XX, 0));
853 rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, FP, SP, DA, ctx.arguments));
854 rvm_codegen_addins(co->cg, rvm_asm(RVM_CALL, R0, XX, XX, 0));
855 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
856 rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(TP,LR)));
857 rjs_compiler_debugtail(co, records, rec);
858 r_array_removelast(co->coctx);
862 r_array_removelast(co->coctx);
867 rint rjs_compiler_rh_argument(rjs_compiler_t *co, rarray_t *records, rlong rec)
870 rjs_coctx_functioncall_t *ctx = (rjs_coctx_functioncall_t *)rjs_compiler_getctx(co, RJS_COCTX_FUNCTIONCALL);
872 prec = (rparecord_t *)r_array_slot(records, rec);
873 rjs_compiler_debughead(co, records, rec);
875 rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec);
879 rjs_compiler_debugtail(co, records, rec);
881 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
884 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
885 prec = (rparecord_t *)r_array_slot(records, rec);
886 rjs_compiler_debughead(co, records, rec);
887 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
889 rjs_compiler_debugtail(co, records, rec);
894 rint rjs_compiler_rh_arguments(rjs_compiler_t *co, rarray_t *records, rlong rec)
897 rjs_coctx_functioncall_t *ctx = (rjs_coctx_functioncall_t *)rjs_compiler_getctx(co, RJS_COCTX_FUNCTIONCALL);
899 prec = (rparecord_t *)r_array_slot(records, rec);
900 rjs_compiler_debughead(co, records, rec);
902 rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec);
906 rjs_compiler_debugtail(co, records, rec);
908 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
911 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
912 prec = (rparecord_t *)r_array_slot(records, rec);
913 rjs_compiler_debughead(co, records, rec);
914 rjs_compiler_debugtail(co, records, rec);
919 rint rjs_compiler_rh_returnstatement(rjs_compiler_t *co, rarray_t *records, rlong rec)
922 prec = (rparecord_t *)r_array_slot(records, rec);
923 rjs_compiler_debughead(co, records, rec);
924 rjs_compiler_debugtail(co, records, rec);
926 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
929 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
930 prec = (rparecord_t *)r_array_slot(records, rec);
931 rjs_compiler_debughead(co, records, rec);
932 rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
933 rjs_compiler_debugtail(co, records, rec);
938 rint rjs_compiler_rh_ifstatement(rjs_compiler_t *co, rarray_t *records, rlong rec)
941 rjs_coctx_ifstatement_t ctx;
943 r_memset(&ctx, 0, sizeof(ctx));
944 ctx.base.type = RJS_COCTX_IFSTATEMENT;
945 ctx.start = rvm_codegen_getcodesize(co->cg);
946 ctx.trueidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__iftrue", ctx.start);
947 ctx.falseidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__iffalse", ctx.start);
948 ctx.endidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__ifend", ctx.start);
949 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
950 prec = (rparecord_t *)r_array_slot(records, rec);
951 rjs_compiler_debughead(co, records, rec);
952 rjs_compiler_debugtail(co, records, rec);
954 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
957 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
958 prec = (rparecord_t *)r_array_slot(records, rec);
959 rjs_compiler_debughead(co, records, rec);
960 rvm_codegen_redefinelabel_default(co->cg, ctx.endidx);
961 if (!rvm_codegen_validlabel(co->cg, ctx.falseidx))
962 rvm_codegen_redefinelabel_default(co->cg, ctx.falseidx);
963 rjs_compiler_debugtail(co, records, rec);
965 r_array_removelast(co->coctx);
969 r_array_removelast(co->coctx);
974 rint rjs_compiler_rh_ifconditionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
977 rjs_coctx_ifstatement_t *ctx = (rjs_coctx_ifstatement_t *)rjs_compiler_getctx(co, RJS_COCTX_IFSTATEMENT);
979 prec = (rparecord_t *)r_array_slot(records, rec);
980 rjs_compiler_debughead(co, records, rec);
982 rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec);
986 rjs_compiler_debugtail(co, records, rec);
987 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
989 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
990 prec = (rparecord_t *)r_array_slot(records, rec);
991 rjs_compiler_debughead(co, records, rec);
992 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx->falseidx, rvm_asm(RVM_BEQ, DA, XX, XX, 0));
993 rjs_compiler_debugtail(co, records, rec);
998 rint rjs_compiler_rh_iftruestatement(rjs_compiler_t *co, rarray_t *records, rlong rec)
1001 rjs_coctx_ifstatement_t *ctx = (rjs_coctx_ifstatement_t *)rjs_compiler_getctx(co, RJS_COCTX_IFSTATEMENT);
1003 prec = (rparecord_t *)r_array_slot(records, rec);
1004 rjs_compiler_debughead(co, records, rec);
1006 rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec);
1010 rjs_compiler_debugtail(co, records, rec);
1012 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1015 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1016 prec = (rparecord_t *)r_array_slot(records, rec);
1017 rjs_compiler_debughead(co, records, rec);
1018 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx->endidx, rvm_asm(RVM_B, DA, XX, XX, 0));
1019 rjs_compiler_debugtail(co, records, rec);
1024 rint rjs_compiler_rh_iffalsestatement(rjs_compiler_t *co, rarray_t *records, rlong rec)
1027 rjs_coctx_ifstatement_t *ctx = (rjs_coctx_ifstatement_t *)rjs_compiler_getctx(co, RJS_COCTX_IFSTATEMENT);
1029 prec = (rparecord_t *)r_array_slot(records, rec);
1030 rjs_compiler_debughead(co, records, rec);
1032 rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec);
1036 rvm_codegen_redefinelabel_default(co->cg, ctx->falseidx);
1037 rjs_compiler_debugtail(co, records, rec);
1039 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1042 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1043 prec = (rparecord_t *)r_array_slot(records, rec);
1044 rjs_compiler_debughead(co, records, rec);
1045 rjs_compiler_debugtail(co, records, rec);
1050 rint rjs_compiler_rh_iterationfor(rjs_compiler_t *co, rarray_t *records, rlong rec)
1054 rjs_coctx_iteration_t ctx;
1056 r_memset(&ctx, 0, sizeof(ctx));
1057 ctx.base.type = RJS_COCTX_ITERATION;
1058 ctx.start = rvm_codegen_getcodesize(co->cg);
1059 ctx.iterationidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__iteration", ctx.start);
1060 ctx.continueidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__continue", ctx.start);
1061 ctx.endidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__end", ctx.start);
1062 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
1063 rvm_scope_push(co->scope);
1065 prec = (rparecord_t *)r_array_slot(records, rec);
1066 rjs_compiler_debughead(co, records, rec);
1067 rjs_compiler_debugtail(co, records, rec);
1069 for (childrec = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START); childrec >= 0; childrec = rpa_recordtree_next(records, childrec, RPA_RECORD_START)) {
1070 if (rpa_record_getruleuid(records, childrec) == UID_FOREXPRESSIONINIT) {
1071 if (rjs_compiler_playrecord(co, records, childrec) < 0)
1077 rvm_codegen_redefinelabel_default(co->cg, ctx.iterationidx);
1078 for (childrec = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START); childrec >= 0; childrec = rpa_recordtree_next(records, childrec, RPA_RECORD_START)) {
1079 if (rpa_record_getruleuid(records, childrec) == UID_FOREXPRESSIONCOMPARE) {
1080 if (rjs_compiler_playrecord(co, records, childrec) < 0)
1086 for (childrec = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START); childrec >= 0; childrec = rpa_recordtree_next(records, childrec, RPA_RECORD_START)) {
1087 if (rpa_record_getruleuid(records, childrec) == UID_FORITERATIONSTATEMENT) {
1088 if (rjs_compiler_playrecord(co, records, childrec) < 0)
1094 rvm_codegen_redefinelabel_default(co->cg, ctx.continueidx);
1095 for (childrec = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START); childrec >= 0; childrec = rpa_recordtree_next(records, childrec, RPA_RECORD_START)) {
1096 if (rpa_record_getruleuid(records, childrec) == UID_FOREXPRESSIONINCREMENT) {
1097 if (rjs_compiler_playrecord(co, records, childrec) < 0)
1103 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1104 prec = (rparecord_t *)r_array_slot(records, rec);
1105 rjs_compiler_debughead(co, records, rec);
1106 rvm_codegen_redefinelabel_default(co->cg, ctx.endidx);
1107 rjs_compiler_debugtail(co, records, rec);
1109 rvm_scope_pop(co->scope);
1110 r_array_removelast(co->coctx);
1114 rvm_scope_pop(co->scope);
1115 r_array_removelast(co->coctx);
1120 rint rjs_compiler_rh_iterationwhile(rjs_compiler_t *co, rarray_t *records, rlong rec)
1123 rjs_coctx_iteration_t ctx;
1125 r_memset(&ctx, 0, sizeof(ctx));
1126 ctx.base.type = RJS_COCTX_ITERATION;
1127 ctx.start = rvm_codegen_getcodesize(co->cg);
1128 ctx.iterationidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__iteration", ctx.start);
1129 ctx.continueidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__continue", ctx.start);
1130 ctx.endidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__end", ctx.start);
1131 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
1132 rvm_scope_push(co->scope);
1134 prec = (rparecord_t *)r_array_slot(records, rec);
1135 rjs_compiler_debughead(co, records, rec);
1136 rjs_compiler_debugtail(co, records, rec);
1139 rvm_codegen_redefinelabel_default(co->cg, ctx.iterationidx);
1140 rvm_codegen_redefinelabel_default(co->cg, ctx.continueidx);
1142 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1145 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1146 prec = (rparecord_t *)r_array_slot(records, rec);
1147 rjs_compiler_debughead(co, records, rec);
1148 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx.iterationidx, rvm_asm(RVM_B, DA, XX, XX, 0));
1149 rvm_codegen_redefinelabel_default(co->cg, ctx.endidx);
1150 rjs_compiler_debugtail(co, records, rec);
1152 rvm_scope_pop(co->scope);
1153 r_array_removelast(co->coctx);
1157 rvm_scope_pop(co->scope);
1158 r_array_removelast(co->coctx);
1163 rint rjs_compiler_rh_iterationdo(rjs_compiler_t *co, rarray_t *records, rlong rec)
1166 rjs_coctx_iteration_t ctx;
1168 r_memset(&ctx, 0, sizeof(ctx));
1169 ctx.base.type = RJS_COCTX_ITERATION;
1170 ctx.start = rvm_codegen_getcodesize(co->cg);
1171 ctx.iterationidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__iteration", ctx.start);
1172 ctx.continueidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__continue", ctx.start);
1173 ctx.endidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__end", ctx.start);
1174 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
1175 rvm_scope_push(co->scope);
1177 prec = (rparecord_t *)r_array_slot(records, rec);
1178 rjs_compiler_debughead(co, records, rec);
1179 rjs_compiler_debugtail(co, records, rec);
1182 rvm_codegen_redefinelabel_default(co->cg, ctx.iterationidx);
1184 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1187 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1188 prec = (rparecord_t *)r_array_slot(records, rec);
1189 rjs_compiler_debughead(co, records, rec);
1190 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx.iterationidx, rvm_asm(RVM_B, DA, XX, XX, 0));
1191 rvm_codegen_redefinelabel_default(co->cg, ctx.endidx);
1192 rjs_compiler_debugtail(co, records, rec);
1194 rvm_scope_pop(co->scope);
1195 r_array_removelast(co->coctx);
1199 rvm_scope_pop(co->scope);
1200 r_array_removelast(co->coctx);
1205 rint rjs_compiler_rh_dowhileexpressioncompare(rjs_compiler_t *co, rarray_t *records, rlong rec)
1208 rjs_coctx_iteration_t *ctx = (rjs_coctx_iteration_t *)rjs_compiler_getctx(co, RJS_COCTX_ITERATION);
1210 prec = (rparecord_t *)r_array_slot(records, rec);
1211 rjs_compiler_debughead(co, records, rec);
1213 rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
1217 rvm_codegen_redefinelabel_default(co->cg, ctx->continueidx);
1218 rjs_compiler_debugtail(co, records, rec);
1220 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1223 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1224 prec = (rparecord_t *)r_array_slot(records, rec);
1225 rjs_compiler_debughead(co, records, rec);
1226 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx->endidx, rvm_asm(RVM_BEQ, DA, XX, XX, 0));
1227 rjs_compiler_debugtail(co, records, rec);
1232 rint rjs_compiler_rh_forexpressioncompare(rjs_compiler_t *co, rarray_t *records, rlong rec)
1235 rjs_coctx_iteration_t *ctx = (rjs_coctx_iteration_t *)rjs_compiler_getctx(co, RJS_COCTX_ITERATION);
1237 prec = (rparecord_t *)r_array_slot(records, rec);
1238 rjs_compiler_debughead(co, records, rec);
1240 rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
1244 rjs_compiler_debugtail(co, records, rec);
1246 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1249 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1250 prec = (rparecord_t *)r_array_slot(records, rec);
1251 rjs_compiler_debughead(co, records, rec);
1252 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx->endidx, rvm_asm(RVM_BEQ, DA, XX, XX, 0));
1253 rjs_compiler_debugtail(co, records, rec);
1258 rint rjs_compiler_rh_forexpressionincrement(rjs_compiler_t *co, rarray_t *records, rlong rec)
1261 rjs_coctx_iteration_t *ctx = (rjs_coctx_iteration_t *)rjs_compiler_getctx(co, RJS_COCTX_ITERATION);
1263 prec = (rparecord_t *)r_array_slot(records, rec);
1264 rjs_compiler_debughead(co, records, rec);
1266 rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
1270 rjs_compiler_debugtail(co, records, rec);
1272 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1275 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1276 prec = (rparecord_t *)r_array_slot(records, rec);
1277 rjs_compiler_debughead(co, records, rec);
1278 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, ctx->iterationidx, rvm_asm(RVM_B, DA, XX, XX, 0));
1279 rjs_compiler_debugtail(co, records, rec);
1284 rint rjs_compiler_rh_postfixexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
1290 if ((opcoderec = rpa_recordtree_lastchild(records, rec, RPA_RECORD_END)) < 0)
1292 opcode = rjs_compiler_record2opcode((rparecord_t *)r_array_slot(records, opcoderec));
1293 prec = (rparecord_t *)r_array_slot(records, rec);
1294 rjs_compiler_debughead(co, records, rec);
1295 rjs_compiler_debugtail(co, records, rec);
1297 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1300 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1301 prec = (rparecord_t *)r_array_slot(records, rec);
1302 rjs_compiler_debughead(co, records, rec);
1303 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
1304 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
1305 rvm_codegen_addins(co->cg, rvm_asm(opcode, R2, R0, DA, 1));
1306 rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R2, R1, XX, 0));
1308 rjs_compiler_debugtail(co, records, rec);
1313 rint rjs_compiler_rh_prefixexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
1319 if ((opcoderec = rpa_recordtree_firstchild(records, rec, RPA_RECORD_END)) < 0)
1321 opcode = rjs_compiler_record2opcode((rparecord_t *)r_array_slot(records, opcoderec));
1323 prec = (rparecord_t *)r_array_slot(records, rec);
1324 rjs_compiler_debughead(co, records, rec);
1325 rjs_compiler_debugtail(co, records, rec);
1327 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1330 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1331 prec = (rparecord_t *)r_array_slot(records, rec);
1332 rjs_compiler_debughead(co, records, rec);
1333 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));
1334 rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, DA, 1));
1335 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
1336 rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
1338 rjs_compiler_debugtail(co, records, rec);
1343 rint rjs_compiler_rh_newexpressioncall(rjs_compiler_t *co, rarray_t *records, rlong rec)
1346 rjs_coctx_functioncall_t ctx;
1348 r_memset(&ctx, 0, sizeof(ctx));
1349 ctx.base.type = RJS_COCTX_FUNCTIONCALL;
1350 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
1352 prec = (rparecord_t *)r_array_slot(records, rec);
1353 rjs_compiler_debughead(co, records, rec);
1354 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(TP)|BIT(FP)|BIT(SP)|BIT(LR)));
1355 rjs_compiler_debugtail(co, records, rec);
1358 * Important: Function call has two children FunctionCallName, Arguments
1359 * We evaluate them in reverse order, first we evaluate the Arguments and push them on the
1360 * stack, than we evaluate the FunctionCallName -> R0. When we make the call we assume the
1361 * result of the FunctionCallName will be in R0.
1363 if (rjs_compiler_playreversechildrecords(co, records, rec) < 0)
1366 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1367 prec = (rparecord_t *)r_array_slot(records, rec);
1368 rjs_compiler_debughead(co, records, rec);
1369 rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCOBJ, TP, DA, XX, 0));
1370 rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, FP, SP, DA, ctx.arguments));
1371 rvm_codegen_addins(co->cg, rvm_asm(RVM_CALL, R0, XX, XX, 0));
1372 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
1373 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, TP, XX, 0));
1374 rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(TP,LR)));
1375 rjs_compiler_debugtail(co, records, rec);
1376 r_array_removelast(co->coctx);
1380 r_array_removelast(co->coctx);
1385 rint rjs_compiler_rh_this(rjs_compiler_t *co, rarray_t *records, rlong rec)
1388 prec = (rparecord_t *)r_array_slot(records, rec);
1389 rjs_compiler_debughead(co, records, rec);
1390 rjs_compiler_debugtail(co, records, rec);
1392 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1395 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1396 prec = (rparecord_t *)r_array_slot(records, rec);
1397 rjs_compiler_debughead(co, records, rec);
1398 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, TP, XX, 0));
1399 rjs_compiler_debugtail(co, records, rec);
1404 rint rjs_compiler_rh_binaryoperator(rjs_compiler_t *co, rarray_t *records, rlong rec)
1407 rjs_coctx_t *ctx = rjs_compiler_gettopctx(co);
1409 prec = (rparecord_t *)r_array_slot(records, rec);
1410 rjs_compiler_debughead(co, records, rec);
1411 rjs_compiler_debugtail(co, records, rec);
1413 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1416 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1417 prec = (rparecord_t *)r_array_slot(records, rec);
1418 rjs_compiler_debughead(co, records, rec);
1419 if (ctx && ctx->type == RJS_COCTX_OPERATION)
1420 ((rjs_coctx_operation_t *)ctx)->opcode = rjs_compiler_record2opcode(prec);
1421 rjs_compiler_debugtail(co, records, rec);
1426 rint rjs_compiler_rh_unaryoperator(rjs_compiler_t *co, rarray_t *records, rlong rec)
1429 rjs_coctx_t *ctx = rjs_compiler_gettopctx(co);
1431 prec = (rparecord_t *)r_array_slot(records, rec);
1432 rjs_compiler_debughead(co, records, rec);
1433 rjs_compiler_debugtail(co, records, rec);
1435 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1438 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1439 prec = (rparecord_t *)r_array_slot(records, rec);
1440 rjs_compiler_debughead(co, records, rec);
1441 if (ctx && ctx->type == RJS_COCTX_OPERATION)
1442 ((rjs_coctx_operation_t *)ctx)->opcode = rjs_compiler_record2unaryopcode(prec);
1443 rjs_compiler_debugtail(co, records, rec);
1448 rint rjs_compiler_rh_identifiername(rjs_compiler_t *co, rarray_t *records, rlong rec)
1451 prec = (rparecord_t *)r_array_slot(records, rec);
1452 rjs_compiler_debughead(co, records, rec);
1453 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, prec->inputsiz));
1454 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)prec->input));
1455 rjs_compiler_debugtail(co, records, rec);
1457 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1460 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1461 prec = (rparecord_t *)r_array_slot(records, rec);
1462 rjs_compiler_debughead(co, records, rec);
1463 rjs_compiler_debugtail(co, records, rec);
1468 rint rjs_compiler_rh_continue(rjs_compiler_t *co, rarray_t *records, rlong rec)
1472 rjs_coctx_iteration_t *iterctx;
1474 ctx = rjs_compiler_getctx(co, RJS_COCTX_ITERATION);
1475 prec = (rparecord_t *)r_array_slot(records, rec);
1476 rjs_compiler_debughead(co, records, rec);
1478 rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
1482 iterctx = (rjs_coctx_iteration_t *)ctx;
1483 rjs_compiler_debugtail(co, records, rec);
1485 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1488 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1489 prec = (rparecord_t *)r_array_slot(records, rec);
1490 rjs_compiler_debughead(co, records, rec);
1491 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, iterctx->continueidx, rvm_asm(RVM_B, DA, XX, XX, 0));
1492 rjs_compiler_debugtail(co, records, rec);
1497 rint rjs_compiler_rh_break(rjs_compiler_t *co, rarray_t *records, rlong rec)
1501 rjs_coctx_iteration_t *iterctx;
1504 ctx = rjs_compiler_getctx(co, RJS_COCTX_ITERATION);
1505 prec = (rparecord_t *)r_array_slot(records, rec);
1506 rjs_compiler_debughead(co, records, rec);
1508 rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
1512 iterctx = (rjs_coctx_iteration_t *)ctx;
1513 rjs_compiler_debugtail(co, records, rec);
1515 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1518 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1519 prec = (rparecord_t *)r_array_slot(records, rec);
1520 rjs_compiler_debughead(co, records, rec);
1521 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, iterctx->endidx, rvm_asm(RVM_B, DA, XX, XX, 0));
1522 rjs_compiler_debugtail(co, records, rec);
1527 rint rjs_compiler_rh_syntaxerror(rjs_compiler_t *co, rarray_t *records, rlong rec)
1530 prec = (rparecord_t *)r_array_slot(records, rec);
1531 rjs_compiler_debughead(co, records, rec);
1532 rjs_compiler_debugtail(co, records, rec);
1534 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1537 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1538 prec = (rparecord_t *)r_array_slot(records, rec);
1539 rjs_compiler_debughead(co, records, rec);
1540 rjs_compiler_adderror(co, RJS_ERROR_SYNTAX, prec);
1541 rjs_compiler_debugtail(co, records, rec);
1546 rint rjs_compiler_rh_block(rjs_compiler_t *co, rarray_t *records, rlong rec)
1549 prec = (rparecord_t *)r_array_slot(records, rec);
1550 rjs_compiler_debughead(co, records, rec);
1551 rvm_scope_push(co->scope);
1552 rjs_compiler_debugtail(co, records, rec);
1554 if (rjs_compiler_playchildrecords(co, records, rec) < 0) {
1555 rvm_scope_pop(co->scope);
1559 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1560 prec = (rparecord_t *)r_array_slot(records, rec);
1561 rjs_compiler_debughead(co, records, rec);
1562 rvm_scope_pop(co->scope);
1563 rjs_compiler_debugtail(co, records, rec);
1568 rint rjs_compiler_rh_(rjs_compiler_t *co, rarray_t *records, rlong rec)
1571 prec = (rparecord_t *)r_array_slot(records, rec);
1572 rjs_compiler_debughead(co, records, rec);
1573 rjs_compiler_debugtail(co, records, rec);
1575 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1578 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1579 prec = (rparecord_t *)r_array_slot(records, rec);
1580 rjs_compiler_debughead(co, records, rec);
1581 rjs_compiler_debugtail(co, records, rec);
1586 rjs_compiler_t *rjs_compiler_create(rvmcpu_t *cpu)
1588 rjs_compiler_t *co = (rjs_compiler_t *) r_zmalloc(sizeof(*co));
1590 co->scope = rvm_scope_create();
1591 co->coctx = r_array_create(sizeof(rjs_coctx_t *));
1593 r_memset(co->handlers, 0, sizeof(co->handlers));
1595 co->handlers[UID_PROGRAM] = rjs_compiler_rh_program;
1596 co->handlers[UID_EXPRESSION] = rjs_compiler_rh_expression;
1597 co->handlers[UID_LEFTHANDSIDEEXPRESSION] = rjs_compiler_rh_lefthandsideexpression;
1598 co->handlers[UID_LEFTHANDSIDEEXPRESSIONADDR] = rjs_compiler_rh_lefthandsideexpressionaddr;
1599 co->handlers[UID_DECIMALINTEGERLITERAL] = rjs_compiler_rh_decimalintegerliteral;
1600 co->handlers[UID_DECIMALNONINTEGERLITERAL] = rjs_compiler_rh_decimalnonintegerliteral;
1601 co->handlers[UID_STRINGCHARACTERS] = rjs_compiler_rh_stringcharacters;
1602 co->handlers[UID_STRINGLITERAL] = rjs_compiler_rh_stringliteral;
1604 co->handlers[UID_ADDITIVEEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
1605 co->handlers[UID_MULTIPLICATIVEEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
1606 co->handlers[UID_BITWISEANDOP] = rjs_compiler_rh_binaryexpressionop;
1607 co->handlers[UID_BITWISEXOROP] = rjs_compiler_rh_binaryexpressionop;
1608 co->handlers[UID_BITWISEOROP] = rjs_compiler_rh_binaryexpressionop;
1609 co->handlers[UID_SHIFTEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
1610 co->handlers[UID_EQUALITYEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
1611 co->handlers[UID_RELATIONALEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
1612 co->handlers[UID_LOGICALOROP] = rjs_compiler_rh_binaryexpressionop;
1613 co->handlers[UID_LOGICALANDOP] = rjs_compiler_rh_binaryexpressionop;
1614 co->handlers[UID_VARIABLEALLOCATEANDINIT] = rjs_compiler_rh_varallocinit;
1615 co->handlers[UID_VARIABLEALLOCATE] = rjs_compiler_rh_varalloc;
1616 co->handlers[UID_IDENTIFIER] = rjs_compiler_rh_identifier;
1617 co->handlers[UID_IDENTIFIERNAME] = rjs_compiler_rh_identifiername;
1618 co->handlers[UID_INITIALISER] = rjs_compiler_rh_initializer;
1619 co->handlers[UID_ASSIGNMENTEXPRESSIONOP] = rjs_compiler_rh_assignmentexpressionop;
1620 co->handlers[UID_NEWARRAYEXPRESSION] = rjs_compiler_rh_newarrayexpression;
1621 co->handlers[UID_MEMBEREXPRESSIONDOTOP] = rjs_compiler_rh_memberexpressiondotop;
1622 co->handlers[UID_MEMBEREXPRESSIONINDEXOP] = rjs_compiler_rh_memberexpressionindexop;
1623 co->handlers[UID_FUNCTIONDECLARATION] = rjs_compiler_rh_functiondeclaration;
1624 co->handlers[UID_FUNCTIONEXPRESSION] = rjs_compiler_rh_functiondeclaration;
1625 co->handlers[UID_FUNCTIONPARAMETER] = rjs_compiler_rh_functionparameter;
1626 co->handlers[UID_FUNCTIONCALL] = rjs_compiler_rh_functioncall;
1627 co->handlers[UID_ARGUMENT] = rjs_compiler_rh_argument;
1628 co->handlers[UID_ARGUMENTS] = rjs_compiler_rh_arguments;
1629 co->handlers[UID_RETURNSTATEMENT] = rjs_compiler_rh_returnstatement;
1630 co->handlers[UID_IFSTATEMENT] = rjs_compiler_rh_ifstatement;
1631 co->handlers[UID_IFCONDITIONOP] = rjs_compiler_rh_ifconditionop;
1632 co->handlers[UID_IFTRUESTATEMENT] = rjs_compiler_rh_iftruestatement;
1633 co->handlers[UID_IFFALSESTATEMENT] = rjs_compiler_rh_iffalsestatement;
1634 co->handlers[UID_ITERATIONDO] = rjs_compiler_rh_iterationdo;
1635 co->handlers[UID_ITERATIONWHILE] = rjs_compiler_rh_iterationwhile;
1636 co->handlers[UID_ITERATIONFOR] = rjs_compiler_rh_iterationfor;
1637 co->handlers[UID_DOWHILEEXPRESSIONCOMPARE] = rjs_compiler_rh_dowhileexpressioncompare;
1638 co->handlers[UID_WHILEEXPRESSIONCOMPARE] = rjs_compiler_rh_forexpressioncompare;
1639 co->handlers[UID_FOREXPRESSIONCOMPARE] = rjs_compiler_rh_forexpressioncompare;
1640 co->handlers[UID_FOREXPRESSIONINCREMENT] = rjs_compiler_rh_forexpressionincrement;
1641 co->handlers[UID_POSTFIXEXPRESSIONOP] = rjs_compiler_rh_postfixexpressionop;
1642 co->handlers[UID_PREFIXEXPRESSIONOP] = rjs_compiler_rh_prefixexpressionop;
1643 co->handlers[UID_THIS] = rjs_compiler_rh_this;
1644 co->handlers[UID_NEWEXPRESSIONCALL] = rjs_compiler_rh_newexpressioncall;
1645 co->handlers[UID_UNARYEXPRESSIONOP] = rjs_compiler_rh_unaryexpressionop;
1646 co->handlers[UID_BINARYOPERATOR] = rjs_compiler_rh_binaryoperator;
1647 co->handlers[UID_UNARYOPERATOR] = rjs_compiler_rh_unaryoperator;
1648 co->handlers[UID_BREAKSTATEMENT] = rjs_compiler_rh_break;
1649 co->handlers[UID_CONTINUESTATEMENT] = rjs_compiler_rh_continue;
1650 co->handlers[UID_SYNTAXERROR] = rjs_compiler_rh_syntaxerror;
1651 co->handlers[UID_BLOCK] = rjs_compiler_rh_block;
1657 void rjs_compiler_destroy(rjs_compiler_t *co)
1660 rvm_scope_destroy(co->scope);
1661 r_array_destroy(co->coctx);
1669 static rint rjs_compiler_rh_default(rjs_compiler_t *co, rarray_t *records, rlong rec)
1673 prec = (rparecord_t *)r_array_slot(records, rec);
1674 rjs_compiler_debughead(co, records, rec);
1675 rjs_compiler_debugtail(co, records, rec);
1677 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
1680 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
1681 prec = (rparecord_t *)r_array_slot(records, rec);
1682 rjs_compiler_debughead(co, records, rec);
1683 rjs_compiler_debugtail(co, records, rec);
1689 static rint rjs_compiler_playchildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec)
1693 for (child = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START); child >= 0; child = rpa_recordtree_next(records, child, RPA_RECORD_START)) {
1694 if (rjs_compiler_playrecord(co, records, child) < 0)
1702 rint rjs_compiler_playreversechildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec)
1706 for (child = rpa_recordtree_lastchild(records, rec, RPA_RECORD_START); child >= 0; child = rpa_recordtree_prev(records, child, RPA_RECORD_START)) {
1707 if (rjs_compiler_playrecord(co, records, child) < 0)
1715 static rint rjs_compiler_playrecord(rjs_compiler_t *co, rarray_t *records, rlong rec)
1718 prec = (rparecord_t *)r_array_slot(records, rec);
1719 if (prec->ruleuid >= 0 && prec->ruleuid < RJS_COMPILER_NHANDLERS && co->handlers[prec->ruleuid]) {
1720 return co->handlers[prec->ruleuid](co, records, rec);
1722 return rjs_compiler_rh_default(co, records, rec);
1726 rint rjs_compiler_compile(rjs_compiler_t *co, const rchar *script, rsize_t scriptsize, rarray_t *records, rvm_codegen_t *cg, rjs_error_t *error)
1729 rvm_codelabel_t *labelerr;
1731 if (!co || !records || !cg || r_array_empty(records)) {
1739 co->script = script;
1740 co->scriptsize = scriptsize;
1742 for (i = 0; i >= 0; i = rpa_recordtree_next(records, i, RPA_RECORD_START)) {
1743 if (rjs_compiler_playrecord(co, records, i) < 0)
1750 if (rvm_codegen_relocate(co->cg, &labelerr) < 0) {