# # Copyright (C) 2003, 2004 Robert Lougher . # # This file is part of JamVM. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2, # or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # .text .align 2 .global callJNIMethod .type callJNIMethod,function callJNIMethod: mov ip, sp stmfd sp!, {r4, r5, ip, lr} mov r4, ip mov r5, r3 @ save native_arg ldr ip, [r4] @ get ostack pntr ldr r2, [r4, #8] @ get args_count cmp r1, #0 @ is method static? ldreq r1, [ip], #4 @ no, load r0 with "this" addne r2, r2, #1 @ yes, add 1 to cnt for "class" subs r2, r2, #3 @ no. of args fit in registers? ble do_call @ yes, skip stack push add lr, ip, #4 @ loop pushing extra args from ostack @ onto native stack. @ lr = ostack pntr, r2 = loop counter loop: ldr r3, [lr, r2, lsl #2] str r3, [sp, #-4]! subs r2, r2, #1 bne loop do_call: @ load last two registers in calling @ convention. Doesn't matter if args < 4, @ faster than checking and safe to load rubbish ldr r2, [ip] ldr r3, [ip, #4] mov lr, pc ldr pc, [r4, #4] @ call the function... @ reload ostack pntr for pushing return value ldr r2, [r4] @ native_arg holds return type (set in nativeExtraArg) @ 0 = void, 1 = double, 2 = float, 3 = long @ 4 = everything else @ values arranged so that if it's >= 3, it's "int" or @ long, so push low word - r0 is now free so we can @ put opntr into it, for all types cmp r5, #3 strge r0, [r2], #4 mov r0, r2 @ optimise for most often case of "int" return - all others @ jump to 2 instruction "handler", but this falls through addle pc, pc, r5, lsl #3 @ room for one instruction here - enough to just return, all @ we need, as everything's been done above ldmdb r4, {r4, r5, sp, pc} @ void return ldmdb r4, {r4, r5, sp, pc} nop @ double return nop nop @ float return nop nop @long return str r1, [r0], #4 ldmdb r4, {r4, r5, sp, pc}