⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffi.c

📁 gcc的组建
💻 C
📖 第 1 页 / 共 2 页
字号:
      case FFI_TYPE_SINT32:      case FFI_TYPE_UINT16:      case FFI_TYPE_SINT16:      case FFI_TYPE_UINT8:      case FFI_TYPE_SINT8:	/* These are to be extended to word size.  */#ifdef __s390x__	cif->flags = FFI390_RET_INT64;#else	cif->flags = FFI390_RET_INT32;#endif	break;       default:        FFI_ASSERT (0);        break;    }  /* Now for the arguments.  */   for (ptr = cif->arg_types, i = cif->nargs;       i > 0;       i--, ptr++)    {      int type = (*ptr)->type;      /* Check how a structure type is passed.  */      if (type == FFI_TYPE_STRUCT)	{	  type = ffi_check_struct_type (*ptr);	  /* If we pass the struct via pointer, we must reserve space	     to copy its data for proper call-by-value semantics.  */	  if (type == FFI_TYPE_POINTER)	    struct_size += ROUND_SIZE ((*ptr)->size);	}      /* Now handle all primitive int/float data types.  */      switch (type) 	{	  /* The first MAX_FPRARGS floating point arguments	     go in FPRs, the rest overflow to the stack.  */	  case FFI_TYPE_DOUBLE:	    if (n_fpr < MAX_FPRARGS)	      n_fpr++;	    else	      n_ov += sizeof (double) / sizeof (long);	    break;		  case FFI_TYPE_FLOAT:	    if (n_fpr < MAX_FPRARGS)	      n_fpr++;	    else	      n_ov++;	    break;	  /* On 31-bit machines, 64-bit integers are passed in GPR pairs,	     if one is still available, or else on the stack.  If only one	     register is free, skip the register (it won't be used for any 	     subsequent argument either).  */	      #ifndef __s390x__	  case FFI_TYPE_UINT64:	  case FFI_TYPE_SINT64:	    if (n_gpr == MAX_GPRARGS-1)	      n_gpr = MAX_GPRARGS;	    if (n_gpr < MAX_GPRARGS)	      n_gpr += 2;	    else	      n_ov += 2;	    break;#endif	  /* Everything else is passed in GPRs (until MAX_GPRARGS	     have been used) or overflows to the stack.  */	  default: 	    if (n_gpr < MAX_GPRARGS)	      n_gpr++;	    else	      n_ov++;	    break;        }    }  /* Total stack space as required for overflow arguments     and temporary structure copies.  */  cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;   return FFI_OK;} /*======================== End of Routine ============================*/ /*====================================================================*//*                                                                    *//* Name     - ffi_call.                                               *//*                                                                    *//* Function - Call the FFI routine.                                   *//*                                                                    *//*====================================================================*/ voidffi_call(ffi_cif *cif,	 void (*fn)(),	 void *rvalue,	 void **avalue){  int ret_type = cif->flags;  extended_cif ecif;   ecif.cif    = cif;  ecif.avalue = avalue;  ecif.rvalue = rvalue;  /* If we don't have a return value, we need to fake one.  */  if (rvalue == NULL)    {      if (ret_type == FFI390_RET_STRUCT)	ecif.rvalue = alloca (cif->rtype->size);      else	ret_type = FFI390_RET_VOID;    }   switch (cif->abi)    {      case FFI_SYSV:        ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,		       ret_type, ecif.rvalue, fn);        break;       default:        FFI_ASSERT (0);        break;    }} /*======================== End of Routine ============================*//*====================================================================*//*                                                                    *//* Name     - ffi_closure_helper_SYSV.                                *//*                                                                    *//* Function - Call a FFI closure target function.                     *//*                                                                    *//*====================================================================*/ voidffi_closure_helper_SYSV (ffi_closure *closure,			 unsigned long *p_gpr,			 unsigned long long *p_fpr,			 unsigned long *p_ov){  unsigned long long ret_buffer;  void *rvalue = &ret_buffer;  void **avalue;  void **p_arg;  int n_gpr = 0;  int n_fpr = 0;  int n_ov = 0;  ffi_type **ptr;  int i;  /* Allocate buffer for argument list pointers.  */  p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));  /* If we returning a structure, pass the structure address      directly to the target function.  Otherwise, have the target      function store the return value to the GPR save area.  */  if (closure->cif->flags == FFI390_RET_STRUCT)    rvalue = (void *) p_gpr[n_gpr++];  /* Now for the arguments.  */  for (ptr = closure->cif->arg_types, i = closure->cif->nargs;       i > 0;       i--, p_arg++, ptr++)    {      int deref_struct_pointer = 0;      int type = (*ptr)->type;      /* Check how a structure type is passed.  */      if (type == FFI_TYPE_STRUCT)	{	  type = ffi_check_struct_type (*ptr);	  /* If we pass the struct via pointer, remember to 	     retrieve the pointer later.  */	  if (type == FFI_TYPE_POINTER)	    deref_struct_pointer = 1;	}      /* Pointers are passed like UINTs of the same size.  */      if (type == FFI_TYPE_POINTER)#ifdef __s390x__	type = FFI_TYPE_UINT64;#else	type = FFI_TYPE_UINT32;#endif      /* Now handle all primitive int/float data types.  */      switch (type) 	{	  case FFI_TYPE_DOUBLE:	    if (n_fpr < MAX_FPRARGS)	      *p_arg = &p_fpr[n_fpr++];	    else	      *p_arg = &p_ov[n_ov], 	      n_ov += sizeof (double) / sizeof (long);	    break;		  case FFI_TYPE_FLOAT:	    if (n_fpr < MAX_FPRARGS)	      *p_arg = &p_fpr[n_fpr++];	    else	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;	    break; 	  case FFI_TYPE_UINT64:	  case FFI_TYPE_SINT64:#ifdef __s390x__	    if (n_gpr < MAX_GPRARGS)	      *p_arg = &p_gpr[n_gpr++];	    else	      *p_arg = &p_ov[n_ov++];#else	    if (n_gpr == MAX_GPRARGS-1)	      n_gpr = MAX_GPRARGS;	    if (n_gpr < MAX_GPRARGS)	      *p_arg = &p_gpr[n_gpr], n_gpr += 2;	    else	      *p_arg = &p_ov[n_ov], n_ov += 2;#endif	    break; 	  case FFI_TYPE_INT:	  case FFI_TYPE_UINT32:	  case FFI_TYPE_SINT32:	    if (n_gpr < MAX_GPRARGS)	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;	    else	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;	    break; 	  case FFI_TYPE_UINT16:	  case FFI_TYPE_SINT16:	    if (n_gpr < MAX_GPRARGS)	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;	    else	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;	    break;	  case FFI_TYPE_UINT8:	  case FFI_TYPE_SINT8:	    if (n_gpr < MAX_GPRARGS)	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;	    else	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;	    break; 	  default:	    FFI_ASSERT (0);	    break;        }      /* If this is a struct passed via pointer, we need to	 actually retrieve that pointer.  */      if (deref_struct_pointer)	*p_arg = *(void **)*p_arg;    }  /* Call the target function.  */  (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);  /* Convert the return value.  */  switch (closure->cif->rtype->type)    {      /* Void is easy, and so is struct.  */      case FFI_TYPE_VOID:      case FFI_TYPE_STRUCT:	break;      /* Floating point values are returned in fpr 0.  */      case FFI_TYPE_FLOAT:	p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;	break;      case FFI_TYPE_DOUBLE:	p_fpr[0] = *(unsigned long long *) rvalue;	break;      /* Integer values are returned in gpr 2 (and gpr 3	 for 64-bit values on 31-bit machines).  */      case FFI_TYPE_UINT64:      case FFI_TYPE_SINT64:#ifdef __s390x__	p_gpr[0] = *(unsigned long *) rvalue;#else	p_gpr[0] = ((unsigned long *) rvalue)[0],	p_gpr[1] = ((unsigned long *) rvalue)[1];#endif	break;      case FFI_TYPE_POINTER:      case FFI_TYPE_UINT32:      case FFI_TYPE_UINT16:      case FFI_TYPE_UINT8:	p_gpr[0] = *(unsigned long *) rvalue;	break;      case FFI_TYPE_INT:      case FFI_TYPE_SINT32:      case FFI_TYPE_SINT16:      case FFI_TYPE_SINT8:	p_gpr[0] = *(signed long *) rvalue;	break;      default:        FFI_ASSERT (0);        break;    }} /*======================== End of Routine ============================*//*====================================================================*//*                                                                    *//* Name     - ffi_prep_closure.                                       *//*                                                                    *//* Function - Prepare a FFI closure.                                  *//*                                                                    *//*====================================================================*/ ffi_statusffi_prep_closure (ffi_closure *closure,                  ffi_cif *cif,                  void (*fun) (ffi_cif *, void *, void **, void *),                  void *user_data){  FFI_ASSERT (cif->abi == FFI_SYSV);#ifndef __s390x__  *(short *)&closure->tramp [0] = 0x0d10;   /* basr %r1,0 */  *(short *)&closure->tramp [2] = 0x9801;   /* lm %r0,%r1,6(%r1) */  *(short *)&closure->tramp [4] = 0x1006;  *(short *)&closure->tramp [6] = 0x07f1;   /* br %r1 */  *(long  *)&closure->tramp [8] = (long)closure;  *(long  *)&closure->tramp[12] = (long)&ffi_closure_SYSV;#else  *(short *)&closure->tramp [0] = 0x0d10;   /* basr %r1,0 */  *(short *)&closure->tramp [2] = 0xeb01;   /* lmg %r0,%r1,14(%r1) */  *(short *)&closure->tramp [4] = 0x100e;  *(short *)&closure->tramp [6] = 0x0004;  *(short *)&closure->tramp [8] = 0x07f1;   /* br %r1 */  *(long  *)&closure->tramp[16] = (long)closure;  *(long  *)&closure->tramp[24] = (long)&ffi_closure_SYSV;#endif    closure->cif = cif;  closure->user_data = user_data;  closure->fun = fun;   return FFI_OK;}/*======================== End of Routine ============================*/ 

⌨️ 快捷键说明

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