Some formatting unifications.
[jamvm-avr32-jem.git] / src / execute.c
blob99362b3ca8fddb2f65a9851c2ab1c63acfcfbc6d
1 /*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007
3 * Robert Lougher <rob@lougher.org.uk>.
5 * This file is part of JamVM.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include <stdio.h>
23 #include <string.h>
24 #include "jam.h"
25 #include "sig.h"
26 #include "frame.h"
27 #include "lock.h"
28 #include "arch/avr32_jem.h"
30 #define VA_DOUBLE(args, sp) *(u8*)sp = va_arg(args, u8); sp+=2
32 #define VA_SINGLE(args, sp) \
33 if(*sig == 'L' || *sig == '[') \
34 *sp = va_arg(args, uintptr_t); \
35 else if(*sig == 'F') \
36 *(u4*)sp = va_arg(args, u4); \
37 else \
38 *sp = va_arg(args, u4); \
39 sp++
41 #ifdef JEM
42 #define VA_DOUBLE_JEM(args, sp, fp_jem) do { \
43 fp_jem -= 2; \
44 *(u8*)sp = va_arg(args, u8); \
45 *(u8*)fp_jem = *(u8*)sp; \
46 } while (0)
48 #define VA_SINGLE_JEM(args, sp, fp_jem) do { \
49 fp_jem--; \
50 switch (*sig) { \
51 case 'L': \
52 *sp = va_arg(args, uintptr_t); \
53 if (*sp && (!JAM_ON_STACK || IS_JAM_OBJECT(*sp))) \
54 /* If this is an object, we have to calculate a */ \
55 /* pointer to its data for JEM */ \
56 *fp_jem = (uint32_t)INST_DATA((Object*)(*sp)); \
57 else \
58 *fp_jem = *sp; \
59 break; \
60 case '[': \
61 *sp = va_arg(args, uintptr_t); \
62 if (*sp && (!JAM_ON_STACK || IS_JAM_ARRAY(*sp))) \
63 /* Array - similar to object above */ \
64 *fp_jem = (uint32_t)ARRAY_DATA((Object*)(*sp)); \
65 else \
66 *fp_jem = *sp; \
67 break; \
68 case 'F': \
69 default: \
70 *(uint32_t*)sp = va_arg(args, uint32_t); \
71 *(uint32_t*)fp_jem = *(uint32_t*)sp; \
72 break; \
73 } \
74 } while (0)
75 #endif
77 #define JA_DOUBLE(args, sp) *(u8*)sp = *args++; sp+=2
79 #ifdef JEM
80 #define JA_DOUBLE_JEM(args, sp, fp_jem) do { \
81 fp_jem -= 2; \
82 *(u8*)sp = *args++; \
83 *(u8*)fp_jem = *(u8*)sp; \
84 sp += 2; \
85 } while (0)
86 #endif
88 #define JA_SINGLE(args, sp) \
89 switch(*sig) { \
90 case 'L': case '[': case 'F': \
91 *sp = *(uintptr_t*)args; \
92 break; \
93 case 'B': case 'Z': \
94 *sp = *(signed char*)args; \
95 break; \
96 case 'C': \
97 *sp = *(unsigned short*)args; \
98 break; \
99 case 'S': \
100 *sp = *(signed short*)args; \
101 break; \
102 case 'I': \
103 *sp = *(signed int*)args; \
104 break; \
106 sp++; args++
108 #ifdef JEM
109 #define JA_SINGLE_JEM(args, sp, fp_jem) do { \
110 fp_jem--; \
111 switch (*sig) { \
112 case 'L': \
113 *sp = *(uintptr_t*)args; \
114 if (*sp && (!JAM_ON_STACK || IS_JAM_OBJECT(*sp))) \
115 *fp_jem = (uint32_t)INST_DATA((Object*)(*sp)); \
116 else \
117 *fp_jem = *sp; \
118 break; \
119 case '[': \
120 *sp = *(uintptr_t*)args; \
121 if (*sp && (!JAM_ON_STACK || IS_JAM_ARRAY(*sp))) \
122 *fp_jem = (uint32_t)ARRAY_DATA((Object*)(*sp)); \
123 else \
124 *fp_jem = *sp; \
125 break; \
126 case 'F': \
127 *sp = *(uintptr_t*)args; \
128 *fp_jem = *sp; \
129 break; \
130 case 'B': \
131 case 'Z': \
132 *sp = *(signed char*)args; \
133 *fp_jem = *sp; \
134 break; \
135 case 'C': \
136 *sp = *(unsigned short*)args; \
137 *fp_jem = *sp; \
138 break; \
139 case 'S': \
140 *sp = *(signed short*)args; \
141 *fp_jem = *sp; \
142 break; \
143 case 'I': \
144 *sp = *(signed int*)args; \
145 *fp_jem = *sp; \
146 break; \
148 sp++; \
149 args++; \
150 } while (0)
151 #endif
153 void *executeMethodArgs(Object *ob, Class *class, MethodBlock *mb, ...) {
154 va_list jargs;
155 void *ret;
157 va_start(jargs, mb);
158 ret = executeMethodVaList(ob, class, mb, jargs);
159 va_end(jargs);
161 return ret;
164 void *executeMethodVaList(Object *ob, Class *class, MethodBlock *mb, va_list jargs)
166 char *sig = mb->type;
167 ExecEnv *ee = getExecEnv();
168 uintptr_t *sp;
169 uintptr_t tmp[2];
170 #ifdef JEM
171 uint32_t *fp_jem = NULL;
172 #endif
173 void *ret;
175 ret = CREATE_TOP_FRAME(ee, class, mb, &sp);
176 if (!ret)
177 return ret;
179 /* copy args onto stack */
180 /* Do not touch the original stack frame,just allocate lvars_jem from the
181 * native heap and free it after finishing method execution */
182 #ifdef JEM
183 jam_dprintf("[%s] execute method (args %d) %s on obj %x\n", __func__, mb->max_locals, mb->name, ob);
184 if(mb->max_locals > 0)
185 fp_jem = ee->last_frame->lvars_jem;
186 #endif
188 if (ob) {
189 #ifdef JEM
190 if(!JAM_ON_STACK || IS_JAM_OBJECT(ob))
191 *(--fp_jem) = (uint32_t)INST_DATA(ob);
192 else
193 *(--fp_jem) = (uint32_t)ob;
194 #endif
197 #ifndef JEM
198 SCAN_SIG(sig, VA_DOUBLE(jargs, sp), VA_SINGLE(jargs, sp));
199 #else
200 sp = tmp;
201 SCAN_SIG(sig, VA_DOUBLE_JEM(jargs, sp, fp_jem), VA_SINGLE_JEM(jargs, sp, fp_jem));
203 if (JAM_ON_STACK && ob && !IS_JAM_OBJECT(ob))
204 ob = JAM_OBJECT((uintptr_t *)ob);
205 #endif
207 if(mb->access_flags & ACC_SYNCHRONIZED)
208 objectLock(ob ? ob : (Object*)mb->class);
210 if(mb->access_flags & ACC_NATIVE) {
211 jam_dprintf("[%s] execute native method\n", __func__);
212 (*(uintptr_t *(*)(Class*, MethodBlock*, uintptr_t*))mb->native_invoker)(class, mb, ret);
213 } else
214 executeJava();
216 if(mb->access_flags & ACC_SYNCHRONIZED)
217 objectUnlock(ob ? ob : (Object*)mb->class);
219 POP_TOP_FRAME(ee);
220 #ifdef JEM
223 * Since ret might be returnAddressType, here convert back to JAM
224 * objrefs/arrayrefs from JEM refs
226 if (*(uint32_t *)ret)
227 switch (*(strchr(mb->type, ')') + 1)) {
228 case 'L':
229 *(uint32_t*)ret = (uint32_t)JAM_OBJECT((uintptr_t *)*(uint32_t *)ret);
230 break;
231 case '[':
232 *(uint32_t*)ret = (uint32_t)JAM_ARRAY((uintptr_t *)*(uint32_t *)ret);
233 break;
235 jam_dprintf("[%s] %s: return 0x%x @ %p\n", __func__, mb->type, *(uint32_t *)ret, ret);
236 #endif
237 return ret;
240 void *executeMethodList(Object *ob, Class *class, MethodBlock *mb, u8 *jargs) {
241 char *sig = mb->type;
243 ExecEnv *ee = getExecEnv();
244 uintptr_t *sp;
245 void *ret;
246 #ifdef JEM
247 uintptr_t *fp_jem;
248 #endif
250 ret = CREATE_TOP_FRAME(ee, class, mb, &sp);
251 if (!ret)
252 return ret;
254 /* copy args onto stack */
255 /* Do not touch the original stack frame,just allocate lvars_jem from the
256 * native heap and free it after finishing method execution */
257 #ifdef JEM
258 jam_dprintf("[executeMethodList] execute method (args %d) %s\n", mb->max_locals, mb->name);
259 fp_jem = ee->last_frame->lvars_jem;
260 #endif
262 if(ob){
263 #ifdef JEM
264 if(!JAM_ON_STACK || IS_JAM_OBJECT(ob))
265 *(--fp_jem) = (uint32_t)INST_DATA(ob);
266 else
267 *(--fp_jem) = (uint32_t)ob;
268 #endif
269 *sp++ = (uintptr_t) ob; /* push receiver first */
271 #ifdef JEM
272 SCAN_SIG(sig, JA_DOUBLE_JEM(jargs, sp, fp_jem), JA_SINGLE_JEM(jargs, sp, fp_jem));
273 if (JAM_ON_STACK && ob && !IS_JAM_OBJECT(ob))
274 ob = JAM_OBJECT((uintptr_t *)ob);
275 #else
276 SCAN_SIG(sig, JA_DOUBLE(jargs, sp), JA_SINGLE(jargs, sp));
277 #endif
278 if(mb->access_flags & ACC_SYNCHRONIZED)
279 objectLock(ob ? ob : (Object*)mb->class);
281 if(mb->access_flags & ACC_NATIVE)
282 (*(uintptr_t *(*)(Class*, MethodBlock*, uintptr_t*))mb->native_invoker)(class, mb, ret);
283 else
284 executeJava();
286 if(mb->access_flags & ACC_SYNCHRONIZED)
287 objectUnlock(ob ? ob : (Object*)mb->class);
289 POP_TOP_FRAME(ee);
291 #ifdef JEM
292 switch(*(strchr(mb->type,')')+1)){
293 case 'L':
294 *(uint32_t *)ret = (uint32_t)JAM_OBJECT((uintptr_t *)*(uint32_t *)ret);
295 break;
296 case '[':
297 *(uint32_t *)ret = (uint32_t)JAM_ARRAY((uintptr_t *)*(uint32_t *)ret);
298 break;
300 jam_dprintf("[%s] return 0x%x\n", __func__, *(uint32_t *)ret);
301 #endif
303 return ret;