Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
ffi.c
Go to the documentation of this file.
1 /* -----------------------------------------------------------------------
2  ffi.c - Copyright (c) 2011, 2013 Anthony Green
3  Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.
4 
5  SPARC Foreign Function Interface
6 
7  Permission is hereby granted, free of charge, to any person obtaining
8  a copy of this software and associated documentation files (the
9  ``Software''), to deal in the Software without restriction, including
10  without limitation the rights to use, copy, modify, merge, publish,
11  distribute, sublicense, and/or sell copies of the Software, and to
12  permit persons to whom the Software is furnished to do so, subject to
13  the following conditions:
14 
15  The above copyright notice and this permission notice shall be included
16  in all copies or substantial portions of the Software.
17 
18  THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  DEALINGS IN THE SOFTWARE.
26  ----------------------------------------------------------------------- */
27 
28 #include <ffi.h>
29 #include <ffi_common.h>
30 
31 #include <stdlib.h>
32 
33 
34 /* ffi_prep_args is called by the assembly routine once stack space
35  has been allocated for the function's arguments */
36 
37 void ffi_prep_args_v8(char *stack, extended_cif *ecif)
38 {
39  int i;
40  void **p_argv;
41  char *argp;
42  ffi_type **p_arg;
43 
44  /* Skip 16 words for the window save area */
45  argp = stack + 16*sizeof(int);
46 
47  /* This should only really be done when we are returning a structure,
48  however, it's faster just to do it all the time...
49 
50  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
51  *(int *) argp = (long)ecif->rvalue;
52 
53  /* And 1 word for the structure return value. */
54  argp += sizeof(int);
55 
56 #ifdef USING_PURIFY
57  /* Purify will probably complain in our assembly routine, unless we
58  zero out this memory. */
59 
60  ((int*)argp)[0] = 0;
61  ((int*)argp)[1] = 0;
62  ((int*)argp)[2] = 0;
63  ((int*)argp)[3] = 0;
64  ((int*)argp)[4] = 0;
65  ((int*)argp)[5] = 0;
66 #endif
67 
68  p_argv = ecif->avalue;
69 
70  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
71  {
72  size_t z;
73 
74  if ((*p_arg)->type == FFI_TYPE_STRUCT
75 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
76  || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
77 #endif
78  )
79  {
80  *(unsigned int *) argp = (unsigned long)(* p_argv);
81  z = sizeof(int);
82  }
83  else
84  {
85  z = (*p_arg)->size;
86  if (z < sizeof(int))
87  {
88  z = sizeof(int);
89  switch ((*p_arg)->type)
90  {
91  case FFI_TYPE_SINT8:
92  *(signed int *) argp = *(SINT8 *)(* p_argv);
93  break;
94 
95  case FFI_TYPE_UINT8:
96  *(unsigned int *) argp = *(UINT8 *)(* p_argv);
97  break;
98 
99  case FFI_TYPE_SINT16:
100  *(signed int *) argp = *(SINT16 *)(* p_argv);
101  break;
102 
103  case FFI_TYPE_UINT16:
104  *(unsigned int *) argp = *(UINT16 *)(* p_argv);
105  break;
106 
107  default:
108  FFI_ASSERT(0);
109  }
110  }
111  else
112  {
113  memcpy(argp, *p_argv, z);
114  }
115  }
116  p_argv++;
117  argp += z;
118  }
119 
120  return;
121 }
122 
123 int ffi_prep_args_v9(char *stack, extended_cif *ecif)
124 {
125  int i, ret = 0;
126  int tmp;
127  void **p_argv;
128  char *argp;
129  ffi_type **p_arg;
130 
131  tmp = 0;
132 
133  /* Skip 16 words for the window save area */
134  argp = stack + 16*sizeof(long long);
135 
136 #ifdef USING_PURIFY
137  /* Purify will probably complain in our assembly routine, unless we
138  zero out this memory. */
139 
140  ((long long*)argp)[0] = 0;
141  ((long long*)argp)[1] = 0;
142  ((long long*)argp)[2] = 0;
143  ((long long*)argp)[3] = 0;
144  ((long long*)argp)[4] = 0;
145  ((long long*)argp)[5] = 0;
146 #endif
147 
148  p_argv = ecif->avalue;
149 
150  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
151  ecif->cif->rtype->size > 32)
152  {
153  *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
154  argp += sizeof(long long);
155  tmp = 1;
156  }
157 
158  for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
159  i++, p_arg++)
160  {
161  size_t z;
162 
163  z = (*p_arg)->size;
164  switch ((*p_arg)->type)
165  {
166  case FFI_TYPE_STRUCT:
167  if (z > 16)
168  {
169  /* For structures larger than 16 bytes we pass reference. */
170  *(unsigned long long *) argp = (unsigned long)* p_argv;
171  argp += sizeof(long long);
172  tmp++;
173  p_argv++;
174  continue;
175  }
176  /* FALLTHROUGH */
177  case FFI_TYPE_FLOAT:
178  case FFI_TYPE_DOUBLE:
179 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
180  case FFI_TYPE_LONGDOUBLE:
181 #endif
182  ret = 1; /* We should promote into FP regs as well as integer. */
183  break;
184  }
185  if (z < sizeof(long long))
186  {
187  switch ((*p_arg)->type)
188  {
189  case FFI_TYPE_SINT8:
190  *(signed long long *) argp = *(SINT8 *)(* p_argv);
191  break;
192 
193  case FFI_TYPE_UINT8:
194  *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
195  break;
196 
197  case FFI_TYPE_SINT16:
198  *(signed long long *) argp = *(SINT16 *)(* p_argv);
199  break;
200 
201  case FFI_TYPE_UINT16:
202  *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
203  break;
204 
205  case FFI_TYPE_SINT32:
206  *(signed long long *) argp = *(SINT32 *)(* p_argv);
207  break;
208 
209  case FFI_TYPE_UINT32:
210  *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
211  break;
212 
213  case FFI_TYPE_FLOAT:
214  *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
215  break;
216 
217  case FFI_TYPE_STRUCT:
218  memcpy(argp, *p_argv, z);
219  break;
220 
221  default:
222  FFI_ASSERT(0);
223  }
224  z = sizeof(long long);
225  tmp++;
226  }
227  else if (z == sizeof(long long))
228  {
229  memcpy(argp, *p_argv, z);
230  z = sizeof(long long);
231  tmp++;
232  }
233  else
234  {
235  if ((tmp & 1) && (*p_arg)->alignment > 8)
236  {
237  tmp++;
238  argp += sizeof(long long);
239  }
240  memcpy(argp, *p_argv, z);
241  z = 2 * sizeof(long long);
242  tmp += 2;
243  }
244  p_argv++;
245  argp += z;
246  }
247 
248  return ret;
249 }
250 
251 /* Perform machine dependent cif processing */
252 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
253 {
254  int wordsize;
255 
256  if (cif->abi != FFI_V9)
257  {
258  wordsize = 4;
259 
260  /* If we are returning a struct, this will already have been added.
261  Otherwise we need to add it because it's always got to be there! */
262 
263  if (cif->rtype->type != FFI_TYPE_STRUCT)
264  cif->bytes += wordsize;
265 
266  /* sparc call frames require that space is allocated for 6 args,
267  even if they aren't used. Make that space if necessary. */
268 
269  if (cif->bytes < 4*6+4)
270  cif->bytes = 4*6+4;
271  }
272  else
273  {
274  wordsize = 8;
275 
276  /* sparc call frames require that space is allocated for 6 args,
277  even if they aren't used. Make that space if necessary. */
278 
279  if (cif->bytes < 8*6)
280  cif->bytes = 8*6;
281  }
282 
283  /* Adjust cif->bytes. to include 16 words for the window save area,
284  and maybe the struct/union return pointer area, */
285 
286  cif->bytes += 16 * wordsize;
287 
288  /* The stack must be 2 word aligned, so round bytes up
289  appropriately. */
290 
291  cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
292 
293  /* Set the return type flag */
294  switch (cif->rtype->type)
295  {
296  case FFI_TYPE_VOID:
297  case FFI_TYPE_FLOAT:
298  case FFI_TYPE_DOUBLE:
299 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
300  case FFI_TYPE_LONGDOUBLE:
301 #endif
302  cif->flags = cif->rtype->type;
303  break;
304 
305  case FFI_TYPE_STRUCT:
306  if (cif->abi == FFI_V9 && cif->rtype->size > 32)
307  cif->flags = FFI_TYPE_VOID;
308  else
309  cif->flags = FFI_TYPE_STRUCT;
310  break;
311 
312  case FFI_TYPE_SINT8:
313  case FFI_TYPE_UINT8:
314  case FFI_TYPE_SINT16:
315  case FFI_TYPE_UINT16:
316  if (cif->abi == FFI_V9)
317  cif->flags = FFI_TYPE_INT;
318  else
319  cif->flags = cif->rtype->type;
320  break;
321 
322  case FFI_TYPE_SINT64:
323  case FFI_TYPE_UINT64:
324  if (cif->abi == FFI_V9)
325  cif->flags = FFI_TYPE_INT;
326  else
327  cif->flags = FFI_TYPE_SINT64;
328  break;
329 
330  default:
331  cif->flags = FFI_TYPE_INT;
332  break;
333  }
334  return FFI_OK;
335 }
336 
337 int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
338 {
339  ffi_type **ptr = &arg->elements[0];
340 
341  while (*ptr != NULL)
342  {
343  if (off & ((*ptr)->alignment - 1))
344  off = ALIGN(off, (*ptr)->alignment);
345 
346  switch ((*ptr)->type)
347  {
348  case FFI_TYPE_STRUCT:
349  off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt);
350  off = ALIGN(off, FFI_SIZEOF_ARG);
351  break;
352  case FFI_TYPE_FLOAT:
353  case FFI_TYPE_DOUBLE:
354 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
355  case FFI_TYPE_LONGDOUBLE:
356 #endif
357  memmove(ret + off, flt + off, (*ptr)->size);
358  off += (*ptr)->size;
359  break;
360  default:
361  memmove(ret + off, intg + off, (*ptr)->size);
362  off += (*ptr)->size;
363  break;
364  }
365  ptr++;
366  }
367  return off;
368 }
369 
370 
371 #ifdef SPARC64
372 extern int ffi_call_v9(void *, extended_cif *, unsigned,
373  unsigned, unsigned *, void (*fn)(void));
374 #else
375 extern int ffi_call_v8(void *, extended_cif *, unsigned,
376  unsigned, unsigned *, void (*fn)(void));
377 #endif
378 
379 #ifndef __GNUC__
380 void ffi_flush_icache (void *, size_t);
381 #endif
382 
383 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
384 {
385  extended_cif ecif;
386  void *rval = rvalue;
387 
388  ecif.cif = cif;
389  ecif.avalue = avalue;
390 
391  /* If the return value is a struct and we don't have a return */
392  /* value address then we need to make one */
393 
394  ecif.rvalue = rvalue;
395  if (cif->rtype->type == FFI_TYPE_STRUCT)
396  {
397  if (cif->rtype->size <= 32)
398  rval = alloca(64);
399  else
400  {
401  rval = NULL;
402  if (rvalue == NULL)
403  ecif.rvalue = alloca(cif->rtype->size);
404  }
405  }
406 
407  switch (cif->abi)
408  {
409  case FFI_V8:
410 #ifdef SPARC64
411  /* We don't yet support calling 32bit code from 64bit */
412  FFI_ASSERT(0);
413 #else
414  if (rvalue && (cif->rtype->type == FFI_TYPE_STRUCT
415 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
416  || cif->flags == FFI_TYPE_LONGDOUBLE
417 #endif
418  ))
419  {
420  /* For v8, we need an "unimp" with size of returning struct */
421  /* behind "call", so we alloc some executable space for it. */
422  /* l7 is used, we need to make sure v8.S doesn't use %l7. */
423  unsigned int *call_struct = NULL;
424  ffi_closure_alloc(32, (void **)&call_struct);
425  if (call_struct)
426  {
427  unsigned long f = (unsigned long)fn;
428  call_struct[0] = 0xae10001f; /* mov %i7, %l7 */
429  call_struct[1] = 0xbe10000f; /* mov %o7, %i7 */
430  call_struct[2] = 0x03000000 | f >> 10; /* sethi %hi(fn), %g1 */
431  call_struct[3] = 0x9fc06000 | (f & 0x3ff); /* jmp %g1+%lo(fn), %o7 */
432  call_struct[4] = 0x01000000; /* nop */
433  if (cif->rtype->size < 0x7f)
434  call_struct[5] = cif->rtype->size; /* unimp */
435  else
436  call_struct[5] = 0x01000000; /* nop */
437  call_struct[6] = 0x81c7e008; /* ret */
438  call_struct[7] = 0xbe100017; /* mov %l7, %i7 */
439 #ifdef __GNUC__
440  asm volatile ("iflush %0; iflush %0+8; iflush %0+16; iflush %0+24" : :
441  "r" (call_struct) : "memory");
442  /* SPARC v8 requires 5 instructions for flush to be visible */
443  asm volatile ("nop; nop; nop; nop; nop");
444 #else
445  ffi_flush_icache (call_struct, 32);
446 #endif
447  ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
448  cif->flags, rvalue, call_struct);
449  ffi_closure_free(call_struct);
450  }
451  else
452  {
453  ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
454  cif->flags, rvalue, fn);
455  }
456  }
457  else
458  {
459  ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
460  cif->flags, rvalue, fn);
461  }
462 #endif
463  break;
464  case FFI_V9:
465 #ifdef SPARC64
466  ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
467  cif->flags, rval, fn);
468  if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
469  ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
470 #else
471  /* And vice versa */
472  FFI_ASSERT(0);
473 #endif
474  break;
475  default:
476  FFI_ASSERT(0);
477  break;
478  }
479 }
480 
481 
482 #ifdef SPARC64
483 extern void ffi_closure_v9(void);
484 #else
485 extern void ffi_closure_v8(void);
486 #endif
487 
488 ffi_status
489 ffi_prep_closure_loc (ffi_closure* closure,
490  ffi_cif* cif,
491  void (*fun)(ffi_cif*, void*, void**, void*),
492  void *user_data,
493  void *codeloc)
494 {
495  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
496  unsigned long fn;
497 #ifdef SPARC64
498  /* Trampoline address is equal to the closure address. We take advantage
499  of that to reduce the trampoline size by 8 bytes. */
500  if (cif->abi != FFI_V9)
501  return FFI_BAD_ABI;
502  fn = (unsigned long) ffi_closure_v9;
503  tramp[0] = 0x83414000; /* rd %pc, %g1 */
504  tramp[1] = 0xca586010; /* ldx [%g1+16], %g5 */
505  tramp[2] = 0x81c14000; /* jmp %g5 */
506  tramp[3] = 0x01000000; /* nop */
507  *((unsigned long *) &tramp[4]) = fn;
508 #else
509  unsigned long ctx = (unsigned long) codeloc;
510  if (cif->abi != FFI_V8)
511  return FFI_BAD_ABI;
512  fn = (unsigned long) ffi_closure_v8;
513  tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */
514  tramp[1] = 0x05000000 | ctx >> 10; /* sethi %hi(ctx), %g2 */
515  tramp[2] = 0x81c06000 | (fn & 0x3ff); /* jmp %g1+%lo(fn) */
516  tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or %g2, %lo(ctx) */
517 #endif
518 
519  closure->cif = cif;
520  closure->fun = fun;
521  closure->user_data = user_data;
522 
523  /* Flush the Icache. closure is 8 bytes aligned. */
524 #ifdef __GNUC__
525 #ifdef SPARC64
526  asm volatile ("flush %0; flush %0+8" : : "r" (closure) : "memory");
527 #else
528  asm volatile ("iflush %0; iflush %0+8" : : "r" (closure) : "memory");
529  /* SPARC v8 requires 5 instructions for flush to be visible */
530  asm volatile ("nop; nop; nop; nop; nop");
531 #endif
532 #else
533  ffi_flush_icache (closure, 16);
534 #endif
535 
536  return FFI_OK;
537 }
538 
539 int
540 ffi_closure_sparc_inner_v8(ffi_closure *closure,
541  void *rvalue, unsigned long *gpr, unsigned long *scratch)
542 {
543  ffi_cif *cif;
544  ffi_type **arg_types;
545  void **avalue;
546  int i, argn;
547 
548  cif = closure->cif;
549  arg_types = cif->arg_types;
550  avalue = alloca(cif->nargs * sizeof(void *));
551 
552  /* Copy the caller's structure return address so that the closure
553  returns the data directly to the caller. */
554  if (cif->flags == FFI_TYPE_STRUCT
555 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
556  || cif->flags == FFI_TYPE_LONGDOUBLE
557 #endif
558  )
559  rvalue = (void *) gpr[0];
560 
561  /* Always skip the structure return address. */
562  argn = 1;
563 
564  /* Grab the addresses of the arguments from the stack frame. */
565  for (i = 0; i < cif->nargs; i++)
566  {
567  if (arg_types[i]->type == FFI_TYPE_STRUCT
568 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
569  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
570 #endif
571  )
572  {
573  /* Straight copy of invisible reference. */
574  avalue[i] = (void *)gpr[argn++];
575  }
576  else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
577  || arg_types[i]->type == FFI_TYPE_SINT64
578  || arg_types[i]->type == FFI_TYPE_UINT64)
579  /* gpr is 8-byte aligned. */
580  && (argn % 2) != 0)
581  {
582  /* Align on a 8-byte boundary. */
583  scratch[0] = gpr[argn];
584  scratch[1] = gpr[argn+1];
585  avalue[i] = scratch;
586  scratch -= 2;
587  argn += 2;
588  }
589  else
590  {
591  /* Always right-justify. */
592  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
593  avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
594  }
595  }
596 
597  /* Invoke the closure. */
598  (closure->fun) (cif, rvalue, avalue, closure->user_data);
599 
600  /* Tell ffi_closure_sparc how to perform return type promotions. */
601  return cif->rtype->type;
602 }
603 
604 int
605 ffi_closure_sparc_inner_v9(ffi_closure *closure,
606  void *rvalue, unsigned long *gpr, double *fpr)
607 {
608  ffi_cif *cif;
609  ffi_type **arg_types;
610  void **avalue;
611  int i, argn, fp_slot_max;
612 
613  cif = closure->cif;
614  arg_types = cif->arg_types;
615  avalue = alloca(cif->nargs * sizeof(void *));
616 
617  /* Copy the caller's structure return address so that the closure
618  returns the data directly to the caller. */
619  if (cif->flags == FFI_TYPE_VOID
620  && cif->rtype->type == FFI_TYPE_STRUCT)
621  {
622  rvalue = (void *) gpr[0];
623  /* Skip the structure return address. */
624  argn = 1;
625  }
626  else
627  argn = 0;
628 
629  fp_slot_max = 16 - argn;
630 
631  /* Grab the addresses of the arguments from the stack frame. */
632  for (i = 0; i < cif->nargs; i++)
633  {
634  if (arg_types[i]->type == FFI_TYPE_STRUCT)
635  {
636  if (arg_types[i]->size > 16)
637  {
638  /* Straight copy of invisible reference. */
639  avalue[i] = (void *)gpr[argn++];
640  }
641  else
642  {
643  /* Left-justify. */
644  ffi_v9_layout_struct(arg_types[i],
645  0,
646  (char *) &gpr[argn],
647  (char *) &gpr[argn],
648  (char *) &fpr[argn]);
649  avalue[i] = &gpr[argn];
650  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
651  }
652  }
653  else
654  {
655  /* Right-justify. */
656  argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
657 
658  /* Align on a 16-byte boundary. */
659 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
660  if (arg_types[i]->type == FFI_TYPE_LONGDOUBLE && (argn % 2) != 0)
661  argn++;
662 #endif
663  if (i < fp_slot_max
664  && (arg_types[i]->type == FFI_TYPE_FLOAT
665  || arg_types[i]->type == FFI_TYPE_DOUBLE
666 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
667  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
668 #endif
669  ))
670  avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
671  else
672  avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
673  }
674  }
675 
676  /* Invoke the closure. */
677  (closure->fun) (cif, rvalue, avalue, closure->user_data);
678 
679  /* Tell ffi_closure_sparc how to perform return type promotions. */
680  return cif->rtype->type;
681 }
FFI_ASSERT
#define FFI_ASSERT(x)
Definition: ffi_common.h:72
FLOAT32
float FLOAT32
Definition: ffi_common.h:120
ffi_closure_sparc_inner_v9
int ffi_closure_sparc_inner_v9(ffi_closure *closure, void *rvalue, unsigned long *gpr, double *fpr)
Definition: ffi.c:605
ffi_closure_sparc_inner_v8
int ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue, unsigned long *gpr, unsigned long *scratch)
Definition: ffi.c:540
FFI_TYPE_LONGDOUBLE
#define FFI_TYPE_LONGDOUBLE
Definition: ffi.c:40
FFI_SIZEOF_ARG
#define FFI_SIZEOF_ARG
Definition: ffitarget.h:77
ffi_call_v8
int ffi_call_v8(void *, extended_cif *, unsigned, unsigned, unsigned *, void(*fn)(void))
extended_cif::rvalue
void * rvalue
Definition: ffi_common.h:89
ffi_prep_args_v8
void ffi_prep_args_v8(char *stack, extended_cif *ecif)
Definition: ffi.c:37
ffi_common.h
FFI_V9
@ FFI_V9
Definition: ffitarget.h:51
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
ptr
struct RIMemo * ptr
Definition: debug.c:74
ALIGN
#define ALIGN(v, a)
Definition: ffi_common.h:77
NULL
#define NULL
Definition: _sdbm.c:101
FFI_V8
@ FFI_V8
Definition: ffitarget.h:49
if
if((ID)(DISPID) nameid !=nameid)
Definition: win32ole.c:357
memcpy
void * memcpy(void *__restrict, const void *__restrict, size_t)
memmove
#define memmove(dst, src, len)
Definition: rb_mjit_min_header-2.7.0.h:2848
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
ffi_prep_args_v9
int ffi_prep_args_v9(char *stack, extended_cif *ecif)
Definition: ffi.c:123
long
#define long
Definition: rb_mjit_min_header-2.7.0.h:2880
alloca
#define alloca(size)
Definition: rb_mjit_min_header-2.7.0.h:2487
size
int size
Definition: encoding.c:58
ffi_prep_cif_machdep
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
Definition: ffi.c:758
extended_cif
Definition: ffi_common.h:86
ffi_v9_layout_struct
int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
Definition: ffi.c:337
ffi_flush_icache
void ffi_flush_icache(void *, size_t)
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
f
#define f
extended_cif::avalue
void ** avalue
Definition: ffi_common.h:90
ffi_call
void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
Definition: ffi.c:813
ffi_prep_closure_loc
ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc)
Definition: ffi.c:928
extended_cif::cif
ffi_cif * cif
Definition: ffi_common.h:88
ffi_closure_v8
void ffi_closure_v8(void)
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39