1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16/* 17 * JNI method invocation. This is used to call a C/C++ JNI method. The 18 * argument list has to be pushed onto the native stack according to 19 * local calling conventions. 20 * 21 * This version supports 32-bit x86 22 */ 23 24/* 25Function prototype: 26 27void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo, int argc, 28 const u4* argv, const char* signature, void* func, JValue* pReturn) 29 30The method we are calling has the form: 31 32 return_type func(JNIEnv* pEnv, ClassObject* clazz, ...) 33 -or- 34 return_type func(JNIEnv* pEnv, Object* this, ...) 35 36We receive a collection of 32-bit values which correspond to arguments from 37the interpreter (e.g. float occupies one, double occupies two). It's up to 38us to convert these into local calling conventions. 39*/ 40 41/* 42x86 notes: 43 44The native code expects arguments on the stack, pushed from right to left. 45This matches what Dalvik is passing here. 46 47EAX, EDX and ECX are scratch. 48 494-byte alignment is required for long long and double, so we won't pad 50 51Non-FP return types <= 4 bytes come back in EAX 52Non-FP return types of 8 bytes come back in EAX:EDX, with lsw in EAX. 53Float and double returned on top of FP stack. 54 55*/ 56 57 .text 58 .align 4 59 .global dvmPlatformInvoke 60 .type dvmPlatformInvoke, @function 61 62/* 63 * On entry: 64 * [ 8] arg0 JNIEnv (can be left alone) 65 * [12] arg1 clazz (NULL for virtual method calls, non-NULL for static) 66 * [16] arg2 arg info 67 * [20] arg3 argc 68 * [24] arg4 argv 69 * [28] arg5 short signature 70 * [32] arg6 func 71 * [36] arg7 pReturn 72 * 73 * For a virtual method call, the "this" reference is in argv[0]. 74 * 75 * argInfo (32-bit int) layout: 76 * SRRRZZZZ ZZZZZZZZ AAAAAAAA AAAAAAAA 77 * 78 * Z - reserved 79 * S - if set, argInfo hints are invalid 80 * R - return type enumeration (see jniInternal.h) 81 * VOID -> 0 82 * FLOAT -> 1 83 * DOUBLE -> 2 84 * S8 -> 3 85 * S4 -> 4 86 * A - size of the variable argument block in 32-bit words 87 * 88 */ 89dvmPlatformInvoke: 90/* Establish the frame pointer, spill & align to 16b */ 91 pushl %ebp 92 movl %esp,%ebp 93 pushl %edi 94 pushl %esi 95 pushl %ebx 96 subl $12,%esp 97/* For 386 ABI, argInfo hints should always be valid. Abort if not. */ 98 movl 16(%ebp),%ebx 99 testl %ebx,%ebx 100 js dvmAbort 101/* 102 * Get the size of the variable region, add two more slots for the first 103 * two arguments and grow (preserving alignment) 104 */ 105 movl %ebx,%ecx 106 leal 20(,%ecx,4),%ecx 107 andl $0x0003FFF0,%ecx 108 subl %ecx,%esp 109/* Handle this/class */ 110 movl 8(%ebp),%ecx 111 movl 12(%ebp),%eax 112 movl 24(%ebp),%esi 113 testl %eax,%eax 114 jne isClass 115 movl (%esi),%eax 116 addl $4,%esi 117isClass: 118 movl %eax,4(%esp) 119 movl %ecx,0(%esp) 120/* Now, copy the variable arguments region */ 121 movl %ebx,%ecx 122 andl $0x0000FFFF,%ecx 123 leal 8(%esp),%edi 124 cld 125 rep 126 movsd 127/* Ready to go - call the native code */ 128 call *32(%ebp) 129/* Store the result. */ 130 sarl $28,%ebx 131 /* Is void? */ 132 testl %ebx,%ebx 133 je cleanUpAndExit 134 movl 36(%ebp),%ecx 135 /* Is FP? */ 136 cmpl $2,%ebx 137 jle isFP 138 cmpl $4,%ebx /* smaller than 32-bits? */ 139 jg isSmall 140storeRetval: 141 /* Blindly storing 64-bits won't hurt 32-bit case */ 142 movl %eax,(%ecx) 143 movl %edx,4(%ecx) 144 jmp cleanUpAndExit 145isSmall: 146 cmpl $7,%ebx /* S1? */ 147 jne checkShort 148 movsbl %al,%eax 149 movl %eax,(%ecx) 150 jmp cleanUpAndExit 151checkShort: 152 cmpl $6,%ebx /* U2? */ 153 jne isSignedShort 154 movzwl %ax,%eax 155 movl %eax,(%ecx) 156 jmp cleanUpAndExit 157isSignedShort: 158 /* Must be S2 */ 159 movswl %ax,%eax 160 movl %eax,(%ecx) 161 jmp cleanUpAndExit 162isFP: 163 /* Is Float? */ 164 cmpl $1,%ebx 165 je saveFloat 166 fstpl (%ecx) 167 jmp cleanUpAndExit 168saveFloat: 169 fstps (%ecx) 170cleanUpAndExit: 171 leal -12(%ebp),%esp 172 pop %ebx 173 pop %esi 174 pop %edi 175 pop %ebp 176 ret 177 .size dvmPlatformInvoke, .-dvmPlatformInvoke 178 .section .note.GNU-stack,"",@progbits 179