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 .global dvmPlatformInvoke 59 .type dvmPlatformInvoke, @function 60 61 /* 62 * On entry: 63 * [ 8] arg0 JNIEnv (can be left alone) 64 * [12] arg1 clazz (NULL for virtual method calls, non-NULL for static) 65 * [16] arg2 arg info 66 * [20] arg3 argc 67 * [24] arg4 argv 68 * [28] arg5 short signature 69 * [32] arg6 func 70 * [36] arg7 pReturn 71 * 72 * For a virtual method call, the "this" reference is in argv[0]. 73 * 74 * argInfo (32-bit int) layout: 75 * SRRRZZZZ ZZZZZZZZ AAAAAAAA AAAAAAAA 76 * 77 * Z - reserved 78 * S - if set, argInfo hints are invalid 79 * R - return type enumeration (see jniInternal.h) 80 * VOID -> 0 81 * FLOAT -> 1 82 * DOUBLE -> 2 83 * S8 -> 3 84 * S4 -> 4 85 * A - size of the variable argument block in 32-bit words 86 * 87 */ 88 dvmPlatformInvoke: 89 /* Establish the frame pointer, spill & align to 16b */ 90 pushl %ebp 91 movl %esp,%ebp 92 pushl %edi 93 pushl %esi 94 pushl %ebx 95 subl $12,%esp 96 /* For 386 ABI, argInfo hints should always be valid. Abort if not. */ 97 movl 16(%ebp),%ebx 98 testl %ebx,%ebx 99 js dvmAbort 100 /* 101 * Get the size of the variable region, add two more slots for the first 102 * two arguments and grow (preserving alignment) 103 */ 104 movl %ebx,%ecx 105 leal 20(,%ecx,4),%ecx 106 andl $0x0003FFF0,%ecx 107 subl %ecx,%esp 108 /* Handle this/class */ 109 movl 8(%ebp),%ecx 110 movl 12(%ebp),%eax 111 movl 24(%ebp),%esi 112 testl %eax,%eax 113 jne isClass 114 movl (%esi),%eax 115 addl $4,%esi 116 isClass: 117 movl %eax,4(%esp) 118 movl %ecx,0(%esp) 119 /* Now, copy the variable arguments region */ 120 movl %ebx,%ecx 121 andl $0x0000FFFF,%ecx 122 leal 8(%esp),%edi 123 cld 124 rep 125 movsd 126 /* Ready to go - call the native code */ 127 call *32(%ebp) 128 /* Store the result. */ 129 sarl $28,%ebx 130 /* Is void? */ 131 testl %ebx,%ebx 132 je cleanUpAndExit 133 movl 36(%ebp),%ecx 134 /* Is FP? */ 135 cmpl $2,%ebx 136 jle isFP 137 cmpl $4,%ebx /* smaller than 32-bits? */ 138 jg isSmall 139 storeRetval: 140 /* Blindly storing 64-bits won't hurt 32-bit case */ 141 movl %eax,(%ecx) 142 movl %edx,4(%ecx) 143 jmp cleanUpAndExit 144 isSmall: 145 cmpl $7,%ebx /* S1? */ 146 jne checkShort 147 movsbl %al,%eax 148 movl %eax,(%ecx) 149 jmp cleanUpAndExit 150 checkShort: 151 cmpl $6,%ebx /* U2? */ 152 jne isSignedShort 153 movzwl %ax,%eax 154 movl %eax,(%ecx) 155 jmp cleanUpAndExit 156 isSignedShort: 157 /* Must be S2 */ 158 movswl %ax,%eax 159 movl %eax,(%ecx) 160 jmp cleanUpAndExit 161 isFP: 162 /* Is Float? */ 163 cmpl $1,%ebx 164 je saveFloat 165 fstpl (%ecx) 166 jmp cleanUpAndExit 167 saveFloat: 168 fstps (%ecx) 169 cleanUpAndExit: 170 leal -12(%ebp),%esp 171 pop %ebx 172 pop %esi 173 pop %edi 174 pop %ebp 175 ret 176 .size dvmPlatformInvoke, .-dvmPlatformInvoke 177 .section .note.GNU-stack,"",@progbits 178