invokenative_i386.s

来自「This is a resource based on j2me embedde」· S 代码 · 共 309 行

S
309
字号
/* * @(#)invokeNative_i386.S	1.12 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * 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 version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */#include "javavm/include/asmmacros_cpu.h"	.text	ENTRY(CVMjniInvokeNative) # This function translates the "Java" calling convention into the # C convention used in native methods. Java VM passes all the # arguments in the Java stack, and expects the results to be placed there # as well. We therefore have to copy the arguments into the C stack (or # registers), and place the return values back into the Java stack. # # With a small sacrifice in efficiency, this approach avoids having to # generate a stub function for every native method. # # The x86 passes all arguments on stack, and returns floating pointer # results in ST0, 32-bit results in eax, and 64-bit results in eax and # edx. # # The first argument to CVMjniInvokeNative is a pointer to the JNI # environment, which should be passed unmodified as the first argument # to the native method. # # The second argument is a pointer to the "real" native method function. # # The third argument (stk) is a pointer to the Java stack, where all # the arguments are stored (as stk[0], stk[1], etc.). # # The fourth argument is the "terse" signature of the native method, # which basically collapses all objects in the long signature into # one byte, since they're all treated the same.  This makes the parsing # in this routine simpler and faster.  See classload.c and classruntime.c # for details. # # The fifth argument is the total size (in 32-bit words) of the # arguments on the Java stack. Note that the Java stack does not have # any alignment requirement, and stores all arguments consecutively in # words and double words. The argument size includes the "this" pointer # for non-static methods. # # The sixth argument is 0 for non-static methods, or a jclass # for static methods. Non-static native methods receive an object # reference as the second argument (passed in the Java stack as # stk[0]). The "real" method arguments to non-static methods begin at # stk[1]. Static native methods receive a class reference as the second # argument. # # The return value of the native method is placed at stk[0] for # word-sized results, or at stk[0] and stk[1] for # double-word-sized results. The return value of CVMjniInvokeNative is # 0 if the native method returns void, 1 if the native # method returns a word, 2 if the native method returns a # double word, or -1 if the native method returns an object.# #define args_again \	# movb	%dl, %cl; \	# andl	$0xf, %ecx; \	# shrl	$4,%edx; \	# jmp	*arg_jumps(,%ecx,4)	 # _env$ = 8 ; JNI environment # _f$ = 12 ; native method function # _stk$ = 16 ; Java stack # _sig$ = 20 ; method signature # _sz$ = 24 ; total argument size # _cls$ = 28 ; class (if static) # _res$ = 32 ; result pointer	pushl	%ebp	movl	%esp, %ebp	pushl	%esi	pushl	%edi	pushl	%ebx	movl	16(%ebp), %esi	# stk	movl	24(%ebp), %edx	# sz	movl	28(%ebp), %ecx	# cls	cmpl	$0, %ecx	jne	static_call	movl	%esi, %ecx 	addl	$4, %esi 	jmp	static_donestatic_call: 	addl	$1, %edx static_done:	addl	$1, %edx	shll	$2, %edx	# word address -> byte address	# NOTE: At this point, %esp is %ebp + 3 pushl i.e. %ebp - 12.  We will	#       need to restore #esp to this value later after the call.	subl	%edx, %esp	# reserve stack space for JNI method args.        andl    $0xfffffff0, %esp # keep stack 16 byte aligned	movl	%esp, %edi	movl	8(%ebp), %eax	# copy env to outgoing args[0]	movl	%eax, (%edi)	addl	$4, %edi	movl	%ecx, (%edi)    # copy jclass or jobject to args[1]	addl	$4, %edi	movl	20(%ebp), %ebx	xorl	%ecx, %ecx	# zero it # ebx is current index into sig # cl (ecx) is current char in sig # esi is index into java stack # edx is (was) the # args, though we do not # need it anymore.args_loop:	movl	(%ebx),%edx	addl	$4,%ebx	shrl	$4,%edx  # shift over return syllable	# args_again 	movb	%dl, %cl;	andl	$0xf, %ecx;	shrl	$4,%edx;	jmp	*arg_jumps(,%ecx,4)arg_reload: # fetch more signature	movl	(%ebx),%edx	addl	$4,%ebx	# args_again	movb	%dl, %cl;	andl	$0xf, %ecx;	shrl	$4,%edx;	jmp	*arg_jumps(,%ecx,4)arg_32:	movl	(%esi), %eax	addl	$4, %esi	movl	%eax, (%edi)	addl	$4, %edi	# args_again 	movb	%dl, %cl;	andl	$0xf, %ecx;	shrl	$4,%edx;	jmp	*arg_jumps(,%ecx,4)arg_64:	movl	(%esi), %eax	addl	$4, %esi	movl	%eax, (%edi)	addl	$4, %edi	movl	(%esi), %eax	addl	$4, %esi	movl	%eax, (%edi)	addl	$4, %edi	# args_again 	movb	%dl, %cl;	andl	$0xf, %ecx;	shrl	$4,%edx;	jmp	*arg_jumps(,%ecx,4)arg_object:	movl	(%esi), %eax	cmpl	$0, %eax	je	object_checked	movl	%esi, %eaxobject_checked:	movl	%eax, (%edi)	addl	$4, %esi	addl	$4, %edi	# args_again 	movb	%dl, %cl;	andl	$0xf, %ecx;	shrl	$4,%edx;	jmp	*arg_jumps(,%ecx,4)args_done:	call	*12(%ebp)	# f	leal	-12(%ebp), %esp	# restore old stack pointer / pop arguments.				# works for both __stdcall and cdecl.		movl	32(%ebp), %esi	# res	xorl	%ecx, %ecx	# c register volatile cross calls - zero it	movl	20(%ebp), %ebx	# method signature	movb	(%ebx), %cl	andl	$0xf, %ecx	jmp	*ret_jumps(,%ecx,4)ret_obj:	movl	%eax, (%esi)	movl	$-1, %eax	jmp	doneret_f64:	fstpl	(%esi)	movl	$2, %eax	jmp	doneret_f32:	fstps	(%esi)	movl	$1, %eax	jmp	doneret_s32:	movl	%eax, (%esi)	movl	$1, %eax	jmp	doneret_s64:	movl	%eax, (%esi)	movl	$2, %eax	movl	%edx, 4(%esi)	jmp	doneret_s8:	shll	$24, %eax	sarl	$24, %eax	movl	%eax, (%esi)	movl	$1, %eax	jmp	doneret_u8:	shll	$24, %eax	shrl	$24, %eax	movl	%eax, (%esi)	movl	$1, %eax	jmp	doneret_s16:	shll	$16, %eax	sarl	$16, %eax	movl	%eax, (%esi)	movl	$1, %eax	jmp	doneret_u16:	shll	$16, %eax	shrl	$16, %eax	movl	%eax, (%esi)	movl	$1, %eax	jmp	doneret_void:	movl	$0, %eaxdone:	popl	%ebx	popl	%edi	popl	%esi	movl	%ebp, %esp	popl	%ebp	retret_jumps:			.long	ret_void	# this is invalid and should not get called	.long	ret_void	# ENDFUNC should not get called	.long	ret_void	# no void arguments	.long	ret_s32	# int	.long	ret_s16	# short	.long	ret_u16	# char	.long	ret_s64	# long	.long	ret_s8	# byte	.long	ret_f32	# float	.long	ret_f64	# double	.long	ret_u8	# bool	.long	ret_obj	.long	ret_void	# this is invalid and should not get calledarg_jumps:	.long	arg_reload	.long	args_done # end-of-args	.long	ret_void	# this is invalid and should not get called	.long	arg_32	# int	.long	arg_32	# short	.long	arg_32	# char	.long	arg_64	# long	.long	arg_32	# byte	.long	arg_32	# float	.long	arg_64	# double	.long	arg_32	# bool	.long	arg_object	.long	ret_void	# this is invalid and should not get called	.align	4	SET_SIZE(CVMjniInvokeNative)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?