2
* Copyright (C) 2006 - 2009 Campanoni Simone <simo.xan@gmail.com> , Di Biagio Andrea, Tartara Michele <mikyt@users.sourceforge.net>
4
* ir_virtual_machine.c - This is a translator from the IR language into the assembly language.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#include <jit/jit-dump.h>
28
#include <jitsystem.h>
29
#include <ir_language.h>
30
#include <ir_optimization_interface.h>
31
#include <compiler_memory_manager.h>
32
#include <jit_metadata.h>
33
#include <error_codes.h>
36
#include <ir_virtual_machine.h>
37
#include <ir_virtual_machine_system.h>
47
JITUINT32 fromJITTypeToIRType (jit_type_t jitType);
48
static inline t_jit_label * insert_label (XanList *labels, JITUINT32 label_ID);
49
JITINT32 check_labels(XanList *labels);
50
static inline jit_value_t make_variable (IRVM_t *_this, ir_method_t *method, ir_item_t *item, t_jit_function *jitFunction);
51
void insert_tracer (IRVM_t *_this, ir_method_t *method, t_jit_function *jitFunction, JITBOOLEAN exitMethod);
52
JITINT32 insertTraceProfiler (t_ir_instruction *inst, JITINT32 prevIndex, t_jit_function *jitFunction, trace_profiler_t *profiler);
53
static inline JITINT16 bind_instruction_offset (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
54
JITINT16 fetch_parameters (ir_method_t *method, t_jit_function *jitFunction);
55
JITINT32 internal_isRootSetEmpty (ir_method_t *method, t_jit_function *jitFunction);
56
void internal_lockVM (IRVM_t *_this);
57
void internal_unlockVM (IRVM_t *_this);
58
void internal_lockLibjit (IRVM_t *_this);
59
void internal_unlockLibjit (IRVM_t *_this);
60
void variablesToRootSets (IRVM_t *_this, ir_method_t *method, t_jit_function *jitFunction);
61
JITINT32 internal_addRootSetProfile (IRVM_t *_this, ir_method_t *method, t_jit_function *jitFunction);
62
void internal_setExceptionHandler (IRVM_t *_this, void * (*exceptionHandler) (int exception_type));
63
static inline jit_function_t internal_newLibjitMethod (IRVM_t *_this, void *method, jit_type_t signature);
64
static inline void * internal_libjitDriver (jit_function_t function);
66
/* IR -> machine code translation functions */
68
* @brief Translates the IR instruction IRLOADREL in its JIT counterpart
70
* If a static field is being loaded, the first parameter of the IR instruction (inst->param_1) must be an IRMPOINTER containing the address of the field. Otherwise it must be an IROFFSET indicating the number of the local of the function containing the address.
72
static inline JITINT16 translate_ir_load_rel (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
73
static inline JITINT16 translate_ir_ret (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
74
static inline JITINT16 translate_ir_call_indirect_exception_ctor (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
75
static inline JITINT16 translate_ir_newobj (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
76
static inline JITINT16 translate_ir_newarr (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
77
static inline JITINT16 translate_ir_load_elem (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
78
static inline JITINT16 translate_ir_store_elem (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
79
static inline JITINT16 translate_ir_add (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
80
static inline JITINT16 translate_ir_sub (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
81
static inline JITINT16 translate_ir_mul (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
82
static inline JITINT16 translate_ir_div (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
83
static inline JITINT16 translate_ir_rem (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
84
static inline JITINT16 translate_ir_and (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
85
static inline JITINT16 translate_ir_shl (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
86
static inline JITINT16 translate_ir_shr (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
87
static inline JITINT16 translate_ir_not (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
88
static inline JITINT16 translate_ir_or (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
89
static inline JITINT16 translate_ir_xor (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
90
static inline JITINT16 translate_ir_store_rel(IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
91
static inline JITINT16 translate_ir_add_ovf (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
92
static inline JITINT16 translate_ir_sub_ovf (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
93
static inline JITINT16 translate_ir_mul_ovf (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
94
static inline JITINT16 translate_ir_conv (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
95
static inline JITINT16 translate_ir_label(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
96
static inline JITINT16 translate_ir_branch(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
97
static inline JITINT16 translate_ir_branchif (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
98
static inline JITINT16 translate_ir_branchifnot (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
99
static inline JITINT16 translate_ir_call_finally(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
100
static inline JITINT16 translate_ir_call_filter(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
101
static inline JITINT16 translate_ir_start_filter(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
102
static inline JITINT16 translate_ir_start_finally(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
103
static inline JITINT16 translate_ir_branch_if_pc_not_in_range(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction);
104
static inline JITINT16 translate_ir_eq (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
105
static inline JITINT16 translate_ir_checknull (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
106
static inline JITINT16 translate_ir_lt (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
107
static inline JITINT16 translate_ir_gt (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
108
static inline JITINT16 translate_ir_store (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
109
static inline JITINT16 translate_ir_neg (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
110
static inline JITINT16 translate_ir_call (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
111
static inline JITINT16 translate_ir_vcall (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
112
static inline JITINT16 translate_ir_ncall (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
113
static inline JITINT16 translate_ir_icall (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
114
static inline JITINT16 translate_ir_initmemory (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
115
static inline JITINT16 translate_ir_memory_copy (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
116
static inline JITINT16 translate_ir_alloca (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
117
static inline JITINT16 translate_ir_throw (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
118
static inline JITINT16 translate_ir_get_address (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
119
static inline JITINT16 translate_ir_end_filter (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
120
static inline JITINT16 translate_ir_end_finally(ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
121
static inline JITINT16 translate_ir_start_catcher(ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
122
static inline JITINT16 translate_ir_uses_catcher(IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
123
static inline JITINT16 translate_ir_rethrow_unandled(ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
124
static inline JITINT16 translate_ir_thrown_exception_object(ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
125
static inline JITINT16 translate_ir_isNaN (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
126
static inline JITINT16 translate_ir_isInf(IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction);
128
static inline void internal_translateMethodToAssembly (IRVM_t *_this, ir_method_t *method, t_jit_function *jitFunction, JITINT32 enableTraceProfiler, trace_profiler_t *traceProfiler);
129
static inline void internal_makeTheMethodCallable (IRVM_t *_this, t_jit_function *jitFunction, ir_method_t *method);
130
static inline JITINT32 internal_run (t_jit_function *jitFunction, void **args, void *returnArea);
131
static inline jit_type_t internal_fromIRTypeToJITType (IRVM_t *_this, JITUINT32 IRType, ILType *ilType);
132
static inline void internal_shutdownIRVM (IRVM_t *_this);
133
static inline XanList * internal_getReferencedMethods (IRVM_t *_this, ir_method_t *method);
134
static inline void internal_lockMethods (XanList *list);
135
static inline void internal_unlockMethods (XanList *list);
137
void IRVirtualMachineNew (IRVM_t *_this, t_running_garbage_collector *gc, t_type_checker *type_checker, jit_type_t (*lookupValueType) (ILType *type), void (*fillILTypedReference)(ILType *ilType), ir_method_t * (*getIRMethod) (IR_ITEM_VALUE method), t_jit_function * (*getJITMethod) (IR_ITEM_VALUE method), JITINT32 (*recompilerFunction)(jit_function_t function)){
138
pthread_mutexattr_t mutex_attr;
139
jit_type_t params_ctor[1];
142
assert(_this != NULL);
144
assert(lookupValueType != NULL);
145
assert(fillILTypedReference != NULL);
146
assert(type_checker != NULL);
148
_this->type_checker = type_checker;
150
_this->lookupValueType = lookupValueType;
151
_this->fillILTypedReference = fillILTypedReference;
152
_this->getIRMethod = getIRMethod;
153
_this->getJITMethod = getJITMethod;
154
_this->recompilerFunction = recompilerFunction;
156
pthread_mutexattr_init(&mutex_attr);
157
pthread_mutex_init(&(_this->libjitMutex), &mutex_attr);
158
pthread_mutex_init(&(_this->vmMutex), &mutex_attr);
160
_this->shutdown = internal_shutdownIRVM;
161
_this->lock = internal_lockLibjit;
162
_this->unlock = internal_unlockLibjit;
163
_this->translateMethodToAssembly = internal_translateMethodToAssembly;
164
_this->makeTheMethodCallable = internal_makeTheMethodCallable;
165
_this->run = internal_run;
166
_this->setExceptionHandler = internal_setExceptionHandler;
167
_this->newLibjitMethod = internal_newLibjitMethod;
169
/* Create the JIT context */
170
_this->context = jit_context_create();
171
assert(_this->context != NULL);
172
if (!jit_context_supports_threads(_this->context)){
173
print_err("IRVIRTUALMACHINE: ERROR: Libjit does not support threads. ", 0);
177
/* Make the signature of the basic *
178
* constructor of the exceptions */
179
params_ctor[0] = jit_type_void_ptr;
180
_this->basicExceptionConstructorJITSignature = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params_ctor, 1, 1);
182
/* Set the Libjit optimization level */
183
if ((_this->behavior).optimizations >= 3) {
184
(_this->behavior).libjitOptimizations = jit_function_get_max_optimization_level();
191
void internal_setExceptionHandler (IRVM_t *_this, void * (*exceptionHandler) (int exception_type)){
194
assert(_this != NULL);
195
assert(exceptionHandler != NULL);
198
internal_lockLibjit(_this);
200
/* Set a LIBJIT EXCEPTION HANDLER: USED *
201
* TO PROPERLY INITIALIZE EXCEPTION *
203
jit_exception_set_handler(exceptionHandler);
206
internal_unlockLibjit(_this);
212
static inline void internal_makeTheMethodCallable (IRVM_t *_this, t_jit_function *jitFunction, ir_method_t *method){
215
assert(_this != NULL);
216
assert(jitFunction != NULL);
217
assert(jitFunction->entryPoint != NULL);
219
jit_function_setup_entry(jitFunction->function, jitFunction->entryPoint);
221
/* Dump the methods in the target *
223
if ( ((_this->behavior).dumpAssembly.dumpAssembly) &&
224
(!jit_uses_interpreter()) ){
225
assert((_this->behavior).dumpAssembly.dumpFileAssembly != NULL);
226
method->lock(method);
227
jit_dump_function((_this->behavior).dumpAssembly.dumpFileAssembly, jitFunction->function, method->getCompleteName(method));
228
method->unlock(method);
232
static inline void internal_translateMethodToAssembly (IRVM_t *_this, ir_method_t *method, t_jit_function *jitFunction, JITINT32 enableTraceProfiler, trace_profiler_t *traceProfiler){
233
t_ir_instruction *currentIRInstruction;
235
JITUINT32 params_count;
238
XanList *methodsReferenced;
240
jit_type_t profilerStartSign;
241
jit_type_t profilerStopSign;
242
jit_value_t argsStart[1];
243
jit_value_t argsStop[2];
245
JITINT32 labelTraceIndex;
248
assert(method != NULL);
249
assert(_this != NULL);
250
assert(jitFunction != NULL);
252
/* Init the variables */
254
profilerStartSign = NULL;
255
profilerStopSign = NULL;
260
internal_lockVM(_this);
262
/* Check the locals */
263
if (jitFunction->locals != NULL){
264
freeFunction(jitFunction->locals);
265
jitFunction->locals = NULL;
267
assert(jitFunction->locals == NULL);
269
/* Allocate the list of labels */
270
labels = xanListNew(allocFunction, freeFunction, NULL);
271
assert(labels != NULL);
273
/* Lock the method */
274
method->lock(method);
276
/* Fetch the list of methods *
277
* referenced by the current one*/
278
methodsReferenced = internal_getReferencedMethods(_this, method);
279
assert(methodsReferenced != NULL);
281
/* Lock the referenced methods */
282
internal_lockMethods(methodsReferenced);
284
/* Lock the libjit */
285
internal_lockLibjit(_this);
287
/* Translate the feedback code */
288
//translate_enter_method_feedback_code(system, method);
290
/* Fetch the first instruction */
291
PDEBUG("IRVIRTUALMACHINE: Translate the method into the machine language\n");
292
currentIRInstruction = method->getNextInstruction(method, NULL);
295
if ((_this->behavior).profiler >= 4){
296
jit_type_t paramsStop[3];
297
jit_type_t paramsStart[1];
299
/* Make the parameters of the *
300
* profiler functions */
301
paramsStart[0]= jit_type_uint;
302
paramsStop[0] = jit_type_void_ptr;
303
paramsStop[1] = jit_type_void_ptr;
304
paramsStop[2] = jit_type_uint;
306
/* Make the signature of the *
307
* profiler functions */
308
profilerStartSign = jit_type_create_signature(jit_abi_cdecl, jit_type_void, paramsStart, 1, 0);
309
profilerStopSign = jit_type_create_signature(jit_abi_cdecl, jit_type_void, paramsStop, 3, 0);
311
/* Make the arguments of the *
312
* profiler stop functions */
313
argsStop[0] = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (JITNUINT) NULL);
314
argsStop[1] = jit_value_create_nint_constant (jitFunction->function, jit_type_uint, 0);
316
/* Call the profiler stop *
318
//jit_insn_call_native(jitFunction->function, "profilerIRStopTime", profilerIRStopTime, profilerStopSign, argsStop, 2, JIT_CALL_NOTHROW); TODO da decommentare
322
if(enableTraceProfiler){
323
PDEBUG("IRPROFILER: ENABLE TRACE PROFILER\n");
324
PDEBUG("IRPROFILER: CALL TO THE OPTIMIZATOR\n");
325
(_this->optimizer).callMethodOptimization(&(_this->optimizer), method, &(_this->ir_system),BASIC_BLOCK_IDENTIFIER);
326
PDEBUG("IRPROFILER: CALL TO THE TRACE GENERATOR\n");
327
traceProfiler->generateTraces(traceProfiler);
330
/* Create the locals */
331
params_count = method->getParametersNumber(method);
332
PDEBUG("IRVIRTUALMACHINE: Make %d variables\n", method->getMaxVariables(method));
333
PDEBUG("IRVIRTUALMACHINE: %d locals\n", method->getLocalsNumber(method));
334
PDEBUG("IRVIRTUALMACHINE: %d parameters\n", params_count);
335
if (method->getMaxVariables(method) > 0){
336
jitFunction->locals = (jit_value_t *) allocFunction(sizeof(jit_value_t) * (method->getMaxVariables(method) + 1));
337
assert(jitFunction->locals != NULL);
338
memset(jitFunction->locals, 0, sizeof(jit_value_t) * (method->getMaxVariables(method)));
341
/* Create the variables */
342
PDEBUG("IRVIRTUALMACHINE: Create %d locals\n", method->getLocalsNumber(method));
344
sum_count = params_count + method->getLocalsNumber(method);
345
for(count = params_count; count < sum_count; count++) {
346
jit_type_t JITvalueType;
352
param = method->getNextLocal(method, param);
353
assert(param != NULL);
356
PDEBUG("IRVIRTUALMACHINE: Make local %d as INT64\n", count);
357
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_long);
359
type = jit_value_get_type(jitFunction->locals[count]);
360
assert(type == jit_type_long);
364
PDEBUG("IRVIRTUALMACHINE: Make local %d as INT32\n", count);
365
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_int);
367
type = jit_value_get_type(jitFunction->locals[count]);
368
assert(type == jit_type_int);
372
PDEBUG("IRVIRTUALMACHINE: Make local %d as INT16\n", count);
373
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_short);
375
type = jit_value_get_type(jitFunction->locals[count]);
376
assert(type == jit_type_short);
380
PDEBUG("IRVIRTUALMACHINE: Make local %d as INT8\n", count);
381
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_sbyte);
383
type = jit_value_get_type(jitFunction->locals[count]);
384
assert(type == jit_type_sbyte);
388
PDEBUG("IRVIRTUALMACHINE: Make local %d as NINT\n", count);
389
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_nint);
391
type = jit_value_get_type(jitFunction->locals[count]);
392
assert(type == jit_type_nint);
396
PDEBUG("IRVIRTUALMACHINE: Make local %d as UINT64\n", count);
397
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_ulong);
399
type = jit_value_get_type(jitFunction->locals[count]);
400
assert(type == jit_type_ulong);
404
PDEBUG("IRVIRTUALMACHINE: Make local %d as UINT32\n", count);
405
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_uint);
407
type = jit_value_get_type(jitFunction->locals[count]);
408
assert(type == jit_type_uint);
412
PDEBUG("IRVIRTUALMACHINE: Make local %d as UINT16\n", count);
413
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_ushort);
415
type = jit_value_get_type(jitFunction->locals[count]);
416
assert(type == jit_type_ushort);
420
PDEBUG("IRVIRTUALMACHINE: Make local %d as UINT8\n", count);
421
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_ubyte);
423
type = jit_value_get_type(jitFunction->locals[count]);
424
assert(type == jit_type_ubyte);
428
PDEBUG("IRVIRTUALMACHINE: Make local %d as NUINT\n", count);
429
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_nuint);
431
type = jit_value_get_type(jitFunction->locals[count]);
432
assert(type == jit_type_nuint);
436
PDEBUG("IRVIRTUALMACHINE: Make local %d as FLOAT32\n", count);
437
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_float32);
439
type = jit_value_get_type(jitFunction->locals[count]);
440
assert(type == jit_type_float32);
444
PDEBUG("IRVIRTUALMACHINE: Make local %d as FLOAT64\n", count);
445
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_float64);
447
type = jit_value_get_type(jitFunction->locals[count]);
448
assert(type == jit_type_float64);
452
if (sizeof(JITNUINT) == 4){
453
PDEBUG("IRVIRTUALMACHINE: Make local %d as FLOAT32\n", count);
454
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_float32);
456
type = jit_value_get_type(jitFunction->locals[count]);
457
assert(type == jit_type_float32);
460
PDEBUG("IRVIRTUALMACHINE: Make local %d as FLOAT64\n", count);
461
jitFunction->locals[count] = jit_value_create(jitFunction->function, jit_type_float64);
463
type = jit_value_get_type(jitFunction->locals[count]);
464
assert(type == jit_type_float64);
472
PDEBUG("IRVIRTUALMACHINE: Make local %d as POINTER\n", count);
473
jitFunction->locals[count] = jit_value_create (jitFunction->function, jit_type_void_ptr);
475
type = jit_value_get_type(jitFunction->locals[count]);
476
assert(type == jit_type_void_ptr);
480
assert(method->local_signature->decoded_locals != NULL);
481
assert(((method->local_signature->decoded_locals) + (count - params_count)) != NULL);
482
assert((method->local_signature->decoded_locals[count - params_count]).type != NULL);
483
assert(((method->local_signature->decoded_locals[count - params_count]).type)->type == ELEMENT_TYPE_VALUETYPE);
484
assert(((method->local_signature->decoded_locals[count - params_count]).type)->type_infos != NULL);
485
PDEBUG("IRVIRTUALMACHINE: Make local %d as VALUETYPE\n", count);
487
/* retrieve the IL type associated with the valuetype */
488
valueType = (ILType *)((method->local_signature->decoded_locals[count - params_count]).type)->type_infos;
489
assert(valueType != NULL);
490
assert(valueType->ID != NULL);
491
assert(valueType->binary != NULL);
493
/* retrieve the JIT type associated with the valuetype */
494
JITvalueType = _this->lookupValueType(valueType);
495
assert(JITvalueType != NULL);
497
/* create the JIT variable for the current valuetype */
498
jitFunction->locals[count] = jit_value_create(jitFunction->function, JITvalueType);
499
assert(jitFunction->locals[count] != NULL);
502
type = jit_value_get_type(jitFunction->locals[count]);
503
assert(type == JITvalueType);
507
PDEBUG("IRVIRTUALMACHINE: Make local %d as TYPEDREFERENCE\n", count);
509
/* retrieve the IL type associated with the valuetype */
510
_this->fillILTypedReference(&iltype);
511
assert(iltype.ID != NULL);
512
assert(iltype.binary != NULL);
514
/* retrieve the JIT type associated with the valuetype */
515
JITvalueType = _this->lookupValueType(&iltype);
516
assert(JITvalueType != NULL);
518
/* create the JIT variable for the current valuetype */
519
jitFunction->locals[count] = jit_value_create(jitFunction->function, JITvalueType);
520
assert(jitFunction->locals[count] != NULL);
523
type = jit_value_get_type(jitFunction->locals[count]);
524
assert(type == JITvalueType);
528
PDEBUG("%d \n", (*param));
529
snprintf(buf, sizeof(buf), "IRVIRTUALMACHINE: ERROR = Type of local %u is not known. ", count - method->getParametersNumber(method));
533
assert((jitFunction->locals[count]) != NULL);
536
/* Fetch the parameters */
537
fetch_parameters(method, jitFunction);
540
if ((_this->behavior).tracer){
541
if (method->getInstructionType(method, currentIRInstruction) != IRUSESCATCHER){
542
PDEBUG("IRVIRTUALMACHINE: Insert the tracer call\n");
543
insert_tracer(_this, method, jitFunction, JITFALSE);
547
/* Insert the native start call */
549
internal_insert_native_start_function(method);
552
/* Update the root set */
553
method->updateRootSet(method);
555
/* Translate the IR method to *
556
* the libjit method */
560
while (currentIRInstruction != NULL){
561
assert(currentIRInstruction != NULL);
564
PDEBUG("IRVIRTUALMACHINE: Instruction %d\n", count);
569
if ((_this->behavior).profiler >= 4){
570
argsStart[0] = jit_value_create_nint_constant (jitFunction->function, jit_type_uint , (JITNUINT) currentIRInstruction->type);
571
//jit_insn_call_native(jitFunction->function, "profilerIRStopTime" , profilerIRStopTime, profilerStopSign , argsStop, 2, JIT_CALL_NOTHROW); TODO da decommentare
572
//jit_insn_call_native(jitFunction->function, "profilerIRStartTime" , profilerIRStartTime, profilerStartSign , argsStart, 1, JIT_CALL_NOTHROW); TODO da decommentare
576
if(enableTraceProfiler){
577
PDEBUG("IRPROFILER: INSERT TRACE PROFILER NATIVE CALLS\n");
578
labelTraceIndex = insertTraceProfiler(currentIRInstruction, labelTraceIndex, jitFunction, traceProfiler);
581
/* Bind the offset information to the jit *
583
bind_instruction_offset(_this, method, currentIRInstruction, jitFunction);
585
/* Convert the current IR instruction */
586
switch (currentIRInstruction->type){
588
translate_ir_add(_this, method, currentIRInstruction, jitFunction);
591
translate_ir_add_ovf(_this, method, currentIRInstruction, jitFunction);
594
translate_ir_and(_this, method, currentIRInstruction, jitFunction);
597
translate_ir_branch(method, currentIRInstruction, labels, jitFunction);
600
translate_ir_branchif(_this, method, currentIRInstruction, labels, jitFunction);
603
translate_ir_branchifnot(_this, method, currentIRInstruction, labels, jitFunction);
606
translate_ir_call(_this, method, currentIRInstruction, jitFunction);
609
translate_ir_checknull(_this, method, currentIRInstruction, jitFunction);
612
translate_ir_conv(_this, method, currentIRInstruction, jitFunction);
615
translate_ir_div(_this, method, currentIRInstruction, jitFunction);
618
translate_ir_eq(_this, method, currentIRInstruction, jitFunction);
621
translate_ir_get_address(_this, method, currentIRInstruction, jitFunction);
624
translate_ir_gt(_this, method, currentIRInstruction, jitFunction);
627
translate_ir_label(method, currentIRInstruction, labels, jitFunction);
630
translate_ir_load_elem(_this, method, currentIRInstruction, jitFunction);
633
translate_ir_load_rel(_this, method, currentIRInstruction, jitFunction);
636
translate_ir_lt(_this, method, currentIRInstruction, jitFunction);
641
translate_ir_not(_this, method, currentIRInstruction, jitFunction);
644
translate_ir_ncall(_this, method, currentIRInstruction, jitFunction);
647
translate_ir_neg(_this, method, currentIRInstruction, jitFunction);
650
translate_ir_newarr(_this, method, currentIRInstruction, jitFunction);
653
translate_ir_newobj(_this, method, currentIRInstruction, jitFunction);
656
translate_ir_mul(_this, method, currentIRInstruction, jitFunction);
659
translate_ir_mul_ovf(_this, method, currentIRInstruction, jitFunction);
662
translate_ir_or(_this, method, currentIRInstruction, jitFunction);
665
translate_ir_rem(_this, method, currentIRInstruction, jitFunction);
668
translate_ir_ret(_this, method, currentIRInstruction, jitFunction);
671
translate_ir_shl(_this, method, currentIRInstruction, jitFunction);
674
translate_ir_shr(_this, method, currentIRInstruction, jitFunction);
677
translate_ir_sub(_this, method, currentIRInstruction, jitFunction);
680
translate_ir_sub_ovf(_this, method, currentIRInstruction, jitFunction);
683
translate_ir_store(_this, method, currentIRInstruction, jitFunction);
686
translate_ir_store_elem(_this, method, currentIRInstruction, jitFunction);
689
translate_ir_store_rel(_this, method, currentIRInstruction, jitFunction);
692
translate_ir_vcall(_this, method, currentIRInstruction, jitFunction);
695
translate_ir_xor(_this, method, currentIRInstruction, jitFunction);
698
translate_ir_call_finally(method, currentIRInstruction, labels, jitFunction);
701
translate_ir_throw(_this, method, currentIRInstruction, jitFunction);
704
translate_ir_start_filter(method, currentIRInstruction, labels, jitFunction);
707
translate_ir_end_filter(_this, method, currentIRInstruction, jitFunction);
710
translate_ir_start_finally(method, currentIRInstruction, labels, jitFunction);
713
translate_ir_end_finally(method, currentIRInstruction, jitFunction);
716
translate_ir_start_catcher(method, currentIRInstruction, jitFunction);
719
translate_ir_uses_catcher(_this, method, currentIRInstruction, jitFunction);
721
case IRBRANCHIFPCNOTINRANGE:
722
translate_ir_branch_if_pc_not_in_range(method, currentIRInstruction, labels, jitFunction);
724
case IRRETHROWUNHANDLED:
725
translate_ir_rethrow_unandled(method , currentIRInstruction, jitFunction);
728
translate_ir_call_filter(method, currentIRInstruction, labels, jitFunction);
730
case IRTHROWNEXCEPTIONOBJECT:
731
translate_ir_thrown_exception_object(method, currentIRInstruction, jitFunction);
734
translate_ir_isNaN(_this, method, currentIRInstruction, jitFunction);
737
translate_ir_isInf(_this, method, currentIRInstruction, jitFunction);
739
case IRCALLINDIRECTCCTOR:
740
translate_ir_call_indirect_exception_ctor(_this, method, currentIRInstruction, jitFunction);
743
translate_ir_icall(_this, method, currentIRInstruction, jitFunction);
746
translate_ir_initmemory(_this, method, currentIRInstruction, jitFunction);
749
translate_ir_memory_copy(_this, method, currentIRInstruction, jitFunction);
752
translate_ir_alloca(_this, method, currentIRInstruction, jitFunction);
755
snprintf(buf, sizeof(buf), "IRVIRTUALMACHINE: ERROR= IR instruction %d not knwon\n", currentIRInstruction->type);
759
PDEBUG("IRVIRTUALMACHINE: Translated\n");
761
/* Insert call for trace profiler after label */
762
if((enableTraceProfiler) && (labelTraceIndex >= 0)){
763
labelTraceIndex = insertTraceProfiler(currentIRInstruction, labelTraceIndex, jitFunction, traceProfiler);
767
if ((_this->behavior).profiler >= 4){
768
//jit_insn_call_native(jitFunction->function, "profilerIRStopTime", profilerIRStopTime, profilerStopSign, argsStop, 2, JIT_CALL_NOTHROW); TODO da decommentare
771
/* Fetch the next item */
772
assert(currentIRInstruction != NULL);
773
currentIRInstruction = method->getNextInstruction(method, currentIRInstruction);
776
/* Check the labels */
778
check_labels(labels);
781
/* Refresh the root set */
782
variablesToRootSets(_this, method, jitFunction);
784
/* Free the signature */
785
if ((_this->behavior).profiler >= 4){
786
jit_type_free(profilerStartSign);
787
jit_type_free(profilerStopSign);
790
/* Dump the assembly */
791
if ((_this->behavior).dumpAssembly.dumpAssembly){
792
assert((_this->behavior).dumpAssembly.dumpFileJIT != NULL);
793
jit_dump_function((_this->behavior).dumpAssembly.dumpFileJIT, jitFunction->function, method->getName(method));
796
/* Compile the function */
797
PDEBUG("IRVIRTUALMACHINE: Compile the method\n");
798
jitFunction->entryPoint = NULL;
799
if (jit_function_compile_entry(jitFunction->function, &(jitFunction->entryPoint)) == 0){
800
print_err("IRVIRTUALMACHINE: ERROR = During compiling the function. ", 0);
803
assert(jitFunction->entryPoint != NULL);
806
internal_unlockLibjit(_this);
808
/* Unlock the methods referenced*/
809
internal_unlockMethods(methodsReferenced);
811
/* Unlock the method */
812
method->unlock(method);
814
/* Free the memory */
815
labels->destroyList(labels);
816
methodsReferenced->destroyList(methodsReferenced);
819
internal_unlockVM(_this);
822
PDEBUG("IRVIRTUALMACHINE: Exit from the build phase\n");
826
static inline jit_type_t internal_fromIRTypeToJITType (IRVM_t *_this, JITUINT32 IRType, ILType *ilType){
831
assert(_this != NULL);
833
/* initialize the local variable */
836
/* Make the type conversion */
839
type = jit_type_sbyte;
842
type = jit_type_short;
848
type = jit_type_long;
851
type = jit_type_nint;
854
type = jit_type_ubyte;
857
type = jit_type_ushort;
860
type = jit_type_uint;
863
type = jit_type_ulong;
866
type = jit_type_nuint;
869
type = jit_type_float32;
872
type = jit_type_float64;
875
type = jit_type_nfloat;
883
type = jit_type_void_ptr;
887
assert(ilType != NULL);
888
assert(ilType->ID != NULL);
889
assert(ilType->binary != NULL);
890
type = _this->lookupValueType(ilType);
893
type = jit_type_void;
896
snprintf(buf, sizeof(char)*1024, "IRVIRTUALMACHINE: fromIRTypeToJitType: ERROR = IR type %u is not known. ", IRType);
905
void insert_tracer (IRVM_t *_this, ir_method_t *method, t_jit_function *jitFunction, JITBOOLEAN exitMethod){
907
jit_type_t params[2];
911
assert(_this != NULL);
912
assert(_this->type_checker != NULL);
913
assert(method != NULL);
914
assert(jitFunction != NULL);
916
/* Create the parameters */
917
params[0] = jit_type_void_ptr;
918
params[1] = jit_type_void_ptr;
920
/* Create the signature */
921
sign = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 2, 0);
922
assert(sign != NULL);
924
/* Create the arguments */
925
args[0] = jit_value_create_nint_constant(jitFunction->function, jit_type_void_ptr, (JITNUINT) _this);
926
args[1] = jit_value_create_nint_constant(jitFunction->function, jit_type_void_ptr, (JITNUINT) method);
928
/* Call the tracer */
929
if (exitMethod == 0){
930
jit_insn_call_native(jitFunction->function , "tracer_startMethod", tracer_startMethod, sign, args, 2, JIT_CALL_NOTHROW);
932
jit_insn_call_native(jitFunction->function , "tracer_exitMethod", tracer_exitMethod, sign, args, 2, JIT_CALL_NOTHROW);
935
/* Free the signature */
942
JITINT32 insertTraceProfiler (t_ir_instruction *inst, JITINT32 prevIndex, t_jit_function *jitFunction, trace_profiler_t *profiler){
944
jit_type_t params[1];
947
JITUINT32 traceNumber;
952
assert(profiler != NULL);
955
PDEBUG("IRPROFILER: REAL INSERT START AFTER LABEL FOR INSTRUCTION %d\n", prevIndex);
957
trace = profiler->getTrace(profiler, index);
959
params[0] = jit_type_void_ptr;
960
sign = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 1, 0);
961
args[0] = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (JITNUINT) trace);
963
jit_insn_call_native(jitFunction->function , "trace_startTraceProfiling", trace_startTraceProfiling, sign, args, 1, JIT_CALL_NOTHROW);
966
trace->printTrace(trace, stderr);
972
PDEBUG("IRPROFILER: SEARCH IF INSERT NATIVE CALL ");
974
traceNumber = profiler->getTraceNumber(profiler);
977
PDEBUG("FOR INSTRUCTION %d : ", instID);
979
for(index = 0; index < traceNumber; index ++){
980
trace = profiler->getTrace(profiler, index);
983
if(trace->getFirstInstID(trace) == instID){
985
PDEBUG("INSERT START CALL AT TRACE %d (%p, %u)\n", index, trace, (JITNUINT) trace);
989
} else if(trace->getLastInstID(trace) == instID){
990
PDEBUG("INSERT END CALL AT TRACE %d (%p, %u)\n", index, trace, (JITNUINT) trace);
992
params[0] = jit_type_void_ptr;
993
sign = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 1, 0);
994
args[0] = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (JITNUINT) trace);
996
jit_insn_call_native(jitFunction->function , "trace_stopTraceProfiling", trace_stopTraceProfiling, sign, args, 1, JIT_CALL_NOTHROW);
1000
trace->printTrace(trace, stderr);
1008
PDEBUG("INSTRUCTION SKIP\n");
1012
static inline jit_value_t make_variable (IRVM_t *_this, ir_method_t *method, ir_item_t *item, t_jit_function *jitFunction){
1018
jit_type_t JITvalueType;
1021
assert(_this != NULL);
1022
assert(method != NULL);
1023
assert(item != NULL);
1024
assert(jitFunction != NULL);
1026
/* Init the variables */
1030
switch (item->type){
1032
PDEBUG("Variable %lld", item->value);
1033
assert(item->value < method->getMaxVariables(method));
1034
if (jitFunction->locals[item->value] == NULL){
1035
jitFunction->locals[item->value] = jit_value_create(jitFunction->function, internal_fromIRTypeToJITType(_this, item->internal_type, (item->value_type_infos).type_infos));
1037
assert (jitFunction->locals[item->value] != NULL);
1038
param = jitFunction->locals[item->value];
1042
PDEBUG("INT8 %lld", item->value);
1043
param = jit_value_create_nint_constant(jitFunction->function, jit_type_sbyte, (JITINT32) item->value);
1046
PDEBUG("INT16 %lld", item->value);
1047
param = jit_value_create_nint_constant(jitFunction->function, jit_type_short, (JITINT32) item->value);
1050
PDEBUG("INT32 %lld", item->value);
1051
param = jit_value_create_nint_constant(jitFunction->function, jit_type_int, (JITINT32) item->value);
1054
PDEBUG("INT64 %lld", item->value);
1055
param = jit_value_create_long_constant(jitFunction->function, jit_type_long, (JITINT64) item->value);
1058
PDEBUG("NINT %lld", item->value);
1059
param = jit_value_create_nint_constant(jitFunction->function, jit_type_nint, (JITINT32) item->value);
1062
PDEBUG("UINT8 %lld", item->value);
1063
param = jit_value_create_nint_constant(jitFunction->function, jit_type_ubyte, (JITINT32) item->value);
1066
PDEBUG("UINT16 %lld", item->value);
1067
param = jit_value_create_nint_constant(jitFunction->function, jit_type_ushort, (JITINT32) item->value);
1070
PDEBUG("UINT32 %lld", item->value);
1071
param = jit_value_create_nint_constant(jitFunction->function, jit_type_uint, (JITUINT32) item->value);
1074
PDEBUG("UINT64 %lld", item->value);
1075
param = jit_value_create_long_constant (jitFunction->function, jit_type_ulong , (JITUINT64) item->value);
1078
PDEBUG("NUINT %lld", item->value);
1079
param = jit_value_create_nint_constant (jitFunction->function, jit_type_nint , (JITINT32) item->value);
1082
PDEBUG("FLOAT32 %f", item->fvalue);
1083
param = jit_value_create_float32_constant(jitFunction->function, jit_type_float32 , (JITFLOAT32) item->fvalue);
1086
PDEBUG("FLOAT64 %f", item->fvalue);
1087
param = jit_value_create_float64_constant(jitFunction->function, jit_type_float64 , (JITFLOAT64) item->fvalue);
1090
if (sizeof(JITNUINT) == 4){
1091
PDEBUG("FLOAT32 %f", item->fvalue);
1092
param = jit_value_create_float32_constant(jitFunction->function, jit_type_float32 , (JITFLOAT32) item->fvalue);
1094
PDEBUG("FLOAT64 %f", item->fvalue);
1095
param = jit_value_create_float64_constant(jitFunction->function, jit_type_float64 , (JITFLOAT64) item->fvalue);
1099
PDEBUG("UPOINTER %p", (void *) (JITNUINT) item->value);
1100
param = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr , (JITNUINT) item->value);
1103
PDEBUG("MPOINTER %p", (void *) (JITNUINT) item->value);
1104
param = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr , (JITNUINT) item->value);
1107
PDEBUG("TPOINTER %p", (void *) (JITNUINT) item->value);
1108
param = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr , (JITNUINT) item->value);
1111
PDEBUG("OBJECT %p", (void *) (JITNUINT) item->value);
1112
param = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr , (JITNUINT) item->value);
1115
PDEBUG("CLASSID %p", (void *) (JITNUINT) item->value);
1116
param = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr , (JITNUINT) item->value);
1119
PDEBUG("METHODID %p", (void *) (JITNUINT) item->value);
1120
param = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr , (JITNUINT) item->value);
1123
PDEBUG("TYPEDREFERENCE %p", (void *) (JITNUINT) item->value);
1125
/* retrieve the IL type associated with the valuetype */
1126
_this->fillILTypedReference(&iltype);
1127
assert(iltype.ID != NULL);
1128
assert(iltype.binary != NULL);
1130
/* retrieve the JIT type associated with the valuetype */
1131
JITvalueType = _this->lookupValueType(&iltype);
1132
assert(JITvalueType != NULL);
1134
/* create the JIT variable for the current valuetype */
1135
param = jit_value_create(jitFunction->function, JITvalueType);
1140
snprintf(buf, sizeof(char) * 1024, "IRVIRTUALMACHINE: make_variable: ERROR= Type %d not known. ", item->type);
1144
assert(param != NULL);
1146
/* Make the variable */
1147
var = jit_value_create(jitFunction->function, internal_fromIRTypeToJITType(_this, item->internal_type, ilt));
1148
assert(var != NULL);
1149
jit_insn_store(jitFunction->function, var, param);
1155
JITINT32 check_labels(XanList *labels){
1159
PDEBUG("IRVIRTUALMACHINE: Check the %d labels\n", labels->length(labels));
1160
item = labels->first(labels);
1161
if (labels == NULL) {
1162
PDEBUG("IRVIRTUALMACHINE: There isn't label\n");
1166
/* Check if the label is in the list */
1167
while (item != NULL){
1168
label = (t_jit_label *) item->data;
1169
assert(label != NULL);
1170
if (label->label == jit_label_undefined){
1171
PDEBUG("IRVIRTUALMACHINE: Label %d is undefined\n", label->ID);
1173
PDEBUG("IRVIRTUALMACHINE: Label %d is OK\n", label->ID);
1175
item = labels->next(labels, item);
1178
PDEBUG("IRVIRTUALMACHINE: Labels OK\n");
1182
static inline t_jit_label * insert_label (XanList *labels, JITUINT32 label_ID){
1186
/* Init the variables */
1187
PDEBUG("IRVIRTUALMACHINE: INSERT_LABEL: %d Labels present\n", labels->length(labels));
1191
/* Check if the label is in the list */
1192
item = labels->first(labels);
1193
while (item != NULL){
1194
label = (t_jit_label *) item->data;
1195
assert(label != NULL);
1196
if (label->ID == label_ID){
1197
PDEBUG("IRVIRTUALMACHINE: INSERT_LABEL: Found the target label\n");
1200
item = labels->next(labels, item);
1203
/* The label is not in the list */
1204
PDEBUG("IRVIRTUALMACHINE: INSERT_LABEL: The target label is not found\n");
1205
PDEBUG("IRVIRTUALMACHINE: INSERT_LABEL: Insert the new label\n");
1206
label = (t_jit_label *) allocFunction(sizeof(t_jit_label));
1207
label->ID = label_ID;
1208
label->label = jit_label_undefined;
1209
labels->append(labels, label);
1214
static inline JITINT16 translate_ir_neg (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
1218
assert(method != NULL);
1219
assert(inst != NULL);
1220
assert(jitFunction != NULL);
1221
assert((inst->result).type == IROFFSET);
1222
PDEBUG("IRVIRTUALMACHINE: Variable %lld = neg(", (inst->result).value);
1224
/* Create the first parameter */
1225
param = make_variable (_this, method, &(inst->param_1), jitFunction);
1226
assert(param != NULL);
1229
/* Create the neg instruction */
1230
if (jitFunction->locals[(inst->result).value] != NULL){
1232
temp = jit_insn_neg(jitFunction->function, param);
1233
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1235
jitFunction->locals[(inst->result).value] = jit_insn_neg(jitFunction->function, param);
1242
static inline JITINT16 translate_ir_store_elem (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1243
jit_value_t field_number;
1248
jit_value_t args[2];
1252
assert(_this != NULL);
1253
assert(method != NULL);
1254
assert(jitFunction != NULL);
1255
assert(inst != NULL);
1256
assert((inst->param_1).type == IROFFSET);
1257
assert((inst->param_4).type == IRTYPE);
1258
assert((inst->result).type == NOPARAM);
1260
/* Init the variables */
1263
field_number = NULL;
1265
/* Print the array */
1267
PDEBUG("IRVIRTUALMACHINE: store_elem: Call the printArray\n");
1268
args[0] = jitFunction->locals[(inst->param_1).value];
1269
args[1] = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (JITNUINT) "Before store_elem");
1270
jit_insn_call_native( jitFunction->function, "printArray" , _this->gc->printArray , _this->gc->signPrintArray , args, 2, JIT_CALL_NOTHROW);
1273
/* Print the instruction */
1274
PDEBUG("IRVIRTUALMACHINE: store_elem(Array in variable %lld, Element number in ", (inst->param_1).value);
1276
/* Fetch the array */
1277
array = make_variable(_this, method, &(inst->param_1), jitFunction);
1279
/* Create the field number */
1280
field_number = make_variable(_this, method, &(inst->param_2), jitFunction);
1281
assert(field_number != NULL);
1282
PDEBUG(", Value in ");
1284
/* Create the value to store */
1285
value = make_variable(_this, method, &(inst->param_3), jitFunction);
1286
assert(value != NULL);
1287
PDEBUG(", Type array element ");
1289
/* Fetch the type of the value to store */
1290
type = jit_value_get_type(value);
1291
assert(type != NULL);
1293
/* Check that the value has the same type of *
1294
* the elements of the array */
1295
switch ((inst->param_4).value){
1297
PDEBUG("Value = UINT8 %lld)\n", (inst->param_2).value);
1298
if (type != jit_type_ubyte){
1299
value = jit_insn_convert(jitFunction->function, value, jit_type_ubyte, 0);
1303
PDEBUG("Value = UINT16 %lld)\n", (inst->param_2).value);
1304
if (type != jit_type_ushort){
1305
value = jit_insn_convert(jitFunction->function, value, jit_type_ushort, 0);
1309
PDEBUG("Value = UINT32 %lld)\n", (inst->param_2).value);
1310
if (type != jit_type_uint){
1311
value = jit_insn_convert(jitFunction->function, value, jit_type_uint, 0);
1315
PDEBUG("Value = UINT64 %lld)\n", (inst->param_2).value);
1316
if (type != jit_type_ulong){
1317
value = jit_insn_convert(jitFunction->function, value, jit_type_ulong, 0);
1321
PDEBUG("Value = INT8 %lld)\n", (inst->param_2).value);
1322
if (type != jit_type_sbyte){
1323
value = jit_insn_convert(jitFunction->function, value, jit_type_sbyte, 0);
1327
PDEBUG("Value = INT16 %lld)\n", (inst->param_2).value);
1328
if (type != jit_type_short){
1329
value = jit_insn_convert(jitFunction->function, value, jit_type_short, 0);
1333
PDEBUG("Value = INT32 %lld)\n", (inst->param_2).value);
1334
if (type != jit_type_int){
1335
value = jit_insn_convert(jitFunction->function, value, jit_type_int, 0);
1339
PDEBUG("Value = INT64 %lld)\n", (inst->param_2).value);
1340
if (type != jit_type_long){
1341
value = jit_insn_convert(jitFunction->function, value, jit_type_long, 0);
1345
PDEBUG("Value = IRNINT %lld)\n", (inst->param_2).value);
1346
if (type != jit_type_int) {
1347
value = jit_insn_convert(jitFunction->function, value, jit_type_int, 0);
1351
PDEBUG("Value = FLOAT32 %f)\n", (JITFLOAT32) (inst->param_2).fvalue);
1352
if (type != jit_type_float32){
1353
value = jit_insn_convert(jitFunction->function,
1354
value, jit_type_float32, 0);
1358
PDEBUG("Value = FLOAT64 %f)\n", (JITFLOAT64) (inst->param_2).fvalue);
1359
if (type != jit_type_float64){
1360
value = jit_insn_convert(jitFunction->function, value, jit_type_float64, 0);
1364
if (sizeof(JITNUINT) == 4){
1365
PDEBUG("Value = FLOAT32 %f)\n", (JITFLOAT32) (inst->param_2).fvalue);
1366
if (type != jit_type_float32){
1367
value = jit_insn_convert(jitFunction->function, value, jit_type_float32, 0);
1370
PDEBUG("Value = FLOAT64 %f)\n", (JITFLOAT64) (inst->param_2).fvalue);
1371
if (type != jit_type_float64){
1372
value = jit_insn_convert(jitFunction->function, value, jit_type_float64, 0);
1377
PDEBUG("Value = UPOINTER 0x%p)\n", (void *) (JITNUINT) (inst->param_2).value);
1378
if (type != jit_type_void_ptr)
1380
value = jit_insn_convert(jitFunction->function,
1381
value, jit_type_void_ptr, 0);
1385
PDEBUG("Value = MPOINTER 0x%p)\n", (void *) (JITNUINT) (inst->param_2).value);
1386
if (type != jit_type_void_ptr)
1388
value = jit_insn_convert(jitFunction->function,
1389
value, jit_type_void_ptr, 0);
1393
PDEBUG("Value = TPOINTER 0x%p)\n", (void *) (JITNUINT) (inst->param_2).value);
1394
if (type != jit_type_void_ptr)
1396
value = jit_insn_convert(jitFunction->function,
1397
value, jit_type_void_ptr, 0);
1401
PDEBUG("Value = OBJECT 0x%p)\n", (void *) (JITNUINT) (inst->param_2).value);
1402
if (type != jit_type_void_ptr)
1404
value = jit_insn_convert(jitFunction->function,
1405
value, jit_type_void_ptr, 0);
1409
PDEBUG("Value = VALUETYPE 0x%p)\n", (void *) (JITNUINT) (inst->param_2).value);
1410
/* Nothing to be done here */
1413
print_err("IRVIRTUALMACHINE: translate_ir_store_elem: ERROR = Type of the parameter 2 is not known. ", 0);
1416
assert(value != NULL);
1417
assert(field_number != NULL);
1419
/* Create the Store_elem instruction */
1420
if (jit_insn_store_elem(jitFunction->function , array , field_number, value) == 0) {
1421
print_err("IRVIRTUALMACHINE: store_elem: ERROR = The jit_insn_store_elem return an error. ", 0);
1425
/* Print the array */
1427
PDEBUG("IRVIRTUALMACHINE: store_elem: Call the printArray\n");
1428
args[0] = jitFunction->locals[(inst->param_1).value];
1429
args[1] = jit_value_create_nint_constant(jitFunction->function, jit_type_void_ptr, (JITNUINT) "After store_elem");
1430
jit_insn_call_native(jitFunction->function, "printArray" , _this->gc->printArray , _this->gc->signPrintArray, args, 2, JIT_CALL_NOTHROW);
1437
static inline JITINT16 translate_ir_load_elem (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1440
jit_value_t field_number;
1442
jit_type_t arraySlotType;
1445
assert(_this != NULL);
1446
assert(method != NULL);
1447
assert(jitFunction != NULL);
1448
assert(inst != NULL);
1449
assert((inst->result).type == IROFFSET);
1450
assert((inst->param_1).type == IROFFSET);
1451
assert((inst->param_3).type == IRTYPE);
1452
PDEBUG("IRVIRTUALMACHINE: Variable %lld = load_elem(Array = Variable %lld, Field = ", (inst->result).value, (inst->param_1).value);
1454
/* Initialize the variables */
1455
arraySlotType = NULL;
1456
field_number = NULL;
1460
/* Fetch the array */
1461
array = make_variable(_this, method, &(inst->param_1), jitFunction);
1463
/* Create the field number */
1464
field_number = make_variable(_this, method, &(inst->param_2), jitFunction);
1465
PDEBUG(", IRTYPE = ");
1467
/* Compute the type of the single slot */
1468
typeSlot = (inst->param_3).value;
1470
/* Make the JIT type */
1474
arraySlotType = jit_type_sbyte;
1477
arraySlotType = jit_type_short;
1478
PDEBUG("IRINT16\n");
1481
PDEBUG("IRINT32\n");
1482
arraySlotType = jit_type_int;
1485
PDEBUG("IRINT64\n");
1486
arraySlotType = jit_type_long;
1489
PDEBUG("IRUINT8\n");
1490
arraySlotType = jit_type_ubyte;
1493
PDEBUG("IRUINT16\n");
1494
arraySlotType = jit_type_ushort;
1497
PDEBUG("IRUINT32\n");
1498
arraySlotType = jit_type_uint;
1501
PDEBUG("IRUINT64\n");
1502
arraySlotType = jit_type_ulong;
1505
PDEBUG("IRFLOAT32\n");
1506
arraySlotType = jit_type_float32;
1509
PDEBUG("IRFLOAT64\n");
1510
arraySlotType = jit_type_float64;
1514
arraySlotType = jit_type_nint;
1517
PDEBUG("IRNUINT\n");
1518
arraySlotType = jit_type_nuint;
1521
if (sizeof(JITNUINT) == 4) {
1522
PDEBUG("IRFLOAT32\n");
1523
arraySlotType = jit_type_float32;
1525
PDEBUG("IRFLOAT64\n");
1526
arraySlotType = jit_type_float64;
1530
PDEBUG("IRUPOINTER\n");
1531
arraySlotType = jit_type_void_ptr;
1534
PDEBUG("IRMPOINTER\n");
1535
arraySlotType = jit_type_void_ptr;
1538
PDEBUG("IRTPOINTER\n");
1539
arraySlotType = jit_type_void_ptr;
1542
PDEBUG("IROBJECT\n");
1543
arraySlotType = jit_type_void_ptr;
1546
snprintf(buffer, sizeof(buffer), "IRVIRTUALMACHINE: load_elem: ERROR = Type %d is not known. ", typeSlot);
1547
print_err(buffer, 0);
1551
/* Make the JIT instruction */
1552
if (jitFunction->locals[(inst->result).value] != NULL){
1554
temp = jit_insn_load_elem (jitFunction->function , array , field_number, arraySlotType);
1555
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1557
jitFunction->locals[(inst->result).value] = jit_insn_load_elem (jitFunction->function , array, field_number, arraySlotType);
1559
assert(jitFunction->locals[(inst->result).value] != NULL);
1561
/* Print the array */
1564
jit_value_t args[2];
1565
PDEBUG("IRVIRTUALMACHINE: load_elem: Call the printArray\n");
1566
args[0] = jitFunction->locals[(inst->param_1).value];
1567
args[1] = jit_value_create_nint_constant(jitFunction->function , jit_type_void_ptr, (JITNUINT) "load_elem");
1568
jit_insn_call_native(jitFunction->function, "printArray" , _this->gc->printArray , _this->gc->signPrintArray , args, 3, JIT_CALL_NOTHROW);
1575
static inline JITINT16 translate_ir_newobj (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
1576
jit_value_t args[3];
1580
assert(_this != NULL);
1581
assert(inst != NULL);
1582
assert((inst->param_1).type == IRCLASSID);
1583
assert((inst->param_2).type == IRUINT32);
1584
assert((inst->param_2).internal_type == IRUINT32);
1586
/* Fetch the class */
1587
classID = (ILClassID) (JITNUINT)(inst->param_1).value;
1588
assert(classID != NULL);
1592
char *type_name_space;
1593
type_name = get_string(&((inst->binary->metadata).streams_metadata.string_stream)
1594
, ((t_row_type_def_table *) classID)->type_name);
1595
type_name_space = get_string(&((inst->binary->metadata).streams_metadata.string_stream)
1596
, ((t_row_type_def_table *) classID)->type_name_space);
1597
PDEBUG("IRVIRTUALMACHINE: Variable %lld = newobj(%s.%s)\n"
1598
, (inst->result).value, type_name_space, type_name);
1599
PDEBUG("IRVIRTUALMACHINE: Call the allocObject function of the garbage Collector\n");
1602
/* Create the arguments */
1603
args[0] = jit_value_create_nint_constant(jitFunction->function, jit_type_void_ptr, (JITNUINT) inst->binary);
1604
args[1] = jit_value_create_nint_constant(jitFunction->function, jit_type_void_ptr, (JITNUINT) classID);
1605
args[2] = make_variable(_this, method, &(inst->param_2), jitFunction);
1607
/* Call the Allocator */
1608
if (jitFunction->locals[(inst->result).value] != NULL){
1610
temp = jit_insn_call_native(jitFunction->function , "allocObject", _this->gc->allocObject , _this->gc->signAllocObject, args, 3, JIT_CALL_NOTHROW);
1611
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1613
jitFunction->locals[(inst->result).value] = jit_insn_call_native(jitFunction->function , "allocObject", _this->gc->allocObject , _this->gc->signAllocObject, args, 3, JIT_CALL_NOTHROW);
1615
assert(jitFunction->locals[(inst->result).value] != NULL);
1621
static inline JITINT16 translate_ir_label (ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction) {
1625
assert(method != NULL);
1626
assert(inst != NULL);
1628
PDEBUG("IRVIRTUALMACHINE: Label \"L%lld\"\n", (inst->param_1).value);
1629
assert((inst->param_1).type == IRLABELITEM);
1630
PDEBUG("IRVIRTUALMACHINE: %d Labels present\n", labels->length(labels));
1631
PDEBUG("IRVIRTUALMACHINE: Insert a label\n");
1632
label = insert_label(labels, (inst->param_1).value);
1633
assert(label != NULL);
1634
jit_insn_label(jitFunction->function, &(label->label));
1635
PDEBUG("IRVIRTUALMACHINE: %d Labels present\n", labels->length(labels));
1640
static inline JITINT16 translate_ir_xor (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
1641
jit_value_t param_1;
1642
jit_value_t param_2;
1645
assert(_this != NULL);
1646
assert(method != NULL);
1647
assert(inst != NULL);
1648
assert((inst->result).type == IROFFSET);
1649
PDEBUG("IRVIRTUALMACHINE: Variable %lld = xor(", (inst->result).value);
1651
/* Create the first parameter */
1652
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
1654
assert(param_1 != NULL);
1656
/* Create the second parameter */
1657
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
1659
assert(param_2 != NULL);
1661
/* Create the xor instruction */
1662
if (jitFunction->locals[(inst->result).value] != NULL){
1664
temp = jit_insn_xor (jitFunction->function, param_1, param_2);
1665
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1667
jitFunction->locals[(inst->result).value] = jit_insn_xor (jitFunction->function, param_1, param_2);
1669
assert(jitFunction->locals[(inst->result).value] != NULL);
1675
static inline JITINT16 translate_ir_and (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1676
jit_value_t param_1;
1677
jit_value_t param_2;
1680
assert(_this != NULL);
1681
assert(method != NULL);
1682
assert(inst != NULL);
1683
assert((inst->result).type == IROFFSET);
1684
PDEBUG("IRVIRTUALMACHINE: Variable %lld = and(", (inst->result).value);
1686
/* Create the first parameter */
1687
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
1689
assert(param_1 != NULL);
1691
/* Create the second parameter */
1692
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
1694
assert(param_2 != NULL);
1696
/* Create the and instruction */
1697
if (jitFunction->locals[(inst->result).value] != NULL){
1699
temp = jit_insn_and (jitFunction->function, param_1, param_2);
1700
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1702
jitFunction->locals[(inst->result).value] = jit_insn_and (jitFunction->function, param_1, param_2);
1704
assert(jitFunction->locals[(inst->result).value] != NULL);
1710
static inline JITINT16 translate_ir_or (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1711
jit_value_t param_1;
1712
jit_value_t param_2;
1715
assert(_this != NULL);
1716
assert(method != NULL);
1717
assert(inst != NULL);
1718
assert((inst->result).type == IROFFSET);
1719
PDEBUG("IRVIRTUALMACHINE: Variable %lld = or(", (inst->result).value);
1721
/* Create the first parameter */
1722
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
1724
assert(param_1 != NULL);
1726
/* Create the second parameter */
1727
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
1729
assert(param_2 != NULL);
1731
/* Create the aor instruction */
1732
if (jitFunction->locals[(inst->result).value] != NULL){
1734
temp = jit_insn_or (jitFunction->function, param_1, param_2);
1735
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1737
jitFunction->locals[(inst->result).value] = jit_insn_or (jitFunction->function, param_1, param_2);
1739
assert(jitFunction->locals[(inst->result).value] != NULL);
1745
static inline JITINT16 translate_ir_mul (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1746
jit_value_t param_1;
1747
jit_value_t param_2;
1750
assert(_this != NULL);
1751
assert(method != NULL);
1752
assert(inst != NULL);
1753
assert((inst->result).type == IROFFSET);
1754
PDEBUG("IRVIRTUALMACHINE: Variable %lld = mul(", (inst->result).value);
1756
/* Create the first parameter */
1757
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
1759
assert(param_1 != NULL);
1761
/* Create the second parameter */
1762
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
1764
assert(param_2 != NULL);
1766
/* Create the lt instruction */
1767
if (jitFunction->locals[(inst->result).value] != NULL){
1769
temp = jit_insn_mul (jitFunction->function, param_1, param_2);
1770
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1772
jitFunction->locals[(inst->result).value] = jit_insn_mul (jitFunction->function, param_1, param_2);
1774
assert(jitFunction->locals[(inst->result).value] != NULL);
1780
static inline JITINT16 translate_ir_div (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1781
jit_value_t param_1;
1782
jit_value_t param_2;
1785
assert(method != NULL);
1786
assert(inst != NULL);
1787
assert((inst->result).type == IROFFSET);
1788
PDEBUG("IRVIRTUALMACHINE: Variable %lld = div(", (inst->result).value);
1790
/* Create the first parameter */
1791
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
1793
assert(param_1 != NULL);
1795
/* Create the second parameter */
1796
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
1798
assert(param_2 != NULL);
1800
/* Create the div instruction */
1801
if (jitFunction->locals[(inst->result).value] != NULL){
1803
temp = jit_insn_div (jitFunction->function, param_1, param_2);
1804
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1806
jitFunction->locals[(inst->result).value] = jit_insn_div (jitFunction->function, param_1, param_2);
1808
assert(jitFunction->locals[(inst->result).value] != NULL);
1814
static inline JITINT16 translate_ir_sub (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1815
jit_value_t param_1;
1816
jit_value_t param_2;
1819
assert(_this != NULL);
1820
assert(method != NULL);
1821
assert(inst != NULL);
1822
assert((inst->result).type == IROFFSET);
1823
PDEBUG("IRVIRTUALMACHINE: Variable %lld = sub(", (inst->result).value);
1825
/* Create the first parameter */
1826
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
1828
assert(param_1 != NULL);
1830
/* Create the second parameter */
1831
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
1833
assert(param_2 != NULL);
1835
/* Create the sub instruction */
1836
if (jitFunction->locals[(inst->result).value] != NULL){
1838
temp = jit_insn_sub(jitFunction->function, param_1, param_2);
1839
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1841
jitFunction->locals[(inst->result).value] = jit_insn_sub(jitFunction->function, param_1, param_2);
1843
assert(jitFunction->locals[(inst->result).value] != NULL);
1849
static inline JITINT16 translate_ir_add (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1850
jit_value_t param_1;
1851
jit_value_t param_2;
1854
assert(_this != NULL);
1855
assert(method != NULL);
1856
assert(inst != NULL);
1857
assert((inst->result).type == IROFFSET);
1858
PDEBUG("IRVIRTUALMACHINE: Variable %lld = add(", (inst->result).value);
1860
/* Create the first parameter */
1861
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
1863
assert(param_1 != NULL);
1865
/* Create the second parameter */
1866
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
1868
assert(param_2 != NULL);
1870
/* Create the add instruction */
1871
if (jitFunction->locals[(inst->result).value] != NULL){
1873
temp = jit_insn_add(jitFunction->function, param_1, param_2);
1874
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
1876
jitFunction->locals[(inst->result).value] = jit_insn_add(jitFunction->function, param_1, param_2);
1878
assert(jitFunction->locals[(inst->result).value] != NULL);
1884
static inline JITINT16 translate_ir_branch(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction){
1888
assert(method != NULL);
1889
assert(inst != NULL);
1890
assert(labels != NULL);
1892
PDEBUG("IRVIRTUALMACHINE: branch(Label \"L%lld\")\n", (inst->param_1).value);
1893
assert((inst->param_1).type == IRLABELITEM);
1894
label = insert_label(labels, (inst->param_1).value);
1895
assert(label != NULL);
1896
jit_insn_branch(jitFunction->function, &(label->label));
1901
static inline JITINT16 translate_ir_branch_if_pc_not_in_range(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction){
1902
t_jit_label *label_from;
1903
t_jit_label *label_to;
1904
t_jit_label *label_target;
1907
assert(method != NULL);
1908
assert(inst != NULL);
1909
assert((inst->param_1).type == IRLABELITEM);
1910
assert((inst->param_2).type == IRLABELITEM);
1911
assert((inst->param_3).type == IRLABELITEM);
1912
PDEBUG("IRVIRTUALMACHINE: branch_if_pc_not_in_range(Label_from \"L%lld\" , Label_to \"L%lld\" , Label_target \"L%lld\")\n", (inst->param_1).value, (inst->param_2).value, (inst->param_3).value);
1914
label_from = insert_label(labels, (inst->param_1).value);
1915
assert(label_from != NULL);
1916
label_to = insert_label(labels, (inst->param_2).value);
1917
assert(label_to != NULL);
1918
label_target = insert_label(labels, (inst->param_3).value);
1919
assert(label_target != NULL);
1921
jit_insn_branch_if_pc_not_in_range (jitFunction->function, (label_from->label), (label_to->label), &(label_target->label));
1926
static inline JITINT16 translate_ir_start_filter (ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction) {
1930
assert(method != NULL);
1931
assert(inst != NULL);
1932
assert((inst->result).type == IROFFSET);
1933
assert((inst->param_1).type == IRLABELITEM);
1934
assert((inst->param_2).type == NOPARAM);
1935
assert((inst->param_3).type == NOPARAM);
1936
assert((inst->param_4).type == NOPARAM);
1938
PDEBUG("IRVIRTUALMACHINE: start_filter (Label \"L%lld\")\n", (inst->param_1).value);
1939
label = insert_label(labels, (inst->param_1).value);
1940
assert(label != NULL);
1941
jitFunction->locals[(inst->result).value] = jit_insn_start_filter(jitFunction->function, &(label->label), jit_type_void_ptr);
1946
static inline JITINT16 translate_ir_start_finally(ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction) {
1950
assert(method != NULL);
1951
assert(inst != NULL);
1952
assert((inst->param_1).type == IRLABELITEM);
1953
assert((inst->param_2).type == NOPARAM);
1954
assert((inst->param_3).type == NOPARAM);
1955
assert((inst->param_4).type == NOPARAM);
1956
assert((inst->result).type == NOPARAM);
1958
PDEBUG("IRVIRTUALMACHINE: start_finally (Label \"L%lld\")\n", (inst->param_1).value);
1959
label = insert_label(labels, (inst->param_1).value);
1960
assert(label != NULL);
1961
jit_insn_start_finally(jitFunction->function, &(label->label));
1966
static inline JITINT16 translate_ir_end_finally(ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
1968
assert(method != NULL);
1969
assert(inst != NULL);
1970
assert(((inst->param_1).type == NOPARAM) || ((inst->param_1).type == IRLABELITEM));
1971
assert((inst->param_2).type == IRLABELITEM);
1972
assert((inst->param_3).type == NOPARAM);
1973
assert((inst->param_4).type == NOPARAM);
1974
assert((inst->result).type == NOPARAM);
1976
PDEBUG("IRVIRTUALMACHINE: end_finally \n");
1977
jit_insn_return_from_finally(jitFunction->function);
1982
static inline JITINT16 translate_ir_call_indirect_exception_ctor (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
1983
jit_value_t param_1;
1984
jit_value_t param_2;
1987
assert(inst != NULL);
1988
assert(method != NULL);
1989
assert(jitFunction != NULL);
1990
assert(jitFunction->locals != NULL);
1991
assert(_this != NULL);
1992
assert(_this->basicExceptionConstructorJITSignature != NULL);
1993
assert((inst->param_1).type == IROFFSET);
1994
assert((inst->param_2).type == IROFFSET);
1995
assert((inst->param_3).type == NOPARAM);
1996
assert((inst->param_4).type == NOPARAM);
1997
assert((inst->result).type == NOPARAM);
1998
PDEBUG("IRVIRTUALMACHINE: call the exception constructor via indirect call \n");
2000
/* Fetch the parameters */
2001
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2002
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
2003
assert(param_1 != NULL);
2004
assert(param_2 != NULL);
2006
/* Call the constructor on the exception-object */
2007
jit_insn_call_indirect_vtable(jitFunction->function, param_1, _this->basicExceptionConstructorJITSignature, ¶m_2, 1, JIT_CALL_NOTHROW);
2013
static inline JITINT16 translate_ir_start_catcher (ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
2016
assert(method != NULL);
2017
assert(inst != NULL);
2018
assert((inst->param_1).type == NOPARAM);
2019
assert((inst->param_2).type == NOPARAM);
2020
assert((inst->param_3).type == NOPARAM);
2021
assert((inst->param_4).type == NOPARAM);
2022
assert((inst->result).type == NOPARAM);
2025
/* create the jit-instruction that marks the start of the catcher */
2026
PDEBUG("IRVIRTUALMACHINE: start_catcher : jit_insn_start_catcher \n");
2027
jit_insn_start_catcher(jitFunction->function);
2032
static inline JITINT16 translate_ir_uses_catcher(IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
2035
assert(method != NULL);
2036
assert(inst != NULL);
2037
assert((inst->param_1).type == NOPARAM);
2038
assert((inst->param_2).type == NOPARAM);
2039
assert((inst->param_3).type == NOPARAM);
2040
assert((inst->param_4).type == NOPARAM);
2041
assert((inst->result).type == NOPARAM);
2043
PDEBUG("IRVIRTUALMACHINE: uses_catcher \n");
2044
jit_insn_uses_catcher(jitFunction->function);
2046
/* Set the tracer */
2047
if ((_this->behavior).tracer){
2048
PDEBUG("IRVIRTUALMACHINE: Insert the tracer call\n");
2049
insert_tracer(_this, method, jitFunction, JITFALSE);
2056
static inline JITINT16 translate_ir_rethrow_unandled(ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
2059
assert(method != NULL);
2060
assert(inst != NULL);
2061
assert((inst->param_1).type == NOPARAM);
2062
assert((inst->param_2).type == NOPARAM);
2063
assert((inst->param_3).type == NOPARAM);
2064
assert((inst->param_4).type == NOPARAM);
2065
assert((inst->result).type == NOPARAM);
2067
PDEBUG("IRVIRTUALMACHINE: rethrow_unhandled \n");
2068
jit_insn_rethrow_unhandled(jitFunction->function);
2073
static inline JITINT16 translate_ir_end_filter (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
2074
jit_value_t param_1;
2077
assert(_this != NULL);
2078
assert(method != NULL);
2079
assert(inst != NULL);
2080
assert((inst->param_1).type != NOPARAM);
2081
assert((inst->param_2).type == NOPARAM);
2082
assert((inst->param_2).type == NOPARAM);
2083
assert((inst->param_2).type == NOPARAM);
2084
assert((inst->result).type == NOPARAM);
2085
PDEBUG("IRVIRTUALMACHINE: end_filter \n");
2087
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2089
jit_insn_return_from_filter (jitFunction->function, param_1);
2094
static inline JITINT16 translate_ir_call_filter (ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction) {
2096
jit_value_t filter_parameter;
2099
assert(method != NULL);
2100
assert(inst != NULL);
2101
assert((inst->result).type == IROFFSET);
2102
assert((inst->param_1).type == IRLABELITEM);
2103
assert((inst->param_2).type == NOPARAM);
2104
assert((inst->param_3).type == NOPARAM);
2105
assert((inst->param_4).type == NOPARAM);
2106
assert((inst->result).type == NOPARAM);
2108
PDEBUG("IRVIRTUALMACHINE: call_filter(Label \"L%lld\")\n", (inst->param_1).value);
2109
label = insert_label(labels, (inst->param_1).value);
2110
assert(label != NULL);
2111
filter_parameter = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (JITNUINT)0);
2113
if (jitFunction->locals[(inst->result).value] != NULL){
2115
temp = jit_insn_call_filter(jitFunction->function, &(label->label), filter_parameter, jit_type_int);
2116
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
2118
jitFunction->locals[(inst->result).value] = jit_insn_call_filter(jitFunction->function, &(label->label), filter_parameter, jit_type_int);
2120
assert(jitFunction->locals[(inst->result).value] != NULL);
2126
static inline JITINT16 translate_ir_call_finally (ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction) {
2130
assert(method != NULL);
2131
assert(inst != NULL);
2132
assert((inst->param_1).type == IRLABELITEM);
2133
assert((inst->param_2).type == NOPARAM);
2134
assert((inst->param_3).type == NOPARAM);
2135
assert((inst->param_4).type == NOPARAM);
2136
assert((inst->result).type == NOPARAM);
2138
PDEBUG("IRVIRTUALMACHINE: call_finally(Label \"L%lld\")\n", (inst->param_1).value);
2139
label = insert_label(labels, (inst->param_1).value);
2140
assert(label != NULL);
2141
jit_insn_call_finally(jitFunction->function, &(label->label));
2146
static inline JITINT16 translate_ir_throw (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
2147
jit_value_t param_1;
2150
assert(_this != NULL);
2151
assert(method != NULL);
2152
assert(inst != NULL);
2153
assert((inst->param_1).type == IROFFSET);
2155
PDEBUG("IRVIRTUALMACHINE: rethrow \n");
2157
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2159
/* RETHROW IT USING THE THROW INSTRUCTION */
2160
jit_insn_throw (jitFunction->function, param_1);
2166
static inline JITINT16 translate_ir_conv (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
2174
assert(_this != NULL);
2175
assert(inst != NULL);
2176
assert(method != NULL);
2177
assert((inst->result).type == IROFFSET);
2178
assert((inst->param_1).type != NOPARAM);
2179
assert((inst->param_2).type == IRTYPE);
2181
/* Init the variables */
2182
PDEBUG("IRVIRTUALMACHINE: Variable %lld = conv(", (inst->result).value);
2185
/* Create the first parameter */
2186
param = make_variable(_this, method, &(inst->param_1), jitFunction);
2187
assert(param != NULL);
2190
/* Fetch the type of the value to store */
2192
_type = jit_value_get_type(param);
2193
assert(_type != NULL);
2196
/* Create the type */
2197
switch ((inst->param_2).value){
2200
type = jit_type_sbyte;
2204
type = jit_type_short;
2208
type = jit_type_int;
2212
type = jit_type_long;
2215
PDEBUG("Native INT)\n");
2216
type = jit_type_nint;
2220
type = jit_type_ubyte;
2223
PDEBUG("UINT16)\n");
2224
type = jit_type_ushort;
2227
PDEBUG("UINT32)\n");
2228
type = jit_type_uint;
2231
PDEBUG("UINT64)\n");
2232
type = jit_type_ulong;
2235
PDEBUG("Native UINT)\n");
2236
type = jit_type_nuint;
2239
PDEBUG("FLOAT32)\n");
2240
type = jit_type_float32;
2243
PDEBUG("FLOAT64)\n");
2244
type = jit_type_float64;
2247
if (sizeof(JITNFLOAT) == 4){
2248
PDEBUG("FLOAT32)\n");
2249
type = jit_type_float32;
2251
PDEBUG("FLOAT64)\n");
2252
type = jit_type_float64;
2259
PDEBUG("UPOINTER)\n");
2260
type = jit_type_void_ptr;
2263
print_err("IRVIRTUALMACHINE: ERROR = Conversion type is not known. ", 0);
2267
/* Create the instruction */
2268
if (jitFunction->locals[(inst->result).value] != NULL){
2270
temp = jit_insn_convert (jitFunction->function, param, type, (inst->param_3).value);
2271
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
2273
jitFunction->locals[(inst->result).value] = jit_insn_convert (jitFunction->function, param, type, (inst->param_3).value);
2275
assert(jitFunction->locals[(inst->result).value] != NULL);
2281
static inline JITINT16 translate_ir_ncall (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
2282
ir_method_t *jumpMethod;
2283
t_jit_function *jumpMethodJIT;
2287
JITUINT32 args_number;
2291
assert(_this != NULL);
2292
assert(method != NULL);
2293
assert(inst != NULL);
2294
assert(inst->binary != NULL);
2295
assert(inst->binary->name != NULL);
2296
assert((inst->param_1).type == IRMETHODID);
2297
assert(jitFunction->function != NULL);
2299
/* Init the variables */
2305
/* Search the jump method */
2306
jumpMethod = _this->getIRMethod((inst->param_1).value);
2307
assert(jumpMethod != NULL);
2308
jumpMethodJIT = _this->getJITMethod((inst->param_1).value);
2309
assert(jumpMethodJIT != NULL);
2310
assert(jumpMethodJIT->jit_signature != NULL);
2311
assert(jumpMethodJIT->nfunction != NULL);
2314
switch ((inst->result).type){
2316
PDEBUG("IRVIRTUALMACHINE: IR_NCALL: Variable %lld = ncall(Method = %s Binary = %s: " , (inst->result).value, jumpMethod->getName(jumpMethod) , inst->binary->name);
2319
PDEBUG("IRVIRTUALMACHINE: IR_NCALL: ncall(Method = %s Binary = %s: " , jumpMethod->getName(jumpMethod), inst->binary->name);
2322
print_err("IRVIRTUALMACHINE: IR_NCALL: ERROR = Result type not known. ", 0);
2327
/* Create the arguments */
2328
args_number = jumpMethod->getParametersNumber(jumpMethod);
2330
/* Alloc the JIT arguments */
2331
if (args_number > 0){
2332
args = (jit_value_t *) allocFunction(sizeof(jit_value_t) * args_number);
2334
/* Fetch the first formal parameter */
2335
item = inst->callParameters->first(inst->callParameters);
2336
assert(item != NULL);
2339
assert(inst->callParameters != NULL);
2340
assert(inst->callParameters->length(inst->callParameters) == 0);
2343
/* Create all the formal arguments */
2345
while (item != NULL){
2346
param = (ir_item_t *) inst->callParameters->data(inst->callParameters, item);
2347
assert(param != NULL);
2349
/* Create the argument */
2350
args[count] = make_variable(_this, method, param, jitFunction);
2352
assert(args[count] != NULL);
2354
/* Fetch the next parameter */
2356
item = inst->callParameters->next(inst->callParameters, item);
2358
assert(count == args_number);
2361
/* Create the JIT call instruction */
2362
PDEBUG("IRVIRTUALMACHINE: IR_NCALL: Insert the JIT call instruction\n");
2363
switch ((inst->result).type){
2365
if (jitFunction->locals[(inst->result).value] != NULL){
2367
temp = jit_insn_call_native(jitFunction->function, jumpMethod->getName(jumpMethod), jumpMethodJIT->nfunction, jumpMethodJIT->jit_signature, args, args_number, 0);
2368
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
2370
jitFunction->locals[(inst->result).value] = jit_insn_call_native(jitFunction->function, jumpMethod->getName(jumpMethod), jumpMethodJIT->nfunction, jumpMethodJIT->jit_signature, args, args_number, 0);
2372
assert(jitFunction->locals[(inst->result).value] != NULL);
2375
jit_insn_call_native(jitFunction->function, jumpMethod->getName(jumpMethod), jumpMethodJIT->nfunction, jumpMethodJIT->jit_signature, args, args_number, 0);
2378
print_err("IRVIRTUALMACHINE: IR_NCALL: ERROR = Result type not known. ", 0);
2383
PDEBUG("IRVIRTUALMACHINE: IR_NCALL: End\n");
2387
static inline JITINT16 translate_ir_icall (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
2388
jit_type_t signature;
2389
jit_type_t returnType;
2390
jit_type_t *jit_param_types;
2391
jit_value_t *jit_param_values;
2392
JITUINT32 param_size;
2394
XanListItem *current_parameter;
2398
assert(method != NULL);
2399
assert(_this != NULL);
2400
assert(inst != NULL);
2401
assert((inst->param_1).type == IRTYPE);
2402
if ((inst->param_1).value == IRVOID){
2403
assert((inst->result).type == NOPARAM);
2405
assert((inst->result).type == IROFFSET);
2409
PDEBUG("IRVIRTUALMACHINE: translate_ir_icall: Start\n");
2410
if ((char *) ((JITNUINT)((inst->param_2).value)) != NULL){
2411
PDEBUG("IRVIRTUALMACHINE: translate_ir_icall: Function = %s\n" , (char *) ((JITNUINT)((inst->param_2).value)) );
2415
/* initialize the local variables */
2418
jit_param_types = NULL;
2419
jit_param_values = NULL;
2420
current_parameter = NULL;
2424
/* retrieve the return_type */
2425
PDEBUG("IRVIRTUALMACHINE: translate_ir_icall: Make the JIT signature\n");
2426
PDEBUG("IRVIRTUALMACHINE: translate_ir_icall: Make the return type\n");
2427
returnType = internal_fromIRTypeToJITType(_this, (inst->param_1).value, (inst->param_1).value_type_infos.type_infos);
2428
assert(returnType != NULL);
2430
/* there are some parameters */
2431
PDEBUG("IRVIRTUALMACHINE: translate_ir_icall: Make the call parameters\n");
2432
if ( (inst->callParameters != NULL) &&
2433
(inst->callParameters->length(inst->callParameters) > 0) ){
2434
param_size = inst->callParameters->length(inst->callParameters);
2435
assert(param_size != 0);
2436
current_parameter = inst->callParameters->first(inst->callParameters);
2437
assert(current_parameter != NULL);
2438
jit_param_types = (jit_type_t *) allocFunction(sizeof(jit_type_t) * param_size);
2439
jit_param_values = (jit_value_t *) allocFunction(sizeof(jit_value_t) * param_size);
2442
/* create the type for each function parameter */
2443
for (count = 0; count < param_size; count++){
2444
jit_type_t current_parameter_type;
2445
jit_value_t current_parameter_value;
2446
ir_item_t *current_stack_item;
2447
PDEBUG("IRVIRTUALMACHINE: translate_ir_icall: Parameter %u: ", count);
2449
/* retrieve the t_stack_item of the current parameter */
2450
assert(current_parameter != NULL);
2451
current_stack_item = (ir_item_t *) inst->callParameters->data(inst->callParameters, current_parameter);
2452
assert(current_stack_item != NULL);
2454
/* retrieve the type & the value of the current parameter */
2455
current_parameter_type = internal_fromIRTypeToJITType(_this, current_stack_item->internal_type, (current_stack_item->value_type_infos).type_infos);
2456
current_parameter_value = make_variable(_this, method, current_stack_item, jitFunction);
2462
type = jit_value_get_type(current_parameter_value);
2463
PDEBUG("IRVIRTUALMACHINE: translate_ir_icall: IR Type: %u\n", current_stack_item->internal_type);
2464
PDEBUG("IRVIRTUALMACHINE: translate_ir_icall: JIT Type: %u\n", fromJITTypeToIRType(type));
2465
assert(current_parameter_type != NULL);
2466
assert(current_parameter_value != NULL);
2469
/* Update the values */
2470
jit_param_types[count] = current_parameter_type;
2471
jit_param_values[count] = current_parameter_value;
2473
/* Fetch the next parameter */
2474
current_parameter = inst->callParameters->next(inst->callParameters, current_parameter);
2477
/* create the signature */
2478
signature = jit_type_create_signature( jit_abi_cdecl, returnType, jit_param_types, param_size, 1);
2479
assert(signature != NULL);
2482
Here we must discriminate if we're doing a native or an indirect invocation.
2483
We check the nfunc field of the structure to determine the invocation:
2484
if this field is not NULL, we've a native invocation so we must use 'jit_insn_call_native'
2485
if it is NULL, the invocation is indirect, so we must reference to 'jit_insn_call_indirect'
2487
With respect to the implementation of IRICALL
2490
3) not used before implementing the calli instruction, now it stores a function pointer (ir_item_t)
2492
In the general case, the third parameter is thus the function pointer, which it's not provided exploiting nfunc.
2494
The callParameters field contains the argument list for the method to invoke
2496
if (returnType != jit_type_void) {
2497
assert( ((JITINT8 *) ((JITNUINT)((inst->param_2).value))) != NULL );
2498
if (inst->nfunc != NULL) {
2499
if (jitFunction->locals[(inst->result).value] != NULL) {
2501
temp = jit_insn_call_native(jitFunction->function, (char *) ((JITNUINT)((inst->param_2).value)), inst->nfunc, signature, jit_param_values, param_size, 0);
2502
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
2504
jitFunction->locals[(inst->result).value] = jit_insn_call_native(jitFunction->function, (char *) ((JITNUINT)((inst->param_2).value)), inst->nfunc, signature, jit_param_values, param_size, 0);
2506
assert(jitFunction->locals[(inst->result).value] != NULL);
2508
jit_value_t function_pointer;
2509
function_pointer = make_variable(_this, method, &(inst->param_3), jitFunction);
2510
assert(function_pointer != NULL);
2511
if (jitFunction->locals[(inst->result).value] != NULL) {
2513
temp = jit_insn_call_indirect(jitFunction->function, function_pointer, signature, jit_param_values, param_size, 0);
2514
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
2516
jitFunction->locals[(inst->result).value] = jit_insn_call_indirect(jitFunction->function, function_pointer, signature, jit_param_values, param_size, 0);
2518
assert(jitFunction->locals[(inst->result).value] != NULL);
2521
if (inst->nfunc != NULL) {
2522
jit_insn_call_native(jitFunction->function, (char *) ((JITNUINT)((inst->param_2).value)), inst->nfunc, signature, jit_param_values, param_size, 0);
2524
jit_value_t function_pointer;
2525
function_pointer = make_variable(_this, method, &(inst->param_3), jitFunction);
2526
assert(function_pointer != NULL);
2527
jit_insn_call_indirect(jitFunction->function, function_pointer, signature, jit_param_values, param_size, 0);
2535
static inline JITINT16 translate_ir_call (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
2536
ir_method_t *ir_jump_method;
2537
t_jit_function *jumpMethodJIT;
2541
JITUINT32 args_number;
2543
JITINT32 call_flags;
2544
jit_type_t jit_signature;
2547
assert(_this != NULL);
2548
assert(method != NULL);
2549
assert(inst != NULL);
2550
assert(inst->binary != NULL);
2551
assert(inst->binary->name != NULL);
2552
assert((inst->param_1).type == IRMETHODID);
2553
assert((inst->param_2).type == IRINT32);
2554
assert((inst->param_3).type == NOPARAM || (inst->param_3).type == IRUPOINTER);
2555
assert((inst->param_4).type == NOPARAM);
2556
assert(jitFunction->function != NULL);
2558
/* Init the variables */
2560
ir_jump_method = NULL;
2567
/* Search the jump method */
2568
jumpMethodJIT = _this->getJITMethod((inst->param_1).value);
2569
assert(jumpMethodJIT != NULL);
2570
assert(jumpMethodJIT->jit_signature != NULL);
2572
/* Fetch the IR jump method */
2573
ir_jump_method = _this->getIRMethod((inst->param_1).value);
2574
assert(ir_jump_method != NULL);
2575
assert(ir_jump_method->getSignature(ir_jump_method) != NULL);
2577
jit_signature = jumpMethodJIT->jit_signature;
2579
/* Print the instruction */
2581
switch ((inst->result).type){
2583
PDEBUG("IRVIRTUALMACHINE: IR_CALL: Variable %lld = call(Method = %s Binary = %s)\n", (inst->result).value, ir_jump_method->getName(ir_jump_method), inst->binary->name);
2586
PDEBUG("IRVIRTUALMACHINE: IR_CALL: call(Method = %s Binary = %s)\n", ir_jump_method->getName(ir_jump_method), inst->binary->name);
2589
print_err("IRVIRTUALMACHINE: IR_CALL: ERROR = Result type not known. ", 0);
2594
/* Create the arguments */
2595
PDEBUG("IRVIRTUALMACHINE: IR_CALL: Set the arguments\n");
2596
if ( (inst->callParameters == NULL) ||
2597
(inst->callParameters->length(inst->callParameters) == 0) ){
2599
/* The method hasn't some parameters */
2600
PDEBUG("IRVIRTUALMACHINE: IR_CALL: No arguments\n");
2605
/* The method has some parameters */
2606
args_number = inst->callParameters->length(inst->callParameters);
2607
PDEBUG("IRVIRTUALMACHINE: IR_CALL: %d arguments\n", args_number);
2608
args = (jit_value_t *) allocFunction(sizeof(jit_value_t) * args_number);
2609
item = inst->callParameters->first(inst->callParameters);
2610
assert(item != NULL);
2613
/* Create the arguments */
2614
while (item != NULL) {
2615
param = (ir_item_t *) inst->callParameters->data(inst->callParameters, item);
2616
assert(param != NULL);
2618
/* Create the argument */
2619
PDEBUG("IRVIRTUALMACHINE: IR_CALL: Argument %d : ", count);
2620
args[count] = make_variable(_this, method, param, jitFunction);
2622
assert(args[count] != NULL);
2624
/* Fetch the next parameter */
2626
item = inst->callParameters->next(inst->callParameters, item);
2630
/* Fetch the call flags */
2631
if ((inst->param_2).value == 1){
2632
call_flags = JIT_CALL_TAIL;
2635
/* Create the JIT call instruction */
2636
PDEBUG("IRVIRTUALMACHINE: IR_CALL: Insert the JIT call instruction\n");
2637
switch ((inst->result).type){
2639
PDEBUG("IRVIRTUALMACHINE: IR_CALL: Variable %lld = call(Token = 0x%llX Binary = %s)\n",
2640
(inst->result).value, (inst->param_1).value, inst->binary->name);
2643
if (jitFunction->locals[(inst->result).value] != NULL){
2645
temp = jit_insn_call(jitFunction->function, ir_jump_method->getName(ir_jump_method), jumpMethodJIT->function, jit_signature, args, args_number, call_flags);
2646
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
2648
jitFunction->locals[(inst->result).value] = jit_insn_call(jitFunction->function, ir_jump_method->getName(ir_jump_method), jumpMethodJIT->function, jit_signature, args, args_number, call_flags);
2650
assert(jitFunction->locals[(inst->result).value] != NULL);
2653
PDEBUG("IRVIRTUALMACHINE: IR_CALL: call(Token = 0x%llX Binary = %s)\n",
2654
(inst->param_1).value, inst->binary->name);
2656
/* Call the method */
2657
jit_insn_call(jitFunction->function, ir_jump_method->getName(ir_jump_method), jumpMethodJIT->function, jit_signature, args, args_number, call_flags);
2660
print_err("IRVIRTUALMACHINE: ERROR = Result type not known. ", 0);
2665
PDEBUG("IRVIRTUALMACHINE: IR_CALL: End\n");
2669
static inline JITINT16 translate_ir_ret (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction) {
2673
assert(method != NULL);
2674
assert(inst != NULL);
2675
PDEBUG("IRVIRTUALMACHINE: translate_ir_ret: Start\n");
2677
/* Init the variable */
2680
/* Set the tracer */
2681
if ((_this->behavior).tracer){
2682
insert_tracer(_this, method, jitFunction, JITTRUE);
2685
/* Check if we have to profile the root *
2687
if (internal_addRootSetProfile(_this, method, jitFunction)){
2688
jit_insn_call_native(jitFunction->function, "popLastRootSet", _this->gc->popLastRootSet, _this->gc->signPopLastRootSet, NULL, 0, 0);
2691
/* Translate the feedback code */
2692
//translate_exit_method_feedback_code(system, method);
2694
switch ((method->signature).result_type){
2696
assert((inst->param_1).type == NOPARAM);
2697
PDEBUG("IRVIRTUALMACHINE: Return(VOID)\n");
2700
assert((inst->param_1).type != NOPARAM);
2701
/* Check where the value is */
2702
switch ((inst->param_1).type){
2704
PDEBUG("IRVIRTUALMACHINE: Return(Variable %lld)\n", (inst->param_1).value);
2705
if (jitFunction->locals[(inst->param_1).value] == NULL){
2706
jitFunction->locals[(inst->param_1).value] = jit_value_create(jitFunction->function, internal_fromIRTypeToJITType(_this, (inst->param_1).internal_type, (inst->param_1).value_type_infos.type_infos));
2707
assert(jitFunction->locals[(inst->param_1).value] != NULL);
2709
result = jitFunction->locals[(inst->param_1).value];
2712
PDEBUG("IRVIRTUALMACHINE: Return(INT32 %lld)\n", (inst->param_1).value);
2713
result = jit_value_create_nint_constant (jitFunction->function, jit_type_int, (JITINT32) (inst->param_1).value);
2716
PDEBUG("IRVIRTUALMACHINE: Return(INT64 %lld)\n", (inst->param_1).value);
2717
result = jit_value_create_long_constant (jitFunction->function, jit_type_long, (JITINT64) (inst->param_1).value);
2720
PDEBUG("IRVIRTUALMACHINE: Return(UINT32 %lld)\n", (inst->result).value);
2721
result = jit_value_create_nint_constant (jitFunction->function, jit_type_uint, (JITUINT32) (inst->param_1).value);
2724
PDEBUG("IRVIRTUALMACHINE: Return(UINT64 %lld)\n", (inst->result).value );
2725
result = jit_value_create_long_constant(jitFunction->function, jit_type_ulong, (JITUINT64) (inst->param_1).value);
2728
PDEBUG("IRVIRTUALMACHINE: Return(FLOAT32 %f)\n", (inst->result).fvalue);
2729
result = jit_value_create_float32_constant (jitFunction->function, jit_type_float32, (JITFLOAT32) (inst->param_1).fvalue);
2732
PDEBUG("IRVIRTUALMACHINE: Return(FLOAT64 %f)\n", (inst->result).fvalue);
2733
result = jit_value_create_float64_constant (jitFunction->function, jit_type_float64, (JITFLOAT64) (inst->param_1).fvalue);
2736
if (sizeof(JITNUINT) == 4){
2737
PDEBUG("IRVIRTUALMACHINE: Return(FLOAT32 %f)\n", (inst->result).fvalue);
2738
result = jit_value_create_float32_constant (jitFunction->function, jit_type_float32, (JITFLOAT32) (inst->param_1).fvalue);
2740
PDEBUG("IRVIRTUALMACHINE: Return(FLOAT64 %f)\n", (inst->result).fvalue);
2741
result = jit_value_create_float64_constant (jitFunction->function, jit_type_float64, (JITFLOAT64) (inst->param_1).fvalue);
2745
PDEBUG("IRVIRTUALMACHINE: Return(Unmanaged_POINTER %p)\n", (void *)(JITNUINT)(inst->param_1).value);
2746
result = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (inst->param_1).value);
2749
PDEBUG("IRVIRTUALMACHINE: Return(Managed_POINTER %p)\n", (void *)(JITNUINT)(inst->param_1).value);
2750
result = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (inst->param_1).value);
2753
PDEBUG("IRVIRTUALMACHINE: Return(Transient_POINTER %p)\n", (void *)(JITNUINT)(inst->param_1).value);
2754
result = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (inst->param_1).value);
2757
PDEBUG("IRVIRTUALMACHINE: Return(OBJECT %p)\n", (void *)(JITNUINT)(inst->param_1).value);
2758
result = jit_value_create_nint_constant (jitFunction->function, jit_type_void_ptr, (inst->param_1).value);
2761
print_err("IRVIRTUALMACHINE: ERROR = Result type is not known. ", 0);
2764
assert(result != NULL);
2767
/* Insert the native stop call */
2769
internal_insert_native_stop_function(method);
2772
/* Create the return instruction */
2773
jit_insn_return(jitFunction->function, result);
2775
PDEBUG("IRVIRTUALMACHINE: translate_ir_ret: End\n");
2779
static inline JITINT16 translate_ir_eq (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
2780
jit_value_t param_1;
2781
jit_value_t param_2;
2786
assert(_this != NULL);
2787
assert(method != NULL);
2788
assert(inst != NULL);
2789
assert((inst->result).type == IROFFSET);
2791
/* Create the first parameter */
2792
PDEBUG("IRVIRTUALMACHINE: IREQ: Variable %lld = equal(", (inst->result).value);
2793
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2795
assert(param_1 != NULL);
2797
/* Create the second parameter */
2798
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
2800
assert(param_2 != NULL);
2802
/* Create the equal instruction */
2803
temp = jit_insn_eq(jitFunction->function, param_1, param_2);
2804
temp2 = jit_insn_to_bool(jitFunction->function, temp);
2805
assert(temp2 != NULL);
2807
/* Store the result */
2808
if (jitFunction->locals[(inst->result).value] != NULL){
2809
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp2);
2811
jitFunction->locals[(inst->result).value] = temp2;
2813
assert(jitFunction->locals[(inst->result).value] != NULL);
2819
static inline JITINT16 translate_ir_branchifnot (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction){
2821
jit_value_t param_1;
2824
assert(method != NULL);
2825
assert(inst != NULL);
2826
assert(_this != NULL);
2827
assert((inst->param_2).type == IRLABELITEM);
2828
PDEBUG("IRVIRTUALMACHINE: branch_if_not(Variable %lld, Label \"L%lld\")\n",(inst->param_1).value, (inst->param_2).value);
2830
/* Insert the label */
2831
label = insert_label(labels, (inst->param_2).value);
2832
assert(label != NULL);
2834
/* Create the condition */
2835
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2836
assert(param_1 != NULL);
2838
/* Create the jump */
2839
jit_insn_branch_if_not(jitFunction->function, param_1, &(label->label));
2845
static inline JITINT16 translate_ir_branchif (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, XanList *labels, t_jit_function *jitFunction){
2847
jit_value_t param_1;
2850
assert(_this != NULL);
2851
assert(method != NULL);
2852
assert(inst != NULL);
2853
assert((inst->param_2).type == IRLABELITEM);
2855
PDEBUG("IRVIRTUALMACHINE: branch_if(Variable %lld, Label \"L%lld\")\n", (inst->param_1).value, (inst->param_2).value);
2856
label = insert_label(labels, (inst->param_2).value);
2857
assert(label != NULL);
2859
/* Make the condition of the branch */
2860
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2861
assert(param_1 != NULL);
2863
/* Generate the jump */
2864
jit_insn_branch_if(jitFunction->function , param_1, &(label->label));
2870
static inline JITINT16 translate_ir_gt (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
2871
jit_value_t param_1;
2872
jit_value_t param_2;
2877
assert(_this != NULL);
2878
assert(method != NULL);
2879
assert(inst != NULL);
2880
assert((inst->result).type == IROFFSET);
2882
/* Create the first parameter */
2883
PDEBUG("IRVIRTUALMACHINE: Variable %lld = gt(", (inst->result).value);
2884
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2886
assert(param_1 != NULL);
2888
/* Create the second parameter */
2889
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
2891
assert(param_2 != NULL);
2893
/* Create the gt instruction */
2894
temp = jit_insn_gt(jitFunction->function, param_1, param_2);
2895
temp2 = jit_insn_to_bool(jitFunction->function, temp);
2896
assert(temp2 != NULL);
2898
/* Store the result */
2899
if (jitFunction->locals[(inst->result).value] != NULL){
2900
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp2);
2902
jitFunction->locals[(inst->result).value] = temp2;
2904
assert(jitFunction->locals[(inst->result).value] != NULL);
2910
static inline JITINT16 translate_ir_not (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
2911
jit_value_t param_1;
2914
assert(_this != NULL);
2915
assert(method != NULL);
2916
assert(inst != NULL);
2917
assert((inst->result).type == IROFFSET);
2919
/* Create the first parameter */
2920
PDEBUG("IRVIRTUALMACHINE: Variable %lld = not (", (inst->result).value);
2921
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2922
assert(param_1 != NULL);
2925
/* Create the lt instruction */
2926
if (jitFunction->locals[(inst->result).value] != NULL){
2928
temp = jit_insn_not(jitFunction->function, param_1);
2929
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
2931
jitFunction->locals[(inst->result).value] = jit_insn_not(jitFunction->function, param_1);
2933
assert(jitFunction->locals[(inst->result).value] != NULL);
2939
static inline JITINT16 translate_ir_lt (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
2940
jit_value_t param_1;
2941
jit_value_t param_2;
2946
assert(method != NULL);
2947
assert(inst != NULL);
2948
assert((inst->result).type == IROFFSET);
2950
/* Create the first parameter */
2951
PDEBUG("IRVIRTUALMACHINE: Variable %lld = lt(", (inst->result).value);
2952
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
2954
assert(param_1 != NULL);
2956
/* Create the second parameter */
2957
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
2959
assert(param_2 != NULL);
2961
/* Create the lt instruction */
2962
temp = jit_insn_lt(jitFunction->function, param_1, param_2);
2963
temp2 = jit_insn_to_bool(jitFunction->function, temp);
2964
assert(temp2 != NULL);
2966
/* Store the result */
2967
if (jitFunction->locals[(inst->result).value] != NULL){
2968
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp2);
2970
jitFunction->locals[(inst->result).value] = temp2;
2972
assert(jitFunction->locals[(inst->result).value] != NULL);
2978
static inline JITINT16 translate_ir_store (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
2982
assert(method != NULL);
2983
assert(_this != NULL);
2984
assert(inst != NULL);
2985
assert((inst->param_1).type == IROFFSET);
2987
if ((inst->param_1).internal_type == IRVALUETYPE){
2988
assert( (inst->param_1).value_type_infos.type_infos != NULL
2989
|| (inst->param_1).value_type_infos.isByref != 0);
2992
PDEBUG("IRVIRTUALMACHINE: translate_ir_store: Start\n");
2994
/* Init the variables */
2997
/* Check the parameters */
2998
jitFunction->locals[(inst->param_1).value] = make_variable(_this, method, &(inst->param_1), jitFunction);
2999
assert(jitFunction->locals[(inst->param_1).value] != NULL);
3001
/* Create the second parameter */
3002
PDEBUG("IRVIRTUALMACHINE: store(Variable %lld, ", (inst->param_1).value);
3003
temp = make_variable(_this, method, &(inst->param_2), jitFunction);
3005
assert(temp != NULL);
3007
/* Create the store instruction */
3008
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->param_1).value], temp);
3010
PDEBUG("IRVIRTUALMACHINE: translate_ir_store: End\n");
3016
static inline JITINT16 translate_ir_rem (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
3017
jit_value_t param_1;
3018
jit_value_t param_2;
3021
assert(_this != NULL);
3022
assert(method != NULL);
3023
assert(inst != NULL);
3024
assert((inst->result).type == IROFFSET);
3025
PDEBUG("IRVIRTUALMACHINE: Variable %lld = rem(", (inst->result).value);
3027
/* Create the first parameter */
3028
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
3030
assert(param_1 != NULL);
3032
/* Create the second parameter */
3033
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
3035
assert(param_2 != NULL);
3037
/* Create the instruction */
3038
if (jitFunction->locals[(inst->result).value] != NULL){
3040
temp = jit_insn_rem (jitFunction->function, param_1, param_2);
3041
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
3043
jitFunction->locals[(inst->result).value] = jit_insn_rem (jitFunction->function, param_1, param_2);
3045
assert(jitFunction->locals[(inst->result).value] != NULL);
3051
JITINT16 fetch_parameters (ir_method_t *method, t_jit_function *jitFunction){
3055
assert(method != NULL);
3056
assert(jitFunction != NULL);
3058
if (method->getParametersNumber(method) == 0) return 0;
3059
assert(jitFunction->locals != NULL);
3061
PDEBUG("IRVIRTUALMACHINE: Fetch the parameters\n");
3062
for (count=0; count < method->getParametersNumber(method); count++) {
3063
PDEBUG("IRVIRTUALMACHINE: Parameter %d\n", count);
3064
jitFunction->locals[count] = jit_value_get_param(jitFunction->function, count);
3071
static inline JITINT16 translate_ir_add_ovf (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
3072
jit_value_t param_1;
3073
jit_value_t param_2;
3076
assert(method != NULL);
3077
assert(inst != NULL);
3078
assert((inst->result).type == IROFFSET);
3079
PDEBUG("IRVIRTUALMACHINE: Variable %lld = add_ovf(", (inst->result).value);
3081
/* Create the first parameter */
3082
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
3084
assert(param_1 != NULL);
3086
/* Create the second parameter */
3087
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
3089
assert(param_2 != NULL);
3091
/* Create the add_ovf instruction */
3092
if (jitFunction->locals[(inst->result).value] != NULL){
3094
temp = jit_insn_add_ovf (jitFunction->function, param_1, param_2);
3095
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
3097
jitFunction->locals[(inst->result).value] = jit_insn_add_ovf (jitFunction->function, param_1, param_2);
3099
assert(jitFunction->locals[(inst->result).value] != NULL);
3105
static inline JITINT16 translate_ir_sub_ovf (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
3106
jit_value_t param_1;
3107
jit_value_t param_2;
3110
assert(method != NULL);
3111
assert(inst != NULL);
3112
assert((inst->result).type == IROFFSET);
3113
PDEBUG("IRVIRTUALMACHINE: Variable %lld = sub_ovf(", (inst->result).value);
3115
/* Create the first parameter */
3116
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
3118
assert(param_1 != NULL);
3120
/* Create the second parameter */
3121
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
3123
assert(param_2 != NULL);
3125
/* Create the instruction */
3126
if (jitFunction->locals[(inst->result).value] != NULL){
3128
temp = jit_insn_sub_ovf (jitFunction->function, param_1, param_2);
3129
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
3131
jitFunction->locals[(inst->result).value] = jit_insn_sub_ovf (jitFunction->function, param_1, param_2);
3133
assert(jitFunction->locals[(inst->result).value] != NULL);
3139
static inline JITINT16 translate_ir_mul_ovf (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
3140
jit_value_t param_1;
3141
jit_value_t param_2;
3144
assert(method != NULL);
3145
assert(inst != NULL);
3146
assert((inst->result).type == IROFFSET);
3147
PDEBUG("IRVIRTUALMACHINE: Variable %lld = mul_ovf(", (inst->result).value);
3149
/* Create the first parameter */
3150
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
3152
assert(param_1 != NULL);
3154
/* Create the second parameter */
3155
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
3157
assert(param_2 != NULL);
3159
/* Create the instruction */
3160
if (jitFunction->locals[(inst->result).value] != NULL){
3162
temp = jit_insn_mul_ovf (jitFunction->function, param_1, param_2);
3163
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);
3165
jitFunction->locals[(inst->result).value] = jit_insn_mul_ovf (jitFunction->function, param_1, param_2);
3167
assert(jitFunction->locals[(inst->result).value] != NULL);
3173
static inline JITINT16 translate_ir_shl (IRVM_t *_this, ir_method_t *method, t_ir_instruction *inst, t_jit_function *jitFunction){
3174
jit_value_t param_1;
3175
jit_value_t param_2;
3178
assert(method != NULL);
3179
assert(inst != NULL);
3180
assert((inst->result).type == IROFFSET);
3181
PDEBUG("IRVIRTUALMACHINE: Variable %lld = shl(", (inst->result).value);
3183
/* Create the first parameter */
3184
param_1 = make_variable(_this, method, &(inst->param_1), jitFunction);
3186
assert(param_1 != NULL);
3188
/* Create the second parameter */
3189
param_2 = make_variable(_this, method, &(inst->param_2), jitFunction);
3191
assert(param_2 != NULL);
3193
/* Create the shl instruction */
3194
if (jitFunction->locals[(inst->result).value] != NULL){
3196
temp = jit_insn_shl (jitFunction->function, param_1, param_2);
3197
jit_insn_store(jitFunction->function, jitFunction->locals[(inst->result).value], temp);