LCOV - code coverage report
Current view: top level - js/src/ctypes/libffi/src - prep_cif.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 48 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -----------------------------------------------------------------------
       2             :    prep_cif.c - Copyright (c) 2011, 2012  Anthony Green
       3             :                 Copyright (c) 1996, 1998, 2007  Red Hat, Inc.
       4             : 
       5             :    Permission is hereby granted, free of charge, to any person obtaining
       6             :    a copy of this software and associated documentation files (the
       7             :    ``Software''), to deal in the Software without restriction, including
       8             :    without limitation the rights to use, copy, modify, merge, publish,
       9             :    distribute, sublicense, and/or sell copies of the Software, and to
      10             :    permit persons to whom the Software is furnished to do so, subject to
      11             :    the following conditions:
      12             : 
      13             :    The above copyright notice and this permission notice shall be included
      14             :    in all copies or substantial portions of the Software.
      15             : 
      16             :    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
      17             :    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      18             :    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      19             :    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      20             :    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      21             :    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      22             :    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      23             :    DEALINGS IN THE SOFTWARE.
      24             :    ----------------------------------------------------------------------- */
      25             : 
      26             : #include <ffi.h>
      27             : #include <ffi_common.h>
      28             : #include <stdlib.h>
      29             : 
      30             : /* Round up to FFI_SIZEOF_ARG. */
      31             : 
      32             : #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
      33             : 
      34             : /* Perform machine independent initialization of aggregate type
      35             :    specifications. */
      36             : 
      37           0 : static ffi_status initialize_aggregate(ffi_type *arg)
      38             : {
      39             :   ffi_type **ptr;
      40             : 
      41           0 :   if (UNLIKELY(arg == NULL || arg->elements == NULL))
      42           0 :     return FFI_BAD_TYPEDEF;
      43             : 
      44           0 :   arg->size = 0;
      45           0 :   arg->alignment = 0;
      46             : 
      47           0 :   ptr = &(arg->elements[0]);
      48             : 
      49           0 :   if (UNLIKELY(ptr == 0))
      50           0 :     return FFI_BAD_TYPEDEF;
      51             : 
      52           0 :   while ((*ptr) != NULL)
      53             :     {
      54           0 :       if (UNLIKELY(((*ptr)->size == 0)
      55             :                     && (initialize_aggregate((*ptr)) != FFI_OK)))
      56           0 :         return FFI_BAD_TYPEDEF;
      57             : 
      58             :       /* Perform a sanity check on the argument type */
      59           0 :       FFI_ASSERT_VALID_TYPE(*ptr);
      60             : 
      61           0 :       arg->size = ALIGN(arg->size, (*ptr)->alignment);
      62           0 :       arg->size += (*ptr)->size;
      63             : 
      64           0 :       arg->alignment = (arg->alignment > (*ptr)->alignment) ?
      65           0 :         arg->alignment : (*ptr)->alignment;
      66             : 
      67           0 :       ptr++;
      68             :     }
      69             : 
      70             :   /* Structure size includes tail padding.  This is important for
      71             :      structures that fit in one register on ABIs like the PowerPC64
      72             :      Linux ABI that right justify small structs in a register.
      73             :      It's also needed for nested structure layout, for example
      74             :      struct A { long a; char b; }; struct B { struct A x; char y; };
      75             :      should find y at an offset of 2*sizeof(long) and result in a
      76             :      total size of 3*sizeof(long).  */
      77           0 :   arg->size = ALIGN (arg->size, arg->alignment);
      78             : 
      79             :   /* On some targets, the ABI defines that structures have an additional
      80             :      alignment beyond the "natural" one based on their elements.  */
      81             : #ifdef FFI_AGGREGATE_ALIGNMENT
      82             :   if (FFI_AGGREGATE_ALIGNMENT > arg->alignment)
      83             :     arg->alignment = FFI_AGGREGATE_ALIGNMENT;
      84             : #endif
      85             : 
      86           0 :   if (arg->size == 0)
      87           0 :     return FFI_BAD_TYPEDEF;
      88             :   else
      89           0 :     return FFI_OK;
      90             : }
      91             : 
      92             : #ifndef __CRIS__
      93             : /* The CRIS ABI specifies structure elements to have byte
      94             :    alignment only, so it completely overrides this functions,
      95             :    which assumes "natural" alignment and padding.  */
      96             : 
      97             : /* Perform machine independent ffi_cif preparation, then call
      98             :    machine dependent routine. */
      99             : 
     100             : /* For non variadic functions isvariadic should be 0 and
     101             :    nfixedargs==ntotalargs.
     102             : 
     103             :    For variadic calls, isvariadic should be 1 and nfixedargs
     104             :    and ntotalargs set as appropriate. nfixedargs must always be >=1 */
     105             : 
     106             : 
     107           0 : ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
     108             :                              unsigned int isvariadic,
     109             :                              unsigned int nfixedargs,
     110             :                              unsigned int ntotalargs,
     111             :                              ffi_type *rtype, ffi_type **atypes)
     112             : {
     113           0 :   unsigned bytes = 0;
     114             :   unsigned int i;
     115             :   ffi_type **ptr;
     116             : 
     117           0 :   FFI_ASSERT(cif != NULL);
     118           0 :   FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
     119           0 :   FFI_ASSERT(nfixedargs <= ntotalargs);
     120             : 
     121           0 :   if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
     122           0 :     return FFI_BAD_ABI;
     123             : 
     124           0 :   cif->abi = abi;
     125           0 :   cif->arg_types = atypes;
     126           0 :   cif->nargs = ntotalargs;
     127           0 :   cif->rtype = rtype;
     128             : 
     129           0 :   cif->flags = 0;
     130             : 
     131             : #if HAVE_LONG_DOUBLE_VARIANT
     132             :   ffi_prep_types (abi);
     133             : #endif
     134             : 
     135             :   /* Initialize the return type if necessary */
     136           0 :   if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
     137           0 :     return FFI_BAD_TYPEDEF;
     138             : 
     139             :   /* Perform a sanity check on the return type */
     140           0 :   FFI_ASSERT_VALID_TYPE(cif->rtype);
     141             : 
     142             :   /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
     143             : #if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA
     144             :   /* Make space for the return structure pointer */
     145             :   if (cif->rtype->type == FFI_TYPE_STRUCT
     146             : #ifdef SPARC
     147             :       && (cif->abi != FFI_V9 || cif->rtype->size > 32)
     148             : #endif
     149             : #ifdef TILE
     150             :       && (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
     151             : #endif
     152             : #ifdef XTENSA
     153             :       && (cif->rtype->size > 16)
     154             : #endif
     155             : #ifdef NIOS2
     156             :       && (cif->rtype->size > 8)
     157             : #endif
     158             :      )
     159             :     bytes = STACK_ARG_SIZE(sizeof(void*));
     160             : #endif
     161             : 
     162           0 :   for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
     163             :     {
     164             : 
     165             :       /* Initialize any uninitialized aggregate type definitions */
     166           0 :       if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
     167           0 :         return FFI_BAD_TYPEDEF;
     168             : 
     169             :       /* Perform a sanity check on the argument type, do this
     170             :          check after the initialization.  */
     171           0 :       FFI_ASSERT_VALID_TYPE(*ptr);
     172             : 
     173             : #if !defined X86_ANY && !defined S390 && !defined PA
     174             : #ifdef SPARC
     175             :       if (((*ptr)->type == FFI_TYPE_STRUCT
     176             :            && ((*ptr)->size > 16 || cif->abi != FFI_V9))
     177             :           || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
     178             :               && cif->abi != FFI_V9))
     179             :         bytes += sizeof(void*);
     180             :       else
     181             : #endif
     182             :         {
     183             :           /* Add any padding if necessary */
     184             :           if (((*ptr)->alignment - 1) & bytes)
     185             :             bytes = (unsigned)ALIGN(bytes, (*ptr)->alignment);
     186             : 
     187             : #ifdef TILE
     188             :           if (bytes < 10 * FFI_SIZEOF_ARG &&
     189             :               bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG)
     190             :             {
     191             :               /* An argument is never split between the 10 parameter
     192             :                  registers and the stack.  */
     193             :               bytes = 10 * FFI_SIZEOF_ARG;
     194             :             }
     195             : #endif
     196             : #ifdef XTENSA
     197             :           if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4)
     198             :             bytes = 6*4;
     199             : #endif
     200             : 
     201             :           bytes += STACK_ARG_SIZE((*ptr)->size);
     202             :         }
     203             : #endif
     204             :     }
     205             : 
     206           0 :   cif->bytes = bytes;
     207             : 
     208             :   /* Perform machine dependent cif processing */
     209             : #ifdef FFI_TARGET_SPECIFIC_VARIADIC
     210             :   if (isvariadic)
     211             :         return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs);
     212             : #endif
     213             : 
     214           0 :   return ffi_prep_cif_machdep(cif);
     215             : }
     216             : #endif /* not __CRIS__ */
     217             : 
     218           0 : ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
     219             :                              ffi_type *rtype, ffi_type **atypes)
     220             : {
     221           0 :   return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes);
     222             : }
     223             : 
     224           0 : ffi_status ffi_prep_cif_var(ffi_cif *cif,
     225             :                             ffi_abi abi,
     226             :                             unsigned int nfixedargs,
     227             :                             unsigned int ntotalargs,
     228             :                             ffi_type *rtype,
     229             :                             ffi_type **atypes)
     230             : {
     231           0 :   return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes);
     232             : }
     233             : 
     234             : #if FFI_CLOSURES
     235             : 
     236             : ffi_status
     237           0 : ffi_prep_closure (ffi_closure* closure,
     238             :                   ffi_cif* cif,
     239             :                   void (*fun)(ffi_cif*,void*,void**,void*),
     240             :                   void *user_data)
     241             : {
     242           0 :   return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
     243             : }
     244             : 
     245             : #endif

Generated by: LCOV version 1.13