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