• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    .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 */
88dvmPlatformInvoke:
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/* Get the size of the variable region and grow (preserving alignment) */
101    movl     %ebx,%ecx
102    leal     12(,%ecx,4),%ecx
103    andl     $0x0003FFF0,%ecx
104    subl     %ecx,%esp
105/* Handle this/class */
106    movl     8(%ebp),%ecx
107    movl     12(%ebp),%eax
108    movl     24(%ebp),%esi
109    testl    %eax,%eax
110    jne      isClass
111    movl     (%esi),%eax
112    addl     $4,%esi
113isClass:
114    pushl    %eax
115    pushl    %ecx
116/* Now, copy the variable arguments region */
117    movl     %ebx,%ecx
118    andl     $0x0000FFFF,%ecx
119    leal     8(%esp),%edi
120    cld
121    rep
122    movsd
123/* Ready to go - call the native code */
124    call     *32(%ebp)
125/* Store the result. */
126    sarl      $28,%ebx
127    /* Is void? */
128    testl     %ebx,%ebx
129    je       cleanUpAndExit
130    movl     36(%ebp),%ecx
131    /* Is FP? */
132    cmpl     $2,%ebx
133    jle      isFP
134    cmpl     $4,%ebx  /* smaller than 32-bits? */
135    jg       isSmall
136storeRetval:
137    /* Blindly storing 64-bits won't hurt 32-bit case */
138    movl     %eax,(%ecx)
139    movl     %edx,4(%ecx)
140    jmp      cleanUpAndExit
141isSmall:
142    cmpl     $7,%ebx  /* S1? */
143    jne      checkShort
144    movsbl   %al,%eax
145    movl     %eax,(%ecx)
146    jmp      cleanUpAndExit
147checkShort:
148    cmpl     $6,%ebx  /* U2? */
149    jne      isSignedShort
150    movzwl   %ax,%eax
151    movl     %eax,(%ecx)
152    jmp      cleanUpAndExit
153isSignedShort:
154    /* Must be S2 */
155    movswl   %ax,%eax
156    movl     %eax,(%ecx)
157    jmp      cleanUpAndExit
158isFP:
159    /* Is Float? */
160    cmpl    $1,%ebx
161    je       saveFloat
162    fstpl    (%ecx)
163    jmp      cleanUpAndExit
164saveFloat:
165    fstps    (%ecx)
166cleanUpAndExit:
167    leal     -12(%ebp),%esp
168    pop      %ebx
169    pop      %esi
170    pop      %edi
171    pop      %ebp
172    ret
173    .size    dvmPlatformInvoke, .-dvmPlatformInvoke
174    .section .note.GNU-stack,"",@progbits
175