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.
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); \
38 *sp = va_arg(args, u4); \
42 #define VA_DOUBLE_JEM(args, sp, fp_jem) do { \
44 *(u8*)sp = va_arg(args, u8); \
45 *(u8*)fp_jem = *(u8*)sp; \
48 #define VA_SINGLE_JEM(args, sp, fp_jem) do { \
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)); \
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)); \
70 *(uint32_t*)sp = va_arg(args, uint32_t); \
71 *(uint32_t*)fp_jem = *(uint32_t*)sp; \
77 #define JA_DOUBLE(args, sp) *(u8*)sp = *args++; sp+=2
80 #define JA_DOUBLE_JEM(args, sp, fp_jem) do { \
83 *(u8*)fp_jem = *(u8*)sp; \
88 #define JA_SINGLE(args, sp) \
90 case 'L': case '[': case 'F': \
91 *sp = *(uintptr_t*)args; \
94 *sp = *(signed char*)args; \
97 *sp = *(unsigned short*)args; \
100 *sp = *(signed short*)args; \
103 *sp = *(signed int*)args; \
109 #define JA_SINGLE_JEM(args, sp, fp_jem) do { \
113 *sp = *(uintptr_t*)args; \
114 if (*sp && (!JAM_ON_STACK || IS_JAM_OBJECT(*sp))) \
115 *fp_jem = (uint32_t)INST_DATA((Object*)(*sp)); \
120 *sp = *(uintptr_t*)args; \
121 if (*sp && (!JAM_ON_STACK || IS_JAM_ARRAY(*sp))) \
122 *fp_jem = (uint32_t)ARRAY_DATA((Object*)(*sp)); \
127 *sp = *(uintptr_t*)args; \
132 *sp = *(signed char*)args; \
136 *sp = *(unsigned short*)args; \
140 *sp = *(signed short*)args; \
144 *sp = *(signed int*)args; \
153 void *executeMethodArgs(Object
*ob
, Class
*class, MethodBlock
*mb
, ...) {
158 ret
= executeMethodVaList(ob
, class, mb
, jargs
);
164 void *executeMethodVaList(Object
*ob
, Class
*class, MethodBlock
*mb
, va_list jargs
)
166 char *sig
= mb
->type
;
167 ExecEnv
*ee
= getExecEnv();
171 uint32_t *fp_jem
= NULL
;
175 ret
= CREATE_TOP_FRAME(ee
, class, mb
, &sp
);
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 */
183 jam_dprintf("[%s] execute method (locals %d, args %d) %s type %s signature %s on obj %x\n",
184 __func__
, mb
->max_locals
, mb
->args_count
, mb
->name
, sig
, mb
->signature
, ob
);
185 if(mb
->max_locals
> 0)
186 fp_jem
= ee
->last_frame
->lvars_jem
;
191 *sp
++ = (uintptr_t) ob
; /* push receiver first */
193 if(!JAM_ON_STACK
|| IS_JAM_OBJECT(ob
))
194 *(--fp_jem
) = (uint32_t)INST_DATA(ob
);
196 *(--fp_jem
) = (uint32_t)ob
;
201 SCAN_SIG(sig
, VA_DOUBLE(jargs
, sp
), VA_SINGLE(jargs
, sp
));
204 SCAN_SIG(sig
, VA_DOUBLE_JEM(jargs
, sp
, fp_jem
), VA_SINGLE_JEM(jargs
, sp
, fp_jem
));
206 if (JAM_ON_STACK
&& ob
&& !IS_JAM_OBJECT(ob
))
207 ob
= JAM_OBJECT((uintptr_t *)ob
);
210 if(mb
->access_flags
& ACC_SYNCHRONIZED
)
211 objectLock(ob
? ob
: (Object
*)mb
->class);
213 if(mb
->access_flags
& ACC_NATIVE
) {
214 jam_dprintf("[%s] execute native method\n", __func__
);
215 (*(uintptr_t *(*)(Class
*, MethodBlock
*, uintptr_t*))mb
->native_invoker
)(class, mb
, ret
);
219 if(mb
->access_flags
& ACC_SYNCHRONIZED
)
220 objectUnlock(ob
? ob
: (Object
*)mb
->class);
226 * Since ret might be returnAddressType, here convert back to JAM
227 * objrefs/arrayrefs from JEM refs
229 if (*(uint32_t *)ret
)
230 switch (*(strchr(mb
->type
, ')') + 1)) {
232 *(uint32_t*)ret
= (uint32_t)JAM_OBJECT((uintptr_t *)*(uint32_t *)ret
);
235 *(uint32_t*)ret
= (uint32_t)JAM_ARRAY((uintptr_t *)*(uint32_t *)ret
);
238 jam_dprintf("[%s] %s: return 0x%x @ %p\n", __func__
, mb
->type
, *(uint32_t *)ret
, ret
);
243 void *executeMethodList(Object
*ob
, Class
*class, MethodBlock
*mb
, u8
*jargs
) {
244 char *sig
= mb
->type
;
246 ExecEnv
*ee
= getExecEnv();
253 ret
= CREATE_TOP_FRAME(ee
, class, mb
, &sp
);
257 /* copy args onto stack */
258 /* Do not touch the original stack frame,just allocate lvars_jem from the
259 * native heap and free it after finishing method execution */
261 jam_dprintf("[executeMethodList] execute method (args %d) %s\n", mb
->max_locals
, mb
->name
);
262 fp_jem
= ee
->last_frame
->lvars_jem
;
267 if(!JAM_ON_STACK
|| IS_JAM_OBJECT(ob
))
268 *(--fp_jem
) = (uint32_t)INST_DATA(ob
);
270 *(--fp_jem
) = (uint32_t)ob
;
272 *sp
++ = (uintptr_t) ob
; /* push receiver first */
275 SCAN_SIG(sig
, JA_DOUBLE_JEM(jargs
, sp
, fp_jem
), JA_SINGLE_JEM(jargs
, sp
, fp_jem
));
276 if (JAM_ON_STACK
&& ob
&& !IS_JAM_OBJECT(ob
))
277 ob
= JAM_OBJECT((uintptr_t *)ob
);
279 SCAN_SIG(sig
, JA_DOUBLE(jargs
, sp
), JA_SINGLE(jargs
, sp
));
281 if(mb
->access_flags
& ACC_SYNCHRONIZED
)
282 objectLock(ob
? ob
: (Object
*)mb
->class);
284 if(mb
->access_flags
& ACC_NATIVE
)
285 (*(uintptr_t *(*)(Class
*, MethodBlock
*, uintptr_t*))mb
->native_invoker
)(class, mb
, ret
);
289 if(mb
->access_flags
& ACC_SYNCHRONIZED
)
290 objectUnlock(ob
? ob
: (Object
*)mb
->class);
295 switch(*(strchr(mb
->type
,')')+1)){
297 *(uint32_t *)ret
= (uint32_t)JAM_OBJECT((uintptr_t *)*(uint32_t *)ret
);
300 *(uint32_t *)ret
= (uint32_t)JAM_ARRAY((uintptr_t *)*(uint32_t *)ret
);
303 jam_dprintf("[%s] return 0x%x\n", __func__
, *(uint32_t *)ret
);