1 #ifndef __MONO_MINI_INTERPRETER_INTERNALS_H__
2 #define __MONO_MINI_INTERPRETER_INTERNALS_H__
3 
4 #include <setjmp.h>
5 #include <glib.h>
6 #include <mono/metadata/loader.h>
7 #include <mono/metadata/object.h>
8 #include <mono/metadata/domain-internals.h>
9 #include <mono/metadata/class-internals.h>
10 #include <mono/metadata/debug-internals.h>
11 #include "config.h"
12 #include "interp.h"
13 
14 #define MINT_TYPE_I1 0
15 #define MINT_TYPE_U1 1
16 #define MINT_TYPE_I2 2
17 #define MINT_TYPE_U2 3
18 #define MINT_TYPE_I4 4
19 #define MINT_TYPE_I8 5
20 #define MINT_TYPE_R4 6
21 #define MINT_TYPE_R8 7
22 #define MINT_TYPE_O  8
23 #define MINT_TYPE_P  9
24 #define MINT_TYPE_VT 10
25 
26 #define BOX_NOT_CLEAR_VT_SP 0x4000
27 
28 
29 enum {
30 	VAL_I32     = 0,
31 	VAL_DOUBLE  = 1,
32 	VAL_I64     = 2,
33 	VAL_VALUET  = 3,
34 	VAL_POINTER = 4,
35 	VAL_NATI    = 0 + VAL_POINTER,
36 	VAL_MP      = 1 + VAL_POINTER,
37 	VAL_TP      = 2 + VAL_POINTER,
38 	VAL_OBJ     = 3 + VAL_POINTER
39 };
40 
41 #if SIZEOF_VOID_P == 4
42 typedef guint32 mono_u;
43 typedef gint32  mono_i;
44 #elif SIZEOF_VOID_P == 8
45 typedef guint64 mono_u;
46 typedef gint64  mono_i;
47 #endif
48 
49 /*
50  * Value types are represented on the eval stack as pointers to the
51  * actual storage. The size field tells how much storage is allocated.
52  * A value type can't be larger than 16 MB.
53  */
54 typedef struct {
55 	union {
56 		gint32 i;
57 		gint64 l;
58 		struct {
59 			gint32 lo;
60 			gint32 hi;
61 		} pair;
62 		double f;
63 		/* native size integer and pointer types */
64 		gpointer p;
65 		mono_u nati;
66 		gpointer vt;
67 	} data;
68 #if defined(__ppc__) || defined(__powerpc__)
69 	int pad;
70 #endif
71 } stackval;
72 
73 typedef struct _InterpFrame InterpFrame;
74 
75 typedef void (*MonoFuncV) (void);
76 typedef void (*MonoPIFunc) (MonoFuncV callme, void *margs);
77 
78 /*
79  * Structure representing a method transformed for the interpreter
80  * This is domain specific
81  */
82 typedef struct _InterpMethod
83 {
84 	/* NOTE: These first two elements (method and
85 	   next_jit_code_hash) must be in the same order and at the
86 	   same offset as in MonoJitInfo, because of the jit_code_hash
87 	   internal hash table in MonoDomain. */
88 	MonoMethod *method;
89 	struct _InterpMethod *next_jit_code_hash;
90 	guint32 locals_size;
91 	guint32 args_size;
92 	guint32 stack_size;
93 	guint32 vt_stack_size;
94 	guint32 alloca_size;
95 	unsigned int init_locals : 1;
96 	unsigned short *code;
97 	unsigned short *new_body_start; /* after all STINARG instrs */
98 	MonoPIFunc func;
99 	int num_clauses;
100 	MonoExceptionClause *clauses;
101 	void **data_items;
102 	int transformed;
103 	guint32 *arg_offsets;
104 	guint32 *local_offsets;
105 	guint32 *exvar_offsets;
106 	unsigned int param_count;
107 	unsigned int hasthis;
108 	gpointer jit_wrapper;
109 	gpointer jit_addr;
110 	MonoMethodSignature *jit_sig;
111 	gpointer jit_entry;
112 	MonoType *rtype;
113 	MonoType **param_types;
114 	MonoJitInfo *jinfo;
115 	MonoDomain *domain;
116 	MonoProfilerCallInstrumentationFlags prof_flags;
117 } InterpMethod;
118 
119 struct _InterpFrame {
120 	InterpFrame *parent; /* parent */
121 	InterpMethod  *imethod; /* parent */
122 	MonoMethod     *method; /* parent */
123 	stackval       *retval; /* parent */
124 	char           *args;
125 	stackval       *stack_args; /* parent */
126 	stackval       *stack;
127 	stackval       *sp; /* For GC stack marking */
128 	unsigned char  *locals;
129 	/* exception info */
130 	unsigned char  invoke_trap;
131 	const unsigned short  *ip;
132 	MonoException     *ex;
133 	MonoExceptionClause *ex_handler;
134 	MonoDomain *domain;
135 };
136 
137 typedef struct {
138 	MonoDomain *original_domain;
139 	InterpFrame *current_frame;
140 	unsigned char search_for_handler;
141 
142 	/* Resume state for resuming execution in mixed mode */
143 	gboolean       has_resume_state;
144 	/* Frame to resume execution at */
145 	InterpFrame *handler_frame;
146 	/* IP to resume execution at */
147 	gpointer handler_ip;
148 } ThreadContext;
149 
150 extern int mono_interp_traceopt;
151 extern GSList *jit_classes;
152 
153 MonoException *
154 mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context, InterpFrame *frame);
155 
156 void
157 mono_interp_transform_init (void);
158 
159 InterpMethod *
160 mono_interp_get_imethod (MonoDomain *domain, MonoMethod *method, MonoError *error);
161 
162 static inline int
mint_type(MonoType * type_)163 mint_type(MonoType *type_)
164 {
165 	MonoType *type = mini_native_type_replace_type (type_);
166 	if (type->byref)
167 		return MINT_TYPE_P;
168 enum_type:
169 	switch (type->type) {
170 	case MONO_TYPE_I1:
171 		return MINT_TYPE_I1;
172 	case MONO_TYPE_U1:
173 	case MONO_TYPE_BOOLEAN:
174 		return MINT_TYPE_U1;
175 	case MONO_TYPE_I2:
176 		return MINT_TYPE_I2;
177 	case MONO_TYPE_U2:
178 	case MONO_TYPE_CHAR:
179 		return MINT_TYPE_U2;
180 	case MONO_TYPE_I4:
181 	case MONO_TYPE_U4:
182 		return MINT_TYPE_I4;
183 	case MONO_TYPE_I:
184 	case MONO_TYPE_U:
185 #if SIZEOF_VOID_P == 4
186 		return MINT_TYPE_I4;
187 #else
188 		return MINT_TYPE_I8;
189 #endif
190 	case MONO_TYPE_PTR:
191 		return MINT_TYPE_P;
192 	case MONO_TYPE_R4:
193 		return MINT_TYPE_R4;
194 	case MONO_TYPE_I8:
195 	case MONO_TYPE_U8:
196 		return MINT_TYPE_I8;
197 	case MONO_TYPE_R8:
198 		return MINT_TYPE_R8;
199 	case MONO_TYPE_STRING:
200 	case MONO_TYPE_SZARRAY:
201 	case MONO_TYPE_CLASS:
202 	case MONO_TYPE_OBJECT:
203 	case MONO_TYPE_ARRAY:
204 		return MINT_TYPE_O;
205 	case MONO_TYPE_VALUETYPE:
206 		if (type->data.klass->enumtype) {
207 			type = mono_class_enum_basetype (type->data.klass);
208 			goto enum_type;
209 		} else
210 			return MINT_TYPE_VT;
211 	case MONO_TYPE_TYPEDBYREF:
212 		return MINT_TYPE_VT;
213 	case MONO_TYPE_GENERICINST:
214 		type = &type->data.generic_class->container_class->byval_arg;
215 		goto enum_type;
216 	default:
217 		g_warning ("got type 0x%02x", type->type);
218 		g_assert_not_reached ();
219 	}
220 	return -1;
221 }
222 
223 #endif /* __MONO_MINI_INTERPRETER_INTERNALS_H__ */
224