2 #include "rjscompiler.h"
4 rint rjs_compiler_playreversechildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec);
5 static rint rjs_compiler_playrecord(rjs_compiler_t *co, rarray_t *records, rlong rec);
6 static rint rjs_compiler_playchildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec);
9 void rjs_compiler_debughead(rjs_compiler_t *co, rarray_t *records, rlong rec)
12 rpa_record_dump(records, rec);
13 co->headoff = rvm_codegen_getcodesize(co->cg);
18 void rjs_compiler_debugtail(rjs_compiler_t *co, rarray_t *records, rlong rec)
21 rvm_asm_dump(rvm_codegen_getcode(co->cg, co->headoff), rvm_codegen_getcodesize(co->cg) - co->headoff);
27 static const rchar *rjs_compiler_record2str(rjs_compiler_t *co, rarray_t *records, rlong rec)
29 rparecord_t *prec = (rparecord_t *)r_array_slot(records, rpa_recordtree_get(records, rec, RPA_RECORD_END));
30 rsize_t size = 16; /* Min size */
32 if (prec && prec->inputsiz) {
33 size = prec->inputsiz + 1;
35 co->temp = r_realloc(co->temp, size);
36 r_memset(co->temp, 0, size);
37 if (prec->input && prec->inputsiz)
38 r_memcpy(co->temp, prec->input, prec->inputsiz);
43 static rlong rjs_compiler_record2identifer(rjs_compiler_t *co, rarray_t *records, rlong rec)
46 rvm_varmap_t *v = NULL;
47 rjs_coctx_t *ctx = NULL;
48 rparecord_t *prec = (rparecord_t *)r_array_slot(records, rec);
51 * First lets find out if we are within a function definition or
52 * this is a global variable.
54 for (i = r_array_length(co->coctx) - 1; i >= 0; i--) {
55 ctx = r_array_index(co->coctx, i, rjs_coctx_t*);
56 if (ctx->type == RJS_COCTX_FUNCTION || ctx->type == RJS_COCTX_GLOBAL)
61 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
67 r_printf("ERROR: Identifier already defined: %s\n", rjs_compiler_record2str(co, records, rec));
71 if (ctx->type == RJS_COCTX_FUNCTION) {
72 rjs_coctx_function_t *functx = (rjs_coctx_function_t *)ctx;
74 rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, functx->allocs);
76 rjs_coctx_global_t *functx = (rjs_coctx_global_t *)ctx;
78 r_carray_setlength(co->cpu->data, functx->allocs + 1);
79 rvm_scope_addpointer(co->scope, prec->input, prec->inputsiz, r_carray_slot(co->cpu->data, functx->allocs));
81 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
82 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
83 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
85 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
92 rlong rjs_compiler_record2opcode(rparecord_t *prec)
94 const rchar *input = prec->input;
95 rsize_t size = prec->inputsiz;
97 if (r_stringncmp("++", input, size))
99 else if (r_stringncmp("+", input, size))
101 else if (r_stringncmp("+=", input, size))
103 else if (r_stringncmp("--", input, size))
105 else if (r_stringncmp("-", input, size))
107 else if (r_stringncmp("-=", input, size))
109 else if (r_stringncmp("*", input, size))
111 else if (r_stringncmp("*=", input, size))
113 else if (r_stringncmp("/", input, size))
115 else if (r_stringncmp("/=", input, size))
117 else if (r_stringncmp("%", input, size))
119 else if (r_stringncmp("%=", input, size))
121 else if (r_stringncmp("&&", input, size))
123 else if (r_stringncmp("||", input, size))
125 else if (r_stringncmp("&", input, size))
127 else if (r_stringncmp("&=", input, size))
129 else if (r_stringncmp("|", input, size))
131 else if (r_stringncmp("|=", input, size))
133 else if (r_stringncmp("^", input, size))
135 else if (r_stringncmp("^=", input, size))
137 else if (r_stringncmp(">>", input, size))
139 else if (r_stringncmp(">>=", input, size))
141 else if (r_stringncmp("<<", input, size))
143 else if (r_stringncmp("<<=", input, size))
145 else if (r_stringncmp(">>>", input, size))
147 else if (r_stringncmp(">>>=", input, size))
149 else if (r_stringncmp("<=", input, size))
151 else if (r_stringncmp(">=", input, size))
153 else if (r_stringncmp("<", input, size))
155 else if (r_stringncmp(">", input, size))
157 else if (r_stringncmp("===", input, size))
159 else if (r_stringncmp("==", input, size))
161 else if (r_stringncmp("!==", input, size))
163 else if (r_stringncmp("!=", input, size))
165 else if (r_stringncmp("!", input, size))
167 else if (r_stringncmp("~", input, size))
169 else if (r_stringncmp("=", input, size))
176 rint rjs_compiler_rh_program(rjs_compiler_t *co, rarray_t *records, rlong rec)
178 rjs_coctx_global_t ctx;
181 r_memset(&ctx, 0, sizeof(ctx));
182 ctx.base.type = RJS_COCTX_GLOBAL;
183 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
185 prec = (rparecord_t *)r_array_slot(records, rec);
186 rjs_compiler_debughead(co, records, rec);
187 rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
188 rjs_compiler_debugtail(co, records, rec);
190 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
193 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
194 prec = (rparecord_t *)r_array_slot(records, rec);
195 rjs_compiler_debughead(co, records, rec);
196 rvm_codegen_addins(co->cg, rvm_asm(RVM_PRN, R0, XX, XX, 0));
197 rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
198 rjs_compiler_debugtail(co, records, rec);
199 r_array_removelast(co->coctx);
203 r_array_removelast(co->coctx);
208 rint rjs_compiler_rh_varalloc(rjs_compiler_t *co, rarray_t *records, rlong rec)
211 rjs_coctx_t *ctx = NULL;
212 rvm_varmap_t *v = NULL;
215 R_ASSERT(r_array_length(co->coctx));
218 * First lets find out if we are within a function definition or
219 * this is a global variable.
221 for (i = r_array_length(co->coctx) - 1; i >= 0; i--) {
222 ctx = r_array_index(co->coctx, i, rjs_coctx_t*);
223 if (ctx->type == RJS_COCTX_FUNCTION || ctx->type == RJS_COCTX_GLOBAL)
228 prec = (rparecord_t *)r_array_slot(records, rec);
229 rjs_compiler_debughead(co, records, rec);
230 rjs_compiler_debugtail(co, records, rec);
232 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
235 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
236 prec = (rparecord_t *)r_array_slot(records, rec);
237 rjs_compiler_debughead(co, records, rec);
238 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
241 * TBD: Temporary here
244 r_printf("ERROR: variable already defined: %s\n", rjs_compiler_record2str(co, records, rec));
248 if (ctx->type == RJS_COCTX_FUNCTION) {
249 rjs_coctx_function_t *functx = (rjs_coctx_function_t *)ctx;
251 rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, functx->allocs);
253 rjs_coctx_global_t *functx = (rjs_coctx_global_t *)ctx;
255 r_carray_setlength(co->cpu->data, functx->allocs + 1);
256 rvm_scope_addpointer(co->scope, prec->input, prec->inputsiz, r_carray_slot(co->cpu->data, functx->allocs));
258 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
259 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
260 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R1, FP, DA, v->data.offset));
262 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R1, DA, XX, v->data.ptr));
264 rvm_codegen_addins(co->cg, rvm_asm(RVM_CLRR, R1, XX, XX, 0));
266 rjs_compiler_debugtail(co, records, rec);
274 rint rjs_compiler_rh_varallocinit(rjs_compiler_t *co, rarray_t *records, rlong rec)
277 rjs_coctx_t *ctx = NULL;
278 rvm_varmap_t *v = NULL;
281 R_ASSERT(r_array_length(co->coctx));
284 * First lets find out if we are within a function definition or
285 * this is a global variable.
287 for (i = r_array_length(co->coctx) - 1; i >= 0; i--) {
288 ctx = r_array_index(co->coctx, i, rjs_coctx_t*);
289 if (ctx->type == RJS_COCTX_FUNCTION || ctx->type == RJS_COCTX_GLOBAL)
294 prec = (rparecord_t *)r_array_slot(records, rec);
295 rjs_compiler_debughead(co, records, rec);
296 rjs_compiler_debugtail(co, records, rec);
298 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
301 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
302 prec = (rparecord_t *)r_array_slot(records, rec);
303 rjs_compiler_debughead(co, records, rec);
304 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
307 * TBD: Temporary here
310 r_printf("ERROR: variable already defined: %s\n", rjs_compiler_record2str(co, records, rec));
314 if (ctx->type == RJS_COCTX_FUNCTION) {
315 rjs_coctx_function_t *functx = (rjs_coctx_function_t *)ctx;
317 rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, functx->allocs);
319 rjs_coctx_global_t *functx = (rjs_coctx_global_t *)ctx;
321 r_carray_setlength(co->cpu->data, functx->allocs + 1);
322 rvm_scope_addpointer(co->scope, prec->input, prec->inputsiz, r_carray_slot(co->cpu->data, functx->allocs));
324 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
325 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
326 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
328 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
330 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
331 rjs_compiler_debugtail(co, records, rec);
339 rint rjs_compiler_rh_initializer(rjs_compiler_t *co, rarray_t *records, rlong rec)
342 prec = (rparecord_t *)r_array_slot(records, rec);
343 rjs_compiler_debughead(co, records, rec);
344 rjs_compiler_debugtail(co, records, rec);
346 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
349 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
350 prec = (rparecord_t *)r_array_slot(records, rec);
351 rjs_compiler_debughead(co, records, rec);
352 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
353 rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
354 rjs_compiler_debugtail(co, records, rec);
359 rint rjs_compiler_rh_identifier(rjs_compiler_t *co, rarray_t *records, rlong rec)
363 rparecord_t *prec, *pparrec;
364 prec = (rparecord_t *)r_array_slot(records, rec);
365 rjs_compiler_debughead(co, records, rec);
366 rjs_compiler_debugtail(co, records, rec);
368 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
371 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
372 prec = (rparecord_t *)r_array_slot(records, rec);
373 rjs_compiler_debughead(co, records, rec);
374 v = rvm_scope_lookup(co->scope, prec->input, prec->inputsiz);
376 r_printf("ERROR: Undefined identifier: %s\n", rjs_compiler_record2str(co, records, rec));
380 if ((parrec = rpa_recordtree_parent(records, rec, RPA_RECORD_END)) < 0) {
384 pparrec = (rparecord_t *)r_array_slot(records, parrec);
385 if (rpa_recordtree_next(records, rec, RPA_RECORD_START) < 0 && pparrec->ruleuid == UID_LEFTHANDSIDEEXPRESSIONADDR) {
387 * If this is the last child of UID_LEFTHANDSIDEEXPRESSIONADDR
389 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
390 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
392 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
395 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
396 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, FP, DA, v->data.offset));
398 rvm_codegen_addins(co->cg, rvm_asmp(RVM_LDRR, R0, DA, XX, v->data.ptr));
402 rjs_compiler_debugtail(co, records, rec);
407 rint rjs_compiler_rh_expression(rjs_compiler_t *co, rarray_t *records, rlong rec)
410 prec = (rparecord_t *)r_array_slot(records, rec);
411 rjs_compiler_debughead(co, records, rec);
412 rjs_compiler_debugtail(co, records, rec);
414 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
417 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
418 prec = (rparecord_t *)r_array_slot(records, rec);
419 rjs_compiler_debughead(co, records, rec);
420 rjs_compiler_debugtail(co, records, rec);
425 rint rjs_compiler_rh_lefthandsideexpression(rjs_compiler_t *co, rarray_t *records, rlong rec)
428 prec = (rparecord_t *)r_array_slot(records, rec);
429 rjs_compiler_debughead(co, records, rec);
430 rjs_compiler_debugtail(co, records, rec);
432 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
435 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
436 prec = (rparecord_t *)r_array_slot(records, rec);
437 rjs_compiler_debughead(co, records, rec);
438 rjs_compiler_debugtail(co, records, rec);
443 rint rjs_compiler_rh_lefthandsideexpressionaddr(rjs_compiler_t *co, rarray_t *records, rlong rec)
446 prec = (rparecord_t *)r_array_slot(records, rec);
447 rjs_compiler_debughead(co, records, rec);
448 rjs_compiler_debugtail(co, records, rec);
450 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
453 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
454 prec = (rparecord_t *)r_array_slot(records, rec);
455 rjs_compiler_debughead(co, records, rec);
456 rvm_codegen_addins(co->cg, rvm_asmp(RVM_PUSH, R0, XX, XX, 0));
457 rjs_compiler_debugtail(co, records, rec);
462 rint rjs_compiler_rh_decimalintegerliteral(rjs_compiler_t *co, rarray_t *records, rlong rec)
465 prec = (rparecord_t *)r_array_slot(records, rec);
466 rjs_compiler_debughead(co, records, rec);
467 rjs_compiler_debugtail(co, records, rec);
469 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
472 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
473 prec = (rparecord_t *)r_array_slot(records, rec);
474 rjs_compiler_debughead(co, records, rec);
475 rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R0, DA, XX, r_strtol(prec->input, NULL, 10)));
476 rjs_compiler_debugtail(co, records, rec);
481 rint rjs_compiler_rh_decimalnonintegerliteral(rjs_compiler_t *co, rarray_t *records, rlong rec)
484 prec = (rparecord_t *)r_array_slot(records, rec);
485 rjs_compiler_debughead(co, records, rec);
486 rjs_compiler_debugtail(co, records, rec);
488 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
491 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
492 prec = (rparecord_t *)r_array_slot(records, rec);
493 rjs_compiler_debughead(co, records, rec);
494 rvm_codegen_addins(co->cg, rvm_asmd(RVM_MOV, R0, DA, XX, r_strtod(prec->input, NULL)));
496 rjs_compiler_debugtail(co, records, rec);
501 rint rjs_compiler_rh_expressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
505 rlong opcoderec = -1;
507 prec = (rparecord_t *)r_array_slot(records, rec);
508 rjs_compiler_debughead(co, records, rec);
509 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
510 rjs_compiler_debugtail(co, records, rec);
512 if ((opcoderec = rpa_recordtree_firstchild(records, rec, RPA_RECORD_END)) < 0)
514 opcode = rjs_compiler_record2opcode((rparecord_t *)r_array_slot(records, opcoderec));
516 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
519 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
520 prec = (rparecord_t *)r_array_slot(records, rec);
521 rjs_compiler_debughead(co, records, rec);
522 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
523 rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R1, R0, 0));
524 rjs_compiler_debugtail(co, records, rec);
529 rint rjs_compiler_rh_assignmentexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
533 rlong opcoderec = -1;
535 prec = (rparecord_t *)r_array_slot(records, rec);
536 rjs_compiler_debughead(co, records, rec);
537 rjs_compiler_debugtail(co, records, rec);
539 if ((opcoderec = rpa_recordtree_next(records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_END), RPA_RECORD_END)) < 0)
541 opcode = rjs_compiler_record2opcode((rparecord_t *)r_array_slot(records, opcoderec));
543 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
546 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
547 prec = (rparecord_t *)r_array_slot(records, rec);
548 rjs_compiler_debughead(co, records, rec);
549 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
550 if (opcode != RVM_NOP) {
551 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R2, R1, XX, 0));
552 rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R2, R0, 0));
554 rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
555 rjs_compiler_debugtail(co, records, rec);
560 rint rjs_compiler_rh_newarrayexpression(rjs_compiler_t *co, rarray_t *records, rlong rec)
563 prec = (rparecord_t *)r_array_slot(records, rec);
564 rjs_compiler_debughead(co, records, rec);
565 rjs_compiler_debugtail(co, records, rec);
567 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
570 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
571 prec = (rparecord_t *)r_array_slot(records, rec);
572 rjs_compiler_debughead(co, records, rec);
573 rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCOBJ, R0, DA, XX, 0));
574 rjs_compiler_debugtail(co, records, rec);
579 rint rjs_compiler_rh_memberexpressiondotop(rjs_compiler_t *co, rarray_t *records, rlong rec)
582 prec = (rparecord_t *)r_array_slot(records, rec);
583 rjs_compiler_debughead(co, records, rec);
584 rjs_compiler_debugtail(co, records, rec);
586 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
589 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
590 prec = (rparecord_t *)r_array_slot(records, rec);
591 rjs_compiler_debughead(co, records, rec);
592 if (rpa_record_getruleuid(records, rpa_recordtree_parent(records, rec, RPA_RECORD_START)) == UID_LEFTHANDSIDEEXPRESSIONADDR &&
593 rpa_recordtree_next(records, rec, RPA_RECORD_START) == -1) {
594 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0)); // Supposedly an Array
595 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, prec->inputsiz));
596 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)prec->input));
597 rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUPADD, R0, R1, R2, 0)); // Get the offset of the element at offset R0
598 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDROBJH, R0, R1, R0, 0)); // Get the address of the element at offset R0
601 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0)); // Supposedly an Array
602 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, prec->inputsiz));
603 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)prec->input));
604 rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUP, R0, R1, R2, 0)); // Get the offset of the element at offset R0
605 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDOBJH, R0, R1, R0, 0)); // Get the value of the element at offset R0
607 rjs_compiler_debugtail(co, records, rec);
612 rint rjs_compiler_rh_memberexpressionindexop(rjs_compiler_t *co, rarray_t *records, rlong rec)
615 prec = (rparecord_t *)r_array_slot(records, rec);
616 rjs_compiler_debughead(co, records, rec);
617 rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0)); // Supposedly an Array
618 rjs_compiler_debugtail(co, records, rec);
620 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
623 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
624 prec = (rparecord_t *)r_array_slot(records, rec);
625 rjs_compiler_debughead(co, records, rec);
626 if (rpa_record_getruleuid(records, rpa_recordtree_parent(records, rec, RPA_RECORD_START)) == UID_LEFTHANDSIDEEXPRESSIONADDR &&
627 rpa_recordtree_next(records, rec, RPA_RECORD_START) == -1) {
628 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0)); // Supposedly an Array
629 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDROBJN, R0, R1, R0, 0)); // Get the address of the element at offset R0
632 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0)); // Supposedly an Array
633 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDOBJN, R0, R1, R0, 0)); // Get the value of the element at offset R0
635 rjs_compiler_debugtail(co, records, rec);
640 rint rjs_compiler_rh_functiondeclaration(rjs_compiler_t *co, rarray_t *records, rlong rec)
642 rjs_coctx_function_t ctx;
644 rlong start, execidx, endidx, allocsidx;
646 r_memset(&ctx, 0, sizeof(ctx));
647 ctx.base.type = RJS_COCTX_FUNCTION;
649 prec = (rparecord_t *)r_array_slot(records, rec);
650 rjs_compiler_debughead(co, records, rec);
651 start = rvm_codegen_getcodesize(co->cg);
652 endidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__funend", start);
653 execidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__funexec", start);
654 allocsidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__allocs", start);
656 if (rpa_record_getruleuid(records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START)) != UID_FUNCTIONNAME)
658 if (rjs_compiler_record2identifer(co, records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START)) < 0)
661 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
662 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_JUMP, execidx, rvm_asm(RVM_MOV, R0, DA, XX, 0));
663 rvm_codegen_addins(co->cg, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_FUNCTION));
664 rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
665 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, endidx, rvm_asm(RVM_B, DA, XX, XX, 0));
666 rvm_codegen_redefinelabel(co->cg, execidx);
667 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_DEFAULT, allocsidx, rvm_asm(RVM_ADD, SP, FP, DA, 0));
669 rjs_compiler_debugtail(co, records, rec);
671 r_array_push(co->coctx, &ctx, rjs_coctx_t*);
672 rvm_scope_push(co->scope);
673 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
676 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
677 prec = (rparecord_t *)r_array_slot(records, rec);
678 rjs_compiler_debughead(co, records, rec);
680 rvm_codegen_redefinelabel(co->cg, endidx);
681 rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
682 rvm_codegen_redefinepointer(co->cg, allocsidx, (rpointer)ctx.allocs);
683 rjs_compiler_debugtail(co, records, rec);
685 rvm_scope_pop(co->scope);
686 r_array_removelast(co->coctx);
690 rvm_scope_pop(co->scope);
691 r_array_removelast(co->coctx);
696 rint rjs_compiler_rh_functionparameter(rjs_compiler_t *co, rarray_t *records, rlong rec)
698 rjs_coctx_t *ctx = NULL;
699 rjs_coctx_function_t *functx = NULL;
705 * First lets find out if we are within a function definition or
706 * this is a global variable.
708 for (i = r_array_length(co->coctx) - 1; i >= 0; i--) {
709 ctx = r_array_index(co->coctx, i, rjs_coctx_t*);
710 if (ctx->type == RJS_COCTX_FUNCTION)
714 functx = (rjs_coctx_function_t *)ctx;
716 prec = (rparecord_t *)r_array_slot(records, rec);
717 rjs_compiler_debughead(co, records, rec);
718 rjs_compiler_debugtail(co, records, rec);
720 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
723 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
724 prec = (rparecord_t *)r_array_slot(records, rec);
725 rjs_compiler_debughead(co, records, rec);
726 v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
729 * TBD: Temporary here
732 r_printf("ERROR: Identifier already defined: %s\n", rjs_compiler_record2str(co, records, rec));
737 rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, functx->allocs);
739 rjs_compiler_debugtail(co, records, rec);
744 rint rjs_compiler_rh_(rjs_compiler_t *co, rarray_t *records, rlong rec)
747 prec = (rparecord_t *)r_array_slot(records, rec);
748 rjs_compiler_debughead(co, records, rec);
749 rjs_compiler_debugtail(co, records, rec);
751 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
754 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
755 prec = (rparecord_t *)r_array_slot(records, rec);
756 rjs_compiler_debughead(co, records, rec);
757 rjs_compiler_debugtail(co, records, rec);
762 rjs_compiler_t *rjs_compiler_create(rvmcpu_t *cpu)
764 rjs_compiler_t *co = (rjs_compiler_t *) r_zmalloc(sizeof(*co));
766 co->cg = rvm_codegen_create();
767 co->scope = rvm_scope_create();
768 co->coctx = r_array_create(sizeof(rjs_coctx_t *));
770 r_memset(co->handlers, 0, sizeof(co->handlers));
772 co->handlers[UID_PROGRAM] = rjs_compiler_rh_program;
773 co->handlers[UID_EXPRESSION] = rjs_compiler_rh_expression;
774 co->handlers[UID_LEFTHANDSIDEEXPRESSION] = rjs_compiler_rh_lefthandsideexpression;
775 co->handlers[UID_LEFTHANDSIDEEXPRESSIONADDR] = rjs_compiler_rh_lefthandsideexpressionaddr;
776 co->handlers[UID_DECIMALINTEGERLITERAL] = rjs_compiler_rh_decimalintegerliteral;
777 co->handlers[UID_DECIMALNONINTEGERLITERAL] = rjs_compiler_rh_decimalnonintegerliteral;
778 co->handlers[UID_ADDITIVEEXPRESSIONOP] = rjs_compiler_rh_expressionop;
779 co->handlers[UID_MULTIPLICATIVEEXPRESSIONOP] = rjs_compiler_rh_expressionop;
780 co->handlers[UID_BITWISEANDOP] = rjs_compiler_rh_expressionop;
781 co->handlers[UID_BITWISEXOROP] = rjs_compiler_rh_expressionop;
782 co->handlers[UID_BITWISEOROP] = rjs_compiler_rh_expressionop;
783 co->handlers[UID_SHIFTEXPRESSIONOP] = rjs_compiler_rh_expressionop;
784 co->handlers[UID_EQUALITYEXPRESSIONOP] = rjs_compiler_rh_expressionop;
785 co->handlers[UID_RELATIONALEXPRESSIONOP] = rjs_compiler_rh_expressionop;
786 co->handlers[UID_LOGICALOROP] = rjs_compiler_rh_expressionop;
787 co->handlers[UID_LOGICALANDOP] = rjs_compiler_rh_expressionop;
788 co->handlers[UID_VARIABLEALLOCATEANDINIT] = rjs_compiler_rh_varallocinit;
789 co->handlers[UID_VARIABLEALLOCATE] = rjs_compiler_rh_varalloc;
790 co->handlers[UID_IDENTIFIER] = rjs_compiler_rh_identifier;
791 co->handlers[UID_INITIALISER] = rjs_compiler_rh_initializer;
792 co->handlers[UID_ASSIGNMENTEXPRESSIONOP] = rjs_compiler_rh_assignmentexpressionop;
793 co->handlers[UID_NEWARRAYEXPRESSION] = rjs_compiler_rh_newarrayexpression;
794 co->handlers[UID_MEMBEREXPRESSIONDOTOP] = rjs_compiler_rh_memberexpressiondotop;
795 co->handlers[UID_MEMBEREXPRESSIONINDEXOP] = rjs_compiler_rh_memberexpressionindexop;
796 co->handlers[UID_FUNCTIONDECLARATION] = rjs_compiler_rh_functiondeclaration;
797 co->handlers[UID_FUNCTIONPARAMETER] = rjs_compiler_rh_functionparameter;
803 void rjs_compiler_destroy(rjs_compiler_t *co)
806 rvm_codegen_destroy(co->cg);
807 rvm_scope_destroy(co->scope);
808 r_array_destroy(co->coctx);
816 static rint rjs_compiler_rh_default(rjs_compiler_t *co, rarray_t *records, rlong rec)
820 prec = (rparecord_t *)r_array_slot(records, rec);
821 rjs_compiler_debughead(co, records, rec);
822 rjs_compiler_debugtail(co, records, rec);
824 if (rjs_compiler_playchildrecords(co, records, rec) < 0)
827 rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
828 prec = (rparecord_t *)r_array_slot(records, rec);
829 rjs_compiler_debughead(co, records, rec);
830 rjs_compiler_debugtail(co, records, rec);
836 static rint rjs_compiler_playchildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec)
840 for (child = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START); child >= 0; child = rpa_recordtree_next(records, child, RPA_RECORD_START)) {
841 if (rjs_compiler_playrecord(co, records, child) < 0)
849 rint rjs_compiler_playreversechildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec)
853 for (child = rpa_recordtree_lastchild(records, rec, RPA_RECORD_START); child >= 0; child = rpa_recordtree_prev(records, child, RPA_RECORD_START)) {
854 if (rjs_compiler_playrecord(co, records, child) < 0)
862 static rint rjs_compiler_playrecord(rjs_compiler_t *co, rarray_t *records, rlong rec)
865 prec = (rparecord_t *)r_array_slot(records, rec);
866 if (prec->ruleuid >= 0 && prec->ruleuid < RJS_COMPILER_NHANDLERS && co->handlers[prec->ruleuid]) {
867 return co->handlers[prec->ruleuid](co, records, rec);
869 return rjs_compiler_rh_default(co, records, rec);
873 rint rjs_compiler_compile(rjs_compiler_t *co, rarray_t *records)
876 rvm_codelabel_t *labelerr;
878 if (!co || !records || r_array_empty(records)) {
885 for (i = 0; i >= 0; i = rpa_recordtree_next(records, i, RPA_RECORD_START)) {
886 if (rjs_compiler_playrecord(co, records, i) < 0)
893 if (rvm_codegen_relocate(co->cg, &labelerr) < 0) {