~ubuntu-branches/ubuntu/saucy/mozjs17/saucy-proposed

« back to all changes in this revision

Viewing changes to js/src/ctypes/libffi/src/raw_api.c

  • Committer: Package Import Robot
  • Author(s): Rico Tzschichholz
  • Date: 2013-05-25 12:24:23 UTC
  • Revision ID: package-import@ubuntu.com-20130525122423-zmxucrhtensw90xy
Tags: upstream-17.0.0
ImportĀ upstreamĀ versionĀ 17.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -----------------------------------------------------------------------
 
2
   raw_api.c - Copyright (c) 1999, 2008  Red Hat, Inc.
 
3
 
 
4
   Author: Kresten Krab Thorup <krab@gnu.org>
 
5
 
 
6
   Permission is hereby granted, free of charge, to any person obtaining
 
7
   a copy of this software and associated documentation files (the
 
8
   ``Software''), to deal in the Software without restriction, including
 
9
   without limitation the rights to use, copy, modify, merge, publish,
 
10
   distribute, sublicense, and/or sell copies of the Software, and to
 
11
   permit persons to whom the Software is furnished to do so, subject to
 
12
   the following conditions:
 
13
 
 
14
   The above copyright notice and this permission notice shall be included
 
15
   in all copies or substantial portions of the Software.
 
16
 
 
17
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
 
18
   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
19
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
20
   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 
21
   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
22
   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
23
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
24
   DEALINGS IN THE SOFTWARE.
 
25
   ----------------------------------------------------------------------- */
 
26
 
 
27
/* This file defines generic functions for use with the raw api. */
 
28
 
 
29
#include <ffi.h>
 
30
#include <ffi_common.h>
 
31
 
 
32
#if !FFI_NO_RAW_API
 
33
 
 
34
size_t
 
35
ffi_raw_size (ffi_cif *cif)
 
36
{
 
37
  size_t result = 0;
 
38
  int i;
 
39
 
 
40
  ffi_type **at = cif->arg_types;
 
41
 
 
42
  for (i = cif->nargs-1; i >= 0; i--, at++)
 
43
    {
 
44
#if !FFI_NO_STRUCTS
 
45
      if ((*at)->type == FFI_TYPE_STRUCT)
 
46
        result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
 
47
      else
 
48
#endif
 
49
        result += ALIGN ((*at)->size, FFI_SIZEOF_ARG);
 
50
    }
 
51
 
 
52
  return result;
 
53
}
 
54
 
 
55
 
 
56
void
 
57
ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
 
58
{
 
59
  unsigned i;
 
60
  ffi_type **tp = cif->arg_types;
 
61
 
 
62
#if WORDS_BIGENDIAN
 
63
 
 
64
  for (i = 0; i < cif->nargs; i++, tp++, args++)
 
65
    {     
 
66
      switch ((*tp)->type)
 
67
        {
 
68
        case FFI_TYPE_UINT8:
 
69
        case FFI_TYPE_SINT8:
 
70
          *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1);
 
71
          break;
 
72
          
 
73
        case FFI_TYPE_UINT16:
 
74
        case FFI_TYPE_SINT16:
 
75
          *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2);
 
76
          break;
 
77
 
 
78
#if FFI_SIZEOF_ARG >= 4   
 
79
        case FFI_TYPE_UINT32:
 
80
        case FFI_TYPE_SINT32:
 
81
          *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4);
 
82
          break;
 
83
#endif
 
84
        
 
85
#if !FFI_NO_STRUCTS  
 
86
        case FFI_TYPE_STRUCT:
 
87
          *args = (raw++)->ptr;
 
88
          break;
 
89
#endif
 
90
 
 
91
        case FFI_TYPE_POINTER:
 
92
          *args = (void*) &(raw++)->ptr;
 
93
          break;
 
94
          
 
95
        default:
 
96
          *args = raw;
 
97
          raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 
98
        }
 
99
    }
 
100
 
 
101
#else /* WORDS_BIGENDIAN */
 
102
 
 
103
#if !PDP
 
104
 
 
105
  /* then assume little endian */
 
106
  for (i = 0; i < cif->nargs; i++, tp++, args++)
 
107
    {     
 
108
#if !FFI_NO_STRUCTS
 
109
      if ((*tp)->type == FFI_TYPE_STRUCT)
 
110
        {
 
111
          *args = (raw++)->ptr;
 
112
        }
 
113
      else
 
114
#endif
 
115
        {
 
116
          *args = (void*) raw;
 
117
          raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
 
118
        }
 
119
    }
 
120
 
 
121
#else
 
122
#error "pdp endian not supported"
 
123
#endif /* ! PDP */
 
124
 
 
125
#endif /* WORDS_BIGENDIAN */
 
126
}
 
127
 
 
128
void
 
129
ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
 
130
{
 
131
  unsigned i;
 
132
  ffi_type **tp = cif->arg_types;
 
133
 
 
134
  for (i = 0; i < cif->nargs; i++, tp++, args++)
 
135
    {     
 
136
      switch ((*tp)->type)
 
137
        {
 
138
        case FFI_TYPE_UINT8:
 
139
          (raw++)->uint = *(UINT8*) (*args);
 
140
          break;
 
141
 
 
142
        case FFI_TYPE_SINT8:
 
143
          (raw++)->sint = *(SINT8*) (*args);
 
144
          break;
 
145
 
 
146
        case FFI_TYPE_UINT16:
 
147
          (raw++)->uint = *(UINT16*) (*args);
 
148
          break;
 
149
 
 
150
        case FFI_TYPE_SINT16:
 
151
          (raw++)->sint = *(SINT16*) (*args);
 
152
          break;
 
153
 
 
154
#if FFI_SIZEOF_ARG >= 4
 
155
        case FFI_TYPE_UINT32:
 
156
          (raw++)->uint = *(UINT32*) (*args);
 
157
          break;
 
158
 
 
159
        case FFI_TYPE_SINT32:
 
160
          (raw++)->sint = *(SINT32*) (*args);
 
161
          break;
 
162
#endif
 
163
 
 
164
#if !FFI_NO_STRUCTS
 
165
        case FFI_TYPE_STRUCT:
 
166
          (raw++)->ptr = *args;
 
167
          break;
 
168
#endif
 
169
 
 
170
        case FFI_TYPE_POINTER:
 
171
          (raw++)->ptr = **(void***) args;
 
172
          break;
 
173
 
 
174
        default:
 
175
          memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
 
176
          raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 
177
        }
 
178
    }
 
179
}
 
180
 
 
181
#if !FFI_NATIVE_RAW_API
 
182
 
 
183
 
 
184
/* This is a generic definition of ffi_raw_call, to be used if the
 
185
 * native system does not provide a machine-specific implementation.
 
186
 * Having this, allows code to be written for the raw API, without
 
187
 * the need for system-specific code to handle input in that format;
 
188
 * these following couple of functions will handle the translation forth
 
189
 * and back automatically. */
 
190
 
 
191
void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)
 
192
{
 
193
  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
 
194
  ffi_raw_to_ptrarray (cif, raw, avalue);
 
195
  ffi_call (cif, fn, rvalue, avalue);
 
196
}
 
197
 
 
198
#if FFI_CLOSURES                /* base system provides closures */
 
199
 
 
200
static void
 
201
ffi_translate_args (ffi_cif *cif, void *rvalue,
 
202
                    void **avalue, void *user_data)
 
203
{
 
204
  ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));
 
205
  ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
 
206
 
 
207
  ffi_ptrarray_to_raw (cif, avalue, raw);
 
208
  (*cl->fun) (cif, rvalue, raw, cl->user_data);
 
209
}
 
210
 
 
211
ffi_status
 
212
ffi_prep_raw_closure_loc (ffi_raw_closure* cl,
 
213
                          ffi_cif *cif,
 
214
                          void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
 
215
                          void *user_data,
 
216
                          void *codeloc)
 
217
{
 
218
  ffi_status status;
 
219
 
 
220
  status = ffi_prep_closure_loc ((ffi_closure*) cl,
 
221
                                 cif,
 
222
                                 &ffi_translate_args,
 
223
                                 codeloc,
 
224
                                 codeloc);
 
225
  if (status == FFI_OK)
 
226
    {
 
227
      cl->fun       = fun;
 
228
      cl->user_data = user_data;
 
229
    }
 
230
 
 
231
  return status;
 
232
}
 
233
 
 
234
#endif /* FFI_CLOSURES */
 
235
#endif /* !FFI_NATIVE_RAW_API */
 
236
 
 
237
#if FFI_CLOSURES
 
238
 
 
239
/* Again, here is the generic version of ffi_prep_raw_closure, which
 
240
 * will install an intermediate "hub" for translation of arguments from
 
241
 * the pointer-array format, to the raw format */
 
242
 
 
243
ffi_status
 
244
ffi_prep_raw_closure (ffi_raw_closure* cl,
 
245
                      ffi_cif *cif,
 
246
                      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
 
247
                      void *user_data)
 
248
{
 
249
  return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);
 
250
}
 
251
 
 
252
#endif /* FFI_CLOSURES */
 
253
 
 
254
#endif /* !FFI_NO_RAW_API */