source: branches/dev-cw-evaluator/RuntimeLibrary/src/evaluator/jmi_evaluator.c @ 13602

Last change on this file since 13602 was 13602, checked in by Christian Andersson, 2 months ago

Corrected so that we free the dynamic memory. Related to ticket:5837

File size: 11.8 KB
Line 
1#include "jmi_evaluator_util.h"
2
3/* Must be defined here in order to override the methods from jmi_global.c */
4void jmi_global_log(int warning, const char* name, const char* fmt, const char* value) {
5    _jmi_global_log(warning, name, fmt, value);
6}
7void jmi_throw() {
8    _jmi_throw();
9}
10void* jmi_global_calloc(size_t n, size_t s) {
11    return _jmi_global_calloc(n,s);
12}
13
14/* Builtins */
15extern const char* ModelicaStrings_substring(const char*, int, int);
16extern int ModelicaStrings_length(const char*);
17extern int ModelicaStrings_skipWhiteSpace(const char*, int);
18extern int ModelicaStrings_compare(const char*, const char*, int);
19
20/* Record definitions */
21typedef struct R_ddddddddddd_ R_ddddddddddd;
22struct R_ddddddddddd_ {
23    double member_0;
24    double member_1;
25    double member_2;
26    double member_3;
27    double member_4;
28    double member_5;
29    double member_6;
30    double member_7;
31    double member_8;
32    double member_9;
33    double member_10;
34};
35JMI_ARRAY_TYPE(R_ddddddddddd, R_ddddddddddd_a)
36
37#define JMI_EVAL_CALLING_CONVENTION
38
39typedef const char* (JMI_EVAL_CALLING_CONVENTION *f_s_sii)(const char*, int, int);
40typedef double (JMI_EVAL_CALLING_CONVENTION *f_d_dd)(double, double);
41typedef double (JMI_EVAL_CALLING_CONVENTION *f_d_i)(int);
42typedef double(JMI_EVAL_CALLING_CONVENTION *f_d_idd)(int, double, double);
43typedef int (JMI_EVAL_CALLING_CONVENTION *f_i_ii)(int, int);
44typedef int (JMI_EVAL_CALLING_CONVENTION *f_i_s)(const char*);
45typedef int (JMI_EVAL_CALLING_CONVENTION *f_i_si)(const char*, int);
46typedef int (JMI_EVAL_CALLING_CONVENTION *f_i_ssi)(const char*, const char*, int);
47typedef void(JMI_EVAL_CALLING_CONVENTION *f___iddpR_ddddddddddd_)(int, double, double, R_ddddddddddd**);
48typedef void(JMI_EVAL_CALLING_CONVENTION *f___ddpd)(double, double, double*);
49typedef void (*generic_funcptr)(void);
50
51
52void jmi_call_void_fcn_ddpd(generic_funcptr fcn) { 
53    JMI_DEF(REA, arg_0)
54    JMI_DEF(REA, arg_1)
55    JMI_DEF(REA, arg_2)
56
57    JMCEVAL_parse(Real, arg_0);
58    JMCEVAL_parse(Real, arg_1);
59    JMCEVAL_parse(Real, arg_2);
60   
61    JMCEVAL_check("CALC");
62    if (JMCEVAL_try()) {
63        /* Calc phase */
64        ((f___ddpd)fcn)(arg_0, arg_1, &arg_2);
65
66        JMCEVAL_check("DONE");
67        JMCEVAL_print(Real, arg_2);
68    }
69    else {
70        JMCEVAL_failed();
71    }
72}
73
74void jmi_call_void_fcn_iddpR_ddddddddddd_(generic_funcptr fcn) {
75    JMI_DEF(INT, arg_0)
76    JMI_DEF(INT_EXT, tmp_0)   
77    JMI_DEF(REA, arg_1)
78    JMI_DEF(REA, arg_2)
79    JMI_RECORD_STATIC(R_ddddddddddd, arg_3)
80
81    JMCEVAL_parse(Integer, arg_0);
82    JMCEVAL_parse(Real, arg_1);
83    JMCEVAL_parse(Real, arg_2);
84    JMCEVAL_parse(Real, arg_3->member_0);
85    JMCEVAL_parse(Real, arg_3->member_1);
86    JMCEVAL_parse(Real, arg_3->member_2);
87    JMCEVAL_parse(Real, arg_3->member_3);
88    JMCEVAL_parse(Real, arg_3->member_4);
89    JMCEVAL_parse(Real, arg_3->member_5);
90    JMCEVAL_parse(Real, arg_3->member_6);
91    JMCEVAL_parse(Real, arg_3->member_7);
92    JMCEVAL_parse(Real, arg_3->member_8);
93    JMCEVAL_parse(Real, arg_3->member_9);
94    JMCEVAL_parse(Real, arg_3->member_10);
95
96    JMCEVAL_check("CALC");
97    if (JMCEVAL_try()) {
98        /* Calc phase */
99        tmp_0 = (int)arg_0;
100        ((f___iddpR_ddddddddddd_)fcn)(tmp_0, arg_1, arg_2, arg_3);
101
102
103        JMCEVAL_check("DONE");
104        JMCEVAL_print(Real, arg_3->member_0);
105        JMCEVAL_print(Real, arg_3->member_1);
106        JMCEVAL_print(Real, arg_3->member_2);
107        JMCEVAL_print(Real, arg_3->member_3);
108        JMCEVAL_print(Real, arg_3->member_4);
109        JMCEVAL_print(Real, arg_3->member_5);
110        JMCEVAL_print(Real, arg_3->member_6);
111        JMCEVAL_print(Real, arg_3->member_7);
112        JMCEVAL_print(Real, arg_3->member_8);
113        JMCEVAL_print(Real, arg_3->member_9);
114        JMCEVAL_print(Real, arg_3->member_10);
115    }
116    else {
117        JMCEVAL_failed();
118    }
119}
120
121void jmi_call_double_fcn_dd(generic_funcptr fcn, double *out) {
122    JMI_DEF(REA, arg_0)
123    JMI_DEF(REA, arg_1)
124
125    JMCEVAL_parse(Real, arg_0);
126    JMCEVAL_parse(Real, arg_1);
127
128    JMCEVAL_check("CALC");
129    if (JMCEVAL_try()) {
130        /* Calc phase */
131        *out = ((f_d_dd)fcn)(arg_0, arg_1);
132    } else {
133        JMCEVAL_failed();
134    }
135}
136
137void jmi_call_double_fcn_i(generic_funcptr fcn, double *out) {
138    JMI_DEF(INT, arg_0)
139    JMI_DEF(INT_EXT, tmp_1)
140
141    JMCEVAL_parse(Integer, arg_0);
142
143    JMCEVAL_check("CALC");
144    if (JMCEVAL_try()) {
145        /* Calc phase */
146        tmp_1 = (int)arg_0;
147        *out = ((f_d_i)fcn)(tmp_1);
148    } else {
149        JMCEVAL_failed();
150    }
151}
152
153void jmi_call_double_fcn_idd(generic_funcptr fcn, double *out) {
154    JMI_DEF(INT, arg_0)
155    JMI_DEF(INT_EXT, tmp_0)
156    JMI_DEF(REA, arg_1)
157    JMI_DEF(REA, arg_2)
158
159    JMCEVAL_parse(Integer, arg_0);
160    JMCEVAL_parse(Real, arg_1);
161    JMCEVAL_parse(Real, arg_2);
162
163    JMCEVAL_check("CALC");
164    if (JMCEVAL_try()) {
165        /* Calc phase */
166        tmp_0 = (int)arg_0;
167        *out = ((f_d_idd)fcn)(tmp_0, arg_1, arg_2);
168    }
169    else {
170        JMCEVAL_failed();
171    }
172}
173
174void jmi_call_double_fcn(generic_funcptr fcn, const char* inputs) {
175    JMI_DEF(REA, d_output)
176    JMCEVAL_parse(Real, d_output);
177
178    if (strcmp(inputs, "d,d,") == 0) {
179        jmi_call_double_fcn_dd(fcn, &d_output);
180    } else if (strcmp(inputs, "i,") == 0) {
181        jmi_call_double_fcn_i(fcn, &d_output);
182    } else if (strcmp(inputs, "i,d,d,") == 0) {
183        jmi_call_double_fcn_idd(fcn, &d_output);
184    } else {
185        printf(ERROR_NOT_SUPPORTED_INPUT_ARGS_MSG);
186        exit(ERROR_NOT_SUPPORTED_INPUT_ARGS);
187    }
188
189    JMCEVAL_check("DONE");
190    JMCEVAL_print(Real, d_output);
191}
192
193void jmi_call_integer_fcn_s(generic_funcptr fcn, int *out) {
194    JMI_DEF(STR, arg_0)
195
196    JMCEVAL_parse(String, arg_0);
197
198    JMCEVAL_check("CALC");
199    if (JMCEVAL_try()) {
200        /* Calc phase */
201        *out = ((f_i_s)fcn)(arg_0);
202    }
203    else {
204        JMCEVAL_failed();
205    }
206}
207
208void jmi_call_integer_fcn_si(generic_funcptr fcn, int *out) {
209    JMI_DEF(STR, arg_0)
210    JMI_DEF(INT, arg_1)
211    JMI_DEF(INT_EXT, tmp_1)
212
213    JMCEVAL_parse(String, arg_0);
214    JMCEVAL_parse(Integer, arg_1);
215
216    JMCEVAL_check("CALC");
217    if (JMCEVAL_try()) {
218        /* Calc phase */
219        tmp_1 = (int)arg_1;
220        *out = ((f_i_si)fcn)(arg_0, tmp_1);
221    }
222    else {
223        JMCEVAL_failed();
224    }
225}
226
227void jmi_call_integer_fcn_ssi(generic_funcptr fcn, int *out) {
228    JMI_DEF(STR, arg_0)
229    JMI_DEF(STR, arg_1)
230    JMI_DEF(INT, arg_2)
231    JMI_DEF(INT_EXT, tmp_2)
232
233    JMCEVAL_parse(String, arg_0);
234    JMCEVAL_parse(String, arg_1);
235    JMCEVAL_parse(Integer, arg_2);
236
237    JMCEVAL_check("CALC");
238    if (JMCEVAL_try()) {
239        /* Calc phase */
240        tmp_2 = (int)arg_2;
241        *out = ((f_i_ssi)fcn)(arg_0, arg_1, tmp_2);
242    }
243    else {
244        JMCEVAL_failed();
245    }
246}
247
248void jmi_call_integer_fcn(generic_funcptr fcn, const char* inputs) {
249    JMI_DEF(INT, i_output)
250    JMI_DEF(INT_EXT, tmp_output)
251    JMCEVAL_parse(Integer, i_output);
252   
253    tmp_output = (int)i_output;
254
255    if (strcmp(inputs, "s,") == 0) {
256        jmi_call_integer_fcn_s(fcn, &tmp_output);
257    } else if (strcmp(inputs, "s,i,") == 0) {
258        jmi_call_integer_fcn_si(fcn, &tmp_output);
259    } else if (strcmp(inputs, "s,s,i,") == 0) {
260        jmi_call_integer_fcn_ssi(fcn, &tmp_output);
261    } else {
262        printf(ERROR_NOT_SUPPORTED_INPUT_ARGS_MSG);
263        exit(ERROR_NOT_SUPPORTED_INPUT_ARGS);
264    }
265   
266    i_output = (double)tmp_output;
267
268    JMCEVAL_check("DONE");
269    JMCEVAL_print(Integer, i_output);
270}
271
272void jmi_call_string_fcn_sii(generic_funcptr fcn, char **out) {
273    JMI_DEF(STR, arg_0)
274    JMI_DEF(INT, arg_1)
275    JMI_DEF(INT, arg_2)
276    JMI_DEF(INT_EXT, tmp_1)
277    JMI_DEF(INT_EXT, tmp_2)
278
279    JMCEVAL_parse(String, arg_0);
280    JMCEVAL_parse(Integer, arg_1);
281    JMCEVAL_parse(Integer, arg_2);
282
283    JMCEVAL_check("CALC");
284    if (JMCEVAL_try()) {
285        /* Calc phase */
286        tmp_1 = (int)arg_1;
287        tmp_2 = (int)arg_2;
288        *out = ((f_s_sii)fcn)(arg_0, tmp_1, tmp_2);
289    } else {
290        JMCEVAL_failed();
291    }
292}
293
294void jmi_call_string_fcn(generic_funcptr fcn, const char* inputs) {
295    JMI_DEF(STR, s_output)
296    JMCEVAL_parse(String, s_output);
297
298    if (strcmp(inputs, "s,i,i,") == 0) {
299        jmi_call_string_fcn_sii(fcn, &s_output);
300    } else {
301        printf(ERROR_NOT_SUPPORTED_INPUT_ARGS_MSG);
302        exit(ERROR_NOT_SUPPORTED_INPUT_ARGS);
303    }
304
305    JMCEVAL_check("DONE");
306    JMCEVAL_print(String, s_output);
307}
308
309void jmi_call_void_fcn(generic_funcptr fcn, const char* inputs) {
310
311    if (strcmp(inputs, "i,d,d,*R[d,d,d,d,d,d,d,d,d,d,d,],") == 0) {
312        jmi_call_void_fcn_iddpR_ddddddddddd_(fcn);
313    } else if (strcmp(inputs, "d,d,*d,") == 0) {
314        jmi_call_void_fcn_ddpd(fcn);
315    } else {
316        printf(ERROR_NOT_SUPPORTED_INPUT_ARGS_MSG);
317        exit(ERROR_NOT_SUPPORTED_INPUT_ARGS);
318    }
319}
320
321/* Main */
322int main(int argc, const char* argv[])
323{
324    /* Size buffer for reading array dimensions */
325    int d[25];
326   
327    /* Indices for parsing/printing vars, dimensions */
328    size_t vi,di;
329
330    /* Function ptr that holds the specific function */
331    generic_funcptr funci = NULL;
332
333    const char *output_args = NULL;
334    const char *input_args = NULL;
335
336    /* Builtins */
337    if (strcmp(argv[2], "ModelicaStrings_substring") == 0) {
338        funci = (generic_funcptr)ModelicaStrings_substring;
339    } else if (strcmp(argv[2], "ModelicaStrings_length") == 0) {
340        funci = (generic_funcptr)ModelicaStrings_length;
341    } else if (strcmp(argv[2], "ModelicaStrings_skipWhiteSpace") == 0) {
342        funci = (generic_funcptr)ModelicaStrings_skipWhiteSpace;
343    } else if (strcmp(argv[2], "ModelicaStrings_compare") == 0) {
344        funci = (generic_funcptr)ModelicaStrings_compare;
345    }
346
347    if (funci == NULL) {
348        #ifdef _WIN32
349            HINSTANCE dll = LoadLibrary(argv[1]);
350       
351            if (!dll) {
352                DWORD error_code = GetLastError();
353                printf(ERROR_LOAD_DLL_MSG);
354                printf("error code: %d\n", error_code);
355                exit(ERROR_LOAD_DLL);
356            }
357
358            funci = (generic_funcptr)GetProcAddress(dll, argv[2]);
359            if (!funci) {
360                printf(ERROR_LOAD_FUNCTION_MSG);
361                exit(ERROR_LOAD_FUNCTION);
362            }
363        #else
364            void *so = dlopen(argv[1], RTLD_LOCAL | RTLD_LAZY);
365           
366            if (!so) {
367                printf(ERROR_LOAD_DLL_MSG);
368                exit(ERROR_LOAD_DLL);
369            }
370           
371            funci = (generic_funcptr)dlsym(so, argv[2]);
372            if (!funci) {
373                printf(ERROR_LOAD_FUNCTION_MSG);
374                exit(ERROR_LOAD_FUNCTION);
375            }
376        #endif
377    }
378
379    output_args = argv[3];
380    if (output_args == NULL) { 
381        printf(ERROR_OUTPUT_ARGS_NOT_SPECIFIED_MSG);
382        exit(ERROR_OUTPUT_ARGS_NOT_SPECIFIED); 
383    }
384
385    input_args  = argv[4];
386    if (input_args == NULL) { 
387        printf(ERROR_INPUT_ARGS_NOT_SPECIFIED_MSG);
388        exit(ERROR_INPUT_ARGS_NOT_SPECIFIED); 
389    }
390
391    JMCEVAL_setup(); /* This needs to happen first */
392
393    JMCEVAL_check("START");
394    if (JMCEVAL_try()) {
395        JMI_DYNAMIC_INIT()
396        /* Init phase */
397
398        JMI_DYNAMIC_FREE()
399    } else {
400        JMCEVAL_failed();
401    }
402   
403    JMCEVAL_check("READY");
404    while (JMCEVAL_cont("EVAL\n")) {
405        JMI_DYNAMIC_INIT()
406
407        if (strcmp(output_args, "d") == 0) {
408            jmi_call_double_fcn(funci, input_args);
409        } else if (strcmp(output_args, "s") == 0) {
410            jmi_call_string_fcn(funci, input_args);
411        } else if (strcmp(output_args, "i") == 0) {
412            jmi_call_integer_fcn(funci, input_args);
413        } else if (strcmp(output_args, "void") == 0) {
414            jmi_call_void_fcn(funci, input_args);
415        } else {
416            printf(ERROR_NOT_SUPPORTED_OUTPUT_ARGS_MSG);
417            exit(ERROR_NOT_SUPPORTED_OUTPUT_ARGS);
418        }
419
420        JMI_DYNAMIC_FREE()
421        JMCEVAL_check("READY");
422    }
423
424    if (JMCEVAL_try()) {
425        /* End phase */
426
427
428    } else {
429        JMCEVAL_failed();
430    }
431    _jmi_dynamic_function_pool_destroy();
432    JMCEVAL_check("END");
433    return 0;
434}
435
Note: See TracBrowser for help on using the repository browser.