1 #include <stdlib.h>
2 #include "lib/mlr_globals.h"
3 #include "lib/mlrutil.h"
4 #include "mlr_dsl_cst.h"
5 #include "context_flags.h"
6 
7 // ================================================================
handle_return_void(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)8 static void handle_return_void(
9 	mlr_dsl_cst_statement_t* pstatement,
10 	variables_t*             pvars,
11 	cst_outputs_t*           pcst_outputs)
12 {
13 	pvars->return_state.returned = TRUE;
14 }
15 
free_return_void(mlr_dsl_cst_statement_t * pstatement,context_t * _)16 static void free_return_void(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
17 }
18 
alloc_return_void(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int type_inferencing,int context_flags)19 mlr_dsl_cst_statement_t* alloc_return_void(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode,
20 	int type_inferencing, int context_flags)
21 {
22 	return mlr_dsl_cst_statement_valloc(
23 		pnode,
24 		handle_return_void,
25 		free_return_void,
26 		NULL);
27 }
28 
29 // ================================================================
30 typedef struct _return_value_state_t {
31 	rxval_evaluator_t* preturn_value_xevaluator;
32 } return_value_state_t;
33 
34 // ----------------------------------------------------------------
return_value_func(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)35 static void return_value_func(
36 	mlr_dsl_cst_statement_t* pstatement,
37 	variables_t*             pvars,
38 	cst_outputs_t*           pcst_outputs)
39 {
40 	return_value_state_t* pstate = pstatement->pvstate;
41 	rxval_evaluator_t* pxev = pstate->preturn_value_xevaluator;
42 	boxed_xval_t retval = pxev->pprocess_func(pxev->pvstate, pvars);
43 
44 	// Copy even if referenced since we are returning: otherwise the referent can be freed
45 	// by stack-frame exit before the caller can copy it.
46 	if (retval.is_ephemeral) {
47 		pvars->return_state.retval = retval;
48 	} else {
49 		pvars->return_state.retval = box_ephemeral_xval(mlhmmv_xvalue_copy(&retval.xval));
50 	}
51 
52 	pvars->return_state.returned = TRUE;
53 }
54 
55 // ----------------------------------------------------------------
return_value_free(mlr_dsl_cst_statement_t * pstatement,context_t * _)56 static void return_value_free(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
57 	return_value_state_t* pstate = pstatement->pvstate;
58 	rxval_evaluator_t* pxev = pstate->preturn_value_xevaluator;
59 	pxev->pfree_func(pxev);
60 	free(pstate);
61 }
62 
63 // ----------------------------------------------------------------
alloc_return_value(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int type_inferencing,int context_flags)64 mlr_dsl_cst_statement_t* alloc_return_value(
65 	mlr_dsl_cst_t*      pcst,
66 	mlr_dsl_ast_node_t* pnode,
67 	int                 type_inferencing,
68 	int                 context_flags)
69 {
70 	mlr_dsl_ast_node_t* prhs_node = pnode->pchildren->phead->pvvalue;
71 
72 	return_value_state_t* pstate = mlr_malloc_or_die(sizeof(return_value_state_t));
73 
74 	pstate->preturn_value_xevaluator = rxval_evaluator_alloc_from_ast(prhs_node, pcst->pfmgr,
75 		type_inferencing, context_flags);
76 
77 	return mlr_dsl_cst_statement_valloc(
78 		pnode,
79 		return_value_func,
80 		return_value_free,
81 		pstate);
82 }
83