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

📄 ffi.c

📁 linux下编程用 编译软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	  for (m = 0; m < n; m++)	    cif->flags += FFI_TYPE_INT << (2 * j++);	  break;	}    }#else  for (i = j = 0; i < cif->nargs && j < 4; i++)    {      size = (cif->arg_types)[i]->size;      n = (size + sizeof (int) - 1) / sizeof (int);      if (greg >= NGREGARG)	continue;      else if (greg + n - 1 >= NGREGARG)	n = NGREGARG - greg;      greg += n;      for (m = 0; m < n; m++)        cif->flags += FFI_TYPE_INT << (2 * j++);    }#endif  /* Set the return type flag */  switch (cif->rtype->type)    {    case FFI_TYPE_STRUCT:      cif->flags += (unsigned) (return_type (cif->rtype)) << 24;      break;    case FFI_TYPE_VOID:    case FFI_TYPE_FLOAT:    case FFI_TYPE_DOUBLE:    case FFI_TYPE_SINT64:    case FFI_TYPE_UINT64:      cif->flags += (unsigned) cif->rtype->type << 24;      break;    default:      cif->flags += FFI_TYPE_INT << 24;      break;    }  return FFI_OK;}/*@-declundef@*//*@-exportheader@*/extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 			  /*@out@*/ extended_cif *, 			  unsigned, unsigned, 			  /*@out@*/ unsigned *, 			  void (*fn)());/*@=declundef@*//*@=exportheader@*/void ffi_call(/*@dependent@*/ ffi_cif *cif, 	      void (*fn)(), 	      /*@out@*/ void *rvalue, 	      /*@dependent@*/ void **avalue){  extended_cif ecif;  UINT64 trvalue;  ecif.cif = cif;  ecif.avalue = avalue;    /* If the return value is a struct and we don't have a return	*/  /* value address then we need to make one		        */  if (cif->rtype->type == FFI_TYPE_STRUCT      && return_type (cif->rtype) != FFI_TYPE_STRUCT)    ecif.rvalue = &trvalue;  else if ((rvalue == NULL) &&       (cif->rtype->type == FFI_TYPE_STRUCT))    {      /*@-sysunrecog@*/      ecif.rvalue = alloca(cif->rtype->size);      /*@=sysunrecog@*/    }  else    ecif.rvalue = rvalue;  switch (cif->abi)     {    case FFI_SYSV:      /*@-usedef@*/      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 		    cif->flags, ecif.rvalue, fn);      /*@=usedef@*/      break;    default:      FFI_ASSERT(0);      break;    }  if (rvalue      && cif->rtype->type == FFI_TYPE_STRUCT      && return_type (cif->rtype) != FFI_TYPE_STRUCT)    memcpy (rvalue, &trvalue, cif->rtype->size);}extern void ffi_closure_SYSV (void);#if defined(__SH4__)extern void __ic_invalidate (void *line);#endifffi_statusffi_prep_closure (ffi_closure* closure,		  ffi_cif* cif,		  void (*fun)(ffi_cif*, void*, void**, void*),		  void *user_data){  unsigned int *tramp;  unsigned short insn;  FFI_ASSERT (cif->abi == FFI_GCC_SYSV);  tramp = (unsigned int *) &closure->tramp[0];  /* Set T bit if the function returns a struct pointed with R2.  */  insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT	  ? 0x0018 /* sett */	  : 0x0008 /* clrt */);#ifdef __LITTLE_ENDIAN__  tramp[0] = 0xd301d102;  tramp[1] = 0x0000412b | (insn << 16);#else  tramp[0] = 0xd102d301;  tramp[1] = 0x412b0000 | insn;#endif  *(void **) &tramp[2] = (void *)closure;          /* ctx */  *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */  closure->cif = cif;  closure->fun = fun;  closure->user_data = user_data;#if defined(__SH4__)  /* Flush the icache.  */  __ic_invalidate(&closure->tramp[0]);#endif  return FFI_OK;}/* Basically the trampoline invokes ffi_closure_SYSV, and on  * entry, r3 holds the address of the closure. * After storing the registers that could possibly contain * parameters to be passed into the stack frame and setting * up space for a return value, ffi_closure_SYSV invokes the  * following helper function to do most of the work. */#ifdef __LITTLE_ENDIAN__#define OFS_INT8	0#define OFS_INT16	0#else#define OFS_INT8	3#define OFS_INT16	2#endifintffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, 			 unsigned long *pgr, unsigned long *pfr, 			 unsigned long *pst){  void **avalue;  ffi_type **p_arg;  int i, avn;  int ireg, greg = 0;#if defined(__SH4__)  int freg = 0;#endif  ffi_cif *cif;   double temp;   cif = closure->cif;  avalue = alloca(cif->nargs * sizeof(void *));  /* Copy the caller's structure return value address so that the closure     returns the data directly to the caller.  */  if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)    {      rvalue = *pgr++;      ireg = 1;    }  else    ireg = 0;  cif = closure->cif;  greg = ireg;  avn = cif->nargs;  /* Grab the addresses of the arguments from the stack frame.  */  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)    {      size_t z;      z = (*p_arg)->size;      if (z < sizeof(int))	{	  if (greg++ >= NGREGARG)	    continue;	  z = sizeof(int);	  switch ((*p_arg)->type)	    {	    case FFI_TYPE_SINT8:	    case FFI_TYPE_UINT8:	      avalue[i] = (((char *)pgr) + OFS_INT8);	      break;  	    case FFI_TYPE_SINT16:	    case FFI_TYPE_UINT16:	      avalue[i] = (((char *)pgr) + OFS_INT16);	      break;  	    case FFI_TYPE_STRUCT:	      avalue[i] = pgr;	      break;	    default:	      FFI_ASSERT(0);	    }	  pgr++;	}      else if (z == sizeof(int))	{#if defined(__SH4__)	  if ((*p_arg)->type == FFI_TYPE_FLOAT)	    {	      if (freg++ >= NFREGARG)		continue;	      avalue[i] = pfr;	      pfr++;	    }	  else#endif	    {	      if (greg++ >= NGREGARG)		continue;	      avalue[i] = pgr;	      pgr++;	    }	}#if defined(__SH4__)      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)	{	  if (freg + 1 >= NFREGARG)	    continue;	  freg = (freg + 1) & ~1;	  freg += 2;	  avalue[i] = pfr;	  pfr += 2;	}#endif      else	{	  int n = (z + sizeof (int) - 1) / sizeof (int);#if defined(__SH4__)	  if (greg + n - 1 >= NGREGARG)	    continue;#else	  if (greg >= NGREGARG)	    continue;#endif	  greg += n;	  avalue[i] = pgr;	  pgr += n;	}    }  greg = ireg;#if defined(__SH4__)  freg = 0;#endif  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)    {      size_t z;      z = (*p_arg)->size;      if (z < sizeof(int))	{	  if (greg++ < NGREGARG)	    continue;	  z = sizeof(int);	  switch ((*p_arg)->type)	    {	    case FFI_TYPE_SINT8:	    case FFI_TYPE_UINT8:	      avalue[i] = (((char *)pst) + OFS_INT8);	      break;  	    case FFI_TYPE_SINT16:	    case FFI_TYPE_UINT16:	      avalue[i] = (((char *)pst) + OFS_INT16);	      break;  	    case FFI_TYPE_STRUCT:	      avalue[i] = pst;	      break;	    default:	      FFI_ASSERT(0);	    }	  pst++;	}      else if (z == sizeof(int))	{#if defined(__SH4__)	  if ((*p_arg)->type == FFI_TYPE_FLOAT)	    {	      if (freg++ < NFREGARG)		continue;	    }	  else#endif	    {	      if (greg++ < NGREGARG)		continue;	    }	  avalue[i] = pst;	  pst++;	}#if defined(__SH4__)      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)	{	  if (freg + 1 < NFREGARG)	    {	      freg = (freg + 1) & ~1;	      freg += 2;	      continue;	    }	  avalue[i] = pst;	  pst += 2;	}#endif      else	{	  int n = (z + sizeof (int) - 1) / sizeof (int);	  if (greg + n - 1 < NGREGARG)	    {	      greg += n;	      continue;	    }#if (! defined(__SH4__))	  else if (greg < NGREGARG)	    {	      greg += n;	      pst += greg - NGREGARG;	      continue;	    }#endif	  avalue[i] = pst;	  pst += n;	}    }  (closure->fun) (cif, rvalue, avalue, closure->user_data);  /* Tell ffi_closure_SYSV how to perform return type promotions.  */  return return_type (cif->rtype);}

⌨️ 快捷键说明

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