BASIC compiler/interpreter for PIC32MX/MZ-80K
リビジョン | 9ef619c3cb83964c1ab02130e663e62713388c75 (tree) |
---|---|
日時 | 2019-02-07 10:45:49 |
作者 | Katsumi <kmorimatsu@sour...> |
コミッター | Katsumi |
Avoid overwriting field in recursive object structure.
@@ -420,6 +420,13 @@ char* obj_method(int method){ | ||
420 | 420 | // Note that '(' has been passed. |
421 | 421 | char* err; |
422 | 422 | int stack,opos; |
423 | + // When method of an object is called from object, | |
424 | + // current variables must be saved to object fields | |
425 | + if (g_compiling_class) { | |
426 | + check_obj_space(1); | |
427 | + g_object[g_objpos++]=0x00402821; // addu a1,v0,zero | |
428 | + call_quicklib_code(lib_save_vars_to_fields,ASM_LW_A0_XXXX_S5|ARGS_S5_V0_OBJ); | |
429 | + } | |
423 | 430 | // Parameters preparation (to $s5) here. |
424 | 431 | next_position(); |
425 | 432 | opos=g_objpos; |
@@ -451,6 +458,13 @@ char* obj_method(int method){ | ||
451 | 458 | // Remove stack |
452 | 459 | err=remove_args_stack(); |
453 | 460 | if (err) return err; |
461 | + // When method of an object is called from object, | |
462 | + // current variables must be saved to object fields | |
463 | + if (g_compiling_class) { | |
464 | + check_obj_space(1); | |
465 | + g_object[g_objpos++]=0x00402821; // addu a1,v0,zero | |
466 | + call_quicklib_code(lib_load_vars_from_fields,ASM_LW_A0_XXXX_S5|ARGS_S5_V0_OBJ); | |
467 | + } | |
454 | 468 | return 0; |
455 | 469 | } |
456 | 470 |
@@ -558,6 +572,12 @@ void lib_let_str_field(char* prev_str, char* new_str){ | ||
558 | 572 | Library for calling method statement |
559 | 573 | */ |
560 | 574 | |
575 | +int lib_load_vars_from_fields(int* object, int v0){ | |
576 | + // Do nothing if no object | |
577 | + if (object) lib_pre_method(object,LABEL_INIT); | |
578 | + return v0; | |
579 | +} | |
580 | + | |
561 | 581 | int lib_pre_method(int* object, int methodname){ |
562 | 582 | int i,num,nums; |
563 | 583 | int* class; |
@@ -604,6 +624,19 @@ int lib_pre_method(int* object, int methodname){ | ||
604 | 624 | return class[1]; |
605 | 625 | } |
606 | 626 | |
627 | +int lib_save_vars_to_fields(int* object,int v0){ | |
628 | + int* class; | |
629 | + // Do nothing if no object | |
630 | + if (!object) return; | |
631 | + // Check if this is an object (if within the RAM). | |
632 | + if (!withinRAM(object)) err_not_obj(); | |
633 | + class=(int*)object[0]; | |
634 | + if (!withinRAM(class)) err_not_obj(); | |
635 | + // save vars | |
636 | + lib_post_method(object,0); | |
637 | + return v0; | |
638 | +} | |
639 | + | |
607 | 640 | int lib_post_method(int* object, int v0){ |
608 | 641 | // Note that v0 (a1) contains the return value from a method. |
609 | 642 | int i,num,nums; |
@@ -350,6 +350,9 @@ char* float_obj_field(); | ||
350 | 350 | int lib_obj_field(int* object, int fieldname); |
351 | 351 | int lib_pre_method(int* object, int methodname); |
352 | 352 | int lib_post_method(int* object, int v0); |
353 | +int lib_save_vars_to_fields(int* object,int v0); | |
354 | +int lib_load_vars_from_fields(int* object, int v0); | |
355 | + | |
353 | 356 | char* method_statement(); |
354 | 357 | char* delete_statement(); |
355 | 358 | char* call_statement(); |
@@ -463,6 +466,7 @@ char* resolve_unresolved(int class); | ||
463 | 466 | #define ASM_ADDU_A3_V0_ZERO 0x00403821 |
464 | 467 | #define ASM_ORI_A0_ZERO_ 0x34040000 |
465 | 468 | #define ASM_LW_A0_XXXX_S8 0x8FC40000 |
469 | +#define ASM_LW_A0_XXXX_S5 0x8EA40000 | |
466 | 470 | |
467 | 471 | // Division macro for unsigned long |
468 | 472 | // Valid for 31 bits for all cases and 32 bits for some cases |
@@ -249,7 +249,7 @@ static const char classtext[]= | ||
249 | 249 | " T6=rnd()\n" |
250 | 250 | " return\n" |
251 | 251 | "METHOD T3\n" |
252 | -" o=new(CLASS1)\n" // TODO: save variables to object field before calling method of another object | |
252 | +" o=new(CLASS1)\n" | |
253 | 253 | " return o\n" |
254 | 254 | "METHOD T4\n" |
255 | 255 | " return T6\n" |
@@ -269,10 +269,7 @@ static const void* debugjumptable[]={ | ||
269 | 269 | |
270 | 270 | int _debug_test(int a0, int a1, int a2, int a3, int param4, int param5){ |
271 | 271 | asm volatile(".set noreorder"); |
272 | - asm volatile("lw $a0,0($v1)"); | |
273 | - asm volatile("sw $sp,-12($s5)"); | |
274 | - asm volatile("lw $sp,-12($s5)"); | |
275 | - asm volatile("lw $v0,-8($s5)"); | |
272 | + asm volatile("lw $a0,-8($s5)"); | |
276 | 273 | asm volatile("nop"); |
277 | 274 | asm volatile("nop"); |
278 | 275 | asm volatile("nop"); |