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 /* 25 Function prototype: 26 27 void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo, int argc, 28 const u4* argv, const char* signature, void* func, JValue* pReturn) 29 30 The 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 36 We receive a collection of 32-bit values which correspond to arguments from 37 the interpreter (e.g. float occupies one, double occupies two). It's up to 38 us to convert these into local calling conventions. 39 */ 40 41 /* 42 x86 notes: 43 44 The native code expects arguments on the stack, pushed from right to left. 45 This matches what Dalvik is passing here. 46 47 EAX, EDX and ECX are scratch. 48 49 4-byte alignment is required for long long and double, so we won't pad 50 51 Non-FP return types <= 4 bytes come back in EAX 52 Non-FP return types of 8 bytes come back in EAX:EDX, with lsw in EAX. 53 Float 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 */ 89 dvmPlatformInvoke: 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 117 isClass: 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 140 storeRetval: 141 /* Blindly storing 64-bits won't hurt 32-bit case */ 142 movl %eax,(%ecx) 143 movl %edx,4(%ecx) 144 jmp cleanUpAndExit 145 isSmall: 146 cmpl $7,%ebx /* S1? */ 147 jne checkShort 148 movsbl %al,%eax 149 movl %eax,(%ecx) 150 jmp cleanUpAndExit 151 checkShort: 152 cmpl $6,%ebx /* U2? */ 153 jne isSignedShort 154 movzwl %ax,%eax 155 movl %eax,(%ecx) 156 jmp cleanUpAndExit 157 isSignedShort: 158 /* Must be S2 */ 159 movswl %ax,%eax 160 movl %eax,(%ecx) 161 jmp cleanUpAndExit 162 isFP: 163 /* Is Float? */ 164 cmpl $1,%ebx 165 je saveFloat 166 fstpl (%ecx) 167 jmp cleanUpAndExit 168 saveFloat: 169 fstps (%ecx) 170 cleanUpAndExit: 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