handle returns better

This commit is contained in:
ceriel 1987-08-06 09:55:00 +00:00
parent 285654f044
commit 0b8262a167
2 changed files with 19 additions and 16 deletions
lang/cem/cemcom

View file

@ -97,7 +97,7 @@ HFILES = $(HSRC) $(GHSRC) $(GHSTRSRC)
# generated files, for 'make clean' only # generated files, for 'make clean' only
GENERATED = tab tokenfile.g Lpars.h LLfiles LL.output lint.out \ GENERATED = tab tokenfile.g Lpars.h LLfiles LL.output lint.out \
print Xref lxref hfiles Cfiles $(GHSRC) $(GSRC) longnames $(LCSRC) print hfiles Cfiles $(GHSRC) $(GSRC) longnames $(LCSRC)
# include files containing ALLOCDEF specifications # include files containing ALLOCDEF specifications
OBJ = $(COBJ) $(LOBJ) $(GOBJ) OBJ = $(COBJ) $(LOBJ) $(GOBJ)

View file

@ -161,8 +161,8 @@ code_scope(text, def)
} }
} }
static label return_label; static label return_label, return2_label;
/* static char return_expr_occurred; */ static char return_expr_occurred;
static struct type *func_tp; static struct type *func_tp;
static arith func_size; static arith func_size;
static label func_res_label; static label func_res_label;
@ -217,7 +217,8 @@ begin_proc(name, def) /* to be called when entering a procedure */
*/ */
lab_count = (label) 1; lab_count = (label) 1;
return_label = text_label(); return_label = text_label();
/* return_expr_occurred = 0; */ return2_label = text_label();
return_expr_occurred = 0;
LocalInit(); LocalInit();
prc_entry(name); prc_entry(name);
if (! options['L']) { /* profiling */ if (! options['L']) { /* profiling */
@ -255,18 +256,21 @@ end_proc(fbytes)
if (options['d']) if (options['d'])
DfaEndFunction(); DfaEndFunction();
#endif DATAFLOW #endif DATAFLOW
prc_exit(); C_df_ilb(return2_label);
C_asp(-func_size); /* arbitrary return value */ if (return_expr_occurred) C_asp(-func_size);
C_df_ilb(return_label); C_df_ilb(return_label);
prc_exit(); prc_exit();
if (func_res_label != 0) { if (return_expr_occurred) {
C_lae_dlb(func_res_label, (arith)0); if (func_res_label != 0) {
store_block(func_size, func_tp->tp_align); C_lae_dlb(func_res_label, (arith)0);
C_lae_dlb(func_res_label, (arith)0); store_block(func_size, func_tp->tp_align);
C_ret(pointer_size); C_lae_dlb(func_res_label, (arith)0);
C_ret(pointer_size);
}
else
C_ret(func_size);
} }
else else C_ret((arith) 0);
C_ret(func_size);
/* getting the number of "local" bytes is posponed until here, /* getting the number of "local" bytes is posponed until here,
because copying the function result in "func_res_label" may because copying the function result in "func_res_label" may
@ -300,8 +304,7 @@ do_return()
probably smarter than generating a direct return. probably smarter than generating a direct return.
Return sequences may be expensive. Return sequences may be expensive.
*/ */
C_asp(-func_size); /* arbitrary return value */ C_bra(return2_label);
C_bra(return_label);
} }
do_return_expr(expr) do_return_expr(expr)
@ -313,7 +316,7 @@ do_return_expr(expr)
ch7cast(&expr, RETURN, func_tp); ch7cast(&expr, RETURN, func_tp);
code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL); code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
C_bra(return_label); C_bra(return_label);
/* return_expr_occurred = 1; */ return_expr_occurred = 1;
} }
code_declaration(idf, expr, lvl, sc) code_declaration(idf, expr, lvl, sc)